Merge pull request #342 from Blizzard/update-curl
Update to Curl 7.45.0
This commit is contained in:
commit
760859825b
55
contrib/curl/include/README
Normal file
55
contrib/curl/include/README
Normal file
@ -0,0 +1,55 @@
|
||||
_ _ ____ _
|
||||
___| | | | _ \| |
|
||||
/ __| | | | |_) | |
|
||||
| (__| |_| | _ <| |___
|
||||
\___|\___/|_| \_\_____|
|
||||
|
||||
Include files for libcurl, external users.
|
||||
|
||||
They're all placed in the curl subdirectory here for better fit in any kind
|
||||
of environment. You must include files from here using...
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
||||
... style and point the compiler's include path to the directory holding the
|
||||
curl subdirectory. It makes it more likely to survive future modifications.
|
||||
|
||||
NOTE FOR LIBCURL HACKERS
|
||||
|
||||
The following notes apply to libcurl version 7.19.0 and later.
|
||||
|
||||
* The distributed curl/curlbuild.h file is only intended to be used on systems
|
||||
which can not run the also distributed configure script.
|
||||
|
||||
* The distributed curlbuild.h file is generated as a copy of curlbuild.h.dist
|
||||
when the libcurl source code distribution archive file is originally created.
|
||||
|
||||
* If you check out from git on a non-configure platform, you must run the
|
||||
appropriate buildconf* script to set up curlbuild.h and other local files
|
||||
before being able of compiling the library.
|
||||
|
||||
* On systems capable of running the configure script, the configure process
|
||||
will overwrite the distributed include/curl/curlbuild.h file with one that
|
||||
is suitable and specific to the library being configured and built, which
|
||||
is generated from the include/curl/curlbuild.h.in template file.
|
||||
|
||||
* If you intend to distribute an already compiled libcurl library you _MUST_
|
||||
also distribute along with it the generated curl/curlbuild.h which has been
|
||||
used to compile it. Otherwise the library will be of no use for the users of
|
||||
the library that you have built. It is _your_ responsibility to provide this
|
||||
file. No one at the cURL project can know how you have built the library.
|
||||
|
||||
* File curl/curlbuild.h includes platform and configuration dependent info,
|
||||
and must not be modified by anyone. Configure script generates it for you.
|
||||
|
||||
* We cannot assume anything else but very basic compiler features being
|
||||
present. While libcurl requires an ANSI C compiler to build, some of the
|
||||
earlier ANSI compilers clearly can't deal with some preprocessor operators.
|
||||
|
||||
* Newlines must remain unix-style for older compilers' sake.
|
||||
|
||||
* Comments must be written in the old-style /* unnested C-fashion */
|
||||
|
||||
To figure out how to do good and portable checks for features, operating
|
||||
systems or specific hardwarare, a very good resource is Bjorn Reese's
|
||||
collection at http://predef.sf.net/
|
@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -521,6 +521,9 @@ typedef enum {
|
||||
CURLE_CHUNK_FAILED, /* 88 - chunk callback reported error */
|
||||
CURLE_NO_CONNECTION_AVAILABLE, /* 89 - No connection available, the
|
||||
session will be queued */
|
||||
CURLE_SSL_PINNEDPUBKEYNOTMATCH, /* 90 - specified pinned public key did not
|
||||
match */
|
||||
CURLE_SSL_INVALIDCERTSTATUS, /* 91 - invalid certificate status */
|
||||
CURL_LAST /* never use! */
|
||||
} CURLcode;
|
||||
|
||||
@ -722,6 +725,10 @@ typedef enum {
|
||||
servers, a user can this way allow the vulnerability back. */
|
||||
#define CURLSSLOPT_ALLOW_BEAST (1<<0)
|
||||
|
||||
/* - NO_REVOKE tells libcurl to disable certificate revocation checks for those
|
||||
SSL backends where such behavior is present. */
|
||||
#define CURLSSLOPT_NO_REVOKE (1<<1)
|
||||
|
||||
#ifndef CURL_NO_OLDIES /* define this to test if your app builds with all
|
||||
the obsolete stuff removed! */
|
||||
|
||||
@ -803,6 +810,8 @@ typedef enum {
|
||||
#define CURLPROTO_RTMPS (1<<23)
|
||||
#define CURLPROTO_RTMPTS (1<<24)
|
||||
#define CURLPROTO_GOPHER (1<<25)
|
||||
#define CURLPROTO_SMB (1<<26)
|
||||
#define CURLPROTO_SMBS (1<<27)
|
||||
#define CURLPROTO_ALL (~0) /* enable everything */
|
||||
|
||||
/* long may be 32 or 64 bits, but we should never depend on anything else
|
||||
@ -985,7 +994,7 @@ typedef enum {
|
||||
CINIT(HEADER, LONG, 42), /* throw the header out too */
|
||||
CINIT(NOPROGRESS, LONG, 43), /* shut off the progress meter */
|
||||
CINIT(NOBODY, LONG, 44), /* use HEAD to get http document */
|
||||
CINIT(FAILONERROR, LONG, 45), /* no output on http error codes >= 300 */
|
||||
CINIT(FAILONERROR, LONG, 45), /* no output on http error codes >= 400 */
|
||||
CINIT(UPLOAD, LONG, 46), /* this is an upload */
|
||||
CINIT(POST, LONG, 47), /* HTTP POST method */
|
||||
CINIT(DIRLISTONLY, LONG, 48), /* bare names when listing directories */
|
||||
@ -1611,6 +1620,34 @@ typedef enum {
|
||||
/* Pass in a bitmask of "header options" */
|
||||
CINIT(HEADEROPT, LONG, 229),
|
||||
|
||||
/* The public key in DER form used to validate the peer public key
|
||||
this option is used only if SSL_VERIFYPEER is true */
|
||||
CINIT(PINNEDPUBLICKEY, OBJECTPOINT, 230),
|
||||
|
||||
/* Path to Unix domain socket */
|
||||
CINIT(UNIX_SOCKET_PATH, OBJECTPOINT, 231),
|
||||
|
||||
/* Set if we should verify the certificate status. */
|
||||
CINIT(SSL_VERIFYSTATUS, LONG, 232),
|
||||
|
||||
/* Set if we should enable TLS false start. */
|
||||
CINIT(SSL_FALSESTART, LONG, 233),
|
||||
|
||||
/* Do not squash dot-dot sequences */
|
||||
CINIT(PATH_AS_IS, LONG, 234),
|
||||
|
||||
/* Proxy Service Name */
|
||||
CINIT(PROXY_SERVICE_NAME, OBJECTPOINT, 235),
|
||||
|
||||
/* Service Name */
|
||||
CINIT(SERVICE_NAME, OBJECTPOINT, 236),
|
||||
|
||||
/* Wait/don't wait for pipe/mutex to clarify */
|
||||
CINIT(PIPEWAIT, LONG, 237),
|
||||
|
||||
/* Set the protocol used when curl is given a URL without a protocol */
|
||||
CINIT(DEFAULT_PROTOCOL, OBJECTPOINT, 238),
|
||||
|
||||
CURLOPT_LASTENTRY /* the last unused */
|
||||
} CURLoption;
|
||||
|
||||
@ -1647,8 +1684,8 @@ typedef enum {
|
||||
option might be handy to force libcurl to use a specific IP version. */
|
||||
#define CURL_IPRESOLVE_WHATEVER 0 /* default, resolves addresses to all IP
|
||||
versions that your system allows */
|
||||
#define CURL_IPRESOLVE_V4 1 /* resolve to ipv4 addresses */
|
||||
#define CURL_IPRESOLVE_V6 2 /* resolve to ipv6 addresses */
|
||||
#define CURL_IPRESOLVE_V4 1 /* resolve to IPv4 addresses */
|
||||
#define CURL_IPRESOLVE_V6 2 /* resolve to IPv6 addresses */
|
||||
|
||||
/* three convenient "aliases" that follow the name scheme better */
|
||||
#define CURLOPT_RTSPHEADER CURLOPT_HTTPHEADER
|
||||
@ -1665,6 +1702,11 @@ enum {
|
||||
CURL_HTTP_VERSION_LAST /* *ILLEGAL* http version */
|
||||
};
|
||||
|
||||
/* Convenience definition simple because the name of the version is HTTP/2 and
|
||||
not 2.0. The 2_0 version of the enum name was set while the version was
|
||||
still planned to be 2.0 and we stick to it for compatibility. */
|
||||
#define CURL_HTTP_VERSION_2 CURL_HTTP_VERSION_2_0
|
||||
|
||||
/*
|
||||
* Public API enums for RTSP requests
|
||||
*/
|
||||
@ -2028,7 +2070,7 @@ typedef enum {
|
||||
CURLSSLBACKEND_OPENSSL = 1,
|
||||
CURLSSLBACKEND_GNUTLS = 2,
|
||||
CURLSSLBACKEND_NSS = 3,
|
||||
CURLSSLBACKEND_QSOSSL = 4,
|
||||
CURLSSLBACKEND_OBSOLETE4 = 4, /* Was QSOSSL. */
|
||||
CURLSSLBACKEND_GSKIT = 5,
|
||||
CURLSSLBACKEND_POLARSSL = 6,
|
||||
CURLSSLBACKEND_CYASSL = 7,
|
||||
@ -2049,6 +2091,7 @@ struct curl_tlssessioninfo {
|
||||
#define CURLINFO_LONG 0x200000
|
||||
#define CURLINFO_DOUBLE 0x300000
|
||||
#define CURLINFO_SLIST 0x400000
|
||||
#define CURLINFO_SOCKET 0x500000
|
||||
#define CURLINFO_MASK 0x0fffff
|
||||
#define CURLINFO_TYPEMASK 0xf00000
|
||||
|
||||
@ -2097,9 +2140,10 @@ typedef enum {
|
||||
CURLINFO_LOCAL_IP = CURLINFO_STRING + 41,
|
||||
CURLINFO_LOCAL_PORT = CURLINFO_LONG + 42,
|
||||
CURLINFO_TLS_SESSION = CURLINFO_SLIST + 43,
|
||||
CURLINFO_ACTIVESOCKET = CURLINFO_SOCKET + 44,
|
||||
/* Fill in new entries below here! */
|
||||
|
||||
CURLINFO_LASTONE = 43
|
||||
CURLINFO_LASTONE = 44
|
||||
} CURLINFO;
|
||||
|
||||
/* CURLINFO_RESPONSE_CODE is the new name for the option previously known as
|
||||
@ -2236,24 +2280,29 @@ typedef struct {
|
||||
} curl_version_info_data;
|
||||
|
||||
#define CURL_VERSION_IPV6 (1<<0) /* IPv6-enabled */
|
||||
#define CURL_VERSION_KERBEROS4 (1<<1) /* kerberos auth is supported */
|
||||
#define CURL_VERSION_KERBEROS4 (1<<1) /* Kerberos V4 auth is supported
|
||||
(deprecated) */
|
||||
#define CURL_VERSION_SSL (1<<2) /* SSL options are present */
|
||||
#define CURL_VERSION_LIBZ (1<<3) /* libz features are present */
|
||||
#define CURL_VERSION_NTLM (1<<4) /* NTLM auth is supported */
|
||||
#define CURL_VERSION_GSSNEGOTIATE (1<<5) /* Negotiate auth support
|
||||
#define CURL_VERSION_GSSNEGOTIATE (1<<5) /* Negotiate auth is supported
|
||||
(deprecated) */
|
||||
#define CURL_VERSION_DEBUG (1<<6) /* built with debug capabilities */
|
||||
#define CURL_VERSION_ASYNCHDNS (1<<7) /* asynchronous dns resolves */
|
||||
#define CURL_VERSION_DEBUG (1<<6) /* Built with debug capabilities */
|
||||
#define CURL_VERSION_ASYNCHDNS (1<<7) /* Asynchronous DNS resolves */
|
||||
#define CURL_VERSION_SPNEGO (1<<8) /* SPNEGO auth is supported */
|
||||
#define CURL_VERSION_LARGEFILE (1<<9) /* supports files bigger than 2GB */
|
||||
#define CURL_VERSION_IDN (1<<10) /* International Domain Names support */
|
||||
#define CURL_VERSION_SSPI (1<<11) /* SSPI is supported */
|
||||
#define CURL_VERSION_CONV (1<<12) /* character conversions supported */
|
||||
#define CURL_VERSION_CURLDEBUG (1<<13) /* debug memory tracking supported */
|
||||
#define CURL_VERSION_LARGEFILE (1<<9) /* Supports files larger than 2GB */
|
||||
#define CURL_VERSION_IDN (1<<10) /* Internationized Domain Names are
|
||||
supported */
|
||||
#define CURL_VERSION_SSPI (1<<11) /* Built against Windows SSPI */
|
||||
#define CURL_VERSION_CONV (1<<12) /* Character conversions supported */
|
||||
#define CURL_VERSION_CURLDEBUG (1<<13) /* Debug memory tracking supported */
|
||||
#define CURL_VERSION_TLSAUTH_SRP (1<<14) /* TLS-SRP auth is supported */
|
||||
#define CURL_VERSION_NTLM_WB (1<<15) /* NTLM delegating to winbind helper */
|
||||
#define CURL_VERSION_NTLM_WB (1<<15) /* NTLM delegation to winbind helper
|
||||
is suported */
|
||||
#define CURL_VERSION_HTTP2 (1<<16) /* HTTP2 support built-in */
|
||||
#define CURL_VERSION_GSSAPI (1<<17) /* GSS-API is supported */
|
||||
#define CURL_VERSION_GSSAPI (1<<17) /* Built against a GSS-API library */
|
||||
#define CURL_VERSION_KERBEROS5 (1<<18) /* Kerberos V5 auth is supported */
|
||||
#define CURL_VERSION_UNIX_SOCKETS (1<<19) /* Unix domain sockets support */
|
||||
|
||||
/*
|
||||
* NAME curl_version_info()
|
||||
|
@ -1,693 +0,0 @@
|
||||
#ifndef HEADER_CURL_SETUP_H
|
||||
#define HEADER_CURL_SETUP_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at http://curl.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
/*
|
||||
* Define WIN32 when build target is Win32 API
|
||||
*/
|
||||
|
||||
#if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32) && \
|
||||
!defined(__SYMBIAN32__)
|
||||
#define WIN32
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Include configuration script results or hand-crafted
|
||||
* configuration file for platforms which lack config tool.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
|
||||
#include "curl_config.h"
|
||||
|
||||
#else /* HAVE_CONFIG_H */
|
||||
|
||||
#ifdef _WIN32_WCE
|
||||
# include "config-win32ce.h"
|
||||
#else
|
||||
# ifdef WIN32
|
||||
# include "config-win32.h"
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(macintosh) && defined(__MRC__)
|
||||
# include "config-mac.h"
|
||||
#endif
|
||||
|
||||
#ifdef __riscos__
|
||||
# include "config-riscos.h"
|
||||
#endif
|
||||
|
||||
#ifdef __AMIGA__
|
||||
# include "config-amigaos.h"
|
||||
#endif
|
||||
|
||||
#ifdef __SYMBIAN32__
|
||||
# include "config-symbian.h"
|
||||
#endif
|
||||
|
||||
#ifdef __OS400__
|
||||
# include "config-os400.h"
|
||||
#endif
|
||||
|
||||
#ifdef TPF
|
||||
# include "config-tpf.h"
|
||||
#endif
|
||||
|
||||
#ifdef __VXWORKS__
|
||||
# include "config-vxworks.h"
|
||||
#endif
|
||||
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
/* ================================================================ */
|
||||
/* Definition of preprocessor macros/symbols which modify compiler */
|
||||
/* behavior or generated code characteristics must be done here, */
|
||||
/* as appropriate, before any system header file is included. It is */
|
||||
/* also possible to have them defined in the config file included */
|
||||
/* before this point. As a result of all this we frown inclusion of */
|
||||
/* system header files in our config files, avoid this at any cost. */
|
||||
/* ================================================================ */
|
||||
|
||||
/*
|
||||
* AIX 4.3 and newer needs _THREAD_SAFE defined to build
|
||||
* proper reentrant code. Others may also need it.
|
||||
*/
|
||||
|
||||
#ifdef NEED_THREAD_SAFE
|
||||
# ifndef _THREAD_SAFE
|
||||
# define _THREAD_SAFE
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Tru64 needs _REENTRANT set for a few function prototypes and
|
||||
* things to appear in the system header files. Unixware needs it
|
||||
* to build proper reentrant code. Others may also need it.
|
||||
*/
|
||||
|
||||
#ifdef NEED_REENTRANT
|
||||
# ifndef _REENTRANT
|
||||
# define _REENTRANT
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Solaris needs this to get a POSIX-conformant getpwuid_r */
|
||||
#if defined(sun) || defined(__sun)
|
||||
# ifndef _POSIX_PTHREAD_SEMANTICS
|
||||
# define _POSIX_PTHREAD_SEMANTICS 1
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* ================================================================ */
|
||||
/* If you need to include a system header file for your platform, */
|
||||
/* please, do it beyond the point further indicated in this file. */
|
||||
/* ================================================================ */
|
||||
|
||||
/*
|
||||
* libcurl's external interface definitions are also used internally,
|
||||
* and might also include required system header files to define them.
|
||||
*/
|
||||
|
||||
#include <curl/curlbuild.h>
|
||||
|
||||
/*
|
||||
* Compile time sanity checks must also be done when building the library.
|
||||
*/
|
||||
|
||||
#include <curl/curlrules.h>
|
||||
|
||||
/*
|
||||
* Ensure that no one is using the old SIZEOF_CURL_OFF_T macro
|
||||
*/
|
||||
|
||||
#ifdef SIZEOF_CURL_OFF_T
|
||||
# error "SIZEOF_CURL_OFF_T shall not be defined!"
|
||||
Error Compilation_aborted_SIZEOF_CURL_OFF_T_shall_not_be_defined
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Disable other protocols when http is the only one desired.
|
||||
*/
|
||||
|
||||
#ifdef HTTP_ONLY
|
||||
# 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
|
||||
# ifndef CURL_DISABLE_POP3
|
||||
# define CURL_DISABLE_POP3
|
||||
# endif
|
||||
# ifndef CURL_DISABLE_IMAP
|
||||
# define CURL_DISABLE_IMAP
|
||||
# endif
|
||||
# ifndef CURL_DISABLE_SMTP
|
||||
# define CURL_DISABLE_SMTP
|
||||
# endif
|
||||
# ifndef CURL_DISABLE_RTSP
|
||||
# define CURL_DISABLE_RTSP
|
||||
# endif
|
||||
# ifndef CURL_DISABLE_RTMP
|
||||
# define CURL_DISABLE_RTMP
|
||||
# endif
|
||||
# ifndef CURL_DISABLE_GOPHER
|
||||
# define CURL_DISABLE_GOPHER
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* When http is disabled rtsp is not supported.
|
||||
*/
|
||||
|
||||
#if defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_RTSP)
|
||||
# define CURL_DISABLE_RTSP
|
||||
#endif
|
||||
|
||||
/* ================================================================ */
|
||||
/* No system header file shall be included in this file before this */
|
||||
/* point. The only allowed ones are those included from curlbuild.h */
|
||||
/* ================================================================ */
|
||||
|
||||
/*
|
||||
* OS/400 setup file includes some system headers.
|
||||
*/
|
||||
|
||||
#ifdef __OS400__
|
||||
# include "setup-os400.h"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* VMS setup file includes some system headers.
|
||||
*/
|
||||
|
||||
#ifdef __VMS
|
||||
# include "setup-vms.h"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Include header files for windows builds before redefining anything.
|
||||
* Use this preprocessor block only to include or exclude windows.h,
|
||||
* winsock2.h, ws2tcpip.h or winsock.h. Any other windows thing belongs
|
||||
* to any other further and independent block. Under Cygwin things work
|
||||
* just as under linux (e.g. <sys/socket.h>) and the winsock headers should
|
||||
* never be included when __CYGWIN__ is defined. configure script takes
|
||||
* care of this, not defining HAVE_WINDOWS_H, HAVE_WINSOCK_H, HAVE_WINSOCK2_H,
|
||||
* neither HAVE_WS2TCPIP_H when __CYGWIN__ is defined.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_WINDOWS_H
|
||||
# if defined(UNICODE) && !defined(_UNICODE)
|
||||
# define _UNICODE
|
||||
# endif
|
||||
# if defined(_UNICODE) && !defined(UNICODE)
|
||||
# define UNICODE
|
||||
# endif
|
||||
# ifndef WIN32_LEAN_AND_MEAN
|
||||
# define WIN32_LEAN_AND_MEAN
|
||||
# endif
|
||||
# include <windows.h>
|
||||
# ifdef HAVE_WINSOCK2_H
|
||||
# include <winsock2.h>
|
||||
# ifdef HAVE_WS2TCPIP_H
|
||||
# include <ws2tcpip.h>
|
||||
# endif
|
||||
# else
|
||||
# ifdef HAVE_WINSOCK_H
|
||||
# include <winsock.h>
|
||||
# endif
|
||||
# endif
|
||||
# include <tchar.h>
|
||||
# ifdef UNICODE
|
||||
typedef wchar_t *(*curl_wcsdup_callback)(const wchar_t *str);
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Define USE_WINSOCK to 2 if we have and use WINSOCK2 API, else
|
||||
* define USE_WINSOCK to 1 if we have and use WINSOCK API, else
|
||||
* undefine USE_WINSOCK.
|
||||
*/
|
||||
|
||||
#undef USE_WINSOCK
|
||||
|
||||
#ifdef HAVE_WINSOCK2_H
|
||||
# define USE_WINSOCK 2
|
||||
#else
|
||||
# ifdef HAVE_WINSOCK_H
|
||||
# define USE_WINSOCK 1
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef USE_LWIPSOCK
|
||||
# include <lwip/init.h>
|
||||
# include <lwip/sockets.h>
|
||||
# include <lwip/netdb.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_EXTRA_STRICMP_H
|
||||
# include <extra/stricmp.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_EXTRA_STRDUP_H
|
||||
# include <extra/strdup.h>
|
||||
#endif
|
||||
|
||||
#ifdef TPF
|
||||
# include <strings.h> /* for bzero, strcasecmp, and strncasecmp */
|
||||
# include <string.h> /* for strcpy and strlen */
|
||||
# include <stdlib.h> /* for rand and srand */
|
||||
# include <sys/socket.h> /* for select and ioctl*/
|
||||
# include <netdb.h> /* for in_addr_t definition */
|
||||
# include <tpf/sysapi.h> /* for tpf_process_signals */
|
||||
/* change which select is used for libcurl */
|
||||
# define select(a,b,c,d,e) tpf_select_libcurl(a,b,c,d,e)
|
||||
#endif
|
||||
|
||||
#ifdef __VXWORKS__
|
||||
# include <sockLib.h> /* for generic BSD socket functions */
|
||||
# include <ioLib.h> /* for basic I/O interface functions */
|
||||
#endif
|
||||
|
||||
#ifdef __AMIGA__
|
||||
# ifndef __ixemul__
|
||||
# include <exec/types.h>
|
||||
# include <exec/execbase.h>
|
||||
# include <proto/exec.h>
|
||||
# include <proto/dos.h>
|
||||
# define select(a,b,c,d,e) WaitSelect(a,b,c,d,e,0)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#ifdef HAVE_ASSERT_H
|
||||
#include <assert.h>
|
||||
#endif
|
||||
|
||||
#ifdef __TANDEM /* for nsr-tandem-nsk systems */
|
||||
#include <floss.h>
|
||||
#endif
|
||||
|
||||
#ifndef STDC_HEADERS /* no standard C headers! */
|
||||
#include <curl/stdcheaders.h>
|
||||
#endif
|
||||
|
||||
#ifdef __POCC__
|
||||
# include <sys/types.h>
|
||||
# include <unistd.h>
|
||||
# define sys_nerr EILSEQ
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Salford-C kludge section (mostly borrowed from wxWidgets).
|
||||
*/
|
||||
#ifdef __SALFORDC__
|
||||
#pragma suppress 353 /* Possible nested comments */
|
||||
#pragma suppress 593 /* Define not used */
|
||||
#pragma suppress 61 /* enum has no name */
|
||||
#pragma suppress 106 /* unnamed, unused parameter */
|
||||
#include <clib.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Large file (>2Gb) support using WIN32 functions.
|
||||
*/
|
||||
|
||||
#ifdef USE_WIN32_LARGE_FILES
|
||||
# include <io.h>
|
||||
# include <sys/types.h>
|
||||
# include <sys/stat.h>
|
||||
# undef lseek
|
||||
# define lseek(fdes,offset,whence) _lseeki64(fdes, offset, whence)
|
||||
# undef fstat
|
||||
# define fstat(fdes,stp) _fstati64(fdes, stp)
|
||||
# undef stat
|
||||
# define stat(fname,stp) _stati64(fname, stp)
|
||||
# define struct_stat struct _stati64
|
||||
# define LSEEK_ERROR (__int64)-1
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Small file (<2Gb) support using WIN32 functions.
|
||||
*/
|
||||
|
||||
#ifdef USE_WIN32_SMALL_FILES
|
||||
# include <io.h>
|
||||
# include <sys/types.h>
|
||||
# include <sys/stat.h>
|
||||
# ifndef _WIN32_WCE
|
||||
# undef lseek
|
||||
# define lseek(fdes,offset,whence) _lseek(fdes, (long)offset, whence)
|
||||
# define fstat(fdes,stp) _fstat(fdes, stp)
|
||||
# define stat(fname,stp) _stat(fname, stp)
|
||||
# define struct_stat struct _stat
|
||||
# endif
|
||||
# define LSEEK_ERROR (long)-1
|
||||
#endif
|
||||
|
||||
#ifndef struct_stat
|
||||
# define struct_stat struct stat
|
||||
#endif
|
||||
|
||||
#ifndef LSEEK_ERROR
|
||||
# define LSEEK_ERROR (off_t)-1
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Default sizeof(off_t) in case it hasn't been defined in config file.
|
||||
*/
|
||||
|
||||
#ifndef SIZEOF_OFF_T
|
||||
# if defined(__VMS) && !defined(__VAX)
|
||||
# if defined(_LARGEFILE)
|
||||
# define SIZEOF_OFF_T 8
|
||||
# endif
|
||||
# elif defined(__OS400__) && defined(__ILEC400__)
|
||||
# if defined(_LARGE_FILES)
|
||||
# define SIZEOF_OFF_T 8
|
||||
# endif
|
||||
# elif defined(__MVS__) && defined(__IBMC__)
|
||||
# if defined(_LP64) || defined(_LARGE_FILES)
|
||||
# define SIZEOF_OFF_T 8
|
||||
# endif
|
||||
# elif defined(__370__) && defined(__IBMC__)
|
||||
# if defined(_LP64) || defined(_LARGE_FILES)
|
||||
# define SIZEOF_OFF_T 8
|
||||
# endif
|
||||
# endif
|
||||
# ifndef SIZEOF_OFF_T
|
||||
# define SIZEOF_OFF_T 4
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Arg 2 type for gethostname in case it hasn't been defined in config file.
|
||||
*/
|
||||
|
||||
#ifndef GETHOSTNAME_TYPE_ARG2
|
||||
# ifdef USE_WINSOCK
|
||||
# define GETHOSTNAME_TYPE_ARG2 int
|
||||
# else
|
||||
# define GETHOSTNAME_TYPE_ARG2 size_t
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Below we define some functions. They should
|
||||
|
||||
4. set the SIGALRM signal timeout
|
||||
5. set dir/file naming defines
|
||||
*/
|
||||
|
||||
#ifdef WIN32
|
||||
|
||||
# define DIR_CHAR "\\"
|
||||
# define DOT_CHAR "_"
|
||||
|
||||
#else /* WIN32 */
|
||||
|
||||
# ifdef MSDOS /* Watt-32 */
|
||||
|
||||
# include <sys/ioctl.h>
|
||||
# define select(n,r,w,x,t) select_s(n,r,w,x,t)
|
||||
# define ioctl(x,y,z) ioctlsocket(x,y,(char *)(z))
|
||||
# include <tcp.h>
|
||||
# ifdef word
|
||||
# undef word
|
||||
# endif
|
||||
# ifdef byte
|
||||
# undef byte
|
||||
# endif
|
||||
|
||||
# endif /* MSDOS */
|
||||
|
||||
# ifdef __minix
|
||||
/* Minix 3 versions up to at least 3.1.3 are missing these prototypes */
|
||||
extern char * strtok_r(char *s, const char *delim, char **last);
|
||||
extern struct tm * gmtime_r(const time_t * const timep, struct tm *tmp);
|
||||
# endif
|
||||
|
||||
# define DIR_CHAR "/"
|
||||
# ifndef DOT_CHAR
|
||||
# define DOT_CHAR "."
|
||||
# endif
|
||||
|
||||
# ifdef MSDOS
|
||||
# undef DOT_CHAR
|
||||
# define DOT_CHAR "_"
|
||||
# endif
|
||||
|
||||
# ifndef fileno /* sunos 4 have this as a macro! */
|
||||
int fileno( FILE *stream);
|
||||
# endif
|
||||
|
||||
#endif /* WIN32 */
|
||||
|
||||
/*
|
||||
* msvc 6.0 requires PSDK in order to have INET6_ADDRSTRLEN
|
||||
* defined in ws2tcpip.h as well as to provide IPv6 support.
|
||||
*/
|
||||
|
||||
#if defined(_MSC_VER) && !defined(__POCC__)
|
||||
# if !defined(HAVE_WS2TCPIP_H) || \
|
||||
((_MSC_VER < 1300) && !defined(INET6_ADDRSTRLEN))
|
||||
# undef HAVE_GETADDRINFO_THREADSAFE
|
||||
# undef HAVE_FREEADDRINFO
|
||||
# undef HAVE_GETADDRINFO
|
||||
# undef HAVE_GETNAMEINFO
|
||||
# undef ENABLE_IPV6
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* ---------------------------------------------------------------- */
|
||||
/* resolver specialty compile-time defines */
|
||||
/* CURLRES_* defines to use in the host*.c sources */
|
||||
/* ---------------------------------------------------------------- */
|
||||
|
||||
/*
|
||||
* lcc-win32 doesn't have _beginthreadex(), lacks threads support.
|
||||
*/
|
||||
|
||||
#if defined(__LCC__) && defined(WIN32)
|
||||
# undef USE_THREADS_POSIX
|
||||
# undef USE_THREADS_WIN32
|
||||
#endif
|
||||
|
||||
/*
|
||||
* MSVC threads support requires a multi-threaded runtime library.
|
||||
* _beginthreadex() is not available in single-threaded ones.
|
||||
*/
|
||||
|
||||
#if defined(_MSC_VER) && !defined(__POCC__) && !defined(_MT)
|
||||
# undef USE_THREADS_POSIX
|
||||
# undef USE_THREADS_WIN32
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Mutually exclusive CURLRES_* definitions.
|
||||
*/
|
||||
|
||||
#ifdef USE_ARES
|
||||
# define CURLRES_ASYNCH
|
||||
# define CURLRES_ARES
|
||||
/* now undef the stock libc functions just to avoid them being used */
|
||||
# undef HAVE_GETADDRINFO
|
||||
# undef HAVE_GETHOSTBYNAME
|
||||
#elif defined(USE_THREADS_POSIX) || defined(USE_THREADS_WIN32)
|
||||
# define CURLRES_ASYNCH
|
||||
# define CURLRES_THREADED
|
||||
#else
|
||||
# define CURLRES_SYNCH
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_IPV6
|
||||
# define CURLRES_IPV6
|
||||
#else
|
||||
# define CURLRES_IPV4
|
||||
#endif
|
||||
|
||||
/* ---------------------------------------------------------------- */
|
||||
|
||||
/*
|
||||
* When using WINSOCK, TELNET protocol requires WINSOCK2 API.
|
||||
*/
|
||||
|
||||
#if defined(USE_WINSOCK) && (USE_WINSOCK != 2)
|
||||
# define CURL_DISABLE_TELNET 1
|
||||
#endif
|
||||
|
||||
/*
|
||||
* msvc 6.0 does not have struct sockaddr_storage and
|
||||
* does not define IPPROTO_ESP in winsock2.h. But both
|
||||
* are available if PSDK is properly installed.
|
||||
*/
|
||||
|
||||
#if defined(_MSC_VER) && !defined(__POCC__)
|
||||
# if !defined(HAVE_WINSOCK2_H) || ((_MSC_VER < 1300) && !defined(IPPROTO_ESP))
|
||||
# undef HAVE_STRUCT_SOCKADDR_STORAGE
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Intentionally fail to build when using msvc 6.0 without PSDK installed.
|
||||
* The brave of heart can circumvent this, defining ALLOW_MSVC6_WITHOUT_PSDK
|
||||
* in lib/config-win32.h although absolutely discouraged and unsupported.
|
||||
*/
|
||||
|
||||
#if defined(_MSC_VER) && !defined(__POCC__)
|
||||
# if !defined(HAVE_WINDOWS_H) || ((_MSC_VER < 1300) && !defined(_FILETIME_))
|
||||
# if !defined(ALLOW_MSVC6_WITHOUT_PSDK)
|
||||
# error MSVC 6.0 requires "February 2003 Platform SDK" a.k.a. \
|
||||
"Windows Server 2003 PSDK"
|
||||
# else
|
||||
# define CURL_DISABLE_LDAP 1
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef NETWARE
|
||||
int netware_init(void);
|
||||
#ifndef __NOVELL_LIBC__
|
||||
#include <sys/bsdskt.h>
|
||||
#include <sys/timeval.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_LIBIDN) && defined(HAVE_TLD_H)
|
||||
/* The lib was present and the tld.h header (which is missing in libidn 0.3.X
|
||||
but we only work with libidn 0.4.1 or later) */
|
||||
#define USE_LIBIDN
|
||||
#endif
|
||||
|
||||
#ifndef SIZEOF_TIME_T
|
||||
/* assume default size of time_t to be 32 bit */
|
||||
#define SIZEOF_TIME_T 4
|
||||
#endif
|
||||
|
||||
#define LIBIDN_REQUIRED_VERSION "0.4.1"
|
||||
|
||||
#if defined(USE_GNUTLS) || defined(USE_SSLEAY) || defined(USE_NSS) || \
|
||||
defined(USE_QSOSSL) || defined(USE_POLARSSL) || defined(USE_AXTLS) || \
|
||||
defined(USE_CYASSL) || defined(USE_SCHANNEL) || \
|
||||
defined(USE_DARWINSSL) || defined(USE_GSKIT)
|
||||
#define USE_SSL /* SSL support has been enabled */
|
||||
#endif
|
||||
|
||||
#if !defined(CURL_DISABLE_CRYPTO_AUTH) && \
|
||||
(defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI))
|
||||
#define USE_SPNEGO
|
||||
#endif
|
||||
|
||||
/* Single point where USE_NTLM definition might be done */
|
||||
#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_NTLM) && \
|
||||
!defined(CURL_DISABLE_CRYPTO_AUTH)
|
||||
#if defined(USE_SSLEAY) || defined(USE_WINDOWS_SSPI) || \
|
||||
defined(USE_GNUTLS) || defined(USE_NSS) || defined(USE_DARWINSSL)
|
||||
#define USE_NTLM
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* non-configure builds may define CURL_WANTS_CA_BUNDLE_ENV */
|
||||
#if defined(CURL_WANTS_CA_BUNDLE_ENV) && !defined(CURL_CA_BUNDLE)
|
||||
#define CURL_CA_BUNDLE getenv("CURL_CA_BUNDLE")
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Provide a mechanism to silence picky compilers, such as gcc 4.6+.
|
||||
* Parameters should of course normally not be unused, but for example when
|
||||
* we have multiple implementations of the same interface it may happen.
|
||||
*/
|
||||
|
||||
#if defined(__GNUC__) && ((__GNUC__ >= 3) || \
|
||||
((__GNUC__ == 2) && defined(__GNUC_MINOR__) && (__GNUC_MINOR__ >= 7)))
|
||||
# define UNUSED_PARAM __attribute__((__unused__))
|
||||
#else
|
||||
# define UNUSED_PARAM /*NOTHING*/
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Include macros and defines that should only be processed once.
|
||||
*/
|
||||
|
||||
#ifndef HEADER_CURL_SETUP_ONCE_H
|
||||
#include "curl_setup_once.h"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Definition of our NOP statement Object-like macro
|
||||
*/
|
||||
|
||||
#ifndef Curl_nop_stmt
|
||||
# define Curl_nop_stmt do { } WHILE_FALSE
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Ensure that Winsock and lwIP TCP/IP stacks are not mixed.
|
||||
*/
|
||||
|
||||
#if defined(__LWIP_OPT_H__)
|
||||
# if defined(SOCKET) || \
|
||||
defined(USE_WINSOCK) || \
|
||||
defined(HAVE_WINSOCK_H) || \
|
||||
defined(HAVE_WINSOCK2_H) || \
|
||||
defined(HAVE_WS2TCPIP_H)
|
||||
# error "Winsock and lwIP TCP/IP stack definitions shall not coexist!"
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Portable symbolic names for Winsock shutdown() mode flags.
|
||||
*/
|
||||
|
||||
#ifdef USE_WINSOCK
|
||||
# define SHUT_RD 0x00
|
||||
# define SHUT_WR 0x01
|
||||
# define SHUT_RDWR 0x02
|
||||
#endif
|
||||
|
||||
/* Define S_ISREG if not defined by system headers, f.e. MSVC */
|
||||
#if !defined(S_ISREG) && defined(S_IFMT) && defined(S_IFREG)
|
||||
#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
|
||||
#endif
|
||||
|
||||
/* Define S_ISDIR if not defined by system headers, f.e. MSVC */
|
||||
#if !defined(S_ISDIR) && defined(S_IFMT) && defined(S_IFDIR)
|
||||
#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
|
||||
#endif
|
||||
|
||||
#endif /* HEADER_CURL_SETUP_H */
|
@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -26,16 +26,16 @@
|
||||
a script at release-time. This was made its own header file in 7.11.2 */
|
||||
|
||||
/* This is the global package copyright */
|
||||
#define LIBCURL_COPYRIGHT "1996 - 2014 Daniel Stenberg, <daniel@haxx.se>."
|
||||
#define LIBCURL_COPYRIGHT "1996 - 2015 Daniel Stenberg, <daniel@haxx.se>."
|
||||
|
||||
/* This is the version number of the libcurl package from which this header
|
||||
file origins: */
|
||||
#define LIBCURL_VERSION "7.38.0-20140825"
|
||||
#define LIBCURL_VERSION "7.45.0"
|
||||
|
||||
/* The numeric version number is also available "in parts" by using these
|
||||
defines: */
|
||||
#define LIBCURL_VERSION_MAJOR 7
|
||||
#define LIBCURL_VERSION_MINOR 38
|
||||
#define LIBCURL_VERSION_MINOR 45
|
||||
#define LIBCURL_VERSION_PATCH 0
|
||||
|
||||
/* This is the numeric version of the libcurl version number, meant for easier
|
||||
@ -52,8 +52,12 @@
|
||||
This 6-digit (24 bits) hexadecimal number does not show pre-release number,
|
||||
and it is always a greater number in a more recent release. It makes
|
||||
comparisons with greater than and less than work.
|
||||
|
||||
Note: This define is the full hex number and _does not_ use the
|
||||
CURL_VERSION_BITS() macro since curl's own configure script greps for it
|
||||
and needs it to contain the full number.
|
||||
*/
|
||||
#define LIBCURL_VERSION_NUM 0x072600
|
||||
#define LIBCURL_VERSION_NUM 0x072d00
|
||||
|
||||
/*
|
||||
* This is the date and time when the full source package was created. The
|
||||
@ -64,6 +68,10 @@
|
||||
*
|
||||
* "Mon Feb 12 11:35:33 UTC 2007"
|
||||
*/
|
||||
#define LIBCURL_TIMESTAMP "Mon Aug 25 02:01:35 UTC 2014"
|
||||
#define LIBCURL_TIMESTAMP "ons 7 okt 2015 08:14:10 UTC"
|
||||
|
||||
#define CURL_VERSION_BITS(x,y,z) ((x)<<16|(y)<<8|z)
|
||||
#define CURL_AT_LEAST_VERSION(x,y,z) \
|
||||
(LIBCURL_VERSION_NUM >= CURL_VERSION_BITS(x, y, z))
|
||||
|
||||
#endif /* __CURL_CURLVER_H */
|
||||
|
@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -57,15 +57,8 @@ CURL_EXTERN char *curl_mvaprintf(const char *format, va_list args);
|
||||
# undef vaprintf
|
||||
# define printf curl_mprintf
|
||||
# define fprintf curl_mfprintf
|
||||
#ifdef CURLDEBUG
|
||||
/* When built with CURLDEBUG we define away the sprintf functions since we
|
||||
don't want internal code to be using them */
|
||||
# define sprintf sprintf_was_used
|
||||
# define vsprintf vsprintf_was_used
|
||||
#else
|
||||
# define sprintf curl_msprintf
|
||||
# define vsprintf curl_mvsprintf
|
||||
#endif
|
||||
# define snprintf curl_msnprintf
|
||||
# define vprintf curl_mvprintf
|
||||
# define vfprintf curl_mvfprintf
|
||||
|
@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -74,6 +74,11 @@ typedef enum {
|
||||
curl_multi_perform() and CURLM_CALL_MULTI_PERFORM */
|
||||
#define CURLM_CALL_MULTI_SOCKET CURLM_CALL_MULTI_PERFORM
|
||||
|
||||
/* bitmask bits for CURLMOPT_PIPELINING */
|
||||
#define CURLPIPE_NOTHING 0L
|
||||
#define CURLPIPE_HTTP1 1L
|
||||
#define CURLPIPE_MULTIPLEX 2L
|
||||
|
||||
typedef enum {
|
||||
CURLMSG_NONE, /* first, not used */
|
||||
CURLMSG_DONE, /* This easy handle has completed. 'result' contains
|
||||
@ -365,6 +370,12 @@ typedef enum {
|
||||
/* maximum number of open connections in total */
|
||||
CINIT(MAX_TOTAL_CONNECTIONS, LONG, 13),
|
||||
|
||||
/* This is the server push callback function pointer */
|
||||
CINIT(PUSHFUNCTION, FUNCTIONPOINT, 14),
|
||||
|
||||
/* This is the argument passed to the server push callback */
|
||||
CINIT(PUSHDATA, OBJECTPOINT, 15),
|
||||
|
||||
CURLMOPT_LASTENTRY /* the last unused */
|
||||
} CURLMoption;
|
||||
|
||||
@ -392,6 +403,31 @@ CURL_EXTERN CURLMcode curl_multi_setopt(CURLM *multi_handle,
|
||||
CURL_EXTERN CURLMcode curl_multi_assign(CURLM *multi_handle,
|
||||
curl_socket_t sockfd, void *sockp);
|
||||
|
||||
|
||||
/*
|
||||
* Name: curl_push_callback
|
||||
*
|
||||
* Desc: This callback gets called when a new stream is being pushed by the
|
||||
* server. It approves or denies the new stream.
|
||||
*
|
||||
* Returns: CURL_PUSH_OK or CURL_PUSH_DENY.
|
||||
*/
|
||||
#define CURL_PUSH_OK 0
|
||||
#define CURL_PUSH_DENY 1
|
||||
|
||||
struct curl_pushheaders; /* forward declaration only */
|
||||
|
||||
CURL_EXTERN char *curl_pushheader_bynum(struct curl_pushheaders *h,
|
||||
size_t num);
|
||||
CURL_EXTERN char *curl_pushheader_byname(struct curl_pushheaders *h,
|
||||
const char *name);
|
||||
|
||||
typedef int (*curl_push_callback)(CURL *parent,
|
||||
CURL *easy,
|
||||
size_t num_headers,
|
||||
struct curl_pushheaders *headers,
|
||||
void *userp);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* end of extern "C" */
|
||||
#endif
|
||||
|
@ -270,6 +270,8 @@ _CURL_WARNING(_curl_easy_getinfo_err_curl_slist,
|
||||
(option) == CURLOPT_DNS_LOCAL_IP4 || \
|
||||
(option) == CURLOPT_DNS_LOCAL_IP6 || \
|
||||
(option) == CURLOPT_LOGIN_OPTIONS || \
|
||||
(option) == CURLOPT_PROXY_SERVICE_NAME || \
|
||||
(option) == CURLOPT_SERVICE_NAME || \
|
||||
0)
|
||||
|
||||
/* evaluates to true if option takes a curl_write_callback argument */
|
||||
|
@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -71,7 +71,7 @@ bool Curl_amiga_init()
|
||||
}
|
||||
|
||||
#ifdef __libnix__
|
||||
ADD2EXIT(Curl_amiga_cleanup,-50);
|
||||
ADD2EXIT(Curl_amiga_cleanup, -50);
|
||||
#endif
|
||||
|
||||
#endif /* __AMIGA__ && ! __ixemul__ */
|
||||
|
@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -68,9 +68,7 @@
|
||||
#include "connect.h"
|
||||
#include "select.h"
|
||||
#include "progress.h"
|
||||
|
||||
#define _MPRINTF_REPLACE /* use our functions only */
|
||||
#include <curl/mprintf.h>
|
||||
#include "curl_printf.h"
|
||||
|
||||
# if defined(CURL_STATICLIB) && !defined(CARES_STATICLIB) && \
|
||||
(defined(WIN32) || defined(_WIN32) || defined(__SYMBIAN32__))
|
||||
@ -166,7 +164,7 @@ void Curl_resolver_cleanup(void *resolver)
|
||||
int Curl_resolver_duphandle(void **to, void *from)
|
||||
{
|
||||
/* Clone the ares channel for the new handle */
|
||||
if(ARES_SUCCESS != ares_dup((ares_channel*)to,(ares_channel)from))
|
||||
if(ARES_SUCCESS != ares_dup((ares_channel*)to, (ares_channel)from))
|
||||
return CURLE_FAILED_INIT;
|
||||
return CURLE_OK;
|
||||
}
|
||||
@ -178,7 +176,7 @@ static void destroy_async_data (struct Curl_async *async);
|
||||
*/
|
||||
void Curl_resolver_cancel(struct connectdata *conn)
|
||||
{
|
||||
if(conn && conn->data && conn->data->state.resolver)
|
||||
if(conn->data && conn->data->state.resolver)
|
||||
ares_cancel((ares_channel)conn->data->state.resolver);
|
||||
destroy_async_data(&conn->async);
|
||||
}
|
||||
@ -188,7 +186,6 @@ void Curl_resolver_cancel(struct connectdata *conn)
|
||||
*/
|
||||
static void destroy_async_data (struct Curl_async *async)
|
||||
{
|
||||
if(async->hostname)
|
||||
free(async->hostname);
|
||||
|
||||
if(async->os_specific) {
|
||||
@ -235,7 +232,7 @@ int Curl_resolver_getsock(struct connectdata *conn,
|
||||
milli = (timeout->tv_sec * 1000) + (timeout->tv_usec/1000);
|
||||
if(milli == 0)
|
||||
milli += 10;
|
||||
Curl_expire(conn->data, milli);
|
||||
Curl_expire_latest(conn->data, milli);
|
||||
|
||||
return max;
|
||||
}
|
||||
@ -315,7 +312,7 @@ CURLcode Curl_resolver_is_resolved(struct connectdata *conn,
|
||||
struct SessionHandle *data = conn->data;
|
||||
struct ResolverResults *res = (struct ResolverResults *)
|
||||
conn->async.os_specific;
|
||||
CURLcode rc = CURLE_OK;
|
||||
CURLcode result = CURLE_OK;
|
||||
|
||||
*dns = NULL;
|
||||
|
||||
@ -329,7 +326,7 @@ CURLcode Curl_resolver_is_resolved(struct connectdata *conn,
|
||||
if(!conn->async.dns) {
|
||||
failf(data, "Could not resolve: %s (%s)",
|
||||
conn->async.hostname, ares_strerror(conn->async.status));
|
||||
rc = conn->bits.proxy?CURLE_COULDNT_RESOLVE_PROXY:
|
||||
result = conn->bits.proxy?CURLE_COULDNT_RESOLVE_PROXY:
|
||||
CURLE_COULDNT_RESOLVE_HOST;
|
||||
}
|
||||
else
|
||||
@ -338,7 +335,7 @@ CURLcode Curl_resolver_is_resolved(struct connectdata *conn,
|
||||
destroy_async_data(&conn->async);
|
||||
}
|
||||
|
||||
return rc;
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -355,7 +352,7 @@ CURLcode Curl_resolver_is_resolved(struct connectdata *conn,
|
||||
CURLcode Curl_resolver_wait_resolv(struct connectdata *conn,
|
||||
struct Curl_dns_entry **entry)
|
||||
{
|
||||
CURLcode rc=CURLE_OK;
|
||||
CURLcode result = CURLE_OK;
|
||||
struct SessionHandle *data = conn->data;
|
||||
long timeout;
|
||||
struct timeval now = Curl_tvnow();
|
||||
@ -388,13 +385,13 @@ CURLcode Curl_resolver_wait_resolv(struct connectdata *conn,
|
||||
timeout_ms = 1000;
|
||||
|
||||
waitperform(conn, timeout_ms);
|
||||
Curl_resolver_is_resolved(conn,&temp_entry);
|
||||
Curl_resolver_is_resolved(conn, &temp_entry);
|
||||
|
||||
if(conn->async.done)
|
||||
break;
|
||||
|
||||
if(Curl_pgrsUpdate(conn)) {
|
||||
rc = CURLE_ABORTED_BY_CALLBACK;
|
||||
result = CURLE_ABORTED_BY_CALLBACK;
|
||||
timeout = -1; /* trigger the cancel below */
|
||||
}
|
||||
else {
|
||||
@ -403,6 +400,7 @@ CURLcode Curl_resolver_wait_resolv(struct connectdata *conn,
|
||||
timeout -= timediff?timediff:1; /* always deduct at least 1 */
|
||||
now = now2; /* for next loop */
|
||||
}
|
||||
|
||||
if(timeout < 0) {
|
||||
/* our timeout, so we cancel the ares operation */
|
||||
ares_cancel((ares_channel)data->state.resolver);
|
||||
@ -412,18 +410,17 @@ CURLcode Curl_resolver_wait_resolv(struct connectdata *conn,
|
||||
|
||||
/* Operation complete, if the lookup was successful we now have the entry
|
||||
in the cache. */
|
||||
|
||||
if(entry)
|
||||
*entry = conn->async.dns;
|
||||
|
||||
if(rc)
|
||||
if(result)
|
||||
/* close the connection, since we can't return failure here without
|
||||
cleaning up this connection properly.
|
||||
TODO: remove this action from here, it is not a name resolver decision.
|
||||
*/
|
||||
connclose(conn, "c-ares resolve failed");
|
||||
|
||||
return rc;
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Connects results to the list */
|
||||
@ -536,15 +533,15 @@ Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata *conn,
|
||||
bufp = strdup(hostname);
|
||||
if(bufp) {
|
||||
struct ResolverResults *res = NULL;
|
||||
Curl_safefree(conn->async.hostname);
|
||||
free(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 */
|
||||
res = calloc(sizeof(struct ResolverResults),1);
|
||||
res = calloc(sizeof(struct ResolverResults), 1);
|
||||
if(!res) {
|
||||
Curl_safefree(conn->async.hostname);
|
||||
free(conn->async.hostname);
|
||||
conn->async.hostname = NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -69,11 +69,9 @@
|
||||
#include "inet_ntop.h"
|
||||
#include "curl_threads.h"
|
||||
#include "connect.h"
|
||||
|
||||
#define _MPRINTF_REPLACE /* use our functions only */
|
||||
#include <curl/mprintf.h>
|
||||
|
||||
#include "curl_printf.h"
|
||||
#include "curl_memory.h"
|
||||
|
||||
/* The last #include file should be: */
|
||||
#include "memdebug.h"
|
||||
|
||||
@ -166,6 +164,7 @@ struct thread_sync_data {
|
||||
#ifdef HAVE_GETADDRINFO
|
||||
struct addrinfo hints;
|
||||
#endif
|
||||
struct thread_data *td; /* for thread-self cleanup */
|
||||
};
|
||||
|
||||
struct thread_data {
|
||||
@ -191,24 +190,26 @@ void destroy_thread_sync_data(struct thread_sync_data * tsd)
|
||||
free(tsd->mtx);
|
||||
}
|
||||
|
||||
if(tsd->hostname)
|
||||
free(tsd->hostname);
|
||||
|
||||
if(tsd->res)
|
||||
Curl_freeaddrinfo(tsd->res);
|
||||
|
||||
memset(tsd,0,sizeof(*tsd));
|
||||
memset(tsd, 0, sizeof(*tsd));
|
||||
}
|
||||
|
||||
/* Initialize resolver thread synchronization data */
|
||||
static
|
||||
int init_thread_sync_data(struct thread_sync_data * tsd,
|
||||
int init_thread_sync_data(struct thread_data * td,
|
||||
const char * hostname,
|
||||
int port,
|
||||
const struct addrinfo *hints)
|
||||
{
|
||||
struct thread_sync_data *tsd = &td->tsd;
|
||||
|
||||
memset(tsd, 0, sizeof(*tsd));
|
||||
|
||||
tsd->td = td;
|
||||
tsd->port = port;
|
||||
#ifdef HAVE_GETADDRINFO
|
||||
DEBUGASSERT(hints);
|
||||
@ -266,6 +267,7 @@ static int getaddrinfo_complete(struct connectdata *conn)
|
||||
static unsigned int CURL_STDCALL getaddrinfo_thread (void *arg)
|
||||
{
|
||||
struct thread_sync_data *tsd = (struct thread_sync_data*)arg;
|
||||
struct thread_data *td = tsd->td;
|
||||
char service[12];
|
||||
int rc;
|
||||
|
||||
@ -280,8 +282,16 @@ static unsigned int CURL_STDCALL getaddrinfo_thread (void *arg)
|
||||
}
|
||||
|
||||
Curl_mutex_acquire(tsd->mtx);
|
||||
if(tsd->done) {
|
||||
/* too late, gotta clean up the mess */
|
||||
Curl_mutex_release(tsd->mtx);
|
||||
destroy_thread_sync_data(tsd);
|
||||
free(td);
|
||||
}
|
||||
else {
|
||||
tsd->done = 1;
|
||||
Curl_mutex_release(tsd->mtx);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -294,6 +304,7 @@ static unsigned int CURL_STDCALL getaddrinfo_thread (void *arg)
|
||||
static unsigned int CURL_STDCALL gethostbyname_thread (void *arg)
|
||||
{
|
||||
struct thread_sync_data *tsd = (struct thread_sync_data *)arg;
|
||||
struct thread_data *td = tsd->td;
|
||||
|
||||
tsd->res = Curl_ipv4_resolve_r(tsd->hostname, tsd->port);
|
||||
|
||||
@ -304,8 +315,16 @@ static unsigned int CURL_STDCALL gethostbyname_thread (void *arg)
|
||||
}
|
||||
|
||||
Curl_mutex_acquire(tsd->mtx);
|
||||
if(tsd->done) {
|
||||
/* too late, gotta clean up the mess */
|
||||
Curl_mutex_release(tsd->mtx);
|
||||
destroy_thread_sync_data(tsd);
|
||||
free(td);
|
||||
}
|
||||
else {
|
||||
tsd->done = 1;
|
||||
Curl_mutex_release(tsd->mtx);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -317,12 +336,23 @@ static unsigned int CURL_STDCALL gethostbyname_thread (void *arg)
|
||||
*/
|
||||
static void destroy_async_data (struct Curl_async *async)
|
||||
{
|
||||
if(async->hostname)
|
||||
free(async->hostname);
|
||||
|
||||
if(async->os_specific) {
|
||||
struct thread_data *td = (struct thread_data*) async->os_specific;
|
||||
int done;
|
||||
|
||||
/*
|
||||
* if the thread is still blocking in the resolve syscall, detach it and
|
||||
* let the thread do the cleanup...
|
||||
*/
|
||||
Curl_mutex_acquire(td->tsd.mtx);
|
||||
done = td->tsd.done;
|
||||
td->tsd.done = 1;
|
||||
Curl_mutex_release(td->tsd.mtx);
|
||||
|
||||
if(!done) {
|
||||
Curl_thread_destroy(td->thread_hnd);
|
||||
}
|
||||
else {
|
||||
if(td->thread_hnd != curl_thread_t_null)
|
||||
Curl_thread_join(&td->thread_hnd);
|
||||
|
||||
@ -330,8 +360,11 @@ static void destroy_async_data (struct Curl_async *async)
|
||||
|
||||
free(async->os_specific);
|
||||
}
|
||||
async->hostname = NULL;
|
||||
}
|
||||
async->os_specific = NULL;
|
||||
|
||||
free(async->hostname);
|
||||
async->hostname = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -357,10 +390,10 @@ static bool init_resolve_thread (struct connectdata *conn,
|
||||
conn->async.dns = NULL;
|
||||
td->thread_hnd = curl_thread_t_null;
|
||||
|
||||
if(!init_thread_sync_data(&td->tsd, hostname, port, hints))
|
||||
if(!init_thread_sync_data(td, hostname, port, hints))
|
||||
goto err_exit;
|
||||
|
||||
Curl_safefree(conn->async.hostname);
|
||||
free(conn->async.hostname);
|
||||
conn->async.hostname = strdup(hostname);
|
||||
if(!conn->async.hostname)
|
||||
goto err_exit;
|
||||
@ -396,19 +429,21 @@ static bool init_resolve_thread (struct connectdata *conn,
|
||||
static CURLcode resolver_error(struct connectdata *conn)
|
||||
{
|
||||
const char *host_or_proxy;
|
||||
CURLcode rc;
|
||||
CURLcode result;
|
||||
|
||||
if(conn->bits.httpproxy) {
|
||||
host_or_proxy = "proxy";
|
||||
rc = CURLE_COULDNT_RESOLVE_PROXY;
|
||||
result = CURLE_COULDNT_RESOLVE_PROXY;
|
||||
}
|
||||
else {
|
||||
host_or_proxy = "host";
|
||||
rc = CURLE_COULDNT_RESOLVE_HOST;
|
||||
result = CURLE_COULDNT_RESOLVE_HOST;
|
||||
}
|
||||
|
||||
failf(conn->data, "Could not resolve %s: %s", host_or_proxy,
|
||||
conn->async.hostname);
|
||||
return rc;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -425,13 +460,13 @@ CURLcode Curl_resolver_wait_resolv(struct connectdata *conn,
|
||||
struct Curl_dns_entry **entry)
|
||||
{
|
||||
struct thread_data *td = (struct thread_data*) conn->async.os_specific;
|
||||
CURLcode rc = CURLE_OK;
|
||||
CURLcode result = CURLE_OK;
|
||||
|
||||
DEBUGASSERT(conn && td);
|
||||
|
||||
/* wait for the thread to resolve the name */
|
||||
if(Curl_thread_join(&td->thread_hnd))
|
||||
rc = getaddrinfo_complete(conn);
|
||||
result = getaddrinfo_complete(conn);
|
||||
else
|
||||
DEBUGASSERT(0);
|
||||
|
||||
@ -442,14 +477,14 @@ CURLcode Curl_resolver_wait_resolv(struct connectdata *conn,
|
||||
|
||||
if(!conn->async.dns)
|
||||
/* a name was not resolved, report error */
|
||||
rc = resolver_error(conn);
|
||||
result = resolver_error(conn);
|
||||
|
||||
destroy_async_data(&conn->async);
|
||||
|
||||
if(!conn->async.dns)
|
||||
connclose(conn, "asynch resolve failed");
|
||||
|
||||
return (rc);
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -479,9 +514,9 @@ CURLcode Curl_resolver_is_resolved(struct connectdata *conn,
|
||||
getaddrinfo_complete(conn);
|
||||
|
||||
if(!conn->async.dns) {
|
||||
CURLcode rc = resolver_error(conn);
|
||||
CURLcode result = resolver_error(conn);
|
||||
destroy_async_data(&conn->async);
|
||||
return rc;
|
||||
return result;
|
||||
}
|
||||
destroy_async_data(&conn->async);
|
||||
*entry = conn->async.dns;
|
||||
@ -595,7 +630,7 @@ Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata *conn,
|
||||
}
|
||||
|
||||
if((pf != PF_INET) && !Curl_ipv6works())
|
||||
/* the stack seems to be a non-ipv6 one */
|
||||
/* The stack seems to be a non-IPv6 one */
|
||||
pf = PF_INET;
|
||||
|
||||
#endif /* CURLRES_IPV6 */
|
||||
|
@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -23,17 +23,14 @@
|
||||
/* Base64 encoding/decoding */
|
||||
|
||||
#include "curl_setup.h"
|
||||
|
||||
#define _MPRINTF_REPLACE /* use our functions only */
|
||||
#include <curl/mprintf.h>
|
||||
|
||||
#include "curl_printf.h"
|
||||
#include "urldata.h" /* for the SessionHandle definition */
|
||||
#include "warnless.h"
|
||||
#include "curl_base64.h"
|
||||
#include "curl_memory.h"
|
||||
#include "non-ascii.h"
|
||||
|
||||
/* include memdebug.h last */
|
||||
/* The last #include files should be: */
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
/* ---- Base64 Encoding/Decoding Table --- */
|
||||
@ -49,10 +46,10 @@ static size_t decodeQuantum(unsigned char *dest, const char *src)
|
||||
{
|
||||
size_t padding = 0;
|
||||
const char *s, *p;
|
||||
unsigned long i, v, x = 0;
|
||||
unsigned long i, x = 0;
|
||||
|
||||
for(i = 0, s = src; i < 4; i++, s++) {
|
||||
v = 0;
|
||||
unsigned long v = 0;
|
||||
|
||||
if(*s == '=') {
|
||||
x = (x << 6);
|
||||
@ -107,7 +104,6 @@ CURLcode Curl_base64_decode(const char *src,
|
||||
size_t length = 0;
|
||||
size_t padding = 0;
|
||||
size_t i;
|
||||
size_t result;
|
||||
size_t numQuantums;
|
||||
size_t rawlen = 0;
|
||||
unsigned char *pos;
|
||||
@ -151,9 +147,9 @@ CURLcode Curl_base64_decode(const char *src,
|
||||
|
||||
/* Decode the quantums */
|
||||
for(i = 0; i < numQuantums; i++) {
|
||||
result = decodeQuantum(pos, src);
|
||||
size_t result = decodeQuantum(pos, src);
|
||||
if(!result) {
|
||||
Curl_safefree(newstr);
|
||||
free(newstr);
|
||||
|
||||
return CURLE_BAD_CONTENT_ENCODING;
|
||||
}
|
||||
@ -256,7 +252,6 @@ static CURLcode base64_encode(const char *table64,
|
||||
*output = '\0';
|
||||
*outptr = base64data; /* return pointer to new data, allocated memory */
|
||||
|
||||
if(convbuf)
|
||||
free(convbuf);
|
||||
|
||||
*outlen = strlen(base64data); /* return the length of the new data */
|
||||
|
@ -1,110 +0,0 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2012, Linus Nielsen Feltzing, <linus@haxx.se>
|
||||
* Copyright (C) 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at http://curl.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include "curl_setup.h"
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
||||
#include "urldata.h"
|
||||
#include "url.h"
|
||||
#include "progress.h"
|
||||
#include "multiif.h"
|
||||
#include "bundles.h"
|
||||
#include "sendf.h"
|
||||
#include "rawstr.h"
|
||||
|
||||
#include "curl_memory.h"
|
||||
/* The last #include file should be: */
|
||||
#include "memdebug.h"
|
||||
|
||||
static void conn_llist_dtor(void *user, void *element)
|
||||
{
|
||||
struct connectdata *data = element;
|
||||
(void)user;
|
||||
|
||||
data->bundle = NULL;
|
||||
}
|
||||
|
||||
CURLcode Curl_bundle_create(struct SessionHandle *data,
|
||||
struct connectbundle **cb_ptr)
|
||||
{
|
||||
(void)data;
|
||||
DEBUGASSERT(*cb_ptr == NULL);
|
||||
*cb_ptr = malloc(sizeof(struct connectbundle));
|
||||
if(!*cb_ptr)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
(*cb_ptr)->num_connections = 0;
|
||||
(*cb_ptr)->server_supports_pipelining = FALSE;
|
||||
|
||||
(*cb_ptr)->conn_list = Curl_llist_alloc((curl_llist_dtor) conn_llist_dtor);
|
||||
if(!(*cb_ptr)->conn_list) {
|
||||
Curl_safefree(*cb_ptr);
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
void Curl_bundle_destroy(struct connectbundle *cb_ptr)
|
||||
{
|
||||
if(!cb_ptr)
|
||||
return;
|
||||
|
||||
if(cb_ptr->conn_list) {
|
||||
Curl_llist_destroy(cb_ptr->conn_list, NULL);
|
||||
cb_ptr->conn_list = NULL;
|
||||
}
|
||||
Curl_safefree(cb_ptr);
|
||||
}
|
||||
|
||||
/* Add a connection to a bundle */
|
||||
CURLcode Curl_bundle_add_conn(struct connectbundle *cb_ptr,
|
||||
struct connectdata *conn)
|
||||
{
|
||||
if(!Curl_llist_insert_next(cb_ptr->conn_list, cb_ptr->conn_list->tail, conn))
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
conn->bundle = cb_ptr;
|
||||
|
||||
cb_ptr->num_connections++;
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
/* Remove a connection from a bundle */
|
||||
int Curl_bundle_remove_conn(struct connectbundle *cb_ptr,
|
||||
struct connectdata *conn)
|
||||
{
|
||||
struct curl_llist_element *curr;
|
||||
|
||||
curr = cb_ptr->conn_list->head;
|
||||
while(curr) {
|
||||
if(curr->ptr == conn) {
|
||||
Curl_llist_remove(cb_ptr->conn_list, curr, NULL);
|
||||
cb_ptr->num_connections--;
|
||||
conn->bundle = NULL;
|
||||
return 1; /* we removed a handle */
|
||||
}
|
||||
curr = curr->next;
|
||||
}
|
||||
return 0;
|
||||
}
|
@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -93,7 +93,6 @@
|
||||
|
||||
#define USE_MANUAL 1
|
||||
#define USE_OPENSSL 1
|
||||
#define USE_SSLEAY 1
|
||||
#define CURL_DISABLE_LDAP 1
|
||||
|
||||
#define OS "AmigaOS"
|
||||
|
@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -132,12 +132,11 @@
|
||||
#define HAVE_LIBZ 1
|
||||
#endif
|
||||
|
||||
/* USE_SSLEAY on cmd-line */
|
||||
#ifdef USE_SSLEAY
|
||||
/* USE_OPENSSL on cmd-line */
|
||||
#ifdef USE_OPENSSL
|
||||
#define HAVE_CRYPTO_CLEANUP_ALL_EX_DATA 1
|
||||
#define HAVE_OPENSSL_ENGINE_H 1
|
||||
#define OPENSSL_NO_KRB5 1
|
||||
#define USE_OPENSSL 1
|
||||
#endif
|
||||
|
||||
/* to disable LDAP */
|
||||
@ -163,11 +162,6 @@
|
||||
#define HAVE_TERMIOS_H 1
|
||||
#define HAVE_VARIADIC_MACROS_GCC 1
|
||||
|
||||
/* Because djgpp <= 2.03 doesn't have snprintf() etc. */
|
||||
#if (DJGPP_MINOR < 4)
|
||||
#define _MPRINTF_REPLACE
|
||||
#endif
|
||||
|
||||
#elif defined(__WATCOMC__)
|
||||
#define HAVE_STRCASECMP 1
|
||||
|
||||
|
964
contrib/curl/lib/config-linux.h
Normal file
964
contrib/curl/lib/config-linux.h
Normal file
@ -0,0 +1,964 @@
|
||||
/* lib/curl_config.h.in. Generated somehow by cmake. */
|
||||
|
||||
/* when building libcurl itself */
|
||||
/* #undef BUILDING_LIBCURL */
|
||||
|
||||
/* Location of default ca bundle */
|
||||
/* #undef CURL_CA_BUNDLE */
|
||||
|
||||
/* Location of default ca path */
|
||||
/* #undef CURL_CA_PATH */
|
||||
|
||||
/* to disable cookies support */
|
||||
/* #undef CURL_DISABLE_COOKIES */
|
||||
|
||||
/* to disable cryptographic authentication */
|
||||
/* #undef CURL_DISABLE_CRYPTO_AUTH */
|
||||
|
||||
/* to disable DICT */
|
||||
/* #undef CURL_DISABLE_DICT */
|
||||
|
||||
/* to disable FILE */
|
||||
/* #undef CURL_DISABLE_FILE */
|
||||
|
||||
/* to disable FTP */
|
||||
/* #undef CURL_DISABLE_FTP */
|
||||
|
||||
/* to disable HTTP */
|
||||
/* #undef CURL_DISABLE_HTTP */
|
||||
|
||||
/* to disable LDAP */
|
||||
/* #undef CURL_DISABLE_LDAP */
|
||||
|
||||
/* to disable LDAPS */
|
||||
/* #undef CURL_DISABLE_LDAPS */
|
||||
|
||||
/* to disable proxies */
|
||||
/* #undef CURL_DISABLE_PROXY */
|
||||
|
||||
/* to disable TELNET */
|
||||
/* #undef CURL_DISABLE_TELNET */
|
||||
|
||||
/* to disable TFTP */
|
||||
/* #undef CURL_DISABLE_TFTP */
|
||||
|
||||
/* to disable verbose strings */
|
||||
/* #undef CURL_DISABLE_VERBOSE_STRINGS */
|
||||
|
||||
/* to make a symbol visible */
|
||||
/* #undef CURL_EXTERN_SYMBOL */
|
||||
/* Ensure using CURL_EXTERN_SYMBOL is possible */
|
||||
#ifndef CURL_EXTERN_SYMBOL
|
||||
#define CURL_EXTERN_SYMBOL
|
||||
#endif
|
||||
|
||||
/* Use Windows LDAP implementation */
|
||||
/* #undef USE_WIN32_LDAP */
|
||||
|
||||
/* when not building a shared library */
|
||||
/* #undef CURL_STATICLIB */
|
||||
|
||||
/* Set to explicitly specify we don't want to use thread-safe functions */
|
||||
/* #undef DISABLED_THREADSAFE */
|
||||
|
||||
/* your Entropy Gathering Daemon socket pathname */
|
||||
/* #undef EGD_SOCKET */
|
||||
|
||||
/* Define if you want to enable IPv6 support */
|
||||
#define ENABLE_IPV6 1
|
||||
|
||||
/* Define to the type qualifier of arg 1 for getnameinfo. */
|
||||
/* #undef GETNAMEINFO_QUAL_ARG1 */
|
||||
|
||||
/* Define to the type of arg 1 for getnameinfo. */
|
||||
/* #undef GETNAMEINFO_TYPE_ARG1 */
|
||||
|
||||
/* Define to the type of arg 2 for getnameinfo. */
|
||||
/* #undef GETNAMEINFO_TYPE_ARG2 */
|
||||
|
||||
/* Define to the type of args 4 and 6 for getnameinfo. */
|
||||
/* #undef GETNAMEINFO_TYPE_ARG46 */
|
||||
|
||||
/* Define to the type of arg 7 for getnameinfo. */
|
||||
/* #undef GETNAMEINFO_TYPE_ARG7 */
|
||||
|
||||
/* Specifies the number of arguments to getservbyport_r */
|
||||
/* #undef GETSERVBYPORT_R_ARGS */
|
||||
|
||||
/* Specifies the size of the buffer to pass to getservbyport_r */
|
||||
/* #undef GETSERVBYPORT_R_BUFSIZE */
|
||||
|
||||
/* Define to 1 if you have the alarm function. */
|
||||
#define HAVE_ALARM 1
|
||||
|
||||
/* Define to 1 if you have the <alloca.h> header file. */
|
||||
#define HAVE_ALLOCA_H 1
|
||||
|
||||
/* Define to 1 if you have the <arpa/inet.h> header file. */
|
||||
#define HAVE_ARPA_INET_H 1
|
||||
|
||||
/* Define to 1 if you have the <arpa/tftp.h> header file. */
|
||||
#define HAVE_ARPA_TFTP_H 1
|
||||
|
||||
/* Define to 1 if you have the <assert.h> header file. */
|
||||
#define HAVE_ASSERT_H 1
|
||||
|
||||
/* Define to 1 if you have the `basename' function. */
|
||||
#define HAVE_BASENAME 1
|
||||
|
||||
/* Define to 1 if bool is an available type. */
|
||||
#define HAVE_BOOL_T 1
|
||||
|
||||
/* Define to 1 if you have the clock_gettime function and monotonic timer. */
|
||||
/* #undef HAVE_CLOCK_GETTIME_MONOTONIC */
|
||||
|
||||
/* Define to 1 if you have the `closesocket' function. */
|
||||
/* #undef HAVE_CLOSESOCKET */
|
||||
|
||||
/* Define to 1 if you have the `CRYPTO_cleanup_all_ex_data' function. */
|
||||
/* #undef HAVE_CRYPTO_CLEANUP_ALL_EX_DATA */
|
||||
|
||||
/* Define to 1 if you have the <crypto.h> header file. */
|
||||
/* #undef HAVE_CRYPTO_H */
|
||||
|
||||
/* Define to 1 if you have the <des.h> header file. */
|
||||
/* #undef HAVE_DES_H */
|
||||
|
||||
/* Define to 1 if you have the <dlfcn.h> header file. */
|
||||
#define HAVE_DLFCN_H 1
|
||||
|
||||
/* Define to 1 if you have the `ENGINE_load_builtin_engines' function. */
|
||||
/* #undef HAVE_ENGINE_LOAD_BUILTIN_ENGINES */
|
||||
|
||||
/* Define to 1 if you have the <errno.h> header file. */
|
||||
#define HAVE_ERRNO_H 1
|
||||
|
||||
/* Define to 1 if you have the <err.h> header file. */
|
||||
#define HAVE_ERR_H 1
|
||||
|
||||
/* Define to 1 if you have the fcntl function. */
|
||||
#define HAVE_FCNTL 1
|
||||
|
||||
/* Define to 1 if you have the <fcntl.h> header file. */
|
||||
#define HAVE_FCNTL_H 1
|
||||
|
||||
/* Define to 1 if you have a working fcntl O_NONBLOCK function. */
|
||||
#define HAVE_FCNTL_O_NONBLOCK 1
|
||||
|
||||
/* Define to 1 if you have the fdopen function. */
|
||||
/* #undef HAVE_FDOPEN */
|
||||
|
||||
/* Define to 1 if you have the `fork' function. */
|
||||
#define HAVE_FORK 1
|
||||
|
||||
/* Define to 1 if you have the freeaddrinfo function. */
|
||||
#define HAVE_FREEADDRINFO 1
|
||||
|
||||
/* Define to 1 if you have the freeifaddrs function. */
|
||||
#define HAVE_FREEIFADDRS 1
|
||||
|
||||
/* Define to 1 if you have the ftruncate function. */
|
||||
#define HAVE_FTRUNCATE 1
|
||||
|
||||
/* Define to 1 if you have a working getaddrinfo function. */
|
||||
#define HAVE_GETADDRINFO 1
|
||||
|
||||
/* Define to 1 if you have the `geteuid' function. */
|
||||
#define HAVE_GETEUID 1
|
||||
|
||||
/* Define to 1 if you have the gethostbyaddr function. */
|
||||
#define HAVE_GETHOSTBYADDR 1
|
||||
|
||||
/* Define to 1 if you have the gethostbyaddr_r function. */
|
||||
#define HAVE_GETHOSTBYADDR_R 1
|
||||
|
||||
/* gethostbyaddr_r() takes 5 args */
|
||||
/* #undef HAVE_GETHOSTBYADDR_R_5 */
|
||||
|
||||
/* gethostbyaddr_r() takes 7 args */
|
||||
/* #undef HAVE_GETHOSTBYADDR_R_7 */
|
||||
|
||||
/* gethostbyaddr_r() takes 8 args */
|
||||
#define HAVE_GETHOSTBYADDR_R_8 1
|
||||
|
||||
/* Define to 1 if you have the gethostbyname function. */
|
||||
#define HAVE_GETHOSTBYNAME 1
|
||||
|
||||
/* Define to 1 if you have the gethostbyname_r function. */
|
||||
#define HAVE_GETHOSTBYNAME_R 1
|
||||
|
||||
/* gethostbyname_r() takes 3 args */
|
||||
/* #undef HAVE_GETHOSTBYNAME_R_3 */
|
||||
|
||||
/* gethostbyname_r() takes 5 args */
|
||||
/* #undef HAVE_GETHOSTBYNAME_R_5 */
|
||||
|
||||
/* gethostbyname_r() takes 6 args */
|
||||
#define HAVE_GETHOSTBYNAME_R_6 1
|
||||
|
||||
/* Define to 1 if you have the gethostname function. */
|
||||
#define HAVE_GETHOSTNAME 1
|
||||
|
||||
/* Define to 1 if you have a working getifaddrs function. */
|
||||
/* #undef HAVE_GETIFADDRS */
|
||||
|
||||
/* Define to 1 if you have the getnameinfo function. */
|
||||
/* #undef HAVE_GETNAMEINFO */
|
||||
|
||||
/* Define to 1 if you have the `getpass_r' function. */
|
||||
/* #undef HAVE_GETPASS_R */
|
||||
|
||||
/* Define to 1 if you have the `getppid' function. */
|
||||
/* #undef HAVE_GETPPID */
|
||||
|
||||
/* Define to 1 if you have the `getprotobyname' function. */
|
||||
#define HAVE_GETPROTOBYNAME 1
|
||||
|
||||
/* Define to 1 if you have the `getpwuid' function. */
|
||||
#define HAVE_GETPWUID 1
|
||||
|
||||
/* Define to 1 if you have the `getrlimit' function. */
|
||||
#define HAVE_GETRLIMIT 1
|
||||
|
||||
/* Define to 1 if you have the getservbyport_r function. */
|
||||
/* #undef HAVE_GETSERVBYPORT_R */
|
||||
|
||||
/* Define to 1 if you have the `gettimeofday' function. */
|
||||
#define HAVE_GETTIMEOFDAY 1
|
||||
|
||||
/* Define to 1 if you have a working glibc-style strerror_r function. */
|
||||
/* #undef HAVE_GLIBC_STRERROR_R */
|
||||
|
||||
/* Define to 1 if you have a working gmtime_r function. */
|
||||
#define HAVE_GMTIME_R 1
|
||||
|
||||
/* if you have the gssapi libraries */
|
||||
/* #undef HAVE_GSSAPI */
|
||||
|
||||
/* Define to 1 if you have the <gssapi/gssapi_generic.h> header file. */
|
||||
/* #undef HAVE_GSSAPI_GSSAPI_GENERIC_H */
|
||||
|
||||
/* Define to 1 if you have the <gssapi/gssapi.h> header file. */
|
||||
/* #undef HAVE_GSSAPI_GSSAPI_H */
|
||||
|
||||
/* Define to 1 if you have the <gssapi/gssapi_krb5.h> header file. */
|
||||
/* #undef HAVE_GSSAPI_GSSAPI_KRB5_H */
|
||||
|
||||
/* if you have the GNU gssapi libraries */
|
||||
/* #undef HAVE_GSSGNU */
|
||||
|
||||
/* if you have the Heimdal gssapi libraries */
|
||||
/* #undef HAVE_GSSHEIMDAL */
|
||||
|
||||
/* if you have the MIT gssapi libraries */
|
||||
/* #undef HAVE_GSSMIT */
|
||||
|
||||
/* Define to 1 if you have the `idna_strerror' function. */
|
||||
/* #undef HAVE_IDNA_STRERROR */
|
||||
|
||||
/* Define to 1 if you have the `idn_free' function. */
|
||||
/* #undef HAVE_IDN_FREE */
|
||||
|
||||
/* Define to 1 if you have the <idn-free.h> header file. */
|
||||
/* #undef HAVE_IDN_FREE_H */
|
||||
|
||||
/* Define to 1 if you have the <ifaddrs.h> header file. */
|
||||
#define HAVE_IFADDRS_H 1
|
||||
|
||||
/* Define to 1 if you have the `inet_addr' function. */
|
||||
#define HAVE_INET_ADDR 1
|
||||
|
||||
/* Define to 1 if you have the inet_ntoa_r function. */
|
||||
/* #undef HAVE_INET_NTOA_R */
|
||||
|
||||
/* inet_ntoa_r() takes 2 args */
|
||||
/* #undef HAVE_INET_NTOA_R_2 */
|
||||
|
||||
/* inet_ntoa_r() takes 3 args */
|
||||
/* #undef HAVE_INET_NTOA_R_3 */
|
||||
|
||||
/* Define to 1 if you have a IPv6 capable working inet_ntop function. */
|
||||
/* #undef HAVE_INET_NTOP */
|
||||
|
||||
/* Define to 1 if you have a IPv6 capable working inet_pton function. */
|
||||
#define HAVE_INET_PTON 1
|
||||
|
||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||
#define HAVE_INTTYPES_H 1
|
||||
|
||||
/* Define to 1 if you have the ioctl function. */
|
||||
#define HAVE_IOCTL 1
|
||||
|
||||
/* Define to 1 if you have the ioctlsocket function. */
|
||||
/* #undef HAVE_IOCTLSOCKET */
|
||||
|
||||
/* Define to 1 if you have the IoctlSocket camel case function. */
|
||||
/* #undef HAVE_IOCTLSOCKET_CAMEL */
|
||||
|
||||
/* Define to 1 if you have a working IoctlSocket camel case FIONBIO function.
|
||||
*/
|
||||
/* #undef HAVE_IOCTLSOCKET_CAMEL_FIONBIO */
|
||||
|
||||
/* Define to 1 if you have a working ioctlsocket FIONBIO function. */
|
||||
/* #undef HAVE_IOCTLSOCKET_FIONBIO */
|
||||
|
||||
/* Define to 1 if you have a working ioctl FIONBIO function. */
|
||||
#define HAVE_IOCTL_FIONBIO 1
|
||||
|
||||
/* Define to 1 if you have a working ioctl SIOCGIFADDR function. */
|
||||
#define HAVE_IOCTL_SIOCGIFADDR 1
|
||||
|
||||
/* Define to 1 if you have the <io.h> header file. */
|
||||
/* #undef HAVE_IO_H */
|
||||
|
||||
/* if you have the Kerberos4 libraries (including -ldes) */
|
||||
/* #undef HAVE_KRB4 */
|
||||
|
||||
/* Define to 1 if you have the `krb_get_our_ip_for_realm' function. */
|
||||
/* #undef HAVE_KRB_GET_OUR_IP_FOR_REALM */
|
||||
|
||||
/* Define to 1 if you have the <krb.h> header file. */
|
||||
/* #undef HAVE_KRB_H */
|
||||
|
||||
/* Define to 1 if you have the lber.h header file. */
|
||||
#define HAVE_LBER_H 1
|
||||
|
||||
/* Define to 1 if you have the ldapssl.h header file. */
|
||||
/* #undef HAVE_LDAPSSL_H */
|
||||
|
||||
/* Define to 1 if you have the ldap.h header file. */
|
||||
#define HAVE_LDAP_H 1
|
||||
|
||||
/* Use LDAPS implementation */
|
||||
/* #undef HAVE_LDAP_SSL */
|
||||
|
||||
/* Define to 1 if you have the ldap_ssl.h header file. */
|
||||
/* #undef HAVE_LDAP_SSL_H */
|
||||
|
||||
/* Define to 1 if you have the `ldap_url_parse' function. */
|
||||
#define HAVE_LDAP_URL_PARSE 1
|
||||
|
||||
/* Define to 1 if you have the <libgen.h> header file. */
|
||||
#define HAVE_LIBGEN_H 1
|
||||
|
||||
/* Define to 1 if you have the `idn' library (-lidn). */
|
||||
/* #undef HAVE_LIBIDN */
|
||||
|
||||
/* Define to 1 if you have the `resolv' library (-lresolv). */
|
||||
/* #undef HAVE_LIBRESOLV */
|
||||
|
||||
/* Define to 1 if you have the `resolve' library (-lresolve). */
|
||||
/* #undef HAVE_LIBRESOLVE */
|
||||
|
||||
/* Define to 1 if you have the `socket' library (-lsocket). */
|
||||
/* #undef HAVE_LIBSOCKET */
|
||||
|
||||
/* Define to 1 if you have the `ssh2' library (-lssh2). */
|
||||
/* #undef HAVE_LIBSSH2 */
|
||||
|
||||
/* Define to 1 if libssh2 provides `libssh2_version'. */
|
||||
/* #undef HAVE_LIBSSH2_VERSION */
|
||||
|
||||
/* Define to 1 if libssh2 provides `libssh2_init'. */
|
||||
/* #undef HAVE_LIBSSH2_INIT */
|
||||
|
||||
/* Define to 1 if libssh2 provides `libssh2_exit'. */
|
||||
/* #undef HAVE_LIBSSH2_EXIT */
|
||||
|
||||
/* Define to 1 if libssh2 provides `libssh2_scp_send64'. */
|
||||
/* #undef HAVE_LIBSSH2_SCP_SEND64 */
|
||||
|
||||
/* Define to 1 if libssh2 provides `libssh2_session_handshake'. */
|
||||
/* #undef HAVE_LIBSSH2_SESSION_HANDSHAKE */
|
||||
|
||||
/* Define to 1 if you have the <libssh2.h> header file. */
|
||||
/* #undef HAVE_LIBSSH2_H */
|
||||
|
||||
/* Define to 1 if you have the `ssl' library (-lssl). */
|
||||
#define HAVE_LIBSSL 1
|
||||
|
||||
/* if zlib is available */
|
||||
#define HAVE_LIBZ 1
|
||||
|
||||
/* Define to 1 if you have the <limits.h> header file. */
|
||||
#define HAVE_LIMITS_H 1
|
||||
|
||||
/* if your compiler supports LL */
|
||||
#define HAVE_LL 1
|
||||
|
||||
/* Define to 1 if you have the <locale.h> header file. */
|
||||
#define HAVE_LOCALE_H 1
|
||||
|
||||
/* Define to 1 if you have a working localtime_r function. */
|
||||
#define HAVE_LOCALTIME_R 1
|
||||
|
||||
/* Define to 1 if the compiler supports the 'long long' data type. */
|
||||
#define HAVE_LONGLONG 1
|
||||
|
||||
/* Define to 1 if you have the malloc.h header file. */
|
||||
#define HAVE_MALLOC_H 1
|
||||
|
||||
/* Define to 1 if you have the <memory.h> header file. */
|
||||
#define HAVE_MEMORY_H 1
|
||||
|
||||
/* Define to 1 if you have the MSG_NOSIGNAL flag. */
|
||||
#define HAVE_MSG_NOSIGNAL 1
|
||||
|
||||
/* Define to 1 if you have the <netdb.h> header file. */
|
||||
#define HAVE_NETDB_H 1
|
||||
|
||||
/* Define to 1 if you have the <netinet/in.h> header file. */
|
||||
#define HAVE_NETINET_IN_H 1
|
||||
|
||||
/* Define to 1 if you have the <netinet/tcp.h> header file. */
|
||||
#define HAVE_NETINET_TCP_H 1
|
||||
|
||||
/* Define to 1 if you have the <net/if.h> header file. */
|
||||
#define HAVE_NET_IF_H 1
|
||||
|
||||
/* Define to 1 if NI_WITHSCOPEID exists and works. */
|
||||
/* #undef HAVE_NI_WITHSCOPEID */
|
||||
|
||||
/* if you have an old MIT gssapi library, lacking GSS_C_NT_HOSTBASED_SERVICE */
|
||||
/* #undef HAVE_OLD_GSSMIT */
|
||||
|
||||
/* Define to 1 if you have the <openssl/crypto.h> header file. */
|
||||
#define HAVE_OPENSSL_CRYPTO_H 1
|
||||
|
||||
/* Define to 1 if you have the <openssl/engine.h> header file. */
|
||||
#define HAVE_OPENSSL_ENGINE_H 1
|
||||
|
||||
/* Define to 1 if you have the <openssl/err.h> header file. */
|
||||
#define HAVE_OPENSSL_ERR_H 1
|
||||
|
||||
/* Define to 1 if you have the <openssl/pem.h> header file. */
|
||||
#define HAVE_OPENSSL_PEM_H 1
|
||||
|
||||
/* Define to 1 if you have the <openssl/pkcs12.h> header file. */
|
||||
#define HAVE_OPENSSL_PKCS12_H 1
|
||||
|
||||
/* Define to 1 if you have the <openssl/rsa.h> header file. */
|
||||
#define HAVE_OPENSSL_RSA_H 1
|
||||
|
||||
/* Define to 1 if you have the <openssl/ssl.h> header file. */
|
||||
#define HAVE_OPENSSL_SSL_H 1
|
||||
|
||||
/* Define to 1 if you have the <openssl/x509.h> header file. */
|
||||
#define HAVE_OPENSSL_X509_H 1
|
||||
|
||||
/* Define to 1 if you have the <pem.h> header file. */
|
||||
/* #undef HAVE_PEM_H */
|
||||
|
||||
/* Define to 1 if you have the `perror' function. */
|
||||
#define HAVE_PERROR 1
|
||||
|
||||
/* Define to 1 if you have the `pipe' function. */
|
||||
#define HAVE_PIPE 1
|
||||
|
||||
/* Define to 1 if you have a working poll function. */
|
||||
#define HAVE_POLL 1
|
||||
|
||||
/* If you have a fine poll */
|
||||
#define HAVE_POLL_FINE 1
|
||||
|
||||
/* Define to 1 if you have the <poll.h> header file. */
|
||||
#define HAVE_POLL_H 1
|
||||
|
||||
/* Define to 1 if you have a working POSIX-style strerror_r function. */
|
||||
#define HAVE_POSIX_STRERROR_R 1
|
||||
|
||||
/* Define to 1 if you have the <pthread.h> header file */
|
||||
/* #undef HAVE_PTHREAD_H */
|
||||
|
||||
/* Define to 1 if you have the <pwd.h> header file. */
|
||||
#define HAVE_PWD_H 1
|
||||
|
||||
/* Define to 1 if you have the `RAND_egd' function. */
|
||||
/* #undef HAVE_RAND_EGD */
|
||||
|
||||
/* Define to 1 if you have the `RAND_screen' function. */
|
||||
/* #undef HAVE_RAND_SCREEN */
|
||||
|
||||
/* Define to 1 if you have the `RAND_status' function. */
|
||||
/* #undef HAVE_RAND_STATUS */
|
||||
|
||||
/* Define to 1 if you have the recv function. */
|
||||
#define HAVE_RECV 1
|
||||
|
||||
/* Define to 1 if you have the recvfrom function. */
|
||||
/* #undef HAVE_RECVFROM */
|
||||
|
||||
/* Define to 1 if you have the <rsa.h> header file. */
|
||||
/* #undef HAVE_RSA_H */
|
||||
|
||||
/* Define to 1 if you have the select function. */
|
||||
#define HAVE_SELECT 1
|
||||
|
||||
/* Define to 1 if you have the send function. */
|
||||
#define HAVE_SEND 1
|
||||
|
||||
/* Define to 1 if you have the <setjmp.h> header file. */
|
||||
#define HAVE_SETJMP_H 1
|
||||
|
||||
/* Define to 1 if you have the `setlocale' function. */
|
||||
#define HAVE_SETLOCALE 1
|
||||
|
||||
/* Define to 1 if you have the `setmode' function. */
|
||||
/* #undef HAVE_SETMODE */
|
||||
|
||||
/* Define to 1 if you have the `setrlimit' function. */
|
||||
#define HAVE_SETRLIMIT 1
|
||||
|
||||
/* Define to 1 if you have the setsockopt function. */
|
||||
#define HAVE_SETSOCKOPT 1
|
||||
|
||||
/* Define to 1 if you have a working setsockopt SO_NONBLOCK function. */
|
||||
/* #undef HAVE_SETSOCKOPT_SO_NONBLOCK */
|
||||
|
||||
/* Define to 1 if you have the <sgtty.h> header file. */
|
||||
#define HAVE_SGTTY_H 1
|
||||
|
||||
/* Define to 1 if you have the sigaction function. */
|
||||
#define HAVE_SIGACTION 1
|
||||
|
||||
/* Define to 1 if you have the siginterrupt function. */
|
||||
#define HAVE_SIGINTERRUPT 1
|
||||
|
||||
/* Define to 1 if you have the signal function. */
|
||||
#define HAVE_SIGNAL 1
|
||||
|
||||
/* Define to 1 if you have the <signal.h> header file. */
|
||||
#define HAVE_SIGNAL_H 1
|
||||
|
||||
/* Define to 1 if you have the sigsetjmp function or macro. */
|
||||
#define HAVE_SIGSETJMP 1
|
||||
|
||||
/* Define to 1 if sig_atomic_t is an available typedef. */
|
||||
#define HAVE_SIG_ATOMIC_T 1
|
||||
|
||||
/* Define to 1 if sig_atomic_t is already defined as volatile. */
|
||||
/* #undef HAVE_SIG_ATOMIC_T_VOLATILE */
|
||||
|
||||
/* Define to 1 if struct sockaddr_in6 has the sin6_scope_id member */
|
||||
#define HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID 1
|
||||
|
||||
/* Define to 1 if you have the `socket' function. */
|
||||
#define HAVE_SOCKET 1
|
||||
|
||||
/* Define to 1 if you have the `SSL_get_shutdown' function. */
|
||||
/* #undef HAVE_SSL_GET_SHUTDOWN */
|
||||
|
||||
/* Define to 1 if you have the <ssl.h> header file. */
|
||||
/* #undef HAVE_SSL_H */
|
||||
|
||||
/* Define to 1 if you have the <stdbool.h> header file. */
|
||||
#define HAVE_STDBOOL_H 1
|
||||
|
||||
/* Define to 1 if you have the <stdint.h> header file. */
|
||||
#define HAVE_STDINT_H 1
|
||||
|
||||
/* Define to 1 if you have the <stdio.h> header file. */
|
||||
#define HAVE_STDIO_H 1
|
||||
|
||||
/* Define to 1 if you have the <stdlib.h> header file. */
|
||||
#define HAVE_STDLIB_H 1
|
||||
|
||||
/* Define to 1 if you have the strcasecmp function. */
|
||||
#define HAVE_STRCASECMP 1
|
||||
|
||||
/* Define to 1 if you have the strcasestr function. */
|
||||
/* #undef HAVE_STRCASESTR */
|
||||
|
||||
/* Define to 1 if you have the strcmpi function. */
|
||||
/* #undef HAVE_STRCMPI */
|
||||
|
||||
/* Define to 1 if you have the strdup function. */
|
||||
#define HAVE_STRDUP 1
|
||||
|
||||
/* Define to 1 if you have the strerror_r function. */
|
||||
#define HAVE_STRERROR_R 1
|
||||
|
||||
/* Define to 1 if you have the stricmp function. */
|
||||
/* #undef HAVE_STRICMP */
|
||||
|
||||
/* Define to 1 if you have the <strings.h> header file. */
|
||||
#define HAVE_STRINGS_H 1
|
||||
|
||||
/* Define to 1 if you have the <string.h> header file. */
|
||||
#define HAVE_STRING_H 1
|
||||
|
||||
/* Define to 1 if you have the strlcat function. */
|
||||
/* #undef HAVE_STRLCAT */
|
||||
|
||||
/* Define to 1 if you have the `strlcpy' function. */
|
||||
/* #undef HAVE_STRLCPY */
|
||||
|
||||
/* Define to 1 if you have the strncasecmp function. */
|
||||
/* #undef HAVE_STRNCASECMP */
|
||||
|
||||
/* Define to 1 if you have the strncmpi function. */
|
||||
/* #undef HAVE_STRNCMPI */
|
||||
|
||||
/* Define to 1 if you have the strnicmp function. */
|
||||
/* #undef HAVE_STRNICMP */
|
||||
|
||||
/* Define to 1 if you have the <stropts.h> header file. */
|
||||
/* #undef HAVE_STROPTS_H */
|
||||
|
||||
/* Define to 1 if you have the strstr function. */
|
||||
#define HAVE_STRSTR 1
|
||||
|
||||
/* Define to 1 if you have the strtok_r function. */
|
||||
#define HAVE_STRTOK_R 1
|
||||
|
||||
/* Define to 1 if you have the strtoll function. */
|
||||
#define HAVE_STRTOLL 1
|
||||
|
||||
/* if struct sockaddr_storage is defined */
|
||||
#define HAVE_STRUCT_SOCKADDR_STORAGE 1
|
||||
|
||||
/* Define to 1 if you have the timeval struct. */
|
||||
#define HAVE_STRUCT_TIMEVAL 1
|
||||
|
||||
/* Define to 1 if you have the <sys/filio.h> header file. */
|
||||
/* #undef HAVE_SYS_FILIO_H */
|
||||
|
||||
/* Define to 1 if you have the <sys/ioctl.h> header file. */
|
||||
#define HAVE_SYS_IOCTL_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/param.h> header file. */
|
||||
#define HAVE_SYS_PARAM_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/poll.h> header file. */
|
||||
#define HAVE_SYS_POLL_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/resource.h> header file. */
|
||||
#define HAVE_SYS_RESOURCE_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/select.h> header file. */
|
||||
#define HAVE_SYS_SELECT_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/socket.h> header file. */
|
||||
#define HAVE_SYS_SOCKET_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/sockio.h> header file. */
|
||||
/* #undef HAVE_SYS_SOCKIO_H */
|
||||
|
||||
/* Define to 1 if you have the <sys/stat.h> header file. */
|
||||
#define HAVE_SYS_STAT_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/time.h> header file. */
|
||||
#define HAVE_SYS_TIME_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/types.h> header file. */
|
||||
#define HAVE_SYS_TYPES_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/uio.h> header file. */
|
||||
#define HAVE_SYS_UIO_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/un.h> header file. */
|
||||
#define HAVE_SYS_UN_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/utime.h> header file. */
|
||||
/* #undef HAVE_SYS_UTIME_H */
|
||||
|
||||
/* Define to 1 if you have the <termios.h> header file. */
|
||||
#define HAVE_TERMIOS_H 1
|
||||
|
||||
/* Define to 1 if you have the <termio.h> header file. */
|
||||
#define HAVE_TERMIO_H 1
|
||||
|
||||
/* Define to 1 if you have the <time.h> header file. */
|
||||
#define HAVE_TIME_H 1
|
||||
|
||||
/* Define to 1 if you have the <tld.h> header file. */
|
||||
/* #undef HAVE_TLD_H */
|
||||
|
||||
/* Define to 1 if you have the `tld_strerror' function. */
|
||||
/* #undef HAVE_TLD_STRERROR */
|
||||
|
||||
/* Define to 1 if you have the `uname' function. */
|
||||
#define HAVE_UNAME 1
|
||||
|
||||
/* Define to 1 if you have the <unistd.h> header file. */
|
||||
#define HAVE_UNISTD_H 1
|
||||
|
||||
/* Define to 1 if you have the `utime' function. */
|
||||
#define HAVE_UTIME 1
|
||||
|
||||
/* Define to 1 if you have the <utime.h> header file. */
|
||||
#define HAVE_UTIME_H 1
|
||||
|
||||
/* Define to 1 if compiler supports C99 variadic macro style. */
|
||||
/* #undef HAVE_VARIADIC_MACROS_C99 */
|
||||
|
||||
/* Define to 1 if compiler supports old gcc variadic macro style. */
|
||||
/* #undef HAVE_VARIADIC_MACROS_GCC */
|
||||
|
||||
/* Define to 1 if you have the winber.h header file. */
|
||||
/* #undef HAVE_WINBER_H */
|
||||
|
||||
/* Define to 1 if you have the windows.h header file. */
|
||||
/* #undef HAVE_WINDOWS_H */
|
||||
|
||||
/* Define to 1 if you have the winldap.h header file. */
|
||||
/* #undef HAVE_WINLDAP_H */
|
||||
|
||||
/* Define to 1 if you have the winsock2.h header file. */
|
||||
/* #undef HAVE_WINSOCK2_H */
|
||||
|
||||
/* Define to 1 if you have the winsock.h header file. */
|
||||
/* #undef HAVE_WINSOCK_H */
|
||||
|
||||
/* Define this symbol if your OS supports changing the contents of argv */
|
||||
/* #undef HAVE_WRITABLE_ARGV */
|
||||
|
||||
/* Define to 1 if you have the writev function. */
|
||||
/* #undef HAVE_WRITEV */
|
||||
|
||||
/* Define to 1 if you have the ws2tcpip.h header file. */
|
||||
/* #undef HAVE_WS2TCPIP_H */
|
||||
|
||||
/* Define to 1 if you have the <x509.h> header file. */
|
||||
/* #undef HAVE_X509_H */
|
||||
|
||||
/* Define if you have the <process.h> header file. */
|
||||
/* #undef HAVE_PROCESS_H */
|
||||
|
||||
/* if you have the zlib.h header file */
|
||||
#define HAVE_ZLIB_H 1
|
||||
|
||||
/* Define to the sub-directory in which libtool stores uninstalled libraries.
|
||||
*/
|
||||
/* #undef LT_OBJDIR */
|
||||
|
||||
/* If you lack a fine basename() prototype */
|
||||
/* #undef NEED_BASENAME_PROTO */
|
||||
|
||||
/* Define to 1 if you need the lber.h header file even with ldap.h */
|
||||
/* #undef NEED_LBER_H */
|
||||
|
||||
/* Define to 1 if you need the malloc.h header file even with stdlib.h */
|
||||
/* #undef NEED_MALLOC_H */
|
||||
|
||||
/* Define to 1 if _REENTRANT preprocessor symbol must be defined. */
|
||||
/* #undef NEED_REENTRANT */
|
||||
|
||||
/* cpu-machine-OS */
|
||||
#define OS "Linux"
|
||||
|
||||
/* Name of package */
|
||||
/* #undef PACKAGE */
|
||||
|
||||
/* Define to the address where bug reports for this package should be sent. */
|
||||
/* #undef PACKAGE_BUGREPORT */
|
||||
|
||||
/* Define to the full name of this package. */
|
||||
/* #undef PACKAGE_NAME */
|
||||
|
||||
/* Define to the full name and version of this package. */
|
||||
/* #undef PACKAGE_STRING */
|
||||
|
||||
/* Define to the one symbol short name of this package. */
|
||||
/* #undef PACKAGE_TARNAME */
|
||||
|
||||
/* Define to the version of this package. */
|
||||
/* #undef PACKAGE_VERSION */
|
||||
|
||||
/* a suitable file to read random data from */
|
||||
#define RANDOM_FILE "/dev/urandom"
|
||||
|
||||
/* Define to the type of arg 1 for recvfrom. */
|
||||
/* #undef RECVFROM_TYPE_ARG1 */
|
||||
|
||||
/* Define to the type pointed by arg 2 for recvfrom. */
|
||||
/* #undef RECVFROM_TYPE_ARG2 */
|
||||
|
||||
/* Define to 1 if the type pointed by arg 2 for recvfrom is void. */
|
||||
/* #undef RECVFROM_TYPE_ARG2_IS_VOID */
|
||||
|
||||
/* Define to the type of arg 3 for recvfrom. */
|
||||
/* #undef RECVFROM_TYPE_ARG3 */
|
||||
|
||||
/* Define to the type of arg 4 for recvfrom. */
|
||||
/* #undef RECVFROM_TYPE_ARG4 */
|
||||
|
||||
/* Define to the type pointed by arg 5 for recvfrom. */
|
||||
/* #undef RECVFROM_TYPE_ARG5 */
|
||||
|
||||
/* Define to 1 if the type pointed by arg 5 for recvfrom is void. */
|
||||
/* #undef RECVFROM_TYPE_ARG5_IS_VOID */
|
||||
|
||||
/* Define to the type pointed by arg 6 for recvfrom. */
|
||||
/* #undef RECVFROM_TYPE_ARG6 */
|
||||
|
||||
/* Define to 1 if the type pointed by arg 6 for recvfrom is void. */
|
||||
/* #undef RECVFROM_TYPE_ARG6_IS_VOID */
|
||||
|
||||
/* Define to the function return type for recvfrom. */
|
||||
/* #undef RECVFROM_TYPE_RETV */
|
||||
|
||||
/* Define to the type of arg 1 for recv. */
|
||||
#define RECV_TYPE_ARG1 int
|
||||
|
||||
/* Define to the type of arg 2 for recv. */
|
||||
#define RECV_TYPE_ARG2 void *
|
||||
|
||||
/* Define to the type of arg 3 for recv. */
|
||||
#define RECV_TYPE_ARG3 size_t
|
||||
|
||||
/* Define to the type of arg 4 for recv. */
|
||||
#define RECV_TYPE_ARG4 int
|
||||
|
||||
/* Define to the function return type for recv. */
|
||||
#define RECV_TYPE_RETV ssize_t
|
||||
|
||||
/* Define as the return type of signal handlers (`int' or `void'). */
|
||||
#define RETSIGTYPE void
|
||||
|
||||
/* Define to the type qualifier of arg 5 for select. */
|
||||
/* #undef SELECT_QUAL_ARG5 */
|
||||
|
||||
/* Define to the type of arg 1 for select. */
|
||||
/* #undef SELECT_TYPE_ARG1 */
|
||||
|
||||
/* Define to the type of args 2, 3 and 4 for select. */
|
||||
/* #undef SELECT_TYPE_ARG234 */
|
||||
|
||||
/* Define to the type of arg 5 for select. */
|
||||
/* #undef SELECT_TYPE_ARG5 */
|
||||
|
||||
/* Define to the function return type for select. */
|
||||
/* #undef SELECT_TYPE_RETV */
|
||||
|
||||
/* Define to the type qualifier of arg 2 for send. */
|
||||
#define SEND_QUAL_ARG2 const
|
||||
|
||||
/* Define to the type of arg 1 for send. */
|
||||
#define SEND_TYPE_ARG1 int
|
||||
|
||||
/* Define to the type of arg 2 for send. */
|
||||
#define SEND_TYPE_ARG2 void *
|
||||
|
||||
/* Define to the type of arg 3 for send. */
|
||||
#define SEND_TYPE_ARG3 size_t
|
||||
|
||||
/* Define to the type of arg 4 for send. */
|
||||
#define SEND_TYPE_ARG4 int
|
||||
|
||||
/* Define to the function return type for send. */
|
||||
#define SEND_TYPE_RETV ssize_t
|
||||
|
||||
/* The size of `int', as computed by sizeof. */
|
||||
#define SIZEOF_INT 4
|
||||
|
||||
/* The size of `short', as computed by sizeof. */
|
||||
#define SIZEOF_SHORT 2
|
||||
|
||||
/* The size of `long', as computed by sizeof. */
|
||||
#define SIZEOF_LONG 8
|
||||
|
||||
/* The size of `off_t', as computed by sizeof. */
|
||||
/* #undef SIZEOF_OFF_T */
|
||||
|
||||
/* The size of `size_t', as computed by sizeof. */
|
||||
#define SIZEOF_SIZE_T 8
|
||||
|
||||
/* The size of `time_t', as computed by sizeof. */
|
||||
#define SIZEOF_TIME_T 8
|
||||
|
||||
/* The size of `void*', as computed by sizeof. */
|
||||
/* #undef SIZEOF_VOIDP */
|
||||
|
||||
/* Define to 1 if you have the ANSI C header files. */
|
||||
#define STDC_HEADERS 1
|
||||
|
||||
/* Define to the type of arg 3 for strerror_r. */
|
||||
/* #undef STRERROR_R_TYPE_ARG3 */
|
||||
|
||||
/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
|
||||
#define TIME_WITH_SYS_TIME 1
|
||||
|
||||
/* Define if you want to enable c-ares support */
|
||||
/* #undef USE_ARES */
|
||||
|
||||
/* Define if you want to enable POSIX threaded DNS lookup */
|
||||
/* #undef USE_THREADS_POSIX */
|
||||
|
||||
/* Define to disable non-blocking sockets. */
|
||||
/* #undef USE_BLOCKING_SOCKETS */
|
||||
|
||||
/* if GnuTLS is enabled */
|
||||
/* #undef USE_GNUTLS */
|
||||
|
||||
/* if PolarSSL is enabled */
|
||||
/* #undef USE_POLARSSL */
|
||||
|
||||
/* if libSSH2 is in use */
|
||||
/* #undef USE_LIBSSH2 */
|
||||
|
||||
/* If you want to build curl with the built-in manual */
|
||||
#define USE_MANUAL 1
|
||||
|
||||
/* if NSS is enabled */
|
||||
/* #undef USE_NSS */
|
||||
|
||||
/* if you want to use OpenLDAP code instead of legacy ldap implementation */
|
||||
/* #undef USE_OPENLDAP */
|
||||
|
||||
/* if OpenSSL is in use */
|
||||
#define USE_OPENSSL 1
|
||||
|
||||
/* if Unix domain sockets are enabled */
|
||||
#define USE_UNIX_SOCKETS
|
||||
|
||||
/* Define to 1 if you are building a Windows target without large file
|
||||
support. */
|
||||
/* #undef USE_WIN32_LARGE_FILES */
|
||||
|
||||
/* to enable SSPI support */
|
||||
/* #undef USE_WINDOWS_SSPI */
|
||||
|
||||
/* to enable Windows SSL */
|
||||
/* #undef USE_SCHANNEL */
|
||||
|
||||
/* Define to 1 if using yaSSL in OpenSSL compatibility mode. */
|
||||
/* #undef USE_YASSLEMUL */
|
||||
|
||||
/* Version number of package */
|
||||
/* #undef VERSION */
|
||||
|
||||
/* Define to avoid automatic inclusion of winsock.h */
|
||||
/* #undef WIN32_LEAN_AND_MEAN */
|
||||
|
||||
/* Define to 1 if OS is AIX. */
|
||||
#ifndef _ALL_SOURCE
|
||||
# undef _ALL_SOURCE
|
||||
#endif
|
||||
|
||||
/* Number of bits in a file offset, on hosts where this is settable. */
|
||||
#define _FILE_OFFSET_BITS 64
|
||||
|
||||
/* Define for large files, on AIX-style hosts. */
|
||||
/* #undef _LARGE_FILES */
|
||||
|
||||
/* define this if you need it to compile thread-safe code */
|
||||
/* #undef _THREAD_SAFE */
|
||||
|
||||
/* Define to empty if `const' does not conform to ANSI C. */
|
||||
/* #undef const */
|
||||
|
||||
/* Type to use in place of in_addr_t when system does not provide it. */
|
||||
/* #undef in_addr_t */
|
||||
|
||||
/* Define to `__inline__' or `__inline' if that's what the C compiler
|
||||
calls it, or to nothing if 'inline' is not supported under any name. */
|
||||
#ifndef __cplusplus
|
||||
#undef inline
|
||||
#endif
|
||||
|
||||
/* Define to `unsigned int' if <sys/types.h> does not define. */
|
||||
/* #undef size_t */
|
||||
|
||||
/* the signed version of size_t */
|
||||
/* #undef ssize_t */
|
@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -70,7 +70,6 @@
|
||||
#define HAVE_SIG_ATOMIC_T 1
|
||||
|
||||
#ifdef MACOS_SSL_SUPPORT
|
||||
# define USE_SSLEAY 1
|
||||
# define USE_OPENSSL 1
|
||||
#endif
|
||||
|
||||
|
@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -537,12 +537,15 @@
|
||||
/* Define to the function return type for send. */
|
||||
#define SEND_TYPE_RETV int
|
||||
|
||||
/* Define to use the QsoSSL package. */
|
||||
#undef USE_QSOSSL
|
||||
|
||||
/* Define to use the GSKit package. */
|
||||
#define USE_GSKIT
|
||||
|
||||
/* Define to use the OS/400 crypto library. */
|
||||
#define USE_OS400CRYPTO
|
||||
|
||||
/* Define to use Unix sockets. */
|
||||
#define USE_UNIX_SOCKETS
|
||||
|
||||
/* Use the system keyring as the default CA bundle. */
|
||||
#define CURL_CA_BUNDLE "/QIBM/UserData/ICSS/Cert/Server/DEFAULT.KDB"
|
||||
|
||||
|
@ -1,5 +1,7 @@
|
||||
/* lib/curl_config.h. Generated from curl_config.h.in by configure. */
|
||||
/* lib/curl_config.h.in. Generated from configure.ac by autoheader. */
|
||||
/* lib/curl_config.h.in. Generated somehow by cmake. */
|
||||
|
||||
/* when building libcurl itself */
|
||||
/* #undef BUILDING_LIBCURL */
|
||||
|
||||
/* Location of default ca bundle */
|
||||
/* #undef CURL_CA_BUNDLE */
|
||||
@ -22,53 +24,42 @@
|
||||
/* to disable FTP */
|
||||
/* #undef CURL_DISABLE_FTP */
|
||||
|
||||
/* to disable Gopher */
|
||||
/* #undef CURL_DISABLE_GOPHER */
|
||||
|
||||
/* to disable HTTP */
|
||||
/* #undef CURL_DISABLE_HTTP */
|
||||
|
||||
/* to disable IMAP */
|
||||
/* #undef CURL_DISABLE_IMAP */
|
||||
|
||||
/* to disable LDAP */
|
||||
#define CURL_DISABLE_LDAP 1
|
||||
/* #undef CURL_DISABLE_LDAP */
|
||||
|
||||
/* to disable LDAPS */
|
||||
#define CURL_DISABLE_LDAPS 1
|
||||
|
||||
/* to disable --libcurl C code generation option */
|
||||
/* #undef CURL_DISABLE_LIBCURL_OPTION */
|
||||
|
||||
/* to disable POP3 */
|
||||
/* #undef CURL_DISABLE_POP3 */
|
||||
/* #undef CURL_DISABLE_LDAPS */
|
||||
|
||||
/* to disable proxies */
|
||||
/* #undef CURL_DISABLE_PROXY */
|
||||
|
||||
/* to disable RTSP */
|
||||
/* #undef CURL_DISABLE_RTSP */
|
||||
|
||||
/* to disable SMTP */
|
||||
/* #undef CURL_DISABLE_SMTP */
|
||||
|
||||
/* to disable TELNET */
|
||||
/* #undef CURL_DISABLE_TELNET */
|
||||
|
||||
/* to disable TFTP */
|
||||
/* #undef CURL_DISABLE_TFTP */
|
||||
|
||||
/* to disable TLS-SRP authentication */
|
||||
/* #undef CURL_DISABLE_TLS_SRP */
|
||||
|
||||
/* to disable verbose strings */
|
||||
/* #undef CURL_DISABLE_VERBOSE_STRINGS */
|
||||
|
||||
/* Definition to make a library symbol externally visible. */
|
||||
#define CURL_EXTERN_SYMBOL __attribute__ ((__visibility__ ("default")))
|
||||
/* to make a symbol visible */
|
||||
/* #undef CURL_EXTERN_SYMBOL */
|
||||
/* Ensure using CURL_EXTERN_SYMBOL is possible */
|
||||
#ifndef CURL_EXTERN_SYMBOL
|
||||
#define CURL_EXTERN_SYMBOL
|
||||
#endif
|
||||
|
||||
/* Use Windows LDAP implementation */
|
||||
/* #undef CURL_LDAP_WIN */
|
||||
/* #undef USE_WIN32_LDAP */
|
||||
|
||||
/* when not building a shared library */
|
||||
/* #undef CURL_STATICLIB */
|
||||
|
||||
/* Set to explicitly specify we don't want to use thread-safe functions */
|
||||
/* #undef DISABLED_THREADSAFE */
|
||||
|
||||
/* your Entropy Gathering Daemon socket pathname */
|
||||
/* #undef EGD_SOCKET */
|
||||
@ -76,29 +67,26 @@
|
||||
/* Define if you want to enable IPv6 support */
|
||||
#define ENABLE_IPV6 1
|
||||
|
||||
/* Define to the type of arg 2 for gethostname. */
|
||||
#define GETHOSTNAME_TYPE_ARG2 size_t
|
||||
|
||||
/* Define to the type qualifier of arg 1 for getnameinfo. */
|
||||
#define GETNAMEINFO_QUAL_ARG1 const
|
||||
/* #undef GETNAMEINFO_QUAL_ARG1 */
|
||||
|
||||
/* Define to the type of arg 1 for getnameinfo. */
|
||||
#define GETNAMEINFO_TYPE_ARG1 struct sockaddr *
|
||||
/* #undef GETNAMEINFO_TYPE_ARG1 */
|
||||
|
||||
/* Define to the type of arg 2 for getnameinfo. */
|
||||
#define GETNAMEINFO_TYPE_ARG2 socklen_t
|
||||
/* #undef GETNAMEINFO_TYPE_ARG2 */
|
||||
|
||||
/* Define to the type of args 4 and 6 for getnameinfo. */
|
||||
#define GETNAMEINFO_TYPE_ARG46 socklen_t
|
||||
/* #undef GETNAMEINFO_TYPE_ARG46 */
|
||||
|
||||
/* Define to the type of arg 7 for getnameinfo. */
|
||||
#define GETNAMEINFO_TYPE_ARG7 unsigned int
|
||||
/* #undef GETNAMEINFO_TYPE_ARG7 */
|
||||
|
||||
/* Specifies the number of arguments to getservbyport_r */
|
||||
#define GETSERVBYPORT_R_ARGS 6
|
||||
/* #undef GETSERVBYPORT_R_ARGS */
|
||||
|
||||
/* Specifies the size of the buffer to pass to getservbyport_r */
|
||||
#define GETSERVBYPORT_R_BUFSIZE 4096
|
||||
/* #undef GETSERVBYPORT_R_BUFSIZE */
|
||||
|
||||
/* Define to 1 if you have the alarm function. */
|
||||
#define HAVE_ALARM 1
|
||||
@ -115,41 +103,30 @@
|
||||
/* Define to 1 if you have the <assert.h> header file. */
|
||||
#define HAVE_ASSERT_H 1
|
||||
|
||||
/* Define to 1 if you have the basename function. */
|
||||
/* Define to 1 if you have the `basename' function. */
|
||||
#define HAVE_BASENAME 1
|
||||
|
||||
/* Define to 1 if bool is an available type. */
|
||||
#define HAVE_BOOL_T 1
|
||||
|
||||
/* Define to 1 if you have the clock_gettime function and monotonic timer. */
|
||||
#ifndef __APPLE__
|
||||
#define HAVE_CLOCK_GETTIME_MONOTONIC 1
|
||||
#endif
|
||||
/* #undef HAVE_CLOCK_GETTIME_MONOTONIC */
|
||||
|
||||
/* Define to 1 if you have the closesocket function. */
|
||||
/* Define to 1 if you have the `closesocket' function. */
|
||||
/* #undef HAVE_CLOSESOCKET */
|
||||
|
||||
/* Define to 1 if you have the CloseSocket camel case function. */
|
||||
/* #undef HAVE_CLOSESOCKET_CAMEL */
|
||||
|
||||
/* Define to 1 if you have the connect function. */
|
||||
#define HAVE_CONNECT 1
|
||||
|
||||
/* Define to 1 if you have the `CRYPTO_cleanup_all_ex_data' function. */
|
||||
/* #undef HAVE_CRYPTO_CLEANUP_ALL_EX_DATA */
|
||||
|
||||
/* Define to 1 if you have the <crypto.h> header file. */
|
||||
/* #undef HAVE_CRYPTO_H */
|
||||
|
||||
/* Define to 1 if you have the <cyassl/error-ssl.h> header file. */
|
||||
/* #undef HAVE_CYASSL_ERROR_SSL_H */
|
||||
/* Define to 1 if you have the <des.h> header file. */
|
||||
/* #undef HAVE_DES_H */
|
||||
|
||||
/* Define to 1 if you have the <dlfcn.h> header file. */
|
||||
#define HAVE_DLFCN_H 1
|
||||
|
||||
/* Define to 1 if you have the `ENGINE_cleanup' function. */
|
||||
/* #undef HAVE_ENGINE_CLEANUP */
|
||||
|
||||
/* Define to 1 if you have the `ENGINE_load_builtin_engines' function. */
|
||||
/* #undef HAVE_ENGINE_LOAD_BUILTIN_ENGINES */
|
||||
|
||||
@ -157,7 +134,7 @@
|
||||
#define HAVE_ERRNO_H 1
|
||||
|
||||
/* Define to 1 if you have the <err.h> header file. */
|
||||
/* #undef HAVE_ERR_H */
|
||||
#define HAVE_ERR_H 1
|
||||
|
||||
/* Define to 1 if you have the fcntl function. */
|
||||
#define HAVE_FCNTL 1
|
||||
@ -169,7 +146,7 @@
|
||||
#define HAVE_FCNTL_O_NONBLOCK 1
|
||||
|
||||
/* Define to 1 if you have the fdopen function. */
|
||||
#define HAVE_FDOPEN 1
|
||||
/* #undef HAVE_FDOPEN */
|
||||
|
||||
/* Define to 1 if you have the `fork' function. */
|
||||
#define HAVE_FORK 1
|
||||
@ -180,27 +157,12 @@
|
||||
/* Define to 1 if you have the freeifaddrs function. */
|
||||
#define HAVE_FREEIFADDRS 1
|
||||
|
||||
/* Define to 1 if you have the fsetxattr function. */
|
||||
#define HAVE_FSETXATTR 1
|
||||
|
||||
/* fsetxattr() takes 5 args */
|
||||
#define HAVE_FSETXATTR_5 1
|
||||
|
||||
/* fsetxattr() takes 6 args */
|
||||
/* #undef HAVE_FSETXATTR_6 */
|
||||
|
||||
/* Define to 1 if you have the ftruncate function. */
|
||||
#define HAVE_FTRUNCATE 1
|
||||
|
||||
/* Define to 1 if you have the gai_strerror function. */
|
||||
#define HAVE_GAI_STRERROR 1
|
||||
|
||||
/* Define to 1 if you have a working getaddrinfo function. */
|
||||
#define HAVE_GETADDRINFO 1
|
||||
|
||||
/* Define to 1 if the getaddrinfo function is threadsafe. */
|
||||
#define HAVE_GETADDRINFO_THREADSAFE 1
|
||||
|
||||
/* Define to 1 if you have the `geteuid' function. */
|
||||
#define HAVE_GETEUID 1
|
||||
|
||||
@ -208,7 +170,7 @@
|
||||
#define HAVE_GETHOSTBYADDR 1
|
||||
|
||||
/* Define to 1 if you have the gethostbyaddr_r function. */
|
||||
#define HAVE_GETHOSTBYADDR_R 1
|
||||
/* #undef HAVE_GETHOSTBYADDR_R */
|
||||
|
||||
/* gethostbyaddr_r() takes 5 args */
|
||||
/* #undef HAVE_GETHOSTBYADDR_R_5 */
|
||||
@ -217,13 +179,13 @@
|
||||
/* #undef HAVE_GETHOSTBYADDR_R_7 */
|
||||
|
||||
/* gethostbyaddr_r() takes 8 args */
|
||||
#define HAVE_GETHOSTBYADDR_R_8 1
|
||||
/* #undef HAVE_GETHOSTBYADDR_R_8 */
|
||||
|
||||
/* Define to 1 if you have the gethostbyname function. */
|
||||
#define HAVE_GETHOSTBYNAME 1
|
||||
|
||||
/* Define to 1 if you have the gethostbyname_r function. */
|
||||
#define HAVE_GETHOSTBYNAME_R 1
|
||||
/* #undef HAVE_GETHOSTBYNAME_R */
|
||||
|
||||
/* gethostbyname_r() takes 3 args */
|
||||
/* #undef HAVE_GETHOSTBYNAME_R_3 */
|
||||
@ -232,22 +194,22 @@
|
||||
/* #undef HAVE_GETHOSTBYNAME_R_5 */
|
||||
|
||||
/* gethostbyname_r() takes 6 args */
|
||||
#define HAVE_GETHOSTBYNAME_R_6 1
|
||||
/* #undef HAVE_GETHOSTBYNAME_R_6 */
|
||||
|
||||
/* Define to 1 if you have the gethostname function. */
|
||||
#define HAVE_GETHOSTNAME 1
|
||||
|
||||
/* Define to 1 if you have a working getifaddrs function. */
|
||||
#define HAVE_GETIFADDRS 1
|
||||
/* #undef HAVE_GETIFADDRS */
|
||||
|
||||
/* Define to 1 if you have the getnameinfo function. */
|
||||
#define HAVE_GETNAMEINFO 1
|
||||
/* #undef HAVE_GETNAMEINFO */
|
||||
|
||||
/* Define to 1 if you have the `getpass_r' function. */
|
||||
/* #undef HAVE_GETPASS_R */
|
||||
|
||||
/* Define to 1 if you have the `getppid' function. */
|
||||
#define HAVE_GETPPID 1
|
||||
/* #undef HAVE_GETPPID */
|
||||
|
||||
/* Define to 1 if you have the `getprotobyname' function. */
|
||||
#define HAVE_GETPROTOBYNAME 1
|
||||
@ -255,14 +217,11 @@
|
||||
/* Define to 1 if you have the `getpwuid' function. */
|
||||
#define HAVE_GETPWUID 1
|
||||
|
||||
/* Define to 1 if you have the `getpwuid_r' function. */
|
||||
#define HAVE_GETPWUID_R 1
|
||||
|
||||
/* Define to 1 if you have the `getrlimit' function. */
|
||||
#define HAVE_GETRLIMIT 1
|
||||
|
||||
/* Define to 1 if you have the getservbyport_r function. */
|
||||
#define HAVE_GETSERVBYPORT_R 1
|
||||
/* #undef HAVE_GETSERVBYPORT_R */
|
||||
|
||||
/* Define to 1 if you have the `gettimeofday' function. */
|
||||
#define HAVE_GETTIMEOFDAY 1
|
||||
@ -273,10 +232,7 @@
|
||||
/* Define to 1 if you have a working gmtime_r function. */
|
||||
#define HAVE_GMTIME_R 1
|
||||
|
||||
/* if you have the function gnutls_srp_verifier */
|
||||
/* #undef HAVE_GNUTLS_SRP */
|
||||
|
||||
/* if you have GSS-API libraries */
|
||||
/* if you have the gssapi libraries */
|
||||
/* #undef HAVE_GSSAPI */
|
||||
|
||||
/* Define to 1 if you have the <gssapi/gssapi_generic.h> header file. */
|
||||
@ -288,13 +244,13 @@
|
||||
/* Define to 1 if you have the <gssapi/gssapi_krb5.h> header file. */
|
||||
/* #undef HAVE_GSSAPI_GSSAPI_KRB5_H */
|
||||
|
||||
/* if you have GNU GSS */
|
||||
/* if you have the GNU gssapi libraries */
|
||||
/* #undef HAVE_GSSGNU */
|
||||
|
||||
/* if you have Heimdal */
|
||||
/* if you have the Heimdal gssapi libraries */
|
||||
/* #undef HAVE_GSSHEIMDAL */
|
||||
|
||||
/* if you have MIT Kerberos */
|
||||
/* if you have the MIT gssapi libraries */
|
||||
/* #undef HAVE_GSSMIT */
|
||||
|
||||
/* Define to 1 if you have the `idna_strerror' function. */
|
||||
@ -309,9 +265,6 @@
|
||||
/* Define to 1 if you have the <ifaddrs.h> header file. */
|
||||
#define HAVE_IFADDRS_H 1
|
||||
|
||||
/* Define to 1 if you have the `if_nametoindex' function. */
|
||||
#define HAVE_IF_NAMETOINDEX 1
|
||||
|
||||
/* Define to 1 if you have the `inet_addr' function. */
|
||||
#define HAVE_INET_ADDR 1
|
||||
|
||||
@ -325,7 +278,7 @@
|
||||
/* #undef HAVE_INET_NTOA_R_3 */
|
||||
|
||||
/* Define to 1 if you have a IPv6 capable working inet_ntop function. */
|
||||
#define HAVE_INET_NTOP 1
|
||||
/* #undef HAVE_INET_NTOP */
|
||||
|
||||
/* Define to 1 if you have a IPv6 capable working inet_pton function. */
|
||||
#define HAVE_INET_PTON 1
|
||||
@ -358,26 +311,32 @@
|
||||
/* Define to 1 if you have the <io.h> header file. */
|
||||
/* #undef HAVE_IO_H */
|
||||
|
||||
/* if you have the Kerberos4 libraries (including -ldes) */
|
||||
/* #undef HAVE_KRB4 */
|
||||
|
||||
/* Define to 1 if you have the `krb_get_our_ip_for_realm' function. */
|
||||
/* #undef HAVE_KRB_GET_OUR_IP_FOR_REALM */
|
||||
|
||||
/* Define to 1 if you have the <krb.h> header file. */
|
||||
/* #undef HAVE_KRB_H */
|
||||
|
||||
/* Define to 1 if you have the lber.h header file. */
|
||||
/* #undef HAVE_LBER_H */
|
||||
#define HAVE_LBER_H 1
|
||||
|
||||
/* Define to 1 if you have the ldapssl.h header file. */
|
||||
/* #undef HAVE_LDAPSSL_H */
|
||||
|
||||
/* Define to 1 if you have the ldap.h header file. */
|
||||
/* #undef HAVE_LDAP_H */
|
||||
|
||||
/* Define to 1 if you have the `ldap_init_fd' function. */
|
||||
/* #undef HAVE_LDAP_INIT_FD */
|
||||
#define HAVE_LDAP_H 1
|
||||
|
||||
/* Use LDAPS implementation */
|
||||
#define HAVE_LDAP_SSL 1
|
||||
/* #undef HAVE_LDAP_SSL */
|
||||
|
||||
/* Define to 1 if you have the ldap_ssl.h header file. */
|
||||
/* #undef HAVE_LDAP_SSL_H */
|
||||
|
||||
/* Define to 1 if you have the `ldap_url_parse' function. */
|
||||
/* #undef HAVE_LDAP_URL_PARSE */
|
||||
#define HAVE_LDAP_URL_PARSE 1
|
||||
|
||||
/* Define to 1 if you have the <libgen.h> header file. */
|
||||
#define HAVE_LIBGEN_H 1
|
||||
@ -385,33 +344,36 @@
|
||||
/* Define to 1 if you have the `idn' library (-lidn). */
|
||||
/* #undef HAVE_LIBIDN */
|
||||
|
||||
/* Define to 1 if you have the `resolv' library (-lresolv). */
|
||||
/* #undef HAVE_LIBRESOLV */
|
||||
|
||||
/* Define to 1 if you have the `resolve' library (-lresolve). */
|
||||
/* #undef HAVE_LIBRESOLVE */
|
||||
|
||||
/* Define to 1 if you have the <librtmp/rtmp.h> header file. */
|
||||
/* #undef HAVE_LIBRTMP_RTMP_H */
|
||||
/* Define to 1 if you have the `socket' library (-lsocket). */
|
||||
/* #undef HAVE_LIBSOCKET */
|
||||
|
||||
/* Define to 1 if you have the `ssh2' library (-lssh2). */
|
||||
/* #undef HAVE_LIBSSH2 */
|
||||
|
||||
/* Define to 1 if you have the `libssh2_exit' function. */
|
||||
/* Define to 1 if libssh2 provides `libssh2_version'. */
|
||||
/* #undef HAVE_LIBSSH2_VERSION */
|
||||
|
||||
/* Define to 1 if libssh2 provides `libssh2_init'. */
|
||||
/* #undef HAVE_LIBSSH2_INIT */
|
||||
|
||||
/* Define to 1 if libssh2 provides `libssh2_exit'. */
|
||||
/* #undef HAVE_LIBSSH2_EXIT */
|
||||
|
||||
/* Define to 1 if libssh2 provides `libssh2_scp_send64'. */
|
||||
/* #undef HAVE_LIBSSH2_SCP_SEND64 */
|
||||
|
||||
/* Define to 1 if libssh2 provides `libssh2_session_handshake'. */
|
||||
/* #undef HAVE_LIBSSH2_SESSION_HANDSHAKE */
|
||||
|
||||
/* Define to 1 if you have the <libssh2.h> header file. */
|
||||
/* #undef HAVE_LIBSSH2_H */
|
||||
|
||||
/* Define to 1 if you have the `libssh2_init' function. */
|
||||
/* #undef HAVE_LIBSSH2_INIT */
|
||||
|
||||
/* Define to 1 if you have the `libssh2_scp_send64' function. */
|
||||
/* #undef HAVE_LIBSSH2_SCP_SEND64 */
|
||||
|
||||
/* Define to 1 if you have the `libssh2_session_handshake' function. */
|
||||
/* #undef HAVE_LIBSSH2_SESSION_HANDSHAKE */
|
||||
|
||||
/* Define to 1 if you have the `libssh2_version' function. */
|
||||
/* #undef HAVE_LIBSSH2_VERSION */
|
||||
|
||||
/* Define to 1 if you have the `ssl' library (-lssl). */
|
||||
/* #undef HAVE_LIBSSL */
|
||||
|
||||
@ -434,18 +396,13 @@
|
||||
#define HAVE_LONGLONG 1
|
||||
|
||||
/* Define to 1 if you have the malloc.h header file. */
|
||||
#define HAVE_MALLOC_H 1
|
||||
/* #undef HAVE_MALLOC_H */
|
||||
|
||||
/* Define to 1 if you have the memory.h header file. */
|
||||
/* Define to 1 if you have the <memory.h> header file. */
|
||||
#define HAVE_MEMORY_H 1
|
||||
|
||||
/* Define to 1 if you have the memrchr function or macro. */
|
||||
/* #undef HAVE_MEMRCHR */
|
||||
|
||||
/* Define to 1 if you have the MSG_NOSIGNAL flag. */
|
||||
#ifndef __APPLE__
|
||||
#define HAVE_MSG_NOSIGNAL 1
|
||||
#endif
|
||||
/* #undef HAVE_MSG_NOSIGNAL */
|
||||
|
||||
/* Define to 1 if you have the <netdb.h> header file. */
|
||||
#define HAVE_NETDB_H 1
|
||||
@ -459,14 +416,10 @@
|
||||
/* Define to 1 if you have the <net/if.h> header file. */
|
||||
#define HAVE_NET_IF_H 1
|
||||
|
||||
/* Define to 1 if you have the <nghttp2/nghttp2.h> header file. */
|
||||
/* #undef HAVE_NGHTTP2_NGHTTP2_H */
|
||||
|
||||
/* Define to 1 if NI_WITHSCOPEID exists and works. */
|
||||
/* #undef HAVE_NI_WITHSCOPEID */
|
||||
|
||||
/* if you have an old MIT Kerberos version, lacking GSS_C_NT_HOSTBASED_SERVICE
|
||||
*/
|
||||
/* if you have an old MIT gssapi library, lacking GSS_C_NT_HOSTBASED_SERVICE */
|
||||
/* #undef HAVE_OLD_GSSMIT */
|
||||
|
||||
/* Define to 1 if you have the <openssl/crypto.h> header file. */
|
||||
@ -514,7 +467,7 @@
|
||||
/* Define to 1 if you have a working POSIX-style strerror_r function. */
|
||||
#define HAVE_POSIX_STRERROR_R 1
|
||||
|
||||
/* if you have <pthread.h> */
|
||||
/* Define to 1 if you have the <pthread.h> header file */
|
||||
/* #undef HAVE_PTHREAD_H */
|
||||
|
||||
/* Define to 1 if you have the <pwd.h> header file. */
|
||||
@ -532,6 +485,9 @@
|
||||
/* Define to 1 if you have the recv function. */
|
||||
#define HAVE_RECV 1
|
||||
|
||||
/* Define to 1 if you have the recvfrom function. */
|
||||
/* #undef HAVE_RECVFROM */
|
||||
|
||||
/* Define to 1 if you have the <rsa.h> header file. */
|
||||
/* #undef HAVE_RSA_H */
|
||||
|
||||
@ -586,30 +542,9 @@
|
||||
/* Define to 1 if struct sockaddr_in6 has the sin6_scope_id member */
|
||||
#define HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID 1
|
||||
|
||||
/* Define to 1 if you have the socket function. */
|
||||
/* Define to 1 if you have the `socket' function. */
|
||||
#define HAVE_SOCKET 1
|
||||
|
||||
/* Define to 1 if you have the socketpair function. */
|
||||
#define HAVE_SOCKETPAIR 1
|
||||
|
||||
/* Define to 1 if you have the <socket.h> header file. */
|
||||
/* #undef HAVE_SOCKET_H */
|
||||
|
||||
/* if you have the function SRP_Calc_client_key */
|
||||
/* #undef HAVE_SSLEAY_SRP */
|
||||
|
||||
/* Define to 1 if you have the `SSLv2_client_method' function. */
|
||||
/* #undef HAVE_SSLV2_CLIENT_METHOD */
|
||||
|
||||
/* Define to 1 if you have the `SSL_CTX_set_alpn_protos' function. */
|
||||
/* #undef HAVE_SSL_CTX_SET_ALPN_PROTOS */
|
||||
|
||||
/* Define to 1 if you have the `SSL_CTX_set_alpn_select_cb' function. */
|
||||
/* #undef HAVE_SSL_CTX_SET_ALPN_SELECT_CB */
|
||||
|
||||
/* Define to 1 if you have the `SSL_CTX_set_next_proto_select_cb' function. */
|
||||
/* #undef HAVE_SSL_CTX_SET_NEXT_PROTO_SELECT_CB */
|
||||
|
||||
/* Define to 1 if you have the `SSL_get_shutdown' function. */
|
||||
/* #undef HAVE_SSL_GET_SHUTDOWN */
|
||||
|
||||
@ -631,6 +566,9 @@
|
||||
/* Define to 1 if you have the strcasecmp function. */
|
||||
#define HAVE_STRCASECMP 1
|
||||
|
||||
/* Define to 1 if you have the strcasestr function. */
|
||||
/* #undef HAVE_STRCASESTR */
|
||||
|
||||
/* Define to 1 if you have the strcmpi function. */
|
||||
/* #undef HAVE_STRCMPI */
|
||||
|
||||
@ -649,8 +587,14 @@
|
||||
/* Define to 1 if you have the <string.h> header file. */
|
||||
#define HAVE_STRING_H 1
|
||||
|
||||
/* Define to 1 if you have the strlcat function. */
|
||||
#define HAVE_STRLCAT 1
|
||||
|
||||
/* Define to 1 if you have the `strlcpy' function. */
|
||||
/* #undef HAVE_STRLCPY */
|
||||
|
||||
/* Define to 1 if you have the strncasecmp function. */
|
||||
#define HAVE_STRNCASECMP 1
|
||||
/* #undef HAVE_STRNCASECMP */
|
||||
|
||||
/* Define to 1 if you have the strncmpi function. */
|
||||
/* #undef HAVE_STRNCMPI */
|
||||
@ -677,7 +621,7 @@
|
||||
#define HAVE_STRUCT_TIMEVAL 1
|
||||
|
||||
/* Define to 1 if you have the <sys/filio.h> header file. */
|
||||
/* #undef HAVE_SYS_FILIO_H */
|
||||
#define HAVE_SYS_FILIO_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/ioctl.h> header file. */
|
||||
#define HAVE_SYS_IOCTL_H 1
|
||||
@ -698,7 +642,7 @@
|
||||
#define HAVE_SYS_SOCKET_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/sockio.h> header file. */
|
||||
/* #undef HAVE_SYS_SOCKIO_H */
|
||||
#define HAVE_SYS_SOCKIO_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/stat.h> header file. */
|
||||
#define HAVE_SYS_STAT_H 1
|
||||
@ -718,17 +662,11 @@
|
||||
/* Define to 1 if you have the <sys/utime.h> header file. */
|
||||
/* #undef HAVE_SYS_UTIME_H */
|
||||
|
||||
/* Define to 1 if you have the <sys/wait.h> header file. */
|
||||
#define HAVE_SYS_WAIT_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/xattr.h> header file. */
|
||||
#define HAVE_SYS_XATTR_H 1
|
||||
|
||||
/* Define to 1 if you have the <termios.h> header file. */
|
||||
#define HAVE_TERMIOS_H 1
|
||||
|
||||
/* Define to 1 if you have the <termio.h> header file. */
|
||||
#define HAVE_TERMIO_H 1
|
||||
/* #undef HAVE_TERMIO_H */
|
||||
|
||||
/* Define to 1 if you have the <time.h> header file. */
|
||||
#define HAVE_TIME_H 1
|
||||
@ -752,10 +690,10 @@
|
||||
#define HAVE_UTIME_H 1
|
||||
|
||||
/* Define to 1 if compiler supports C99 variadic macro style. */
|
||||
#define HAVE_VARIADIC_MACROS_C99 1
|
||||
/* #undef HAVE_VARIADIC_MACROS_C99 */
|
||||
|
||||
/* Define to 1 if compiler supports old gcc variadic macro style. */
|
||||
#define HAVE_VARIADIC_MACROS_GCC 1
|
||||
/* #undef HAVE_VARIADIC_MACROS_GCC */
|
||||
|
||||
/* Define to 1 if you have the winber.h header file. */
|
||||
/* #undef HAVE_WINBER_H */
|
||||
@ -773,10 +711,10 @@
|
||||
/* #undef HAVE_WINSOCK_H */
|
||||
|
||||
/* Define this symbol if your OS supports changing the contents of argv */
|
||||
#define HAVE_WRITABLE_ARGV 1
|
||||
/* #undef HAVE_WRITABLE_ARGV */
|
||||
|
||||
/* Define to 1 if you have the writev function. */
|
||||
#define HAVE_WRITEV 1
|
||||
/* #undef HAVE_WRITEV */
|
||||
|
||||
/* Define to 1 if you have the ws2tcpip.h header file. */
|
||||
/* #undef HAVE_WS2TCPIP_H */
|
||||
@ -784,12 +722,18 @@
|
||||
/* Define to 1 if you have the <x509.h> header file. */
|
||||
/* #undef HAVE_X509_H */
|
||||
|
||||
/* Define if you have the <process.h> header file. */
|
||||
/* #undef HAVE_PROCESS_H */
|
||||
|
||||
/* if you have the zlib.h header file */
|
||||
/* #undef HAVE_ZLIB_H */
|
||||
|
||||
/* Define to the sub-directory in which libtool stores uninstalled libraries.
|
||||
*/
|
||||
#define LT_OBJDIR ".libs/"
|
||||
/* #undef LT_OBJDIR */
|
||||
|
||||
/* If you lack a fine basename() prototype */
|
||||
/* #undef NEED_BASENAME_PROTO */
|
||||
|
||||
/* Define to 1 if you need the lber.h header file even with ldap.h */
|
||||
/* #undef NEED_LBER_H */
|
||||
@ -797,47 +741,62 @@
|
||||
/* Define to 1 if you need the malloc.h header file even with stdlib.h */
|
||||
/* #undef NEED_MALLOC_H */
|
||||
|
||||
/* Define to 1 if you need the memory.h header file even with stdlib.h */
|
||||
/* #undef NEED_MEMORY_H */
|
||||
|
||||
/* Define to 1 if _REENTRANT preprocessor symbol must be defined. */
|
||||
/* #undef NEED_REENTRANT */
|
||||
|
||||
/* Define to 1 if _THREAD_SAFE preprocessor symbol must be defined. */
|
||||
/* #undef NEED_THREAD_SAFE */
|
||||
|
||||
/* Define to enable NTLM delegation to winbind's ntlm_auth helper. */
|
||||
/* #undef NTLM_WB_ENABLED */
|
||||
|
||||
/* Define absolute filename for winbind's ntlm_auth helper. */
|
||||
/* #undef NTLM_WB_FILE */
|
||||
|
||||
/* cpu-machine-OS */
|
||||
#define OS "x86_64-unknown-linux-gnu"
|
||||
#define OS "Darwin"
|
||||
|
||||
/* Name of package */
|
||||
#define PACKAGE "curl"
|
||||
/* #undef PACKAGE */
|
||||
|
||||
/* Define to the address where bug reports for this package should be sent. */
|
||||
#define PACKAGE_BUGREPORT "a suitable curl mailing list: http://curl.haxx.se/mail/"
|
||||
/* #undef PACKAGE_BUGREPORT */
|
||||
|
||||
/* Define to the full name of this package. */
|
||||
#define PACKAGE_NAME "curl"
|
||||
/* #undef PACKAGE_NAME */
|
||||
|
||||
/* Define to the full name and version of this package. */
|
||||
#define PACKAGE_STRING "curl -"
|
||||
/* #undef PACKAGE_STRING */
|
||||
|
||||
/* Define to the one symbol short name of this package. */
|
||||
#define PACKAGE_TARNAME "curl"
|
||||
|
||||
/* Define to the home page for this package. */
|
||||
#define PACKAGE_URL ""
|
||||
/* #undef PACKAGE_TARNAME */
|
||||
|
||||
/* Define to the version of this package. */
|
||||
#define PACKAGE_VERSION "-"
|
||||
/* #undef PACKAGE_VERSION */
|
||||
|
||||
/* a suitable file to read random data from */
|
||||
/* #undef RANDOM_FILE */
|
||||
#define RANDOM_FILE "/dev/urandom"
|
||||
|
||||
/* Define to the type of arg 1 for recvfrom. */
|
||||
/* #undef RECVFROM_TYPE_ARG1 */
|
||||
|
||||
/* Define to the type pointed by arg 2 for recvfrom. */
|
||||
/* #undef RECVFROM_TYPE_ARG2 */
|
||||
|
||||
/* Define to 1 if the type pointed by arg 2 for recvfrom is void. */
|
||||
/* #undef RECVFROM_TYPE_ARG2_IS_VOID */
|
||||
|
||||
/* Define to the type of arg 3 for recvfrom. */
|
||||
/* #undef RECVFROM_TYPE_ARG3 */
|
||||
|
||||
/* Define to the type of arg 4 for recvfrom. */
|
||||
/* #undef RECVFROM_TYPE_ARG4 */
|
||||
|
||||
/* Define to the type pointed by arg 5 for recvfrom. */
|
||||
/* #undef RECVFROM_TYPE_ARG5 */
|
||||
|
||||
/* Define to 1 if the type pointed by arg 5 for recvfrom is void. */
|
||||
/* #undef RECVFROM_TYPE_ARG5_IS_VOID */
|
||||
|
||||
/* Define to the type pointed by arg 6 for recvfrom. */
|
||||
/* #undef RECVFROM_TYPE_ARG6 */
|
||||
|
||||
/* Define to 1 if the type pointed by arg 6 for recvfrom is void. */
|
||||
/* #undef RECVFROM_TYPE_ARG6_IS_VOID */
|
||||
|
||||
/* Define to the function return type for recvfrom. */
|
||||
/* #undef RECVFROM_TYPE_RETV */
|
||||
|
||||
/* Define to the type of arg 1 for recv. */
|
||||
#define RECV_TYPE_ARG1 int
|
||||
@ -858,19 +817,19 @@
|
||||
#define RETSIGTYPE void
|
||||
|
||||
/* Define to the type qualifier of arg 5 for select. */
|
||||
#define SELECT_QUAL_ARG5
|
||||
/* #undef SELECT_QUAL_ARG5 */
|
||||
|
||||
/* Define to the type of arg 1 for select. */
|
||||
#define SELECT_TYPE_ARG1 int
|
||||
/* #undef SELECT_TYPE_ARG1 */
|
||||
|
||||
/* Define to the type of args 2, 3 and 4 for select. */
|
||||
#define SELECT_TYPE_ARG234 fd_set *
|
||||
/* #undef SELECT_TYPE_ARG234 */
|
||||
|
||||
/* Define to the type of arg 5 for select. */
|
||||
#define SELECT_TYPE_ARG5 struct timeval *
|
||||
/* #undef SELECT_TYPE_ARG5 */
|
||||
|
||||
/* Define to the function return type for select. */
|
||||
#define SELECT_TYPE_RETV int
|
||||
/* #undef SELECT_TYPE_RETV */
|
||||
|
||||
/* Define to the type qualifier of arg 2 for send. */
|
||||
#define SEND_QUAL_ARG2 const
|
||||
@ -893,17 +852,14 @@
|
||||
/* The size of `int', as computed by sizeof. */
|
||||
#define SIZEOF_INT 4
|
||||
|
||||
/* The size of `short', as computed by sizeof. */
|
||||
#define SIZEOF_SHORT 2
|
||||
|
||||
/* The size of `long', as computed by sizeof. */
|
||||
#define SIZEOF_LONG 8
|
||||
|
||||
/* The size of `long long', as computed by sizeof. */
|
||||
/* #undef SIZEOF_LONG_LONG */
|
||||
|
||||
/* The size of `off_t', as computed by sizeof. */
|
||||
#define SIZEOF_OFF_T 8
|
||||
|
||||
/* The size of `short', as computed by sizeof. */
|
||||
#define SIZEOF_SHORT 2
|
||||
/* #undef SIZEOF_OFF_T */
|
||||
|
||||
/* The size of `size_t', as computed by sizeof. */
|
||||
#define SIZEOF_SIZE_T 8
|
||||
@ -912,37 +868,31 @@
|
||||
#define SIZEOF_TIME_T 8
|
||||
|
||||
/* The size of `void*', as computed by sizeof. */
|
||||
#define SIZEOF_VOIDP 8
|
||||
/* #undef SIZEOF_VOIDP */
|
||||
|
||||
/* Define to 1 if you have the ANSI C header files. */
|
||||
#define STDC_HEADERS 1
|
||||
|
||||
/* Define to the type of arg 3 for strerror_r. */
|
||||
#define STRERROR_R_TYPE_ARG3 size_t
|
||||
/* #undef STRERROR_R_TYPE_ARG3 */
|
||||
|
||||
/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
|
||||
#define TIME_WITH_SYS_TIME 1
|
||||
|
||||
/* Define to enable c-ares support */
|
||||
/* Define if you want to enable c-ares support */
|
||||
/* #undef USE_ARES */
|
||||
|
||||
/* if axTLS is enabled */
|
||||
/* #undef USE_AXTLS */
|
||||
/* Define if you want to enable POSIX threaded DNS lookup */
|
||||
/* #undef USE_THREADS_POSIX */
|
||||
|
||||
/* if CyaSSL is enabled */
|
||||
/* #undef USE_CYASSL */
|
||||
|
||||
/* to enable iOS/Mac OS X native SSL/TLS support */
|
||||
/* #undef USE_DARWINSSL */
|
||||
/* Define to disable non-blocking sockets. */
|
||||
/* #undef USE_BLOCKING_SOCKETS */
|
||||
|
||||
/* if GnuTLS is enabled */
|
||||
/* #undef USE_GNUTLS */
|
||||
|
||||
/* if GnuTLS uses nettle as crypto backend */
|
||||
/* #undef USE_GNUTLS_NETTLE */
|
||||
|
||||
/* if librtmp is in use */
|
||||
/* #undef USE_LIBRTMP */
|
||||
/* if PolarSSL is enabled */
|
||||
/* #undef USE_POLARSSL */
|
||||
|
||||
/* if libSSH2 is in use */
|
||||
/* #undef USE_LIBSSH2 */
|
||||
@ -950,78 +900,51 @@
|
||||
/* If you want to build curl with the built-in manual */
|
||||
#define USE_MANUAL 1
|
||||
|
||||
/* Define to enable metalink support */
|
||||
/* #undef USE_METALINK */
|
||||
|
||||
/* if nghttp2 is in use */
|
||||
/* #undef USE_NGHTTP2 */
|
||||
|
||||
/* if NSS is enabled */
|
||||
/* #undef USE_NSS */
|
||||
|
||||
/* Use OpenLDAP-specific code */
|
||||
/* if you want to use OpenLDAP code instead of legacy ldap implementation */
|
||||
/* #undef USE_OPENLDAP */
|
||||
|
||||
/* if OpenSSL is in use */
|
||||
/* #undef USE_OPENSSL */
|
||||
|
||||
/* if PolarSSL is enabled */
|
||||
/* #undef USE_POLARSSL */
|
||||
|
||||
/* to enable Windows native SSL/TLS support */
|
||||
/* #undef USE_SCHANNEL */
|
||||
|
||||
/* if SSL is enabled */
|
||||
/* #undef USE_SSLEAY */
|
||||
|
||||
/* if you want POSIX threaded DNS lookup */
|
||||
/* #undef USE_THREADS_POSIX */
|
||||
|
||||
/* Use TLS-SRP authentication */
|
||||
/* #undef USE_TLS_SRP */
|
||||
|
||||
/* Define to 1 if you have the `normaliz' (WinIDN) library (-lnormaliz). */
|
||||
/* #undef USE_WIN32_IDN */
|
||||
|
||||
/* Define to 1 if you are building a Windows target with large file support.
|
||||
*/
|
||||
/* #undef USE_WIN32_LARGE_FILES */
|
||||
/* if Unix domain sockets are enabled */
|
||||
#define USE_UNIX_SOCKETS
|
||||
|
||||
/* Define to 1 if you are building a Windows target without large file
|
||||
support. */
|
||||
/* #undef USE_WIN32_SMALL_FILES */
|
||||
/* #undef USE_WIN32_LARGE_FILES */
|
||||
|
||||
/* to enable SSPI support */
|
||||
/* #undef USE_WINDOWS_SSPI */
|
||||
|
||||
/* to enable Windows SSL */
|
||||
/* #undef USE_SCHANNEL */
|
||||
|
||||
/* Define to 1 if using yaSSL in OpenSSL compatibility mode. */
|
||||
/* #undef USE_YASSLEMUL */
|
||||
|
||||
/* Version number of package */
|
||||
#define VERSION "-"
|
||||
|
||||
/* Define to 1 to provide own prototypes. */
|
||||
/* #undef WANT_IDN_PROTOTYPES */
|
||||
/* #undef VERSION */
|
||||
|
||||
/* Define to avoid automatic inclusion of winsock.h */
|
||||
/* #undef WIN32_LEAN_AND_MEAN */
|
||||
|
||||
/* Define to 1 if OS is AIX. */
|
||||
#ifndef _ALL_SOURCE
|
||||
/* # undef _ALL_SOURCE */
|
||||
#endif
|
||||
|
||||
/* Enable large inode numbers on Mac OS X 10.5. */
|
||||
#ifndef _DARWIN_USE_64_BIT_INODE
|
||||
# define _DARWIN_USE_64_BIT_INODE 1
|
||||
# undef _ALL_SOURCE
|
||||
#endif
|
||||
|
||||
/* Number of bits in a file offset, on hosts where this is settable. */
|
||||
/* #undef _FILE_OFFSET_BITS */
|
||||
#define _FILE_OFFSET_BITS 64
|
||||
|
||||
/* Define for large files, on AIX-style hosts. */
|
||||
/* #undef _LARGE_FILES */
|
||||
|
||||
/* define this if you need it to compile thread-safe code */
|
||||
/* #undef _THREAD_SAFE */
|
||||
|
||||
/* Define to empty if `const' does not conform to ANSI C. */
|
||||
/* #undef const */
|
||||
|
||||
@ -1031,7 +954,7 @@
|
||||
/* Define to `__inline__' or `__inline' if that's what the C compiler
|
||||
calls it, or to nothing if 'inline' is not supported under any name. */
|
||||
#ifndef __cplusplus
|
||||
/* #undef inline */
|
||||
#undef inline
|
||||
#endif
|
||||
|
||||
/* Define to `unsigned int' if <sys/types.h> does not define. */
|
@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -69,7 +69,7 @@
|
||||
/* #undef CURL_EXTERN_SYMBOL */
|
||||
|
||||
/* Use Windows LDAP implementation */
|
||||
/* #undef CURL_LDAP_WIN */
|
||||
/* #undef USE_WIN32_LDAP */
|
||||
|
||||
/* your Entropy Gathering Daemon socket pathname */
|
||||
/* #undef EGD_SOCKET */
|
||||
@ -808,10 +808,4 @@
|
||||
#define HAVE_ZLIB_H 1
|
||||
#endif
|
||||
|
||||
/* Enable appropriate definitions only when OpenSSL support is enabled */
|
||||
#ifdef USE_SSLEAY
|
||||
/* if OpenSSL is in use */
|
||||
#define USE_OPENSSL
|
||||
#endif
|
||||
|
||||
#endif /* HEADER_CURL_CONFIG_SYMBIAN_H */
|
||||
|
@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -646,7 +646,7 @@
|
||||
/* #undef USE_OPENSSL */
|
||||
|
||||
/* if SSL is enabled */
|
||||
/* #undef USE_SSLEAY */
|
||||
/* #undef USE_OPENSSL */
|
||||
|
||||
/* to enable SSPI support */
|
||||
/* #undef USE_WINDOWS_SSPI */
|
||||
|
@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -75,7 +75,7 @@
|
||||
/* #undef CURL_EXTERN_SYMBOL */
|
||||
|
||||
/* Use Windows LDAP implementation */
|
||||
/* #undef CURL_LDAP_WIN */
|
||||
/* #undef USE_WIN32_LDAP */
|
||||
|
||||
/* your Entropy Gathering Daemon socket pathname */
|
||||
/* #undef EGD_SOCKET */
|
||||
@ -883,9 +883,6 @@
|
||||
/* if OpenSSL is in use */
|
||||
#define USE_OPENSSL 1
|
||||
|
||||
/* if SSL is enabled */
|
||||
#define USE_SSLEAY 1
|
||||
|
||||
/* Define to 1 if you are building a Windows target without large file
|
||||
support. */
|
||||
/* #undef USE_WIN32_LARGE_FILES */
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -409,7 +409,7 @@
|
||||
/* LDAP SUPPORT */
|
||||
/* ---------------------------------------------------------------- */
|
||||
|
||||
#define CURL_LDAP_WIN 1
|
||||
#define USE_WIN32_LDAP 1
|
||||
#undef HAVE_LDAP_URL_PARSE
|
||||
|
||||
/* ---------------------------------------------------------------- */
|
||||
@ -443,6 +443,6 @@
|
||||
#define ENOMEM 2
|
||||
#define EAGAIN 3
|
||||
|
||||
extern int stat(const char *path,struct stat *buffer );
|
||||
extern int stat(const char *path, struct stat *buffer);
|
||||
|
||||
#endif /* HEADER_CURL_CONFIG_WIN32CE_H */
|
||||
|
@ -6,7 +6,7 @@
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2012, Linus Nielsen Feltzing, <linus@haxx.se>
|
||||
* Copyright (C) 2012 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 2012 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -31,66 +31,134 @@
|
||||
#include "multiif.h"
|
||||
#include "sendf.h"
|
||||
#include "rawstr.h"
|
||||
#include "bundles.h"
|
||||
#include "conncache.h"
|
||||
#include "curl_printf.h"
|
||||
|
||||
#include "curl_memory.h"
|
||||
/* The last #include file should be: */
|
||||
#include "memdebug.h"
|
||||
|
||||
static void conn_llist_dtor(void *user, void *element)
|
||||
{
|
||||
struct connectdata *data = element;
|
||||
(void)user;
|
||||
|
||||
data->bundle = NULL;
|
||||
}
|
||||
|
||||
static CURLcode bundle_create(struct SessionHandle *data,
|
||||
struct connectbundle **cb_ptr)
|
||||
{
|
||||
(void)data;
|
||||
DEBUGASSERT(*cb_ptr == NULL);
|
||||
*cb_ptr = malloc(sizeof(struct connectbundle));
|
||||
if(!*cb_ptr)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
(*cb_ptr)->num_connections = 0;
|
||||
(*cb_ptr)->multiuse = BUNDLE_UNKNOWN;
|
||||
|
||||
(*cb_ptr)->conn_list = Curl_llist_alloc((curl_llist_dtor) conn_llist_dtor);
|
||||
if(!(*cb_ptr)->conn_list) {
|
||||
Curl_safefree(*cb_ptr);
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
static void bundle_destroy(struct connectbundle *cb_ptr)
|
||||
{
|
||||
if(!cb_ptr)
|
||||
return;
|
||||
|
||||
if(cb_ptr->conn_list) {
|
||||
Curl_llist_destroy(cb_ptr->conn_list, NULL);
|
||||
cb_ptr->conn_list = NULL;
|
||||
}
|
||||
free(cb_ptr);
|
||||
}
|
||||
|
||||
/* Add a connection to a bundle */
|
||||
static CURLcode bundle_add_conn(struct connectbundle *cb_ptr,
|
||||
struct connectdata *conn)
|
||||
{
|
||||
if(!Curl_llist_insert_next(cb_ptr->conn_list, cb_ptr->conn_list->tail, conn))
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
conn->bundle = cb_ptr;
|
||||
|
||||
cb_ptr->num_connections++;
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
/* Remove a connection from a bundle */
|
||||
static int bundle_remove_conn(struct connectbundle *cb_ptr,
|
||||
struct connectdata *conn)
|
||||
{
|
||||
struct curl_llist_element *curr;
|
||||
|
||||
curr = cb_ptr->conn_list->head;
|
||||
while(curr) {
|
||||
if(curr->ptr == conn) {
|
||||
Curl_llist_remove(cb_ptr->conn_list, curr, NULL);
|
||||
cb_ptr->num_connections--;
|
||||
conn->bundle = NULL;
|
||||
return 1; /* we removed a handle */
|
||||
}
|
||||
curr = curr->next;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void free_bundle_hash_entry(void *freethis)
|
||||
{
|
||||
struct connectbundle *b = (struct connectbundle *) freethis;
|
||||
|
||||
Curl_bundle_destroy(b);
|
||||
bundle_destroy(b);
|
||||
}
|
||||
|
||||
struct conncache *Curl_conncache_init(int size)
|
||||
int Curl_conncache_init(struct conncache *connc, int size)
|
||||
{
|
||||
struct conncache *connc;
|
||||
|
||||
connc = calloc(1, sizeof(struct conncache));
|
||||
if(!connc)
|
||||
return NULL;
|
||||
|
||||
connc->hash = Curl_hash_alloc(size, Curl_hash_str,
|
||||
return Curl_hash_init(&connc->hash, size, Curl_hash_str,
|
||||
Curl_str_key_compare, free_bundle_hash_entry);
|
||||
|
||||
if(!connc->hash) {
|
||||
free(connc);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return connc;
|
||||
}
|
||||
|
||||
void Curl_conncache_destroy(struct conncache *connc)
|
||||
{
|
||||
if(connc) {
|
||||
Curl_hash_destroy(connc->hash);
|
||||
connc->hash = NULL;
|
||||
free(connc);
|
||||
}
|
||||
if(connc)
|
||||
Curl_hash_destroy(&connc->hash);
|
||||
}
|
||||
|
||||
struct connectbundle *Curl_conncache_find_bundle(struct conncache *connc,
|
||||
char *hostname)
|
||||
/* returns an allocated key to find a bundle for this connection */
|
||||
static char *hashkey(struct connectdata *conn)
|
||||
{
|
||||
return aprintf("%s:%d",
|
||||
conn->bits.proxy?conn->proxy.name:conn->host.name,
|
||||
conn->localport);
|
||||
}
|
||||
|
||||
/* Look up the bundle with all the connections to the same host this
|
||||
connectdata struct is setup to use. */
|
||||
struct connectbundle *Curl_conncache_find_bundle(struct connectdata *conn,
|
||||
struct conncache *connc)
|
||||
{
|
||||
struct connectbundle *bundle = NULL;
|
||||
|
||||
if(connc)
|
||||
bundle = Curl_hash_pick(connc->hash, hostname, strlen(hostname)+1);
|
||||
if(connc) {
|
||||
char *key = hashkey(conn);
|
||||
if(key) {
|
||||
bundle = Curl_hash_pick(&connc->hash, key, strlen(key));
|
||||
free(key);
|
||||
}
|
||||
}
|
||||
|
||||
return bundle;
|
||||
}
|
||||
|
||||
static bool conncache_add_bundle(struct conncache *connc,
|
||||
char *hostname,
|
||||
char *key,
|
||||
struct connectbundle *bundle)
|
||||
{
|
||||
void *p;
|
||||
|
||||
p = Curl_hash_add(connc->hash, hostname, strlen(hostname)+1, bundle);
|
||||
void *p = Curl_hash_add(&connc->hash, key, strlen(key), bundle);
|
||||
|
||||
return p?TRUE:FALSE;
|
||||
}
|
||||
@ -104,14 +172,14 @@ static void conncache_remove_bundle(struct conncache *connc,
|
||||
if(!connc)
|
||||
return;
|
||||
|
||||
Curl_hash_start_iterate(connc->hash, &iter);
|
||||
Curl_hash_start_iterate(&connc->hash, &iter);
|
||||
|
||||
he = Curl_hash_next_element(&iter);
|
||||
while(he) {
|
||||
if(he->ptr == bundle) {
|
||||
/* The bundle is destroyed by the hash destructor function,
|
||||
free_bundle_hash_entry() */
|
||||
Curl_hash_delete(connc->hash, he->key, he->key_len);
|
||||
Curl_hash_delete(&connc->hash, he->key, he->key_len);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -127,23 +195,32 @@ CURLcode Curl_conncache_add_conn(struct conncache *connc,
|
||||
struct connectbundle *new_bundle = NULL;
|
||||
struct SessionHandle *data = conn->data;
|
||||
|
||||
bundle = Curl_conncache_find_bundle(data->state.conn_cache,
|
||||
conn->host.name);
|
||||
bundle = Curl_conncache_find_bundle(conn, data->state.conn_cache);
|
||||
if(!bundle) {
|
||||
result = Curl_bundle_create(data, &new_bundle);
|
||||
if(result != CURLE_OK)
|
||||
char *key;
|
||||
int rc;
|
||||
|
||||
result = bundle_create(data, &new_bundle);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
if(!conncache_add_bundle(data->state.conn_cache,
|
||||
conn->host.name, new_bundle)) {
|
||||
Curl_bundle_destroy(new_bundle);
|
||||
key = hashkey(conn);
|
||||
if(!key) {
|
||||
bundle_destroy(new_bundle);
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
rc = conncache_add_bundle(data->state.conn_cache, key, new_bundle);
|
||||
free(key);
|
||||
if(!rc) {
|
||||
bundle_destroy(new_bundle);
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
bundle = new_bundle;
|
||||
}
|
||||
|
||||
result = Curl_bundle_add_conn(bundle, conn);
|
||||
if(result != CURLE_OK) {
|
||||
result = bundle_add_conn(bundle, conn);
|
||||
if(result) {
|
||||
if(new_bundle)
|
||||
conncache_remove_bundle(data->state.conn_cache, new_bundle);
|
||||
return result;
|
||||
@ -152,6 +229,10 @@ CURLcode Curl_conncache_add_conn(struct conncache *connc,
|
||||
conn->connection_id = connc->next_connection_id++;
|
||||
connc->num_connections++;
|
||||
|
||||
DEBUGF(infof(conn->data, "Added connection %ld. "
|
||||
"The cache now contains %" CURL_FORMAT_CURL_OFF_TU " members\n",
|
||||
conn->connection_id, (curl_off_t) connc->num_connections));
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
@ -163,7 +244,7 @@ void Curl_conncache_remove_conn(struct conncache *connc,
|
||||
/* The bundle pointer can be NULL, since this function can be called
|
||||
due to a failed connection attempt, before being added to a bundle */
|
||||
if(bundle) {
|
||||
Curl_bundle_remove_conn(bundle, conn);
|
||||
bundle_remove_conn(bundle, conn);
|
||||
if(bundle->num_connections == 0) {
|
||||
conncache_remove_bundle(connc, bundle);
|
||||
}
|
||||
@ -171,8 +252,9 @@ void Curl_conncache_remove_conn(struct conncache *connc,
|
||||
if(connc) {
|
||||
connc->num_connections--;
|
||||
|
||||
DEBUGF(infof(conn->data, "The cache now contains %d members\n",
|
||||
connc->num_connections));
|
||||
DEBUGF(infof(conn->data, "The cache now contains %"
|
||||
CURL_FORMAT_CURL_OFF_TU " members\n",
|
||||
(curl_off_t) connc->num_connections));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -194,12 +276,11 @@ void Curl_conncache_foreach(struct conncache *connc,
|
||||
if(!connc)
|
||||
return;
|
||||
|
||||
Curl_hash_start_iterate(connc->hash, &iter);
|
||||
Curl_hash_start_iterate(&connc->hash, &iter);
|
||||
|
||||
he = Curl_hash_next_element(&iter);
|
||||
while(he) {
|
||||
struct connectbundle *bundle;
|
||||
struct connectdata *conn;
|
||||
|
||||
bundle = he->ptr;
|
||||
he = Curl_hash_next_element(&iter);
|
||||
@ -208,7 +289,7 @@ void Curl_conncache_foreach(struct conncache *connc,
|
||||
while(curr) {
|
||||
/* Yes, we need to update curr before calling func(), because func()
|
||||
might decide to remove the connection */
|
||||
conn = curr->ptr;
|
||||
struct connectdata *conn = curr->ptr;
|
||||
curr = curr->next;
|
||||
|
||||
if(1 == func(conn, param))
|
||||
@ -223,14 +304,14 @@ struct connectdata *
|
||||
Curl_conncache_find_first_connection(struct conncache *connc)
|
||||
{
|
||||
struct curl_hash_iterator iter;
|
||||
struct curl_llist_element *curr;
|
||||
struct curl_hash_element *he;
|
||||
struct connectbundle *bundle;
|
||||
|
||||
Curl_hash_start_iterate(connc->hash, &iter);
|
||||
Curl_hash_start_iterate(&connc->hash, &iter);
|
||||
|
||||
he = Curl_hash_next_element(&iter);
|
||||
while(he) {
|
||||
struct curl_llist_element *curr;
|
||||
bundle = he->ptr;
|
||||
|
||||
curr = bundle->conn_list->head;
|
||||
|
@ -7,6 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 2012 - 2014, Linus Nielsen Feltzing, <linus@haxx.se>
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
@ -23,18 +24,30 @@
|
||||
***************************************************************************/
|
||||
|
||||
struct conncache {
|
||||
struct curl_hash *hash;
|
||||
struct curl_hash hash;
|
||||
size_t num_connections;
|
||||
long next_connection_id;
|
||||
struct timeval last_cleanup;
|
||||
};
|
||||
|
||||
struct conncache *Curl_conncache_init(int size);
|
||||
#define BUNDLE_NO_MULTIUSE -1
|
||||
#define BUNDLE_UNKNOWN 0 /* initial value */
|
||||
#define BUNDLE_PIPELINING 1
|
||||
#define BUNDLE_MULTIPLEX 2
|
||||
|
||||
struct connectbundle {
|
||||
int multiuse; /* supports multi-use */
|
||||
size_t num_connections; /* Number of connections in the bundle */
|
||||
struct curl_llist *conn_list; /* The connectdata members of the bundle */
|
||||
};
|
||||
|
||||
int Curl_conncache_init(struct conncache *, int size);
|
||||
|
||||
void Curl_conncache_destroy(struct conncache *connc);
|
||||
|
||||
struct connectbundle *Curl_conncache_find_bundle(struct conncache *connc,
|
||||
char *hostname);
|
||||
/* return the correct bundle, to a host or a proxy */
|
||||
struct connectbundle *Curl_conncache_find_bundle(struct connectdata *conn,
|
||||
struct conncache *connc);
|
||||
|
||||
CURLcode Curl_conncache_add_conn(struct conncache *connc,
|
||||
struct connectdata *conn);
|
||||
|
@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -56,15 +56,12 @@
|
||||
#include <inet.h>
|
||||
#endif
|
||||
|
||||
#define _MPRINTF_REPLACE /* use our functions only */
|
||||
#include <curl/mprintf.h>
|
||||
|
||||
#include "curl_printf.h"
|
||||
#include "urldata.h"
|
||||
#include "sendf.h"
|
||||
#include "if2ip.h"
|
||||
#include "strerror.h"
|
||||
#include "connect.h"
|
||||
#include "curl_memory.h"
|
||||
#include "select.h"
|
||||
#include "url.h" /* for Curl_safefree() */
|
||||
#include "multiif.h"
|
||||
@ -77,7 +74,8 @@
|
||||
#include "conncache.h"
|
||||
#include "multihandle.h"
|
||||
|
||||
/* The last #include file should be: */
|
||||
/* The last #include files should be: */
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
#ifdef __SYMBIAN32__
|
||||
@ -238,7 +236,7 @@ long Curl_timeleft(struct SessionHandle *data,
|
||||
}
|
||||
|
||||
static CURLcode bindlocal(struct connectdata *conn,
|
||||
curl_socket_t sockfd, int af)
|
||||
curl_socket_t sockfd, int af, unsigned int scope)
|
||||
{
|
||||
struct SessionHandle *data = conn->data;
|
||||
|
||||
@ -257,12 +255,6 @@ static CURLcode bindlocal(struct connectdata *conn,
|
||||
int portnum = data->set.localportrange;
|
||||
const char *dev = data->set.str[STRING_DEVICE];
|
||||
int error;
|
||||
char myhost[256] = "";
|
||||
int done = 0; /* -1 for error, 1 for address found */
|
||||
bool is_interface = FALSE;
|
||||
bool is_host = FALSE;
|
||||
static const char *if_prefix = "if!";
|
||||
static const char *host_prefix = "host!";
|
||||
|
||||
/*************************************************************
|
||||
* Select device to bind socket to
|
||||
@ -274,6 +266,13 @@ static CURLcode bindlocal(struct connectdata *conn,
|
||||
memset(&sa, 0, sizeof(struct Curl_sockaddr_storage));
|
||||
|
||||
if(dev && (strlen(dev)<255) ) {
|
||||
char myhost[256] = "";
|
||||
int done = 0; /* -1 for error, 1 for address found */
|
||||
bool is_interface = FALSE;
|
||||
bool is_host = FALSE;
|
||||
static const char *if_prefix = "if!";
|
||||
static const char *host_prefix = "host!";
|
||||
|
||||
if(strncmp(if_prefix, dev, strlen(if_prefix)) == 0) {
|
||||
dev += strlen(if_prefix);
|
||||
is_interface = TRUE;
|
||||
@ -285,7 +284,8 @@ static CURLcode bindlocal(struct connectdata *conn,
|
||||
|
||||
/* interface */
|
||||
if(!is_host) {
|
||||
switch(Curl_if2ip(af, conn->scope, dev, myhost, sizeof(myhost))) {
|
||||
switch(Curl_if2ip(af, scope, conn->scope_id, dev,
|
||||
myhost, sizeof(myhost))) {
|
||||
case IF2IP_NOT_FOUND:
|
||||
if(is_interface) {
|
||||
/* Do not fall back to treating it as a host name */
|
||||
@ -374,7 +374,7 @@ static CURLcode bindlocal(struct connectdata *conn,
|
||||
|
||||
if(done > 0) {
|
||||
#ifdef ENABLE_IPV6
|
||||
/* ipv6 address */
|
||||
/* IPv6 address */
|
||||
if(af == AF_INET6) {
|
||||
#ifdef HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID
|
||||
char *scope_ptr = strchr(myhost, '%');
|
||||
@ -397,7 +397,7 @@ static CURLcode bindlocal(struct connectdata *conn,
|
||||
}
|
||||
else
|
||||
#endif
|
||||
/* ipv4 address */
|
||||
/* IPv4 address */
|
||||
if((af == AF_INET) &&
|
||||
(Curl_inet_pton(AF_INET, myhost, &si4->sin_addr) > 0)) {
|
||||
si4->sin_family = AF_INET;
|
||||
@ -540,7 +540,8 @@ static CURLcode trynextip(struct connectdata *conn,
|
||||
int sockindex,
|
||||
int tempindex)
|
||||
{
|
||||
CURLcode rc = CURLE_COULDNT_CONNECT;
|
||||
const int other = tempindex ^ 1;
|
||||
CURLcode result = CURLE_COULDNT_CONNECT;
|
||||
|
||||
/* First clean up after the failed socket.
|
||||
Don't close it yet to ensure that the next IP's socket gets a different
|
||||
@ -558,27 +559,29 @@ static CURLcode trynextip(struct connectdata *conn,
|
||||
family = conn->tempaddr[tempindex]->ai_family;
|
||||
ai = conn->tempaddr[tempindex]->ai_next;
|
||||
}
|
||||
#ifdef ENABLE_IPV6
|
||||
else if(conn->tempaddr[0]) {
|
||||
/* happy eyeballs - try the other protocol family */
|
||||
int firstfamily = conn->tempaddr[0]->ai_family;
|
||||
#ifdef ENABLE_IPV6
|
||||
family = (firstfamily == AF_INET) ? AF_INET6 : AF_INET;
|
||||
#else
|
||||
family = firstfamily;
|
||||
#endif
|
||||
ai = conn->tempaddr[0]->ai_next;
|
||||
}
|
||||
#endif
|
||||
|
||||
while(ai) {
|
||||
if(conn->tempaddr[other]) {
|
||||
/* we can safely skip addresses of the other protocol family */
|
||||
while(ai && ai->ai_family != family)
|
||||
ai = ai->ai_next;
|
||||
}
|
||||
|
||||
if(ai) {
|
||||
rc = singleipconnect(conn, ai, &conn->tempsock[tempindex]);
|
||||
if(rc == CURLE_COULDNT_CONNECT) {
|
||||
result = singleipconnect(conn, ai, &conn->tempsock[tempindex]);
|
||||
if(result == CURLE_COULDNT_CONNECT) {
|
||||
ai = ai->ai_next;
|
||||
continue;
|
||||
}
|
||||
|
||||
conn->tempaddr[tempindex] = ai;
|
||||
}
|
||||
break;
|
||||
@ -588,7 +591,7 @@ static CURLcode trynextip(struct connectdata *conn,
|
||||
if(fd_to_close != CURL_SOCKET_BAD)
|
||||
Curl_closesocket(conn, fd_to_close);
|
||||
|
||||
return rc;
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Copies connection info into the session handle to make it available
|
||||
@ -616,7 +619,7 @@ static bool getaddressinfo(struct sockaddr* sa, char* addr,
|
||||
|
||||
switch (sa->sa_family) {
|
||||
case AF_INET:
|
||||
si = (struct sockaddr_in*) sa;
|
||||
si = (struct sockaddr_in*)(void*) sa;
|
||||
if(Curl_inet_ntop(sa->sa_family, &si->sin_addr,
|
||||
addr, MAX_IPADR_LEN)) {
|
||||
us_port = ntohs(si->sin_port);
|
||||
@ -626,7 +629,7 @@ static bool getaddressinfo(struct sockaddr* sa, char* addr,
|
||||
break;
|
||||
#ifdef ENABLE_IPV6
|
||||
case AF_INET6:
|
||||
si6 = (struct sockaddr_in6*)sa;
|
||||
si6 = (struct sockaddr_in6*)(void*) sa;
|
||||
if(Curl_inet_ntop(sa->sa_family, &si6->sin6_addr,
|
||||
addr, MAX_IPADR_LEN)) {
|
||||
us_port = ntohs(si6->sin6_port);
|
||||
@ -656,7 +659,6 @@ static bool getaddressinfo(struct sockaddr* sa, char* addr,
|
||||
connection */
|
||||
void Curl_updateconninfo(struct connectdata *conn, curl_socket_t sockfd)
|
||||
{
|
||||
int error;
|
||||
curl_socklen_t len;
|
||||
struct Curl_sockaddr_storage ssrem;
|
||||
struct Curl_sockaddr_storage ssloc;
|
||||
@ -667,6 +669,7 @@ void Curl_updateconninfo(struct connectdata *conn, curl_socket_t sockfd)
|
||||
return;
|
||||
|
||||
if(!conn->bits.reuse) {
|
||||
int error;
|
||||
|
||||
len = sizeof(struct Curl_sockaddr_storage);
|
||||
if(getpeername(sockfd, (struct sockaddr*) &ssrem, &len)) {
|
||||
@ -677,6 +680,7 @@ void Curl_updateconninfo(struct connectdata *conn, curl_socket_t sockfd)
|
||||
}
|
||||
|
||||
len = sizeof(struct Curl_sockaddr_storage);
|
||||
memset(&ssloc, 0, sizeof(ssloc));
|
||||
if(getsockname(sockfd, (struct sockaddr*) &ssloc, &len)) {
|
||||
error = SOCKERRNO;
|
||||
failf(data, "getsockname() failed with errno %d: %s",
|
||||
@ -716,11 +720,11 @@ CURLcode Curl_is_connected(struct connectdata *conn,
|
||||
bool *connected)
|
||||
{
|
||||
struct SessionHandle *data = conn->data;
|
||||
CURLcode code = CURLE_OK;
|
||||
CURLcode result = CURLE_OK;
|
||||
long allow;
|
||||
int error = 0;
|
||||
struct timeval now;
|
||||
int result;
|
||||
int rc;
|
||||
int i;
|
||||
|
||||
DEBUGASSERT(sockindex >= FIRSTSOCKET && sockindex <= SECONDARYSOCKET);
|
||||
@ -745,6 +749,7 @@ CURLcode Curl_is_connected(struct connectdata *conn,
|
||||
}
|
||||
|
||||
for(i=0; i<2; i++) {
|
||||
const int other = i ^ 1;
|
||||
if(conn->tempsock[i] == CURL_SOCKET_BAD)
|
||||
continue;
|
||||
|
||||
@ -756,9 +761,9 @@ CURLcode Curl_is_connected(struct connectdata *conn,
|
||||
#endif
|
||||
|
||||
/* check socket for connect */
|
||||
result = Curl_socket_ready(CURL_SOCKET_BAD, conn->tempsock[i], 0);
|
||||
rc = Curl_socket_ready(CURL_SOCKET_BAD, conn->tempsock[i], 0);
|
||||
|
||||
if(result == 0) { /* no connection yet */
|
||||
if(rc == 0) { /* no connection yet */
|
||||
if(curlx_tvdiff(now, conn->connecttime) >= conn->timeoutms_per_addr) {
|
||||
infof(data, "After %ldms connect time, move on!\n",
|
||||
conn->timeoutms_per_addr);
|
||||
@ -771,10 +776,9 @@ CURLcode Curl_is_connected(struct connectdata *conn,
|
||||
trynextip(conn, sockindex, 1);
|
||||
}
|
||||
}
|
||||
else if(result == CURL_CSELECT_OUT) {
|
||||
else if(rc == CURL_CSELECT_OUT) {
|
||||
if(verifyconnect(conn->tempsock[i], &error)) {
|
||||
/* we are connected with TCP, awesome! */
|
||||
int other = i ^ 1;
|
||||
|
||||
/* use this socket from now on */
|
||||
conn->sock[sockindex] = conn->tempsock[i];
|
||||
@ -788,9 +792,9 @@ CURLcode Curl_is_connected(struct connectdata *conn,
|
||||
}
|
||||
|
||||
/* see if we need to do any proxy magic first once we connected */
|
||||
code = Curl_connected_proxy(conn, sockindex);
|
||||
if(code)
|
||||
return code;
|
||||
result = Curl_connected_proxy(conn, sockindex);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
conn->bits.tcpconnect[sockindex] = TRUE;
|
||||
|
||||
@ -805,7 +809,7 @@ CURLcode Curl_is_connected(struct connectdata *conn,
|
||||
else
|
||||
infof(data, "Connection failed\n");
|
||||
}
|
||||
else if(result & CURL_CSELECT_ERR)
|
||||
else if(rc & CURL_CSELECT_ERR)
|
||||
(void)verifyconnect(conn->tempsock[i], &error);
|
||||
|
||||
/*
|
||||
@ -813,10 +817,11 @@ CURLcode Curl_is_connected(struct connectdata *conn,
|
||||
* address" for the given host. But first remember the latest error.
|
||||
*/
|
||||
if(error) {
|
||||
char ipaddress[MAX_IPADR_LEN];
|
||||
data->state.os_errno = error;
|
||||
SET_SOCKERRNO(error);
|
||||
if(conn->tempaddr[i]) {
|
||||
CURLcode status;
|
||||
char ipaddress[MAX_IPADR_LEN];
|
||||
Curl_printable_address(conn->tempaddr[i], ipaddress, MAX_IPADR_LEN);
|
||||
infof(data, "connect to %s port %ld failed: %s\n",
|
||||
ipaddress, conn->port, Curl_strerror(conn, error));
|
||||
@ -824,21 +829,24 @@ CURLcode Curl_is_connected(struct connectdata *conn,
|
||||
conn->timeoutms_per_addr = conn->tempaddr[i]->ai_next == NULL ?
|
||||
allow : allow / 2;
|
||||
|
||||
code = trynextip(conn, sockindex, i);
|
||||
status = trynextip(conn, sockindex, i);
|
||||
if(status != CURLE_COULDNT_CONNECT
|
||||
|| conn->tempsock[other] == CURL_SOCKET_BAD)
|
||||
/* the last attempt failed and no other sockets remain open */
|
||||
result = status;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(code) {
|
||||
if(result) {
|
||||
/* no more addresses to try */
|
||||
|
||||
/* if the first address family runs out of addresses to try before
|
||||
the happy eyeball timeout, go ahead and try the next family now */
|
||||
if(conn->tempaddr[1] == NULL) {
|
||||
int rc;
|
||||
rc = trynextip(conn, sockindex, 1);
|
||||
if(rc == CURLE_OK)
|
||||
return CURLE_OK;
|
||||
result = trynextip(conn, sockindex, 1);
|
||||
if(!result)
|
||||
return result;
|
||||
}
|
||||
|
||||
failf(data, "Failed to connect to %s port %ld: %s",
|
||||
@ -846,15 +854,14 @@ CURLcode Curl_is_connected(struct connectdata *conn,
|
||||
conn->port, Curl_strerror(conn, error));
|
||||
}
|
||||
|
||||
return code;
|
||||
return result;
|
||||
}
|
||||
|
||||
static void tcpnodelay(struct connectdata *conn,
|
||||
curl_socket_t sockfd)
|
||||
void Curl_tcpnodelay(struct connectdata *conn, curl_socket_t sockfd)
|
||||
{
|
||||
#ifdef TCP_NODELAY
|
||||
struct SessionHandle *data= conn->data;
|
||||
curl_socklen_t onoff = (curl_socklen_t) data->set.tcp_nodelay;
|
||||
curl_socklen_t onoff = (curl_socklen_t) 1;
|
||||
int level = IPPROTO_TCP;
|
||||
|
||||
#if 0
|
||||
@ -875,7 +882,7 @@ static void tcpnodelay(struct connectdata *conn,
|
||||
infof(data, "Could not set TCP_NODELAY: %s\n",
|
||||
Curl_strerror(conn, SOCKERRNO));
|
||||
else
|
||||
infof(data,"TCP_NODELAY set\n");
|
||||
infof(data, "TCP_NODELAY set\n");
|
||||
#else
|
||||
(void)conn;
|
||||
(void)sockfd;
|
||||
@ -941,16 +948,21 @@ void Curl_sndbufset(curl_socket_t sockfd)
|
||||
detectOsState = DETECT_OS_VISTA_OR_LATER;
|
||||
}
|
||||
#else
|
||||
ULONGLONG majorVersionMask;
|
||||
ULONGLONG cm;
|
||||
OSVERSIONINFOEX osver;
|
||||
|
||||
memset(&osver, 0, sizeof(osver));
|
||||
osver.dwOSVersionInfoSize = sizeof(osver);
|
||||
osver.dwMajorVersion = majorVersion;
|
||||
majorVersionMask = VerSetConditionMask(0, VER_MAJORVERSION,
|
||||
VER_GREATER_EQUAL);
|
||||
|
||||
if(VerifyVersionInfo(&osver, VER_MAJORVERSION, majorVersionMask))
|
||||
cm = VerSetConditionMask(0, VER_MAJORVERSION, VER_GREATER_EQUAL);
|
||||
cm = VerSetConditionMask(cm, VER_MINORVERSION, VER_GREATER_EQUAL);
|
||||
cm = VerSetConditionMask(cm, VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL);
|
||||
cm = VerSetConditionMask(cm, VER_SERVICEPACKMINOR, VER_GREATER_EQUAL);
|
||||
|
||||
if(VerifyVersionInfo(&osver, (VER_MAJORVERSION | VER_MINORVERSION |
|
||||
VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR),
|
||||
cm))
|
||||
detectOsState = DETECT_OS_VISTA_OR_LATER;
|
||||
else
|
||||
detectOsState = DETECT_OS_PREVISTA;
|
||||
@ -977,8 +989,7 @@ void Curl_sndbufset(curl_socket_t sockfd)
|
||||
* singleipconnect() connects to the given IP only, and it may return without
|
||||
* having connected.
|
||||
*/
|
||||
static CURLcode
|
||||
singleipconnect(struct connectdata *conn,
|
||||
static CURLcode singleipconnect(struct connectdata *conn,
|
||||
const Curl_addrinfo *ai,
|
||||
curl_socket_t *sockp)
|
||||
{
|
||||
@ -988,14 +999,15 @@ singleipconnect(struct connectdata *conn,
|
||||
bool isconnected = FALSE;
|
||||
struct SessionHandle *data = conn->data;
|
||||
curl_socket_t sockfd;
|
||||
CURLcode res = CURLE_OK;
|
||||
CURLcode result;
|
||||
char ipaddress[MAX_IPADR_LEN];
|
||||
long port;
|
||||
bool is_tcp;
|
||||
|
||||
*sockp = CURL_SOCKET_BAD;
|
||||
|
||||
res = Curl_socket(conn, ai, &addr, &sockfd);
|
||||
if(res)
|
||||
result = Curl_socket(conn, ai, &addr, &sockfd);
|
||||
if(result)
|
||||
/* Failed to create the socket, but still return OK since we signal the
|
||||
lack of socket as well. This allows the parent function to keep looping
|
||||
over alternative addresses/socket families etc. */
|
||||
@ -1013,14 +1025,20 @@ singleipconnect(struct connectdata *conn,
|
||||
}
|
||||
infof(data, " Trying %s...\n", ipaddress);
|
||||
|
||||
if(data->set.tcp_nodelay)
|
||||
tcpnodelay(conn, sockfd);
|
||||
#ifdef ENABLE_IPV6
|
||||
is_tcp = (addr.family == AF_INET || addr.family == AF_INET6) &&
|
||||
addr.socktype == SOCK_STREAM;
|
||||
#else
|
||||
is_tcp = (addr.family == AF_INET) && addr.socktype == SOCK_STREAM;
|
||||
#endif
|
||||
if(is_tcp && data->set.tcp_nodelay)
|
||||
Curl_tcpnodelay(conn, sockfd);
|
||||
|
||||
nosigpipe(conn, sockfd);
|
||||
|
||||
Curl_sndbufset(sockfd);
|
||||
|
||||
if(data->set.tcp_keepalive)
|
||||
if(is_tcp && data->set.tcp_keepalive)
|
||||
tcpkeepalive(data, sockfd);
|
||||
|
||||
if(data->set.fsockopt) {
|
||||
@ -1038,23 +1056,30 @@ singleipconnect(struct connectdata *conn,
|
||||
}
|
||||
|
||||
/* possibly bind the local end to an IP, interface or port */
|
||||
res = bindlocal(conn, sockfd, addr.family);
|
||||
if(res) {
|
||||
if(addr.family == AF_INET
|
||||
#ifdef ENABLE_IPV6
|
||||
|| addr.family == AF_INET6
|
||||
#endif
|
||||
) {
|
||||
result = bindlocal(conn, sockfd, addr.family,
|
||||
Curl_ipv6_scope((struct sockaddr*)&addr.sa_addr));
|
||||
if(result) {
|
||||
Curl_closesocket(conn, sockfd); /* close socket and bail out */
|
||||
if(res == CURLE_UNSUPPORTED_PROTOCOL) {
|
||||
if(result == CURLE_UNSUPPORTED_PROTOCOL) {
|
||||
/* The address family is not supported on this interface.
|
||||
We can continue trying addresses */
|
||||
return CURLE_OK;
|
||||
return CURLE_COULDNT_CONNECT;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
/* set socket non-blocking */
|
||||
curlx_nonblock(sockfd, TRUE);
|
||||
(void)curlx_nonblock(sockfd, TRUE);
|
||||
|
||||
conn->connecttime = Curl_tvnow();
|
||||
if(conn->num_addr > 1)
|
||||
Curl_expire(data, conn->timeoutms_per_addr);
|
||||
Curl_expire_latest(data, conn->timeoutms_per_addr);
|
||||
|
||||
/* Connect TCP sockets, bind UDP */
|
||||
if(!isconnected && (conn->socktype == SOCK_STREAM)) {
|
||||
@ -1084,25 +1109,25 @@ singleipconnect(struct connectdata *conn,
|
||||
case EAGAIN:
|
||||
#endif
|
||||
#endif
|
||||
res = CURLE_OK;
|
||||
result = CURLE_OK;
|
||||
break;
|
||||
|
||||
default:
|
||||
/* unknown error, fallthrough and try another address! */
|
||||
infof(data, "Immediate connect fail for %s: %s\n",
|
||||
ipaddress, Curl_strerror(conn,error));
|
||||
ipaddress, Curl_strerror(conn, error));
|
||||
data->state.os_errno = error;
|
||||
|
||||
/* connect failed */
|
||||
Curl_closesocket(conn, sockfd);
|
||||
res = CURLE_COULDNT_CONNECT;
|
||||
result = CURLE_COULDNT_CONNECT;
|
||||
}
|
||||
}
|
||||
|
||||
if(!res)
|
||||
if(!result)
|
||||
*sockp = sockfd;
|
||||
|
||||
return res;
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1116,7 +1141,7 @@ CURLcode Curl_connecthost(struct connectdata *conn, /* context */
|
||||
{
|
||||
struct SessionHandle *data = conn->data;
|
||||
struct timeval before = Curl_tvnow();
|
||||
CURLcode res = CURLE_COULDNT_CONNECT;
|
||||
CURLcode result = CURLE_COULDNT_CONNECT;
|
||||
|
||||
long timeout_ms = Curl_timeleft(data, &before, TRUE);
|
||||
|
||||
@ -1139,14 +1164,17 @@ CURLcode Curl_connecthost(struct connectdata *conn, /* context */
|
||||
|
||||
/* start connecting to first IP */
|
||||
while(conn->tempaddr[0]) {
|
||||
res = singleipconnect(conn, conn->tempaddr[0], &(conn->tempsock[0]));
|
||||
if(res == CURLE_OK)
|
||||
result = singleipconnect(conn, conn->tempaddr[0], &(conn->tempsock[0]));
|
||||
if(!result)
|
||||
break;
|
||||
conn->tempaddr[0] = conn->tempaddr[0]->ai_next;
|
||||
}
|
||||
|
||||
if(conn->tempsock[0] == CURL_SOCKET_BAD)
|
||||
return res;
|
||||
if(conn->tempsock[0] == CURL_SOCKET_BAD) {
|
||||
if(!result)
|
||||
result = CURLE_COULDNT_CONNECT;
|
||||
return result;
|
||||
}
|
||||
|
||||
data->info.numconnects++; /* to track the number of connections made */
|
||||
|
||||
@ -1181,15 +1209,20 @@ curl_socket_t Curl_getconnectinfo(struct SessionHandle *data,
|
||||
|
||||
DEBUGASSERT(data);
|
||||
|
||||
/* this only works for an easy handle that has been used for
|
||||
curl_easy_perform()! */
|
||||
if(data->state.lastconnect && data->multi_easy) {
|
||||
/* this works for an easy handle:
|
||||
* - that has been used for curl_easy_perform()
|
||||
* - that is associated with a multi handle, and whose connection
|
||||
* was detached with CURLOPT_CONNECT_ONLY
|
||||
*/
|
||||
if(data->state.lastconnect && (data->multi_easy || data->multi)) {
|
||||
struct connectdata *c = data->state.lastconnect;
|
||||
struct connfind find;
|
||||
find.tofind = data->state.lastconnect;
|
||||
find.found = FALSE;
|
||||
|
||||
Curl_conncache_foreach(data->multi_easy->conn_cache, &find, conn_is_conn);
|
||||
Curl_conncache_foreach(data->multi_easy?
|
||||
&data->multi_easy->conn_cache:
|
||||
&data->multi->conn_cache, &find, conn_is_conn);
|
||||
|
||||
if(!find.found) {
|
||||
data->state.lastconnect = NULL;
|
||||
@ -1240,15 +1273,18 @@ int Curl_closesocket(struct connectdata *conn,
|
||||
accept, then we MUST NOT call the callback but clear the accepted
|
||||
status */
|
||||
conn->sock_accepted[SECONDARYSOCKET] = FALSE;
|
||||
else
|
||||
else {
|
||||
Curl_multi_closed(conn, sock);
|
||||
return conn->fclosesocket(conn->closesocket_client, sock);
|
||||
}
|
||||
sclose(sock);
|
||||
}
|
||||
|
||||
if(conn)
|
||||
/* tell the multi-socket code about this */
|
||||
Curl_multi_closed(conn, sock);
|
||||
|
||||
sclose(sock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1312,9 +1348,9 @@ CURLcode Curl_socket(struct connectdata *conn,
|
||||
return CURLE_COULDNT_CONNECT;
|
||||
|
||||
#if defined(ENABLE_IPV6) && defined(HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID)
|
||||
if(conn->scope && (addr->family == AF_INET6)) {
|
||||
if(conn->scope_id && (addr->family == AF_INET6)) {
|
||||
struct sockaddr_in6 * const sa6 = (void *)&addr->sa_addr;
|
||||
sa6->sin6_scope_id = conn->scope;
|
||||
sa6->sin6_scope_id = conn->scope_id;
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -1325,16 +1361,22 @@ CURLcode Curl_socket(struct connectdata *conn,
|
||||
#ifdef CURLDEBUG
|
||||
/*
|
||||
* Curl_conncontrol() is used to set the conn->bits.close bit on or off. It
|
||||
* MUST be called with the connclose() or connclose() macros with a stated
|
||||
* MUST be called with the connclose() or connkeep() macros with a stated
|
||||
* reason. The reason is only shown in debug builds but helps to figure out
|
||||
* decision paths when connections are or aren't re-used as expected.
|
||||
*/
|
||||
void Curl_conncontrol(struct connectdata *conn, bool closeit,
|
||||
const char *reason)
|
||||
{
|
||||
#if defined(CURL_DISABLE_VERBOSE_STRINGS)
|
||||
(void) reason;
|
||||
#endif
|
||||
if(closeit != conn->bits.close) {
|
||||
infof(conn->data, "Marked for [%s]: %s\n", closeit?"closure":"keep alive",
|
||||
reason);
|
||||
conn->bits.close = closeit; /* the only place in the source code that should
|
||||
assign this bit */
|
||||
|
||||
conn->bits.close = closeit; /* the only place in the source code that
|
||||
should assign this bit */
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -41,7 +41,7 @@ long Curl_timeleft(struct SessionHandle *data,
|
||||
|
||||
#define DEFAULT_CONNECT_TIMEOUT 300000 /* milliseconds == five minutes */
|
||||
#define HAPPY_EYEBALLS_TIMEOUT 200 /* milliseconds to wait between
|
||||
ipv4/ipv6 connection attempts */
|
||||
IPv4/IPv6 connection attempts */
|
||||
|
||||
/*
|
||||
* Used to extract socket and connectdata struct for the most recent
|
||||
@ -102,6 +102,8 @@ CURLcode Curl_socket(struct connectdata *conn,
|
||||
struct Curl_sockaddr_ex *addr,
|
||||
curl_socket_t *sockfd);
|
||||
|
||||
void Curl_tcpnodelay(struct connectdata *conn, curl_socket_t sockfd);
|
||||
|
||||
#ifdef CURLDEBUG
|
||||
/*
|
||||
* Curl_connclose() sets the bit.close bit to TRUE with an explanation.
|
||||
|
@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -26,14 +26,17 @@
|
||||
RECEIVING COOKIE INFORMATION
|
||||
============================
|
||||
|
||||
struct CookieInfo *cookie_init(char *file);
|
||||
struct CookieInfo *Curl_cookie_init(struct SessionHandle *data,
|
||||
const char *file, struct CookieInfo *inc, bool newsession);
|
||||
|
||||
Inits a cookie struct to store data in a local file. This is always
|
||||
called before any cookies are set.
|
||||
|
||||
int cookies_set(struct CookieInfo *cookie, char *cookie_line);
|
||||
struct Cookie *Curl_cookie_add(struct SessionHandle *data,
|
||||
struct CookieInfo *c, bool httpheader, char *lineptr,
|
||||
const char *domain, const char *path);
|
||||
|
||||
The 'cookie_line' parameter is a full "Set-cookie:" line as
|
||||
The 'lineptr' parameter is a full "Set-cookie:" line as
|
||||
received from a server.
|
||||
|
||||
The function need to replace previously stored lines that this new
|
||||
@ -47,7 +50,7 @@ int cookies_set(struct CookieInfo *cookie, char *cookie_line);
|
||||
SENDING COOKIE INFORMATION
|
||||
==========================
|
||||
|
||||
struct Cookies *cookie_getlist(struct CookieInfo *cookie,
|
||||
struct Cookies *Curl_cookie_getlist(struct CookieInfo *cookie,
|
||||
char *host, char *path, bool secure);
|
||||
|
||||
For a given host and path, return a linked list of cookies that
|
||||
@ -81,43 +84,33 @@ Example set of cookies:
|
||||
|
||||
#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)
|
||||
|
||||
#define _MPRINTF_REPLACE
|
||||
#include <curl/mprintf.h>
|
||||
|
||||
#include "curl_printf.h"
|
||||
#include "urldata.h"
|
||||
#include "cookie.h"
|
||||
#include "strequal.h"
|
||||
#include "strtok.h"
|
||||
#include "sendf.h"
|
||||
#include "slist.h"
|
||||
#include "curl_memory.h"
|
||||
#include "share.h"
|
||||
#include "strtoofft.h"
|
||||
#include "rawstr.h"
|
||||
#include "curl_memrchr.h"
|
||||
#include "inet_pton.h"
|
||||
|
||||
/* The last #include file should be: */
|
||||
/* The last #include files should be: */
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
static void freecookie(struct Cookie *co)
|
||||
{
|
||||
if(co->expirestr)
|
||||
free(co->expirestr);
|
||||
if(co->domain)
|
||||
free(co->domain);
|
||||
if(co->path)
|
||||
free(co->path);
|
||||
if(co->spath)
|
||||
free(co->spath);
|
||||
if(co->name)
|
||||
free(co->name);
|
||||
if(co->value)
|
||||
free(co->value);
|
||||
if(co->maxage)
|
||||
free(co->maxage);
|
||||
if(co->version)
|
||||
free(co->version);
|
||||
|
||||
free(co);
|
||||
}
|
||||
|
||||
@ -232,11 +225,14 @@ static char *sanitize_cookie_path(const char *cookie_path)
|
||||
return NULL;
|
||||
|
||||
/* some stupid site sends path attribute with '"'. */
|
||||
len = strlen(new_path);
|
||||
if(new_path[0] == '\"') {
|
||||
memmove((void *)new_path, (const void *)(new_path + 1), strlen(new_path));
|
||||
memmove((void *)new_path, (const void *)(new_path + 1), len);
|
||||
len--;
|
||||
}
|
||||
if(new_path[strlen(new_path) - 1] == '\"') {
|
||||
new_path[strlen(new_path) - 1] = 0x0;
|
||||
if(len && (new_path[len - 1] == '\"')) {
|
||||
new_path[len - 1] = 0x0;
|
||||
len--;
|
||||
}
|
||||
|
||||
/* RFC6265 5.2.4 The Path Attribute */
|
||||
@ -248,8 +244,7 @@ static char *sanitize_cookie_path(const char *cookie_path)
|
||||
}
|
||||
|
||||
/* convert /hoge/ to /hoge */
|
||||
len = strlen(new_path);
|
||||
if(1 < len && new_path[len - 1] == '/') {
|
||||
if(len && new_path[len - 1] == '/') {
|
||||
new_path[len - 1] = 0x0;
|
||||
}
|
||||
|
||||
@ -258,6 +253,8 @@ static char *sanitize_cookie_path(const char *cookie_path)
|
||||
|
||||
/*
|
||||
* Load cookies from all given cookie files (CURLOPT_COOKIEFILE).
|
||||
*
|
||||
* NOTE: OOM or cookie parsing failures are ignored.
|
||||
*/
|
||||
void Curl_cookie_loadfiles(struct SessionHandle *data)
|
||||
{
|
||||
@ -265,10 +262,17 @@ void Curl_cookie_loadfiles(struct SessionHandle *data)
|
||||
if(list) {
|
||||
Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE);
|
||||
while(list) {
|
||||
data->cookies = Curl_cookie_init(data,
|
||||
struct CookieInfo *newcookies = Curl_cookie_init(data,
|
||||
list->data,
|
||||
data->cookies,
|
||||
data->set.cookiesession);
|
||||
if(!newcookies)
|
||||
/* Failure may be due to OOM or a bad cookie; both are ignored
|
||||
* but only the first should be
|
||||
*/
|
||||
infof(data, "ignoring failed cookie_init for %s\n", list->data);
|
||||
else
|
||||
data->cookies = newcookies;
|
||||
list = list->next;
|
||||
}
|
||||
curl_slist_free_all(data->change.cookielist); /* clean up list */
|
||||
@ -285,7 +289,6 @@ void Curl_cookie_loadfiles(struct SessionHandle *data)
|
||||
*/
|
||||
static void strstore(char **str, const char *newstr)
|
||||
{
|
||||
if(*str)
|
||||
free(*str);
|
||||
*str = strdup(newstr);
|
||||
}
|
||||
@ -319,6 +322,28 @@ static void remove_expired(struct CookieInfo *cookies)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Return true if the given string is an IP(v4|v6) address.
|
||||
*/
|
||||
static bool isip(const char *domain)
|
||||
{
|
||||
struct in_addr addr;
|
||||
#ifdef ENABLE_IPV6
|
||||
struct in6_addr addr6;
|
||||
#endif
|
||||
|
||||
if(Curl_inet_pton(AF_INET, domain, &addr)
|
||||
#ifdef ENABLE_IPV6
|
||||
|| Curl_inet_pton(AF_INET6, domain, &addr6)
|
||||
#endif
|
||||
) {
|
||||
/* domain name given as IP address */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
*
|
||||
* Curl_cookie_add()
|
||||
@ -328,6 +353,8 @@ static void remove_expired(struct CookieInfo *cookies)
|
||||
* Be aware that sometimes we get an IP-only host name, and that might also be
|
||||
* a numerical IPv6 address.
|
||||
*
|
||||
* Returns NULL on out of memory or invalid cookie. This is suboptimal,
|
||||
* as they should be treated separately.
|
||||
***************************************************************************/
|
||||
|
||||
struct Cookie *
|
||||
@ -382,7 +409,7 @@ Curl_cookie_add(struct SessionHandle *data,
|
||||
do {
|
||||
/* we have a <what>=<this> pair or a stand-alone word here */
|
||||
name[0]=what[0]=0; /* init the buffers */
|
||||
if(1 <= sscanf(ptr, "%" MAX_NAME_TXT "[^;\r\n =]=%"
|
||||
if(1 <= sscanf(ptr, "%" MAX_NAME_TXT "[^;\r\n =] =%"
|
||||
MAX_COOKIE_LINE_TXT "[^;\r\n]",
|
||||
name, what)) {
|
||||
/* Use strstore() below to properly deal with received cookie
|
||||
@ -439,22 +466,31 @@ Curl_cookie_add(struct SessionHandle *data,
|
||||
}
|
||||
}
|
||||
else if(Curl_raw_equal("domain", name)) {
|
||||
bool is_ip;
|
||||
const char *dotp;
|
||||
|
||||
/* Now, we make sure that our host is within the given domain,
|
||||
or the given domain is not valid and thus cannot be set. */
|
||||
|
||||
if('.' == whatptr[0])
|
||||
whatptr++; /* ignore preceding dot */
|
||||
|
||||
if(!domain || tailmatch(whatptr, domain)) {
|
||||
const char *tailptr=whatptr;
|
||||
if(tailptr[0] == '.')
|
||||
tailptr++;
|
||||
strstore(&co->domain, tailptr); /* don't prefix w/dots
|
||||
internally */
|
||||
is_ip = isip(domain ? domain : whatptr);
|
||||
|
||||
/* check for more dots */
|
||||
dotp = strchr(whatptr, '.');
|
||||
if(!dotp)
|
||||
domain=":";
|
||||
|
||||
if(!domain
|
||||
|| (is_ip && !strcmp(whatptr, domain))
|
||||
|| (!is_ip && tailmatch(whatptr, domain))) {
|
||||
strstore(&co->domain, whatptr);
|
||||
if(!co->domain) {
|
||||
badcookie = TRUE;
|
||||
break;
|
||||
}
|
||||
if(!is_ip)
|
||||
co->tailmatch=TRUE; /* we always do that if the domain name was
|
||||
given */
|
||||
}
|
||||
@ -788,20 +824,12 @@ Curl_cookie_add(struct SessionHandle *data,
|
||||
|
||||
/* then free all the old pointers */
|
||||
free(clist->name);
|
||||
if(clist->value)
|
||||
free(clist->value);
|
||||
if(clist->domain)
|
||||
free(clist->domain);
|
||||
if(clist->path)
|
||||
free(clist->path);
|
||||
if(clist->spath)
|
||||
free(clist->spath);
|
||||
if(clist->expirestr)
|
||||
free(clist->expirestr);
|
||||
|
||||
if(clist->version)
|
||||
free(clist->version);
|
||||
if(clist->maxage)
|
||||
free(clist->maxage);
|
||||
|
||||
*clist = *co; /* then store all the new data */
|
||||
@ -850,6 +878,7 @@ Curl_cookie_add(struct SessionHandle *data,
|
||||
*
|
||||
* If 'newsession' is TRUE, discard all "session cookies" on read from file.
|
||||
*
|
||||
* Returns NULL on out of memory. Invalid cookies are ignored.
|
||||
****************************************************************************/
|
||||
struct CookieInfo *Curl_cookie_init(struct SessionHandle *data,
|
||||
const char *file,
|
||||
@ -857,8 +886,9 @@ struct CookieInfo *Curl_cookie_init(struct SessionHandle *data,
|
||||
bool newsession)
|
||||
{
|
||||
struct CookieInfo *c;
|
||||
FILE *fp;
|
||||
FILE *fp = NULL;
|
||||
bool fromfile=TRUE;
|
||||
char *line = NULL;
|
||||
|
||||
if(NULL == inc) {
|
||||
/* we didn't get a struct, create one */
|
||||
@ -866,6 +896,8 @@ struct CookieInfo *Curl_cookie_init(struct SessionHandle *data,
|
||||
if(!c)
|
||||
return NULL; /* failed to get memory */
|
||||
c->filename = strdup(file?file:"none"); /* copy the name just in case */
|
||||
if(!c->filename)
|
||||
goto fail; /* failed to get memory */
|
||||
}
|
||||
else {
|
||||
/* we got an already existing one, use that */
|
||||
@ -882,7 +914,7 @@ struct CookieInfo *Curl_cookie_init(struct SessionHandle *data,
|
||||
fp = NULL;
|
||||
}
|
||||
else
|
||||
fp = file?fopen(file, "r"):NULL;
|
||||
fp = file?fopen(file, FOPEN_READTEXT):NULL;
|
||||
|
||||
c->newsession = newsession; /* new session? */
|
||||
|
||||
@ -890,8 +922,9 @@ struct CookieInfo *Curl_cookie_init(struct SessionHandle *data,
|
||||
char *lineptr;
|
||||
bool headerline;
|
||||
|
||||
char *line = malloc(MAX_COOKIE_LINE);
|
||||
if(line) {
|
||||
line = malloc(MAX_COOKIE_LINE);
|
||||
if(!line)
|
||||
goto fail;
|
||||
while(fgets(line, MAX_COOKIE_LINE, fp)) {
|
||||
if(checkprefix("Set-Cookie:", line)) {
|
||||
/* This is a cookie line, get it! */
|
||||
@ -908,7 +941,7 @@ struct CookieInfo *Curl_cookie_init(struct SessionHandle *data,
|
||||
Curl_cookie_add(data, c, headerline, lineptr, NULL, NULL);
|
||||
}
|
||||
free(line); /* free the line buffer */
|
||||
}
|
||||
|
||||
if(fromfile)
|
||||
fclose(fp);
|
||||
}
|
||||
@ -916,6 +949,16 @@ struct CookieInfo *Curl_cookie_init(struct SessionHandle *data,
|
||||
c->running = TRUE; /* now, we're running */
|
||||
|
||||
return c;
|
||||
|
||||
fail:
|
||||
free(line);
|
||||
if(!inc)
|
||||
/* Only clean up if we allocated it here, as the original could still be in
|
||||
* use by a share handle */
|
||||
Curl_cookie_cleanup(c);
|
||||
if(fromfile && fp)
|
||||
fclose(fp);
|
||||
return NULL; /* out of memory */
|
||||
}
|
||||
|
||||
/* sort this so that the longest path gets before the shorter path */
|
||||
@ -968,6 +1011,7 @@ struct Cookie *Curl_cookie_getlist(struct CookieInfo *c,
|
||||
time_t now = time(NULL);
|
||||
struct Cookie *mainco=NULL;
|
||||
size_t matches = 0;
|
||||
bool is_ip;
|
||||
|
||||
if(!c || !c->cookies)
|
||||
return NULL; /* no cookie struct or no cookies in the struct */
|
||||
@ -975,6 +1019,9 @@ struct Cookie *Curl_cookie_getlist(struct CookieInfo *c,
|
||||
/* at first, remove expired cookies */
|
||||
remove_expired(c);
|
||||
|
||||
/* check if host is an IP(v4|v6) address */
|
||||
is_ip = isip(host);
|
||||
|
||||
co = c->cookies;
|
||||
|
||||
while(co) {
|
||||
@ -986,8 +1033,8 @@ struct Cookie *Curl_cookie_getlist(struct CookieInfo *c,
|
||||
|
||||
/* now check if the domain is correct */
|
||||
if(!co->domain ||
|
||||
(co->tailmatch && tailmatch(co->domain, host)) ||
|
||||
(!co->tailmatch && Curl_raw_equal(host, co->domain)) ) {
|
||||
(co->tailmatch && !is_ip && tailmatch(co->domain, host)) ||
|
||||
((!co->tailmatch || is_ip) && Curl_raw_equal(host, co->domain)) ) {
|
||||
/* the right part of the host matches the domain stuff in the
|
||||
cookie data */
|
||||
|
||||
@ -1091,7 +1138,6 @@ void Curl_cookie_clearall(struct CookieInfo *cookies)
|
||||
void Curl_cookie_freelist(struct Cookie *co, bool cookiestoo)
|
||||
{
|
||||
struct Cookie *next;
|
||||
if(co) {
|
||||
while(co) {
|
||||
next = co->next;
|
||||
if(cookiestoo)
|
||||
@ -1101,7 +1147,6 @@ void Curl_cookie_freelist(struct Cookie *co, bool cookiestoo)
|
||||
pointed out in the main cookie list! */
|
||||
co = next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1147,23 +1192,14 @@ void Curl_cookie_clearsess(struct CookieInfo *cookies)
|
||||
*
|
||||
* Curl_cookie_cleanup()
|
||||
*
|
||||
* Free a "cookie object" previous created with cookie_init().
|
||||
* Free a "cookie object" previous created with Curl_cookie_init().
|
||||
*
|
||||
****************************************************************************/
|
||||
void Curl_cookie_cleanup(struct CookieInfo *c)
|
||||
{
|
||||
struct Cookie *co;
|
||||
struct Cookie *next;
|
||||
if(c) {
|
||||
if(c->filename)
|
||||
free(c->filename);
|
||||
co = c->cookies;
|
||||
|
||||
while(co) {
|
||||
next = co->next;
|
||||
freecookie(co);
|
||||
co = next;
|
||||
}
|
||||
Curl_cookie_freelist(c->cookies, TRUE);
|
||||
free(c); /* free the base struct as well */
|
||||
}
|
||||
}
|
||||
@ -1226,7 +1262,7 @@ static int cookie_output(struct CookieInfo *c, const char *dumphere)
|
||||
use_stdout=TRUE;
|
||||
}
|
||||
else {
|
||||
out = fopen(dumphere, "w");
|
||||
out = fopen(dumphere, FOPEN_WRITETEXT);
|
||||
if(!out)
|
||||
return 1; /* failure */
|
||||
}
|
||||
@ -1238,9 +1274,10 @@ static int cookie_output(struct CookieInfo *c, const char *dumphere)
|
||||
"# http://curl.haxx.se/docs/http-cookies.html\n"
|
||||
"# This file was generated by libcurl! Edit at your own risk.\n\n",
|
||||
out);
|
||||
co = c->cookies;
|
||||
|
||||
while(co) {
|
||||
for(co = c->cookies; co; co = co->next) {
|
||||
if(!co->domain)
|
||||
continue;
|
||||
format_ptr = get_netscape_format(co);
|
||||
if(format_ptr == NULL) {
|
||||
fprintf(out, "#\n# Fatal libcurl error\n");
|
||||
@ -1250,7 +1287,6 @@ static int cookie_output(struct CookieInfo *c, const char *dumphere)
|
||||
}
|
||||
fprintf(out, "%s\n", format_ptr);
|
||||
free(format_ptr);
|
||||
co=co->next;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1271,10 +1307,9 @@ struct curl_slist *Curl_cookie_list(struct SessionHandle *data)
|
||||
(data->cookies->numcookies == 0))
|
||||
return NULL;
|
||||
|
||||
c = data->cookies->cookies;
|
||||
|
||||
while(c) {
|
||||
/* fill the list with _all_ the cookies we know */
|
||||
for(c = data->cookies->cookies; c; c = c->next) {
|
||||
if(!c->domain)
|
||||
continue;
|
||||
line = get_netscape_format(c);
|
||||
if(!line) {
|
||||
curl_slist_free_all(list);
|
||||
@ -1287,7 +1322,6 @@ struct curl_slist *Curl_cookie_list(struct SessionHandle *data)
|
||||
return NULL;
|
||||
}
|
||||
list = beg;
|
||||
c = c->next;
|
||||
}
|
||||
|
||||
return list;
|
||||
|
@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -33,6 +33,9 @@
|
||||
#ifdef HAVE_ARPA_INET_H
|
||||
# include <arpa/inet.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_UN_H
|
||||
# include <sys/un.h>
|
||||
#endif
|
||||
|
||||
#ifdef __VMS
|
||||
# include <in.h>
|
||||
@ -47,15 +50,12 @@
|
||||
#include "curl_addrinfo.h"
|
||||
#include "inet_pton.h"
|
||||
#include "warnless.h"
|
||||
|
||||
#define _MPRINTF_REPLACE /* use our functions only */
|
||||
#include <curl/mprintf.h>
|
||||
|
||||
#include "curl_printf.h"
|
||||
#include "curl_memory.h"
|
||||
|
||||
/* The last #include file should be: */
|
||||
#include "memdebug.h"
|
||||
|
||||
|
||||
/*
|
||||
* Curl_freeaddrinfo()
|
||||
*
|
||||
@ -80,13 +80,8 @@ Curl_freeaddrinfo(Curl_addrinfo *cahead)
|
||||
Curl_addrinfo *ca;
|
||||
|
||||
for(ca = cahead; ca != NULL; ca = canext) {
|
||||
|
||||
if(ca->ai_addr)
|
||||
free(ca->ai_addr);
|
||||
|
||||
if(ca->ai_canonname)
|
||||
free(ca->ai_canonname);
|
||||
|
||||
canext = ca->ai_next;
|
||||
|
||||
free(ca);
|
||||
@ -354,7 +349,7 @@ Curl_he2ai(const struct hostent *he, int port)
|
||||
prevai = ai;
|
||||
}
|
||||
|
||||
if(result != CURLE_OK) {
|
||||
if(result) {
|
||||
Curl_freeaddrinfo(firstai);
|
||||
firstai = NULL;
|
||||
}
|
||||
@ -477,6 +472,42 @@ Curl_addrinfo *Curl_str2addr(char *address, int port)
|
||||
return NULL; /* bad input format */
|
||||
}
|
||||
|
||||
#ifdef USE_UNIX_SOCKETS
|
||||
/**
|
||||
* Given a path to a Unix domain socket, return a newly allocated Curl_addrinfo
|
||||
* struct initialized with this path.
|
||||
*/
|
||||
Curl_addrinfo *Curl_unix2addr(const char *path)
|
||||
{
|
||||
Curl_addrinfo *ai;
|
||||
struct sockaddr_un *sa_un;
|
||||
size_t path_len;
|
||||
|
||||
ai = calloc(1, sizeof(Curl_addrinfo));
|
||||
if(!ai)
|
||||
return NULL;
|
||||
if((ai->ai_addr = calloc(1, sizeof(struct sockaddr_un))) == NULL) {
|
||||
free(ai);
|
||||
return NULL;
|
||||
}
|
||||
/* sun_path must be able to store the NUL-terminated path */
|
||||
path_len = strlen(path);
|
||||
if(path_len >= sizeof(sa_un->sun_path)) {
|
||||
free(ai->ai_addr);
|
||||
free(ai);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ai->ai_family = AF_UNIX;
|
||||
ai->ai_socktype = SOCK_STREAM; /* assume reliable transport for HTTP */
|
||||
ai->ai_addrlen = (curl_socklen_t) sizeof(struct sockaddr_un);
|
||||
sa_un = (void *) ai->ai_addr;
|
||||
sa_un->sun_family = AF_UNIX;
|
||||
memcpy(sa_un->sun_path, path, path_len + 1); /* copy NUL byte */
|
||||
return ai;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(CURLDEBUG) && defined(HAVE_FREEADDRINFO)
|
||||
/*
|
||||
* curl_dofreeaddrinfo()
|
||||
|
@ -79,6 +79,10 @@ Curl_ip2addr(int af, const void *inaddr, const char *hostname, int port);
|
||||
|
||||
Curl_addrinfo *Curl_str2addr(char *dotted, int port);
|
||||
|
||||
#ifdef USE_UNIX_SOCKETS
|
||||
Curl_addrinfo *Curl_unix2addr(const char *path);
|
||||
#endif
|
||||
|
||||
#if defined(CURLDEBUG) && defined(HAVE_FREEADDRINFO)
|
||||
void
|
||||
curl_dofreeaddrinfo(struct addrinfo *freethis,
|
||||
|
63
contrib/curl/lib/curl_des.c
Normal file
63
contrib/curl/lib/curl_des.c
Normal file
@ -0,0 +1,63 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2015, Steve Holme, <steve_holme@hotmail.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.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include "curl_setup.h"
|
||||
|
||||
#if defined(USE_NTLM) && !defined(HAVE_DES_SET_ODD_PARITY)
|
||||
|
||||
#include "curl_des.h"
|
||||
|
||||
/*
|
||||
* Curl_des_set_odd_parity()
|
||||
*
|
||||
* This is used to apply odd parity to the given byte array. It is typically
|
||||
* used by when a cryptography engines doesn't have it's own version.
|
||||
*
|
||||
* The function is a port of the Java based oddParity() function over at:
|
||||
*
|
||||
* http://davenport.sourceforge.net/ntlm.html
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* bytes [in/out] - The data whose parity bits are to be adjusted for
|
||||
* odd parity.
|
||||
* len [out] - The length of the data.
|
||||
*/
|
||||
void Curl_des_set_odd_parity(unsigned char *bytes, size_t len)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for(i = 0; i < len; i++) {
|
||||
unsigned char b = bytes[i];
|
||||
|
||||
bool needs_parity = (((b >> 7) ^ (b >> 6) ^ (b >> 5) ^
|
||||
(b >> 4) ^ (b >> 3) ^ (b >> 2) ^
|
||||
(b >> 1)) & 0x01) == 0;
|
||||
|
||||
if(needs_parity)
|
||||
bytes[i] |= 0x01;
|
||||
else
|
||||
bytes[i] &= 0xfe;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* USE_NTLM && !HAVE_DES_SET_ODD_PARITY */
|
@ -1,5 +1,5 @@
|
||||
#ifndef HEADER_CURL_BUNDLES_H
|
||||
#define HEADER_CURL_BUNDLES_H
|
||||
#ifndef HEADER_CURL_DES_H
|
||||
#define HEADER_CURL_DES_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2012, Linus Nielsen Feltzing, <linus@haxx.se>
|
||||
* Copyright (C) 2015, Steve Holme, <steve_holme@hotmail.com>.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -22,24 +22,13 @@
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
struct connectbundle {
|
||||
bool server_supports_pipelining; /* TRUE if server supports pipelining,
|
||||
set after first response */
|
||||
size_t num_connections; /* Number of connections in the bundle */
|
||||
struct curl_llist *conn_list; /* The connectdata members of the bundle */
|
||||
};
|
||||
#include "curl_setup.h"
|
||||
|
||||
CURLcode Curl_bundle_create(struct SessionHandle *data,
|
||||
struct connectbundle **cb_ptr);
|
||||
#if defined(USE_NTLM) && (!defined(USE_OPENSSL) || defined(HAVE_BORINGSSL))
|
||||
|
||||
void Curl_bundle_destroy(struct connectbundle *cb_ptr);
|
||||
/* Applies odd parity to the given byte array */
|
||||
void Curl_des_set_odd_parity(unsigned char *bytes, size_t length);
|
||||
|
||||
CURLcode Curl_bundle_add_conn(struct connectbundle *cb_ptr,
|
||||
struct connectdata *conn);
|
||||
|
||||
int Curl_bundle_remove_conn(struct connectbundle *cb_ptr,
|
||||
struct connectdata *conn);
|
||||
|
||||
|
||||
#endif /* HEADER_CURL_BUNDLES_H */
|
||||
#endif /* USE_NTLM && !HAVE_DES_SET_ODD_PARITY */
|
||||
|
||||
#endif /* HEADER_CURL_DES_H */
|
236
contrib/curl/lib/curl_endian.c
Normal file
236
contrib/curl/lib/curl_endian.c
Normal file
@ -0,0 +1,236 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at http://curl.haxx.se/docs/copyright.html.
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so, under the terms of the COPYING file.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include "curl_setup.h"
|
||||
|
||||
#include "curl_endian.h"
|
||||
|
||||
/*
|
||||
* Curl_read16_le()
|
||||
*
|
||||
* This function converts a 16-bit integer from the little endian format, as
|
||||
* used in the incoming package to whatever endian format we're using
|
||||
* natively.
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* buf [in] - A pointer to a 2 byte buffer.
|
||||
*
|
||||
* Returns the integer.
|
||||
*/
|
||||
unsigned short Curl_read16_le(unsigned char *buf)
|
||||
{
|
||||
return (unsigned short)(((unsigned short)buf[0]) |
|
||||
((unsigned short)buf[1] << 8));
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_read32_le()
|
||||
*
|
||||
* This function converts a 32-bit integer from the little endian format, as
|
||||
* used in the incoming package to whatever endian format we're using
|
||||
* natively.
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* buf [in] - A pointer to a 4 byte buffer.
|
||||
*
|
||||
* Returns the integer.
|
||||
*/
|
||||
unsigned int Curl_read32_le(unsigned char *buf)
|
||||
{
|
||||
return ((unsigned int)buf[0]) | ((unsigned int)buf[1] << 8) |
|
||||
((unsigned int)buf[2] << 16) | ((unsigned int)buf[3] << 24);
|
||||
}
|
||||
|
||||
#if (CURL_SIZEOF_CURL_OFF_T > 4)
|
||||
/*
|
||||
* Curl_read64_le()
|
||||
*
|
||||
* This function converts a 64-bit integer from the little endian format, as
|
||||
* used in the incoming package to whatever endian format we're using
|
||||
* natively.
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* buf [in] - A pointer to a 8 byte buffer.
|
||||
*
|
||||
* Returns the integer.
|
||||
*/
|
||||
#if defined(HAVE_LONGLONG)
|
||||
unsigned long long Curl_read64_le(unsigned char *buf)
|
||||
{
|
||||
return ((unsigned long long)buf[0]) |
|
||||
((unsigned long long)buf[1] << 8) |
|
||||
((unsigned long long)buf[2] << 16) |
|
||||
((unsigned long long)buf[3] << 24) |
|
||||
((unsigned long long)buf[4] << 32) |
|
||||
((unsigned long long)buf[5] << 40) |
|
||||
((unsigned long long)buf[6] << 48) |
|
||||
((unsigned long long)buf[7] << 56);
|
||||
}
|
||||
#else
|
||||
unsigned __int64 Curl_read64_le(unsigned char *buf)
|
||||
{
|
||||
return ((unsigned __int64)buf[0]) | ((unsigned __int64)buf[1] << 8) |
|
||||
((unsigned __int64)buf[2] << 16) | ((unsigned __int64)buf[3] << 24) |
|
||||
((unsigned __int64)buf[4] << 32) | ((unsigned __int64)buf[5] << 40) |
|
||||
((unsigned __int64)buf[6] << 48) | ((unsigned __int64)buf[7] << 56);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* CURL_SIZEOF_CURL_OFF_T > 4 */
|
||||
|
||||
/*
|
||||
* Curl_read16_be()
|
||||
*
|
||||
* This function converts a 16-bit integer from the big endian format, as
|
||||
* used in the incoming package to whatever endian format we're using
|
||||
* natively.
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* buf [in] - A pointer to a 2 byte buffer.
|
||||
*
|
||||
* Returns the integer.
|
||||
*/
|
||||
unsigned short Curl_read16_be(unsigned char *buf)
|
||||
{
|
||||
return (unsigned short)(((unsigned short)buf[0] << 8) |
|
||||
((unsigned short)buf[1]));
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_read32_be()
|
||||
*
|
||||
* This function converts a 32-bit integer from the big endian format, as
|
||||
* used in the incoming package to whatever endian format we're using
|
||||
* natively.
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* buf [in] - A pointer to a 4 byte buffer.
|
||||
*
|
||||
* Returns the integer.
|
||||
*/
|
||||
unsigned int Curl_read32_be(unsigned char *buf)
|
||||
{
|
||||
return ((unsigned int)buf[0] << 24) | ((unsigned int)buf[1] << 16) |
|
||||
((unsigned int)buf[2] << 8) | ((unsigned int)buf[3]);
|
||||
}
|
||||
|
||||
#if (CURL_SIZEOF_CURL_OFF_T > 4)
|
||||
/*
|
||||
* Curl_read64_be()
|
||||
*
|
||||
* This function converts a 64-bit integer from the big endian format, as
|
||||
* used in the incoming package to whatever endian format we're using
|
||||
* natively.
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* buf [in] - A pointer to a 8 byte buffer.
|
||||
*
|
||||
* Returns the integer.
|
||||
*/
|
||||
#if defined(HAVE_LONGLONG)
|
||||
unsigned long long Curl_read64_be(unsigned char *buf)
|
||||
{
|
||||
return ((unsigned long long)buf[0] << 56) |
|
||||
((unsigned long long)buf[1] << 48) |
|
||||
((unsigned long long)buf[2] << 40) |
|
||||
((unsigned long long)buf[3] << 32) |
|
||||
((unsigned long long)buf[4] << 24) |
|
||||
((unsigned long long)buf[5] << 16) |
|
||||
((unsigned long long)buf[6] << 8) |
|
||||
((unsigned long long)buf[7]);
|
||||
}
|
||||
#else
|
||||
unsigned __int64 Curl_read64_be(unsigned char *buf)
|
||||
{
|
||||
return ((unsigned __int64)buf[0] << 56) | ((unsigned __int64)buf[1] << 48) |
|
||||
((unsigned __int64)buf[2] << 40) | ((unsigned __int64)buf[3] << 32) |
|
||||
((unsigned __int64)buf[4] << 24) | ((unsigned __int64)buf[5] << 16) |
|
||||
((unsigned __int64)buf[6] << 8) | ((unsigned __int64)buf[7]);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* CURL_SIZEOF_CURL_OFF_T > 4 */
|
||||
|
||||
/*
|
||||
* Curl_write16_le()
|
||||
*
|
||||
* This function converts a 16-bit integer from the native endian format,
|
||||
* to little endian format ready for sending down the wire.
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* value [in] - The 16-bit integer value.
|
||||
* buffer [in] - A pointer to the output buffer.
|
||||
*/
|
||||
void Curl_write16_le(const short value, unsigned char *buffer)
|
||||
{
|
||||
buffer[0] = (char)(value & 0x00FF);
|
||||
buffer[1] = (char)((value & 0xFF00) >> 8);
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_write32_le()
|
||||
*
|
||||
* This function converts a 32-bit integer from the native endian format,
|
||||
* to little endian format ready for sending down the wire.
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* value [in] - The 32-bit integer value.
|
||||
* buffer [in] - A pointer to the output buffer.
|
||||
*/
|
||||
void Curl_write32_le(const int value, unsigned char *buffer)
|
||||
{
|
||||
buffer[0] = (char)(value & 0x000000FF);
|
||||
buffer[1] = (char)((value & 0x0000FF00) >> 8);
|
||||
buffer[2] = (char)((value & 0x00FF0000) >> 16);
|
||||
buffer[3] = (char)((value & 0xFF000000) >> 24);
|
||||
}
|
||||
|
||||
#if (CURL_SIZEOF_CURL_OFF_T > 4)
|
||||
/*
|
||||
* Curl_write64_le()
|
||||
*
|
||||
* This function converts a 64-bit integer from the native endian format,
|
||||
* to little endian format ready for sending down the wire.
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* value [in] - The 64-bit integer value.
|
||||
* buffer [in] - A pointer to the output buffer.
|
||||
*/
|
||||
#if defined(HAVE_LONGLONG)
|
||||
void Curl_write64_le(const long long value, unsigned char *buffer)
|
||||
#else
|
||||
void Curl_write64_le(const __int64 value, unsigned char *buffer)
|
||||
#endif
|
||||
{
|
||||
Curl_write32_le((int)value, buffer);
|
||||
Curl_write32_le((int)(value >> 32), buffer + 4);
|
||||
}
|
||||
#endif /* CURL_SIZEOF_CURL_OFF_T > 4 */
|
70
contrib/curl/lib/curl_endian.h
Normal file
70
contrib/curl/lib/curl_endian.h
Normal file
@ -0,0 +1,70 @@
|
||||
#ifndef HEADER_CURL_ENDIAN_H
|
||||
#define HEADER_CURL_ENDIAN_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* 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.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
/* Converts a 16-bit integer from little endian */
|
||||
unsigned short Curl_read16_le(unsigned char *buf);
|
||||
|
||||
/* Converts a 32-bit integer from little endian */
|
||||
unsigned int Curl_read32_le(unsigned char *buf);
|
||||
|
||||
#if (CURL_SIZEOF_CURL_OFF_T > 4)
|
||||
/* Converts a 64-bit integer from little endian */
|
||||
#if defined(HAVE_LONGLONG)
|
||||
unsigned long long Curl_read64_le(unsigned char *buf);
|
||||
#else
|
||||
unsigned __int64 Curl_read64_le(unsigned char *buf);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Converts a 16-bit integer from big endian */
|
||||
unsigned short Curl_read16_be(unsigned char *buf);
|
||||
|
||||
/* Converts a 32-bit integer from big endian */
|
||||
unsigned int Curl_read32_be(unsigned char *buf);
|
||||
|
||||
#if (CURL_SIZEOF_CURL_OFF_T > 4)
|
||||
/* Converts a 64-bit integer from big endian */
|
||||
#if defined(HAVE_LONGLONG)
|
||||
unsigned long long Curl_read64_be(unsigned char *buf);
|
||||
#else
|
||||
unsigned __int64 Curl_read64_be(unsigned char *buf);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Converts a 16-bit integer to little endian */
|
||||
void Curl_write16_le(const short value, unsigned char *buffer);
|
||||
|
||||
/* Converts a 32-bit integer to little endian */
|
||||
void Curl_write32_le(const int value, unsigned char *buffer);
|
||||
|
||||
#if (CURL_SIZEOF_CURL_OFF_T > 4)
|
||||
/* Converts a 64-bit integer to little endian */
|
||||
#if defined(HAVE_LONGLONG)
|
||||
void Curl_write64_le(const long long value, unsigned char *buffer);
|
||||
#else
|
||||
void Curl_write64_le(const __int64 value, unsigned char *buffer);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif /* HEADER_CURL_ENDIAN_H */
|
@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -23,11 +23,8 @@
|
||||
#include "curl_setup.h"
|
||||
|
||||
#include "curl_fnmatch.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"
|
||||
|
||||
|
@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2011 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 2011 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -27,9 +27,9 @@
|
||||
#include "curl_gssapi.h"
|
||||
#include "sendf.h"
|
||||
|
||||
static const char spnego_oid_bytes[] = "\x2b\x06\x01\x05\x05\x02";
|
||||
static char spnego_oid_bytes[] = "\x2b\x06\x01\x05\x05\x02";
|
||||
gss_OID_desc Curl_spnego_mech_oid = { 6, &spnego_oid_bytes };
|
||||
static const char krb5_oid_bytes[] = "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02";
|
||||
static char krb5_oid_bytes[] = "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02";
|
||||
gss_OID_desc Curl_krb5_mech_oid = { 9, &krb5_oid_bytes };
|
||||
|
||||
OM_uint32 Curl_gss_init_sec_context(
|
||||
@ -41,9 +41,13 @@ OM_uint32 Curl_gss_init_sec_context(
|
||||
gss_channel_bindings_t input_chan_bindings,
|
||||
gss_buffer_t input_token,
|
||||
gss_buffer_t output_token,
|
||||
const bool mutual_auth,
|
||||
OM_uint32 *ret_flags)
|
||||
{
|
||||
OM_uint32 req_flags = GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG;
|
||||
OM_uint32 req_flags = GSS_C_REPLAY_FLAG;
|
||||
|
||||
if(mutual_auth)
|
||||
req_flags |= GSS_C_MUTUAL_FLAG;
|
||||
|
||||
if(data->set.gssapi_delegation & CURLGSSAPI_DELEGATION_POLICY_FLAG) {
|
||||
#ifdef GSS_C_DELEG_POLICY_FLAG
|
||||
@ -72,4 +76,45 @@ OM_uint32 Curl_gss_init_sec_context(
|
||||
NULL /* time_rec */);
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_gss_log_error()
|
||||
*
|
||||
* This is used to log a GSS-API error status.
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* data [in] - The session handle.
|
||||
* status [in] - The status code.
|
||||
* prefix [in] - The prefix of the log message.
|
||||
*/
|
||||
void Curl_gss_log_error(struct SessionHandle *data, OM_uint32 status,
|
||||
const char *prefix)
|
||||
{
|
||||
OM_uint32 maj_stat;
|
||||
OM_uint32 min_stat;
|
||||
OM_uint32 msg_ctx = 0;
|
||||
gss_buffer_desc status_string;
|
||||
char buf[1024];
|
||||
size_t len;
|
||||
|
||||
snprintf(buf, sizeof(buf), "%s", prefix);
|
||||
len = strlen(buf);
|
||||
do {
|
||||
maj_stat = gss_display_status(&min_stat,
|
||||
status,
|
||||
GSS_C_MECH_CODE,
|
||||
GSS_C_NO_OID,
|
||||
&msg_ctx,
|
||||
&status_string);
|
||||
if(sizeof(buf) > len + status_string.length + 1) {
|
||||
snprintf(buf + len, sizeof(buf) - len,
|
||||
": %s", (char*)status_string.value);
|
||||
len += status_string.length;
|
||||
}
|
||||
gss_release_buffer(&min_stat, &status_string);
|
||||
} while(!GSS_ERROR(maj_stat) && msg_ctx != 0);
|
||||
|
||||
infof(data, "%s\n", buf);
|
||||
}
|
||||
|
||||
#endif /* HAVE_GSSAPI */
|
||||
|
@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 2011 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -43,7 +43,6 @@ extern gss_OID_desc Curl_spnego_mech_oid;
|
||||
extern gss_OID_desc Curl_krb5_mech_oid;
|
||||
|
||||
/* Common method for using GSS-API */
|
||||
|
||||
OM_uint32 Curl_gss_init_sec_context(
|
||||
struct SessionHandle *data,
|
||||
OM_uint32 *minor_status,
|
||||
@ -53,8 +52,24 @@ OM_uint32 Curl_gss_init_sec_context(
|
||||
gss_channel_bindings_t input_chan_bindings,
|
||||
gss_buffer_t input_token,
|
||||
gss_buffer_t output_token,
|
||||
const bool mutual_auth,
|
||||
OM_uint32 *ret_flags);
|
||||
|
||||
/* Helper to log a GSS-API error status */
|
||||
void Curl_gss_log_error(struct SessionHandle *data, OM_uint32 status,
|
||||
const char *prefix);
|
||||
|
||||
/* Provide some definitions missing in old headers */
|
||||
#ifdef HAVE_OLD_GSSMIT
|
||||
#define GSS_C_NT_HOSTBASED_SERVICE gss_nt_service_name
|
||||
#define NCOMPAT 1
|
||||
#endif
|
||||
|
||||
/* Define our privacy and integrity protection values */
|
||||
#define GSSAUTH_P_NONE 1
|
||||
#define GSSAUTH_P_INTEGRITY 2
|
||||
#define GSSAUTH_P_PRIVACY 4
|
||||
|
||||
#endif /* HAVE_GSSAPI */
|
||||
|
||||
#endif /* HEADER_CURL_GSSAPI_H */
|
||||
|
@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -24,10 +24,12 @@
|
||||
|
||||
#include "curl_setup.h"
|
||||
|
||||
/* NSS crypto library does not provide the MD4 hash algorithm, so that we have
|
||||
* a local implementation of it */
|
||||
#ifdef USE_NSS
|
||||
/* NSS and OS/400 crypto library do not provide the MD4 hash algorithm, so
|
||||
* that we have a local implementation of it */
|
||||
#if defined(USE_NSS) || defined(USE_OS400CRYPTO)
|
||||
|
||||
void Curl_md4it(unsigned char *output, const unsigned char *input, size_t len);
|
||||
#endif /* USE_NSS */
|
||||
|
||||
#endif /* defined(USE_NSS) || defined(USE_OS400CRYPTO) */
|
||||
|
||||
#endif /* HEADER_CURL_MD4_H */
|
||||
|
@ -28,6 +28,9 @@
|
||||
* File curl_memory.h must be included by _all_ *.c source files
|
||||
* that use memory related functions strdup, malloc, calloc, realloc
|
||||
* or free, and given source file is used to build libcurl library.
|
||||
* It should be included immediately before memdebug.h as the last files
|
||||
* included to avoid undesired interaction with other memory function
|
||||
* headers in dependent libraries.
|
||||
*
|
||||
* There is nearly no exception to above rule. All libcurl source
|
||||
* files in 'lib' subdirectory as well as those living deep inside
|
||||
|
@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -21,13 +21,9 @@
|
||||
***************************************************************************/
|
||||
|
||||
#include "curl_setup.h"
|
||||
|
||||
#include "curl_memrchr.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"
|
||||
|
||||
|
@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -22,18 +22,16 @@
|
||||
|
||||
#include "curl_setup.h"
|
||||
|
||||
#if defined(USE_WIN32_IDN) || (defined(USE_WINDOWS_SSPI) && defined(UNICODE))
|
||||
#if defined(USE_WIN32_IDN) || ((defined(USE_WINDOWS_SSPI) || \
|
||||
defined(USE_WIN32_LDAP)) && defined(UNICODE))
|
||||
|
||||
/*
|
||||
* MultiByte conversions using Windows kernel32 library.
|
||||
*/
|
||||
|
||||
#include "curl_multibyte.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"
|
||||
|
||||
@ -49,7 +47,8 @@ wchar_t *Curl_convert_UTF8_to_wchar(const char *str_utf8)
|
||||
if(str_w) {
|
||||
if(MultiByteToWideChar(CP_UTF8, 0, str_utf8, -1, str_w,
|
||||
str_w_len) == 0) {
|
||||
Curl_safefree(str_w);
|
||||
free(str_w);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -70,7 +69,8 @@ char *Curl_convert_wchar_to_UTF8(const wchar_t *str_w)
|
||||
if(str_utf8) {
|
||||
if(WideCharToMultiByte(CP_UTF8, 0, str_w, -1, str_utf8, str_utf8_len,
|
||||
NULL, FALSE) == 0) {
|
||||
Curl_safefree(str_utf8);
|
||||
free(str_utf8);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -79,4 +79,4 @@ char *Curl_convert_wchar_to_UTF8(const wchar_t *str_w)
|
||||
return str_utf8;
|
||||
}
|
||||
|
||||
#endif /* USE_WIN32_IDN || (USE_WINDOWS_SSPI && UNICODE) */
|
||||
#endif /* USE_WIN32_IDN || ((USE_WINDOWS_SSPI || USE_WIN32_LDAP) && UNICODE) */
|
||||
|
@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -23,7 +23,8 @@
|
||||
***************************************************************************/
|
||||
#include "curl_setup.h"
|
||||
|
||||
#if defined(USE_WIN32_IDN) || (defined(USE_WINDOWS_SSPI) && defined(UNICODE))
|
||||
#if defined(USE_WIN32_IDN) || ((defined(USE_WINDOWS_SSPI) || \
|
||||
defined(USE_WIN32_LDAP)) && defined(UNICODE))
|
||||
|
||||
/*
|
||||
* MultiByte conversions using Windows kernel32 library.
|
||||
@ -32,10 +33,11 @@
|
||||
wchar_t *Curl_convert_UTF8_to_wchar(const char *str_utf8);
|
||||
char *Curl_convert_wchar_to_UTF8(const wchar_t *str_w);
|
||||
|
||||
#endif /* USE_WIN32_IDN || (USE_WINDOWS_SSPI && UNICODE) */
|
||||
#endif /* USE_WIN32_IDN || ((USE_WINDOWS_SSPI || USE_WIN32_LDAP) && UNICODE) */
|
||||
|
||||
|
||||
#if defined(USE_WIN32_IDN) || defined(USE_WINDOWS_SSPI)
|
||||
#if defined(USE_WIN32_IDN) || defined(USE_WINDOWS_SSPI) || \
|
||||
defined(USE_WIN32_LDAP)
|
||||
|
||||
/*
|
||||
* Macros Curl_convert_UTF8_to_tchar(), Curl_convert_tchar_to_UTF8()
|
||||
@ -85,6 +87,6 @@ typedef union {
|
||||
|
||||
#endif /* UNICODE */
|
||||
|
||||
#endif /* USE_WIN32_IDN || USE_WINDOWS_SSPI */
|
||||
#endif /* USE_WIN32_IDN || USE_WINDOWS_SSPI || USE_WIN32_LDAP */
|
||||
|
||||
#endif /* HEADER_CURL_MULTIBYTE_H */
|
||||
|
@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -22,7 +22,7 @@
|
||||
|
||||
#include "curl_setup.h"
|
||||
|
||||
#ifdef USE_NTLM
|
||||
#if !defined(CURL_DISABLE_HTTP) && defined(USE_NTLM)
|
||||
|
||||
/*
|
||||
* NTLM details:
|
||||
@ -39,11 +39,9 @@
|
||||
#include "curl_ntlm.h"
|
||||
#include "curl_ntlm_msgs.h"
|
||||
#include "curl_ntlm_wb.h"
|
||||
#include "curl_sasl.h"
|
||||
#include "url.h"
|
||||
#include "curl_memory.h"
|
||||
|
||||
#define _MPRINTF_REPLACE /* use our functions only */
|
||||
#include <curl/mprintf.h>
|
||||
#include "curl_printf.h"
|
||||
|
||||
#if defined(USE_NSS)
|
||||
#include "vtls/nssg.h"
|
||||
@ -51,7 +49,8 @@
|
||||
#include "curl_sspi.h"
|
||||
#endif
|
||||
|
||||
/* The last #include file should be: */
|
||||
/* The last #include files should be: */
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
#if DEBUG_ME
|
||||
@ -69,12 +68,6 @@ CURLcode Curl_input_ntlm(struct connectdata *conn,
|
||||
struct ntlmdata *ntlm;
|
||||
CURLcode result = CURLE_OK;
|
||||
|
||||
#ifdef USE_NSS
|
||||
result = Curl_nss_force_init(conn->data);
|
||||
if(result)
|
||||
return result;
|
||||
#endif
|
||||
|
||||
ntlm = proxy ? &conn->proxyntlm : &conn->ntlm;
|
||||
|
||||
if(checkprefix("NTLM", header)) {
|
||||
@ -84,14 +77,18 @@ CURLcode Curl_input_ntlm(struct connectdata *conn,
|
||||
header++;
|
||||
|
||||
if(*header) {
|
||||
result = Curl_ntlm_decode_type2_message(conn->data, header, ntlm);
|
||||
if(CURLE_OK != result)
|
||||
result = Curl_sasl_decode_ntlm_type2_message(conn->data, header, ntlm);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
ntlm->state = NTLMSTATE_TYPE2; /* We got a type-2 message */
|
||||
}
|
||||
else {
|
||||
if(ntlm->state == NTLMSTATE_TYPE3) {
|
||||
if(ntlm->state == NTLMSTATE_LAST) {
|
||||
infof(conn->data, "NTLM auth restarted\n");
|
||||
Curl_http_ntlm_cleanup(conn);
|
||||
}
|
||||
else if(ntlm->state == NTLMSTATE_TYPE3) {
|
||||
infof(conn->data, "NTLM handshake rejected\n");
|
||||
Curl_http_ntlm_cleanup(conn);
|
||||
ntlm->state = NTLMSTATE_NONE;
|
||||
@ -112,12 +109,11 @@ CURLcode Curl_input_ntlm(struct connectdata *conn,
|
||||
/*
|
||||
* This is for creating ntlm header output
|
||||
*/
|
||||
CURLcode Curl_output_ntlm(struct connectdata *conn,
|
||||
bool proxy)
|
||||
CURLcode Curl_output_ntlm(struct connectdata *conn, bool proxy)
|
||||
{
|
||||
char *base64 = NULL;
|
||||
size_t len = 0;
|
||||
CURLcode error;
|
||||
CURLcode result;
|
||||
|
||||
/* point to the address of the pointer that holds the string to send to the
|
||||
server, which is for a plain host or for a HTTP proxy */
|
||||
@ -175,38 +171,40 @@ CURLcode Curl_output_ntlm(struct connectdata *conn,
|
||||
case NTLMSTATE_TYPE1:
|
||||
default: /* for the weird cases we (re)start here */
|
||||
/* Create a type-1 message */
|
||||
error = Curl_ntlm_create_type1_message(userp, passwdp, ntlm, &base64,
|
||||
result = Curl_sasl_create_ntlm_type1_message(userp, passwdp, ntlm, &base64,
|
||||
&len);
|
||||
if(error)
|
||||
return error;
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
if(base64) {
|
||||
Curl_safefree(*allocuserpwd);
|
||||
free(*allocuserpwd);
|
||||
*allocuserpwd = aprintf("%sAuthorization: NTLM %s\r\n",
|
||||
proxy ? "Proxy-" : "",
|
||||
base64);
|
||||
free(base64);
|
||||
if(!*allocuserpwd)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
DEBUG_OUT(fprintf(stderr, "**** Header %s\n ", *allocuserpwd));
|
||||
}
|
||||
break;
|
||||
|
||||
case NTLMSTATE_TYPE2:
|
||||
/* We already received the type-2 message, create a type-3 message */
|
||||
error = Curl_ntlm_create_type3_message(conn->data, userp, passwdp,
|
||||
result = Curl_sasl_create_ntlm_type3_message(conn->data, userp, passwdp,
|
||||
ntlm, &base64, &len);
|
||||
if(error)
|
||||
return error;
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
if(base64) {
|
||||
Curl_safefree(*allocuserpwd);
|
||||
free(*allocuserpwd);
|
||||
*allocuserpwd = aprintf("%sAuthorization: NTLM %s\r\n",
|
||||
proxy ? "Proxy-" : "",
|
||||
base64);
|
||||
free(base64);
|
||||
if(!*allocuserpwd)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
DEBUG_OUT(fprintf(stderr, "**** %s\n ", *allocuserpwd));
|
||||
|
||||
ntlm->state = NTLMSTATE_TYPE3; /* we send a type-3 */
|
||||
@ -217,6 +215,9 @@ CURLcode Curl_output_ntlm(struct connectdata *conn,
|
||||
case NTLMSTATE_TYPE3:
|
||||
/* connection is already authenticated,
|
||||
* don't send a header in future requests */
|
||||
ntlm->state = NTLMSTATE_LAST;
|
||||
/* fall-through */
|
||||
case NTLMSTATE_LAST:
|
||||
Curl_safefree(*allocuserpwd);
|
||||
authp->done = TRUE;
|
||||
break;
|
||||
@ -227,22 +228,12 @@ CURLcode Curl_output_ntlm(struct connectdata *conn,
|
||||
|
||||
void Curl_http_ntlm_cleanup(struct connectdata *conn)
|
||||
{
|
||||
#ifdef USE_WINDOWS_SSPI
|
||||
Curl_ntlm_sspi_cleanup(&conn->ntlm);
|
||||
Curl_ntlm_sspi_cleanup(&conn->proxyntlm);
|
||||
#elif defined(NTLM_WB_ENABLED)
|
||||
Curl_sasl_ntlm_cleanup(&conn->ntlm);
|
||||
Curl_sasl_ntlm_cleanup(&conn->proxyntlm);
|
||||
|
||||
#if defined(NTLM_WB_ENABLED)
|
||||
Curl_ntlm_wb_cleanup(conn);
|
||||
#else
|
||||
(void)conn;
|
||||
#endif
|
||||
|
||||
#ifndef USE_WINDOWS_SSPI
|
||||
Curl_safefree(conn->ntlm.target_info);
|
||||
conn->ntlm.target_info_len = 0;
|
||||
|
||||
Curl_safefree(conn->proxyntlm.target_info);
|
||||
conn->proxyntlm.target_info_len = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif /* USE_NTLM */
|
||||
#endif /* !CURL_DISABLE_HTTP && USE_NTLM */
|
||||
|
@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -24,7 +24,7 @@
|
||||
|
||||
#include "curl_setup.h"
|
||||
|
||||
#ifdef USE_NTLM
|
||||
#if !defined(CURL_DISABLE_HTTP) && defined(USE_NTLM)
|
||||
|
||||
/* this is for ntlm header input */
|
||||
CURLcode Curl_input_ntlm(struct connectdata *conn, bool proxy,
|
||||
@ -35,10 +35,6 @@ CURLcode Curl_output_ntlm(struct connectdata *conn, bool proxy);
|
||||
|
||||
void Curl_http_ntlm_cleanup(struct connectdata *conn);
|
||||
|
||||
#else
|
||||
|
||||
#define Curl_http_ntlm_cleanup(a) Curl_nop_stmt
|
||||
|
||||
#endif
|
||||
#endif /* !CURL_DISABLE_HTTP && USE_NTLM */
|
||||
|
||||
#endif /* HEADER_CURL_NTLM_H */
|
||||
|
@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -22,7 +22,7 @@
|
||||
|
||||
#include "curl_setup.h"
|
||||
|
||||
#if defined(USE_NTLM) && !defined(USE_WINDOWS_SSPI)
|
||||
#if defined(USE_NTLM)
|
||||
|
||||
/*
|
||||
* NTLM details:
|
||||
@ -31,7 +31,9 @@
|
||||
* http://www.innovation.ch/java/ntlm.html
|
||||
*/
|
||||
|
||||
#ifdef USE_SSLEAY
|
||||
#if !defined(USE_WINDOWS_SSPI) || defined(USE_WIN32_CRYPTO)
|
||||
|
||||
#ifdef USE_OPENSSL
|
||||
|
||||
# ifdef USE_OPENSSL
|
||||
# include <openssl/des.h>
|
||||
@ -87,6 +89,11 @@
|
||||
# include <CommonCrypto/CommonCryptor.h>
|
||||
# include <CommonCrypto/CommonDigest.h>
|
||||
|
||||
#elif defined(USE_OS400CRYPTO)
|
||||
# include "cipher.mih" /* mih/cipher */
|
||||
# include "curl_md4.h"
|
||||
#elif defined(USE_WIN32_CRYPTO)
|
||||
# include <wincrypt.h>
|
||||
#else
|
||||
# error "Can't compile NTLM support without a crypto library."
|
||||
#endif
|
||||
@ -94,50 +101,25 @@
|
||||
#include "urldata.h"
|
||||
#include "non-ascii.h"
|
||||
#include "rawstr.h"
|
||||
#include "curl_memory.h"
|
||||
#include "curl_ntlm_core.h"
|
||||
#include "curl_md5.h"
|
||||
#include "curl_hmac.h"
|
||||
#include "warnless.h"
|
||||
#include "curl_endian.h"
|
||||
#include "curl_des.h"
|
||||
#include "curl_printf.h"
|
||||
|
||||
#define _MPRINTF_REPLACE /* use our functions only */
|
||||
#include <curl/mprintf.h>
|
||||
|
||||
/* The last #include file should be: */
|
||||
/* The last #include files should be: */
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
#define NTLM_HMAC_MD5_LEN (16)
|
||||
#define NTLMv2_BLOB_SIGNATURE "\x01\x01\x00\x00"
|
||||
#define NTLMv2_BLOB_LEN (44 -16 + ntlm->target_info_len + 4)
|
||||
|
||||
#ifdef USE_SSLEAY
|
||||
/*
|
||||
* Turns a 56 bit key into the 64 bit, odd parity key and sets the key. The
|
||||
* key schedule ks is also set.
|
||||
*/
|
||||
static void setup_des_key(const unsigned char *key_56,
|
||||
DES_key_schedule DESKEYARG(ks))
|
||||
{
|
||||
DES_cblock key;
|
||||
|
||||
key[0] = key_56[0];
|
||||
key[1] = (unsigned char)(((key_56[0] << 7) & 0xFF) | (key_56[1] >> 1));
|
||||
key[2] = (unsigned char)(((key_56[1] << 6) & 0xFF) | (key_56[2] >> 2));
|
||||
key[3] = (unsigned char)(((key_56[2] << 5) & 0xFF) | (key_56[3] >> 3));
|
||||
key[4] = (unsigned char)(((key_56[3] << 4) & 0xFF) | (key_56[4] >> 4));
|
||||
key[5] = (unsigned char)(((key_56[4] << 3) & 0xFF) | (key_56[5] >> 5));
|
||||
key[6] = (unsigned char)(((key_56[5] << 2) & 0xFF) | (key_56[6] >> 6));
|
||||
key[7] = (unsigned char) ((key_56[6] << 1) & 0xFF);
|
||||
|
||||
DES_set_odd_parity(&key);
|
||||
DES_set_key(&key, ks);
|
||||
}
|
||||
|
||||
#else /* defined(USE_SSLEAY) */
|
||||
|
||||
/*
|
||||
* Turns a 56 bit key into the 64 bit, odd parity key. Used by GnuTLS and NSS.
|
||||
*/
|
||||
* Turns a 56-bit key into being 64-bit wide.
|
||||
*/
|
||||
static void extend_key_56_to_64(const unsigned char *key_56, char *key)
|
||||
{
|
||||
key[0] = key_56[0];
|
||||
@ -150,14 +132,45 @@ static void extend_key_56_to_64(const unsigned char *key_56, char *key)
|
||||
key[7] = (unsigned char) ((key_56[6] << 1) & 0xFF);
|
||||
}
|
||||
|
||||
#if defined(USE_GNUTLS_NETTLE)
|
||||
#ifdef USE_OPENSSL
|
||||
/*
|
||||
* Turns a 56 bit key into the 64 bit, odd parity key and sets the key. The
|
||||
* key schedule ks is also set.
|
||||
*/
|
||||
static void setup_des_key(const unsigned char *key_56,
|
||||
DES_key_schedule DESKEYARG(ks))
|
||||
{
|
||||
DES_cblock key;
|
||||
|
||||
/* Expand the 56-bit key to 64-bits */
|
||||
extend_key_56_to_64(key_56, (char *) key);
|
||||
|
||||
/* Set the key parity to odd */
|
||||
#ifndef HAVE_DES_SET_ODD_PARITY /* older boringssl */
|
||||
Curl_des_set_odd_parity((unsigned char *) &key, sizeof(key));
|
||||
#else
|
||||
DES_set_odd_parity(&key);
|
||||
#endif
|
||||
|
||||
/* Set the key */
|
||||
DES_set_key(&key, ks);
|
||||
}
|
||||
|
||||
#elif defined(USE_GNUTLS_NETTLE)
|
||||
|
||||
static void setup_des_key(const unsigned char *key_56,
|
||||
struct des_ctx *des)
|
||||
{
|
||||
char key[8];
|
||||
|
||||
/* Expand the 56-bit key to 64-bits */
|
||||
extend_key_56_to_64(key_56, key);
|
||||
des_set_key(des, (const uint8_t*)key);
|
||||
|
||||
/* Set the key parity to odd */
|
||||
Curl_des_set_odd_parity((unsigned char *) key, sizeof(key));
|
||||
|
||||
/* Set the key */
|
||||
des_set_key(des, (const uint8_t *) key);
|
||||
}
|
||||
|
||||
#elif defined(USE_GNUTLS)
|
||||
@ -169,8 +182,15 @@ static void setup_des_key(const unsigned char *key_56,
|
||||
gcry_cipher_hd_t *des)
|
||||
{
|
||||
char key[8];
|
||||
|
||||
/* Expand the 56-bit key to 64-bits */
|
||||
extend_key_56_to_64(key_56, key);
|
||||
gcry_cipher_setkey(*des, key, 8);
|
||||
|
||||
/* Set the key parity to odd */
|
||||
Curl_des_set_odd_parity((unsigned char *) key, sizeof(key));
|
||||
|
||||
/* Set the key */
|
||||
gcry_cipher_setkey(*des, key, sizeof(key));
|
||||
}
|
||||
|
||||
#elif defined(USE_NSS)
|
||||
@ -198,16 +218,21 @@ static bool encrypt_des(const unsigned char *in, unsigned char *out,
|
||||
if(!slot)
|
||||
return FALSE;
|
||||
|
||||
/* expand the 56 bit key to 64 bit and wrap by NSS */
|
||||
/* Expand the 56-bit key to 64-bits */
|
||||
extend_key_56_to_64(key_56, key);
|
||||
|
||||
/* Set the key parity to odd */
|
||||
Curl_des_set_odd_parity((unsigned char *) key, sizeof(key));
|
||||
|
||||
/* Import the key */
|
||||
key_item.data = (unsigned char *)key;
|
||||
key_item.len = /* hard-wired */ 8;
|
||||
key_item.len = sizeof(key);
|
||||
symkey = PK11_ImportSymKey(slot, mech, PK11_OriginUnwrap, CKA_ENCRYPT,
|
||||
&key_item, NULL);
|
||||
if(!symkey)
|
||||
goto fail;
|
||||
|
||||
/* create DES encryption context */
|
||||
/* Create the DES encryption context */
|
||||
param = PK11_ParamFromIV(mech, /* no IV in ECB mode */ NULL);
|
||||
if(!param)
|
||||
goto fail;
|
||||
@ -215,7 +240,7 @@ static bool encrypt_des(const unsigned char *in, unsigned char *out,
|
||||
if(!ctx)
|
||||
goto fail;
|
||||
|
||||
/* perform the encryption */
|
||||
/* Perform the encryption */
|
||||
if(SECSuccess == PK11_CipherOp(ctx, out, &out_len, /* outbuflen */ 8,
|
||||
(unsigned char *)in, /* inbuflen */ 8)
|
||||
&& SECSuccess == PK11_Finalize(ctx))
|
||||
@ -242,16 +267,95 @@ static bool encrypt_des(const unsigned char *in, unsigned char *out,
|
||||
size_t out_len;
|
||||
CCCryptorStatus err;
|
||||
|
||||
/* Expand the 56-bit key to 64-bits */
|
||||
extend_key_56_to_64(key_56, key);
|
||||
|
||||
/* Set the key parity to odd */
|
||||
Curl_des_set_odd_parity((unsigned char *) key, sizeof(key));
|
||||
|
||||
/* Perform the encryption */
|
||||
err = CCCrypt(kCCEncrypt, kCCAlgorithmDES, kCCOptionECBMode, key,
|
||||
kCCKeySizeDES, NULL, in, 8 /* inbuflen */, out,
|
||||
8 /* outbuflen */, &out_len);
|
||||
|
||||
return err == kCCSuccess;
|
||||
}
|
||||
|
||||
#endif /* defined(USE_DARWINSSL) */
|
||||
#elif defined(USE_OS400CRYPTO)
|
||||
|
||||
#endif /* defined(USE_SSLEAY) */
|
||||
static bool encrypt_des(const unsigned char *in, unsigned char *out,
|
||||
const unsigned char *key_56)
|
||||
{
|
||||
char key[8];
|
||||
_CIPHER_Control_T ctl;
|
||||
|
||||
/* Setup the cipher control structure */
|
||||
ctl.Func_ID = ENCRYPT_ONLY;
|
||||
ctl.Data_Len = sizeof(key);
|
||||
|
||||
/* Expand the 56-bit key to 64-bits */
|
||||
extend_key_56_to_64(key_56, ctl.Crypto_Key);
|
||||
|
||||
/* Set the key parity to odd */
|
||||
Curl_des_set_odd_parity((unsigned char *) ctl.Crypto_Key, ctl.Data_Len);
|
||||
|
||||
/* Perform the encryption */
|
||||
_CIPHER((_SPCPTR *) &out, &ctl, (_SPCPTR *) &in);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#elif defined(USE_WIN32_CRYPTO)
|
||||
|
||||
static bool encrypt_des(const unsigned char *in, unsigned char *out,
|
||||
const unsigned char *key_56)
|
||||
{
|
||||
HCRYPTPROV hprov;
|
||||
HCRYPTKEY hkey;
|
||||
struct {
|
||||
BLOBHEADER hdr;
|
||||
unsigned int len;
|
||||
char key[8];
|
||||
} blob;
|
||||
DWORD len = 8;
|
||||
|
||||
/* Acquire the crypto provider */
|
||||
if(!CryptAcquireContext(&hprov, NULL, NULL, PROV_RSA_FULL,
|
||||
CRYPT_VERIFYCONTEXT))
|
||||
return FALSE;
|
||||
|
||||
/* Setup the key blob structure */
|
||||
memset(&blob, 0, sizeof(blob));
|
||||
blob.hdr.bType = PLAINTEXTKEYBLOB;
|
||||
blob.hdr.bVersion = 2;
|
||||
blob.hdr.aiKeyAlg = CALG_DES;
|
||||
blob.len = sizeof(blob.key);
|
||||
|
||||
/* Expand the 56-bit key to 64-bits */
|
||||
extend_key_56_to_64(key_56, blob.key);
|
||||
|
||||
/* Set the key parity to odd */
|
||||
Curl_des_set_odd_parity((unsigned char *) blob.key, sizeof(blob.key));
|
||||
|
||||
/* Import the key */
|
||||
if(!CryptImportKey(hprov, (BYTE *) &blob, sizeof(blob), 0, 0, &hkey)) {
|
||||
CryptReleaseContext(hprov, 0);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
memcpy(out, in, 8);
|
||||
|
||||
/* Perform the encryption */
|
||||
CryptEncrypt(hkey, 0, FALSE, 0, out, &len, len);
|
||||
|
||||
CryptDestroyKey(hkey);
|
||||
CryptReleaseContext(hprov, 0);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#endif /* defined(USE_WIN32_CRYPTO) */
|
||||
|
||||
/*
|
||||
* takes a 21 byte array and treats it as 3 56-bit DES keys. The
|
||||
@ -262,7 +366,7 @@ void Curl_ntlm_core_lm_resp(const unsigned char *keys,
|
||||
const unsigned char *plaintext,
|
||||
unsigned char *results)
|
||||
{
|
||||
#ifdef USE_SSLEAY
|
||||
#ifdef USE_OPENSSL
|
||||
DES_key_schedule ks;
|
||||
|
||||
setup_des_key(keys, DESKEY(ks));
|
||||
@ -301,7 +405,8 @@ void Curl_ntlm_core_lm_resp(const unsigned char *keys,
|
||||
setup_des_key(keys + 14, &des);
|
||||
gcry_cipher_encrypt(des, results + 16, 8, plaintext, 8);
|
||||
gcry_cipher_close(des);
|
||||
#elif defined(USE_NSS) || defined(USE_DARWINSSL)
|
||||
#elif defined(USE_NSS) || defined(USE_DARWINSSL) || defined(USE_OS400CRYPTO) \
|
||||
|| defined(USE_WIN32_CRYPTO)
|
||||
encrypt_des(plaintext, results, keys);
|
||||
encrypt_des(plaintext, results + 8, keys + 7);
|
||||
encrypt_des(plaintext, results + 16, keys + 14);
|
||||
@ -311,11 +416,11 @@ void Curl_ntlm_core_lm_resp(const unsigned char *keys,
|
||||
/*
|
||||
* Set up lanmanager hashed password
|
||||
*/
|
||||
void Curl_ntlm_core_mk_lm_hash(struct SessionHandle *data,
|
||||
CURLcode Curl_ntlm_core_mk_lm_hash(struct SessionHandle *data,
|
||||
const char *password,
|
||||
unsigned char *lmbuffer /* 21 bytes */)
|
||||
{
|
||||
CURLcode res;
|
||||
CURLcode result;
|
||||
unsigned char pw[14];
|
||||
static const unsigned char magic[] = {
|
||||
0x4B, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25 /* i.e. KGS!@#$% */
|
||||
@ -329,14 +434,14 @@ void Curl_ntlm_core_mk_lm_hash(struct SessionHandle *data,
|
||||
* The LanManager hashed password needs to be created using the
|
||||
* password in the network encoding not the host encoding.
|
||||
*/
|
||||
res = Curl_convert_to_network(data, (char *)pw, 14);
|
||||
if(res)
|
||||
return;
|
||||
result = Curl_convert_to_network(data, (char *)pw, 14);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
{
|
||||
/* Create LanManager hashed password. */
|
||||
|
||||
#ifdef USE_SSLEAY
|
||||
#ifdef USE_OPENSSL
|
||||
DES_key_schedule ks;
|
||||
|
||||
setup_des_key(pw, DESKEY(ks));
|
||||
@ -364,13 +469,16 @@ void Curl_ntlm_core_mk_lm_hash(struct SessionHandle *data,
|
||||
setup_des_key(pw + 7, &des);
|
||||
gcry_cipher_encrypt(des, lmbuffer + 8, 8, magic, 8);
|
||||
gcry_cipher_close(des);
|
||||
#elif defined(USE_NSS) || defined(USE_DARWINSSL)
|
||||
#elif defined(USE_NSS) || defined(USE_DARWINSSL) || defined(USE_OS400CRYPTO) \
|
||||
|| defined(USE_WIN32_CRYPTO)
|
||||
encrypt_des(magic, lmbuffer, pw);
|
||||
encrypt_des(magic, lmbuffer + 8, pw + 7);
|
||||
#endif
|
||||
|
||||
memset(lmbuffer + 16, 0, 21 - 16);
|
||||
}
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
#if USE_NTRESPONSES
|
||||
@ -384,6 +492,8 @@ static void ascii_to_unicode_le(unsigned char *dest, const char *src,
|
||||
}
|
||||
}
|
||||
|
||||
#if USE_NTLM_V2 && !defined(USE_WINDOWS_SSPI)
|
||||
|
||||
static void ascii_uppercase_to_unicode_le(unsigned char *dest,
|
||||
const char *src, size_t srclen)
|
||||
{
|
||||
@ -394,26 +504,11 @@ static void ascii_uppercase_to_unicode_le(unsigned char *dest,
|
||||
}
|
||||
}
|
||||
|
||||
static void write32_le(const int value, unsigned char *buffer)
|
||||
{
|
||||
buffer[0] = (char)(value & 0x000000FF);
|
||||
buffer[1] = (char)((value & 0x0000FF00) >> 8);
|
||||
buffer[2] = (char)((value & 0x00FF0000) >> 16);
|
||||
buffer[3] = (char)((value & 0xFF000000) >> 24);
|
||||
}
|
||||
|
||||
#if defined(HAVE_LONGLONG)
|
||||
static void write64_le(const long long value, unsigned char *buffer)
|
||||
#else
|
||||
static void write64_le(const __int64 value, unsigned char *buffer)
|
||||
#endif
|
||||
{
|
||||
write32_le((int)value, buffer);
|
||||
write32_le((int)(value >> 32), buffer + 4);
|
||||
}
|
||||
#endif /* USE_NTLM_V2 && !USE_WINDOWS_SSPI */
|
||||
|
||||
/*
|
||||
* Set up nt hashed passwords
|
||||
* @unittest: 1600
|
||||
*/
|
||||
CURLcode Curl_ntlm_core_mk_nt_hash(struct SessionHandle *data,
|
||||
const char *password,
|
||||
@ -437,7 +532,7 @@ CURLcode Curl_ntlm_core_mk_nt_hash(struct SessionHandle *data,
|
||||
|
||||
{
|
||||
/* Create NT hashed password. */
|
||||
#ifdef USE_SSLEAY
|
||||
#ifdef USE_OPENSSL
|
||||
MD4_CTX MD4pw;
|
||||
MD4_Init(&MD4pw);
|
||||
MD4_Update(&MD4pw, pw, 2 * len);
|
||||
@ -453,10 +548,23 @@ CURLcode Curl_ntlm_core_mk_nt_hash(struct SessionHandle *data,
|
||||
gcry_md_write(MD4pw, pw, 2 * len);
|
||||
memcpy (ntbuffer, gcry_md_read (MD4pw, 0), MD4_DIGEST_LENGTH);
|
||||
gcry_md_close(MD4pw);
|
||||
#elif defined(USE_NSS)
|
||||
#elif defined(USE_NSS) || defined(USE_OS400CRYPTO)
|
||||
Curl_md4it(ntbuffer, pw, 2 * len);
|
||||
#elif defined(USE_DARWINSSL)
|
||||
(void)CC_MD4(pw, (CC_LONG)(2 * len), ntbuffer);
|
||||
#elif defined(USE_WIN32_CRYPTO)
|
||||
HCRYPTPROV hprov;
|
||||
if(CryptAcquireContext(&hprov, NULL, NULL, PROV_RSA_FULL,
|
||||
CRYPT_VERIFYCONTEXT)) {
|
||||
HCRYPTHASH hhash;
|
||||
if(CryptCreateHash(hprov, CALG_MD4, 0, 0, &hhash)) {
|
||||
DWORD length = 16;
|
||||
CryptHashData(hhash, pw, (unsigned int)len * 2, 0);
|
||||
CryptGetHashParam(hhash, HP_HASHVAL, ntbuffer, &length, 0);
|
||||
CryptDestroyHash(hhash);
|
||||
}
|
||||
CryptReleaseContext(hprov, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
memset(ntbuffer + 16, 0, 21 - 16);
|
||||
@ -467,6 +575,8 @@ CURLcode Curl_ntlm_core_mk_nt_hash(struct SessionHandle *data,
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
#if USE_NTLM_V2 && !defined(USE_WINDOWS_SSPI)
|
||||
|
||||
/* This returns the HMAC MD5 digest */
|
||||
CURLcode Curl_hmac_md5(const unsigned char *key, unsigned int keylen,
|
||||
const unsigned char *data, unsigned int datalen,
|
||||
@ -497,7 +607,7 @@ CURLcode Curl_ntlm_core_mk_ntlmv2_hash(const char *user, size_t userlen,
|
||||
/* Unicode representation */
|
||||
size_t identity_len = (userlen + domlen) * 2;
|
||||
unsigned char *identity = malloc(identity_len);
|
||||
CURLcode res = CURLE_OK;
|
||||
CURLcode result = CURLE_OK;
|
||||
|
||||
if(!identity)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
@ -505,12 +615,12 @@ CURLcode Curl_ntlm_core_mk_ntlmv2_hash(const char *user, size_t userlen,
|
||||
ascii_uppercase_to_unicode_le(identity, user, userlen);
|
||||
ascii_to_unicode_le(identity + (userlen << 1), domain, domlen);
|
||||
|
||||
res = Curl_hmac_md5(ntlmhash, 16, identity, curlx_uztoui(identity_len),
|
||||
result = Curl_hmac_md5(ntlmhash, 16, identity, curlx_uztoui(identity_len),
|
||||
ntlmv2hash);
|
||||
|
||||
Curl_safefree(identity);
|
||||
free(identity);
|
||||
|
||||
return res;
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -559,7 +669,7 @@ CURLcode Curl_ntlm_core_mk_ntlmv2_resp(unsigned char *ntlmv2hash,
|
||||
#else
|
||||
__int64 tw;
|
||||
#endif
|
||||
CURLcode res = CURLE_OK;
|
||||
CURLcode result = CURLE_OK;
|
||||
|
||||
/* Calculate the timestamp */
|
||||
#ifdef DEBUGBUILD
|
||||
@ -586,17 +696,17 @@ CURLcode Curl_ntlm_core_mk_ntlmv2_resp(unsigned char *ntlmv2hash,
|
||||
"%c%c%c%c", /* Reserved = 0 */
|
||||
0, 0, 0, 0);
|
||||
|
||||
write64_le(tw, ptr + 24);
|
||||
Curl_write64_le(tw, ptr + 24);
|
||||
memcpy(ptr + 32, challenge_client, 8);
|
||||
memcpy(ptr + 44, ntlm->target_info, ntlm->target_info_len);
|
||||
|
||||
/* Concatenate the Type 2 challenge with the BLOB and do HMAC MD5 */
|
||||
memcpy(ptr + 8, &ntlm->nonce[0], 8);
|
||||
res = Curl_hmac_md5(ntlmv2hash, NTLM_HMAC_MD5_LEN, ptr + 8,
|
||||
result = Curl_hmac_md5(ntlmv2hash, NTLM_HMAC_MD5_LEN, ptr + 8,
|
||||
NTLMv2_BLOB_LEN + 8, hmac_output);
|
||||
if(res) {
|
||||
Curl_safefree(ptr);
|
||||
return res;
|
||||
if(result) {
|
||||
free(ptr);
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Concatenate the HMAC MD5 output with the BLOB */
|
||||
@ -606,7 +716,7 @@ CURLcode Curl_ntlm_core_mk_ntlmv2_resp(unsigned char *ntlmv2hash,
|
||||
*ntresp = ptr;
|
||||
*ntresp_len = len;
|
||||
|
||||
return res;
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -630,22 +740,26 @@ CURLcode Curl_ntlm_core_mk_lmv2_resp(unsigned char *ntlmv2hash,
|
||||
{
|
||||
unsigned char data[16];
|
||||
unsigned char hmac_output[16];
|
||||
CURLcode res = CURLE_OK;
|
||||
CURLcode result = CURLE_OK;
|
||||
|
||||
memcpy(&data[0], challenge_server, 8);
|
||||
memcpy(&data[8], challenge_client, 8);
|
||||
|
||||
res = Curl_hmac_md5(ntlmv2hash, 16, &data[0], 16, hmac_output);
|
||||
if(res)
|
||||
return res;
|
||||
result = Curl_hmac_md5(ntlmv2hash, 16, &data[0], 16, hmac_output);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
/* Concatenate the HMAC MD5 output with the client nonce */
|
||||
memcpy(lmresp, hmac_output, 16);
|
||||
memcpy(lmresp+16, challenge_client, 8);
|
||||
|
||||
return res;
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif /* USE_NTLM_V2 && !USE_WINDOWS_SSPI */
|
||||
|
||||
#endif /* USE_NTRESPONSES */
|
||||
|
||||
#endif /* USE_NTLM && !USE_WINDOWS_SSPI */
|
||||
#endif /* !USE_WINDOWS_SSPI || USE_WIN32_CRYPTO */
|
||||
|
||||
#endif /* USE_NTLM */
|
||||
|
@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -24,9 +24,11 @@
|
||||
|
||||
#include "curl_setup.h"
|
||||
|
||||
#if defined(USE_NTLM) && !defined(USE_WINDOWS_SSPI)
|
||||
#if defined(USE_NTLM)
|
||||
|
||||
#ifdef USE_SSLEAY
|
||||
#if !defined(USE_WINDOWS_SSPI) || defined(USE_WIN32_CRYPTO)
|
||||
|
||||
#ifdef USE_OPENSSL
|
||||
# if !defined(OPENSSL_VERSION_NUMBER) && \
|
||||
!defined(HEADER_SSL_H) && !defined(HEADER_MD5_H)
|
||||
# error "curl_ntlm_core.h shall not be included before OpenSSL headers."
|
||||
@ -34,38 +36,49 @@
|
||||
# ifdef OPENSSL_NO_MD4
|
||||
# define USE_NTRESPONSES 0
|
||||
# define USE_NTLM2SESSION 0
|
||||
# define USE_NTLM_V2 0
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Define USE_NTRESPONSES to 1 in order to make the type-3 message include
|
||||
* the NT response message. Define USE_NTLM2SESSION to 1 in order to make
|
||||
* the type-3 message include the NTLM2Session response message, requires
|
||||
* USE_NTRESPONSES defined to 1.
|
||||
*/
|
||||
|
||||
/* Define USE_NTRESPONSES to 1 in order to make the type-3 message include
|
||||
* the NT response message. */
|
||||
#ifndef USE_NTRESPONSES
|
||||
# define USE_NTRESPONSES 1
|
||||
# define USE_NTLM2SESSION 1
|
||||
#define USE_NTRESPONSES 1
|
||||
#endif
|
||||
|
||||
/* Define USE_NTLM2SESSION to 1 in order to make the type-3 message include the
|
||||
NTLM2Session response message, requires USE_NTRESPONSES defined to 1 and a
|
||||
Crypto engine that we have curl_ssl_md5sum() for. */
|
||||
#if !defined(USE_NTLM2SESSION) && USE_NTRESPONSES && !defined(USE_WIN32_CRYPTO)
|
||||
#define USE_NTLM2SESSION 1
|
||||
#endif
|
||||
|
||||
/* Define USE_NTLM_V2 to 1 in order to allow the type-3 message to include the
|
||||
LMv2 and NTLMv2 response messages, requires USE_NTRESPONSES defined to 1
|
||||
and support for 64-bit integers. */
|
||||
#if !defined(USE_NTLM_V2) && USE_NTRESPONSES && (CURL_SIZEOF_CURL_OFF_T > 4)
|
||||
#define USE_NTLM_V2 1
|
||||
#endif
|
||||
|
||||
void Curl_ntlm_core_lm_resp(const unsigned char *keys,
|
||||
const unsigned char *plaintext,
|
||||
unsigned char *results);
|
||||
|
||||
void Curl_ntlm_core_mk_lm_hash(struct SessionHandle *data,
|
||||
CURLcode Curl_ntlm_core_mk_lm_hash(struct SessionHandle *data,
|
||||
const char *password,
|
||||
unsigned char *lmbuffer /* 21 bytes */);
|
||||
|
||||
#if USE_NTRESPONSES
|
||||
CURLcode Curl_hmac_md5(const unsigned char *key, unsigned int keylen,
|
||||
const unsigned char *data, unsigned int datalen,
|
||||
unsigned char *output);
|
||||
|
||||
CURLcode Curl_ntlm_core_mk_nt_hash(struct SessionHandle *data,
|
||||
const char *password,
|
||||
unsigned char *ntbuffer /* 21 bytes */);
|
||||
|
||||
#if USE_NTLM_V2 && !defined(USE_WINDOWS_SSPI)
|
||||
|
||||
CURLcode Curl_hmac_md5(const unsigned char *key, unsigned int keylen,
|
||||
const unsigned char *data, unsigned int datalen,
|
||||
unsigned char *output);
|
||||
|
||||
CURLcode Curl_ntlm_core_mk_ntlmv2_hash(const char *user, size_t userlen,
|
||||
const char *domain, size_t domlen,
|
||||
unsigned char *ntlmhash,
|
||||
@ -82,8 +95,12 @@ CURLcode Curl_ntlm_core_mk_lmv2_resp(unsigned char *ntlmv2hash,
|
||||
unsigned char *challenge_server,
|
||||
unsigned char *lmresp);
|
||||
|
||||
#endif
|
||||
#endif /* USE_NTLM_V2 && !USE_WINDOWS_SSPI */
|
||||
|
||||
#endif /* USE_NTLM && !USE_WINDOWS_SSPI */
|
||||
#endif /* USE_NTRESPONSES */
|
||||
|
||||
#endif /* !USE_WINDOWS_SSPI || USE_WIN32_CRYPTO */
|
||||
|
||||
#endif /* USE_NTLM */
|
||||
|
||||
#endif /* HEADER_CURL_NTLM_CORE_H */
|
||||
|
@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -22,7 +22,7 @@
|
||||
|
||||
#include "curl_setup.h"
|
||||
|
||||
#ifdef USE_NTLM
|
||||
#if defined(USE_NTLM) && !defined(USE_WINDOWS_SSPI)
|
||||
|
||||
/*
|
||||
* NTLM details:
|
||||
@ -41,21 +41,21 @@
|
||||
#include "curl_gethostname.h"
|
||||
#include "curl_multibyte.h"
|
||||
#include "warnless.h"
|
||||
#include "curl_memory.h"
|
||||
|
||||
#ifdef USE_WINDOWS_SSPI
|
||||
# include "curl_sspi.h"
|
||||
#endif
|
||||
|
||||
#include "vtls/vtls.h"
|
||||
|
||||
#ifdef USE_NSS
|
||||
#include "vtls/nssg.h" /* for Curl_nss_force_init() */
|
||||
#endif
|
||||
|
||||
#define BUILDING_CURL_NTLM_MSGS_C
|
||||
#include "curl_ntlm_msgs.h"
|
||||
#include "curl_sasl.h"
|
||||
#include "curl_endian.h"
|
||||
#include "curl_printf.h"
|
||||
|
||||
#define _MPRINTF_REPLACE /* use our functions only */
|
||||
#include <curl/mprintf.h>
|
||||
|
||||
/* The last #include file should be: */
|
||||
/* The last #include files should be: */
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
/* "NTLMSSP" signature is always in ASCII regardless of the platform */
|
||||
@ -147,63 +147,38 @@ static void ntlm_print_hex(FILE *handle, const char *buf, size_t len)
|
||||
# define DEBUG_OUT(x) Curl_nop_stmt
|
||||
#endif
|
||||
|
||||
#ifndef USE_WINDOWS_SSPI
|
||||
/*
|
||||
* This function converts from the little endian format used in the
|
||||
* incoming package to whatever endian format we're using natively.
|
||||
* Argument is a pointer to a 4 byte buffer.
|
||||
*/
|
||||
static unsigned int readint_le(unsigned char *buf)
|
||||
{
|
||||
return ((unsigned int)buf[0]) | ((unsigned int)buf[1] << 8) |
|
||||
((unsigned int)buf[2] << 16) | ((unsigned int)buf[3] << 24);
|
||||
}
|
||||
|
||||
/*
|
||||
* This function converts from the little endian format used in the incoming
|
||||
* package to whatever endian format we're using natively. Argument is a
|
||||
* pointer to a 2 byte buffer.
|
||||
*/
|
||||
static unsigned int readshort_le(unsigned char *buf)
|
||||
{
|
||||
return ((unsigned int)buf[0]) | ((unsigned int)buf[1] << 8);
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_ntlm_decode_type2_target()
|
||||
* ntlm_decode_type2_target()
|
||||
*
|
||||
* This is used to decode the "target info" in the ntlm type-2 message
|
||||
* received.
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* data [in] - Pointer to the session handle
|
||||
* buffer [in] - The decoded base64 ntlm header of Type 2
|
||||
* size [in] - The input buffer size, atleast 32 bytes
|
||||
* ntlm [in] - Pointer to ntlm data struct being used and modified.
|
||||
* data [in] - The session handle.
|
||||
* buffer [in] - The decoded type-2 message.
|
||||
* size [in] - The input buffer size, at least 32 bytes.
|
||||
* ntlm [in/out] - The ntlm data struct being used and modified.
|
||||
*
|
||||
* Returns CURLE_OK on success.
|
||||
*/
|
||||
CURLcode Curl_ntlm_decode_type2_target(struct SessionHandle *data,
|
||||
static CURLcode ntlm_decode_type2_target(struct SessionHandle *data,
|
||||
unsigned char *buffer,
|
||||
size_t size,
|
||||
struct ntlmdata *ntlm)
|
||||
{
|
||||
unsigned int target_info_len = 0;
|
||||
unsigned short target_info_len = 0;
|
||||
unsigned int target_info_offset = 0;
|
||||
|
||||
Curl_safefree(ntlm->target_info);
|
||||
ntlm->target_info_len = 0;
|
||||
|
||||
if(size >= 48) {
|
||||
target_info_len = readshort_le(&buffer[40]);
|
||||
target_info_offset = readint_le(&buffer[44]);
|
||||
target_info_len = Curl_read16_le(&buffer[40]);
|
||||
target_info_offset = Curl_read32_le(&buffer[44]);
|
||||
if(target_info_len > 0) {
|
||||
if(((target_info_offset + target_info_len) > size) ||
|
||||
(target_info_offset < 48)) {
|
||||
infof(data, "NTLM handshake failure (bad type-2 message). "
|
||||
"Target Info Offset Len is set incorrect by the peer\n");
|
||||
return CURLE_REMOTE_ACCESS_DENIED;
|
||||
return CURLE_BAD_CONTENT_ENCODING;
|
||||
}
|
||||
|
||||
ntlm->target_info = malloc(target_info_len);
|
||||
@ -211,17 +186,14 @@ CURLcode Curl_ntlm_decode_type2_target(struct SessionHandle *data,
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
memcpy(ntlm->target_info, &buffer[target_info_offset], target_info_len);
|
||||
}
|
||||
}
|
||||
|
||||
ntlm->target_info_len = target_info_len;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
NTLM message structure notes:
|
||||
|
||||
@ -239,29 +211,26 @@ CURLcode Curl_ntlm_decode_type2_target(struct SessionHandle *data,
|
||||
*/
|
||||
|
||||
/*
|
||||
* Curl_ntlm_decode_type2_message()
|
||||
* Curl_sasl_decode_ntlm_type2_message()
|
||||
*
|
||||
* This is used to decode a ntlm type-2 message received from a HTTP or SASL
|
||||
* based (such as SMTP, POP3 or IMAP) server. The message is first decoded
|
||||
* from a base64 string into a raw ntlm message and checked for validity
|
||||
* before the appropriate data for creating a type-3 message is written to
|
||||
* the given ntlm data structure.
|
||||
* This is used to decode an already encoded NTLM type-2 message. The message
|
||||
* is first decoded from a base64 string into a raw NTLM message and checked
|
||||
* for validity before the appropriate data for creating a type-3 message is
|
||||
* written to the given NTLM data structure.
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* data [in] - Pointer to session handle.
|
||||
* header [in] - Pointer to the input buffer.
|
||||
* ntlm [in] - Pointer to ntlm data struct being used and modified.
|
||||
* data [in] - The session handle.
|
||||
* type2msg [in] - The base64 encoded type-2 message.
|
||||
* ntlm [in/out] - The ntlm data struct being used and modified.
|
||||
*
|
||||
* Returns CURLE_OK on success.
|
||||
*/
|
||||
CURLcode Curl_ntlm_decode_type2_message(struct SessionHandle *data,
|
||||
const char *header,
|
||||
CURLcode Curl_sasl_decode_ntlm_type2_message(struct SessionHandle *data,
|
||||
const char *type2msg,
|
||||
struct ntlmdata *ntlm)
|
||||
{
|
||||
#ifndef USE_WINDOWS_SSPI
|
||||
static const char type2_marker[] = { 0x02, 0x00, 0x00, 0x00 };
|
||||
#endif
|
||||
|
||||
/* NTLM type-2 message structure:
|
||||
|
||||
@ -279,52 +248,52 @@ CURLcode Curl_ntlm_decode_type2_message(struct SessionHandle *data,
|
||||
(*) -> Optional
|
||||
*/
|
||||
|
||||
size_t size = 0;
|
||||
unsigned char *buffer = NULL;
|
||||
CURLcode error;
|
||||
CURLcode result = CURLE_OK;
|
||||
unsigned char *type2 = NULL;
|
||||
size_t type2_len = 0;
|
||||
|
||||
#if defined(CURL_DISABLE_VERBOSE_STRINGS) || defined(USE_WINDOWS_SSPI)
|
||||
#if defined(USE_NSS)
|
||||
/* Make sure the crypto backend is initialized */
|
||||
result = Curl_nss_force_init(data);
|
||||
if(result)
|
||||
return result;
|
||||
#elif defined(CURL_DISABLE_VERBOSE_STRINGS)
|
||||
(void)data;
|
||||
#endif
|
||||
|
||||
error = Curl_base64_decode(header, &buffer, &size);
|
||||
if(error)
|
||||
return error;
|
||||
|
||||
if(!buffer) {
|
||||
infof(data, "NTLM handshake failure (unhandled condition)\n");
|
||||
return CURLE_REMOTE_ACCESS_DENIED;
|
||||
/* Decode the base-64 encoded type-2 message */
|
||||
if(strlen(type2msg) && *type2msg != '=') {
|
||||
result = Curl_base64_decode(type2msg, &type2, &type2_len);
|
||||
if(result)
|
||||
return result;
|
||||
}
|
||||
|
||||
#ifdef USE_WINDOWS_SSPI
|
||||
ntlm->type_2 = malloc(size + 1);
|
||||
if(ntlm->type_2 == NULL) {
|
||||
free(buffer);
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
/* Ensure we have a valid type-2 message */
|
||||
if(!type2) {
|
||||
infof(data, "NTLM handshake failure (empty type-2 message)\n");
|
||||
return CURLE_BAD_CONTENT_ENCODING;
|
||||
}
|
||||
ntlm->n_type_2 = curlx_uztoul(size);
|
||||
memcpy(ntlm->type_2, buffer, size);
|
||||
#else
|
||||
|
||||
ntlm->flags = 0;
|
||||
|
||||
if((size < 32) ||
|
||||
(memcmp(buffer, NTLMSSP_SIGNATURE, 8) != 0) ||
|
||||
(memcmp(buffer + 8, type2_marker, sizeof(type2_marker)) != 0)) {
|
||||
if((type2_len < 32) ||
|
||||
(memcmp(type2, NTLMSSP_SIGNATURE, 8) != 0) ||
|
||||
(memcmp(type2 + 8, type2_marker, sizeof(type2_marker)) != 0)) {
|
||||
/* This was not a good enough type-2 message */
|
||||
free(buffer);
|
||||
free(type2);
|
||||
infof(data, "NTLM handshake failure (bad type-2 message)\n");
|
||||
return CURLE_REMOTE_ACCESS_DENIED;
|
||||
return CURLE_BAD_CONTENT_ENCODING;
|
||||
}
|
||||
|
||||
ntlm->flags = readint_le(&buffer[20]);
|
||||
memcpy(ntlm->nonce, &buffer[24], 8);
|
||||
ntlm->flags = Curl_read32_le(&type2[20]);
|
||||
memcpy(ntlm->nonce, &type2[24], 8);
|
||||
|
||||
if(ntlm->flags & NTLMFLAG_NEGOTIATE_TARGET_INFO) {
|
||||
error = Curl_ntlm_decode_type2_target(data, buffer, size, ntlm);
|
||||
if(error) {
|
||||
free(buffer);
|
||||
result = ntlm_decode_type2_target(data, type2, type2_len, ntlm);
|
||||
if(result) {
|
||||
free(type2);
|
||||
infof(data, "NTLM handshake failure (bad type-2 message)\n");
|
||||
return error;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@ -336,32 +305,12 @@ CURLcode Curl_ntlm_decode_type2_message(struct SessionHandle *data,
|
||||
fprintf(stderr, "\n****\n");
|
||||
fprintf(stderr, "**** Header %s\n ", header);
|
||||
});
|
||||
#endif
|
||||
free(buffer);
|
||||
|
||||
return CURLE_OK;
|
||||
free(type2);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#ifdef USE_WINDOWS_SSPI
|
||||
void Curl_ntlm_sspi_cleanup(struct ntlmdata *ntlm)
|
||||
{
|
||||
Curl_safefree(ntlm->type_2);
|
||||
|
||||
if(ntlm->has_handles) {
|
||||
s_pSecFn->DeleteSecurityContext(&ntlm->c_handle);
|
||||
s_pSecFn->FreeCredentialsHandle(&ntlm->handle);
|
||||
ntlm->has_handles = 0;
|
||||
}
|
||||
|
||||
ntlm->max_token_length = 0;
|
||||
Curl_safefree(ntlm->output_token);
|
||||
|
||||
Curl_sspi_free_identity(ntlm->p_identity);
|
||||
ntlm->p_identity = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef USE_WINDOWS_SSPI
|
||||
/* copy the source to the destination and fill in zeroes in every
|
||||
other destination byte! */
|
||||
static void unicodecpy(unsigned char *dest, const char *src, size_t length)
|
||||
@ -372,14 +321,12 @@ static void unicodecpy(unsigned char *dest, const char *src, size_t length)
|
||||
dest[2 * i + 1] = '\0';
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Curl_ntlm_create_type1_message()
|
||||
* Curl_sasl_create_ntlm_type1_message()
|
||||
*
|
||||
* This is used to generate an already encoded NTLM type-1 message ready for
|
||||
* sending to the recipient, be it a HTTP or SASL based (such as SMTP, POP3
|
||||
* or IMAP) server, using the appropriate compile time crypo API.
|
||||
* sending to the recipient using the appropriate compile time crypto API.
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
@ -392,11 +339,10 @@ static void unicodecpy(unsigned char *dest, const char *src, size_t length)
|
||||
*
|
||||
* Returns CURLE_OK on success.
|
||||
*/
|
||||
CURLcode Curl_ntlm_create_type1_message(const char *userp,
|
||||
CURLcode Curl_sasl_create_ntlm_type1_message(const char *userp,
|
||||
const char *passwdp,
|
||||
struct ntlmdata *ntlm,
|
||||
char **outptr,
|
||||
size_t *outlen)
|
||||
char **outptr, size_t *outlen)
|
||||
{
|
||||
/* NTLM type-1 message structure:
|
||||
|
||||
@ -414,89 +360,6 @@ CURLcode Curl_ntlm_create_type1_message(const char *userp,
|
||||
|
||||
size_t size;
|
||||
|
||||
#ifdef USE_WINDOWS_SSPI
|
||||
|
||||
PSecPkgInfo SecurityPackage;
|
||||
SecBuffer type_1_buf;
|
||||
SecBufferDesc type_1_desc;
|
||||
SECURITY_STATUS status;
|
||||
unsigned long attrs;
|
||||
TimeStamp tsDummy; /* For Windows 9x compatibility of SSPI calls */
|
||||
|
||||
Curl_ntlm_sspi_cleanup(ntlm);
|
||||
|
||||
/* Query the security package for NTLM */
|
||||
status = s_pSecFn->QuerySecurityPackageInfo((TCHAR *) TEXT("NTLM"),
|
||||
&SecurityPackage);
|
||||
if(status != SEC_E_OK)
|
||||
return CURLE_NOT_BUILT_IN;
|
||||
|
||||
ntlm->max_token_length = SecurityPackage->cbMaxToken;
|
||||
|
||||
/* Release the package buffer as it is not required anymore */
|
||||
s_pSecFn->FreeContextBuffer(SecurityPackage);
|
||||
|
||||
/* Allocate our output buffer */
|
||||
ntlm->output_token = malloc(ntlm->max_token_length);
|
||||
if(!ntlm->output_token)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
if(userp && *userp) {
|
||||
CURLcode result;
|
||||
|
||||
/* Populate our identity structure */
|
||||
result = Curl_create_sspi_identity(userp, passwdp, &ntlm->identity);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
/* Allow proper cleanup of the identity structure */
|
||||
ntlm->p_identity = &ntlm->identity;
|
||||
}
|
||||
else
|
||||
/* Use the current Windows user */
|
||||
ntlm->p_identity = NULL;
|
||||
|
||||
/* Acquire our credientials handle */
|
||||
status = s_pSecFn->AcquireCredentialsHandle(NULL,
|
||||
(TCHAR *) TEXT("NTLM"),
|
||||
SECPKG_CRED_OUTBOUND, NULL,
|
||||
ntlm->p_identity, NULL, NULL,
|
||||
&ntlm->handle, &tsDummy);
|
||||
if(status != SEC_E_OK)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
/* Setup the type-1 "output" security buffer */
|
||||
type_1_desc.ulVersion = SECBUFFER_VERSION;
|
||||
type_1_desc.cBuffers = 1;
|
||||
type_1_desc.pBuffers = &type_1_buf;
|
||||
type_1_buf.BufferType = SECBUFFER_TOKEN;
|
||||
type_1_buf.pvBuffer = ntlm->output_token;
|
||||
type_1_buf.cbBuffer = curlx_uztoul(ntlm->max_token_length);
|
||||
|
||||
/* Generate our type-1 message */
|
||||
status = s_pSecFn->InitializeSecurityContext(&ntlm->handle, NULL,
|
||||
(TCHAR *) TEXT(""),
|
||||
ISC_REQ_CONFIDENTIALITY |
|
||||
ISC_REQ_REPLAY_DETECT |
|
||||
ISC_REQ_CONNECTION,
|
||||
0, SECURITY_NETWORK_DREP,
|
||||
NULL, 0,
|
||||
&ntlm->c_handle, &type_1_desc,
|
||||
&attrs, &tsDummy);
|
||||
|
||||
if(status == SEC_I_COMPLETE_AND_CONTINUE ||
|
||||
status == SEC_I_CONTINUE_NEEDED)
|
||||
s_pSecFn->CompleteAuthToken(&ntlm->c_handle, &type_1_desc);
|
||||
else if(status != SEC_E_OK) {
|
||||
s_pSecFn->FreeCredentialsHandle(&ntlm->handle);
|
||||
return CURLE_RECV_ERROR;
|
||||
}
|
||||
|
||||
ntlm->has_handles = 1;
|
||||
size = type_1_buf.cbBuffer;
|
||||
|
||||
#else
|
||||
|
||||
unsigned char ntlmbuf[NTLM_BUFSIZE];
|
||||
const char *host = ""; /* empty */
|
||||
const char *domain = ""; /* empty */
|
||||
@ -507,9 +370,11 @@ CURLcode Curl_ntlm_create_type1_message(const char *userp,
|
||||
domain are empty */
|
||||
(void)userp;
|
||||
(void)passwdp;
|
||||
(void)ntlm;
|
||||
|
||||
#if USE_NTLM2SESSION
|
||||
/* Clean up any former leftovers and initialise to defaults */
|
||||
Curl_sasl_ntlm_cleanup(ntlm);
|
||||
|
||||
#if USE_NTRESPONSES && USE_NTLM2SESSION
|
||||
#define NTLM2FLAG NTLMFLAG_NEGOTIATE_NTLM2_KEY
|
||||
#else
|
||||
#define NTLM2FLAG 0
|
||||
@ -550,8 +415,6 @@ CURLcode Curl_ntlm_create_type1_message(const char *userp,
|
||||
/* Initial packet length */
|
||||
size = 32 + hostlen + domlen;
|
||||
|
||||
#endif
|
||||
|
||||
DEBUG_OUT({
|
||||
fprintf(stderr, "* TYPE1 header flags=0x%02.2x%02.2x%02.2x%02.2x "
|
||||
"0x%08.8x ",
|
||||
@ -575,20 +438,14 @@ CURLcode Curl_ntlm_create_type1_message(const char *userp,
|
||||
});
|
||||
|
||||
/* Return with binary blob encoded into base64 */
|
||||
#ifdef USE_WINDOWS_SSPI
|
||||
return Curl_base64_encode(NULL, (char *)ntlm->output_token, size,
|
||||
outptr, outlen);
|
||||
#else
|
||||
return Curl_base64_encode(NULL, (char *)ntlmbuf, size, outptr, outlen);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_ntlm_create_type3_message()
|
||||
* Curl_sasl_create_ntlm_type3_message()
|
||||
*
|
||||
* This is used to generate an already encoded NTLM type-3 message ready for
|
||||
* sending to the recipient, be it a HTTP or SASL based (such as SMTP, POP3
|
||||
* or IMAP) server, using the appropriate compile time crypo API.
|
||||
* sending to the recipient using the appropriate compile time crypto API.
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
@ -602,12 +459,12 @@ CURLcode Curl_ntlm_create_type1_message(const char *userp,
|
||||
*
|
||||
* Returns CURLE_OK on success.
|
||||
*/
|
||||
CURLcode Curl_ntlm_create_type3_message(struct SessionHandle *data,
|
||||
CURLcode Curl_sasl_create_ntlm_type3_message(struct SessionHandle *data,
|
||||
const char *userp,
|
||||
const char *passwdp,
|
||||
struct ntlmdata *ntlm,
|
||||
char **outptr,
|
||||
size_t *outlen)
|
||||
char **outptr, size_t *outlen)
|
||||
|
||||
{
|
||||
/* NTLM type-3 message structure:
|
||||
|
||||
@ -627,65 +484,8 @@ CURLcode Curl_ntlm_create_type3_message(struct SessionHandle *data,
|
||||
(*) -> Optional
|
||||
*/
|
||||
|
||||
size_t size;
|
||||
|
||||
#ifdef USE_WINDOWS_SSPI
|
||||
CURLcode result = CURLE_OK;
|
||||
SecBuffer type_2_buf;
|
||||
SecBuffer type_3_buf;
|
||||
SecBufferDesc type_2_desc;
|
||||
SecBufferDesc type_3_desc;
|
||||
SECURITY_STATUS status;
|
||||
unsigned long attrs;
|
||||
TimeStamp tsDummy; /* For Windows 9x compatibility of SSPI calls */
|
||||
|
||||
(void)passwdp;
|
||||
(void)userp;
|
||||
(void)data;
|
||||
|
||||
/* Setup the type-2 "input" security buffer */
|
||||
type_2_desc.ulVersion = SECBUFFER_VERSION;
|
||||
type_2_desc.cBuffers = 1;
|
||||
type_2_desc.pBuffers = &type_2_buf;
|
||||
type_2_buf.BufferType = SECBUFFER_TOKEN;
|
||||
type_2_buf.pvBuffer = ntlm->type_2;
|
||||
type_2_buf.cbBuffer = ntlm->n_type_2;
|
||||
|
||||
/* Setup the type-3 "output" security buffer */
|
||||
type_3_desc.ulVersion = SECBUFFER_VERSION;
|
||||
type_3_desc.cBuffers = 1;
|
||||
type_3_desc.pBuffers = &type_3_buf;
|
||||
type_3_buf.BufferType = SECBUFFER_TOKEN;
|
||||
type_3_buf.pvBuffer = ntlm->output_token;
|
||||
type_3_buf.cbBuffer = curlx_uztoul(ntlm->max_token_length);
|
||||
|
||||
/* Generate our type-3 message */
|
||||
status = s_pSecFn->InitializeSecurityContext(&ntlm->handle,
|
||||
&ntlm->c_handle,
|
||||
(TCHAR *) TEXT(""),
|
||||
ISC_REQ_CONFIDENTIALITY |
|
||||
ISC_REQ_REPLAY_DETECT |
|
||||
ISC_REQ_CONNECTION,
|
||||
0, SECURITY_NETWORK_DREP,
|
||||
&type_2_desc,
|
||||
0, &ntlm->c_handle,
|
||||
&type_3_desc,
|
||||
&attrs, &tsDummy);
|
||||
if(status != SEC_E_OK)
|
||||
return CURLE_RECV_ERROR;
|
||||
|
||||
size = type_3_buf.cbBuffer;
|
||||
|
||||
/* Return with binary blob encoded into base64 */
|
||||
result = Curl_base64_encode(NULL, (char *)ntlm->output_token, size,
|
||||
outptr, outlen);
|
||||
|
||||
Curl_ntlm_sspi_cleanup(ntlm);
|
||||
|
||||
return result;
|
||||
|
||||
#else
|
||||
|
||||
size_t size;
|
||||
unsigned char ntlmbuf[NTLM_BUFSIZE];
|
||||
int lmrespoff;
|
||||
unsigned char lmresp[24]; /* fixed-size */
|
||||
@ -706,7 +506,6 @@ CURLcode Curl_ntlm_create_type3_message(struct SessionHandle *data,
|
||||
size_t hostlen = 0;
|
||||
size_t userlen = 0;
|
||||
size_t domlen = 0;
|
||||
CURLcode res = CURLE_OK;
|
||||
|
||||
user = strchr(userp, '\\');
|
||||
if(!user)
|
||||
@ -733,7 +532,7 @@ CURLcode Curl_ntlm_create_type3_message(struct SessionHandle *data,
|
||||
hostlen = strlen(host);
|
||||
}
|
||||
|
||||
#if USE_NTRESPONSES
|
||||
#if USE_NTRESPONSES && USE_NTLM_V2
|
||||
if(ntlm->target_info_len) {
|
||||
unsigned char ntbuffer[0x18];
|
||||
unsigned int entropy[2];
|
||||
@ -742,35 +541,35 @@ CURLcode Curl_ntlm_create_type3_message(struct SessionHandle *data,
|
||||
entropy[0] = Curl_rand(data);
|
||||
entropy[1] = Curl_rand(data);
|
||||
|
||||
res = Curl_ntlm_core_mk_nt_hash(data, passwdp, ntbuffer);
|
||||
if(res)
|
||||
return res;
|
||||
result = Curl_ntlm_core_mk_nt_hash(data, passwdp, ntbuffer);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
res = Curl_ntlm_core_mk_ntlmv2_hash(user, userlen, domain, domlen,
|
||||
result = Curl_ntlm_core_mk_ntlmv2_hash(user, userlen, domain, domlen,
|
||||
ntbuffer, ntlmv2hash);
|
||||
if(res)
|
||||
return res;
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
/* LMv2 response */
|
||||
res = Curl_ntlm_core_mk_lmv2_resp(ntlmv2hash,
|
||||
result = Curl_ntlm_core_mk_lmv2_resp(ntlmv2hash,
|
||||
(unsigned char *)&entropy[0],
|
||||
&ntlm->nonce[0], lmresp);
|
||||
if(res)
|
||||
return res;
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
/* NTLMv2 response */
|
||||
res = Curl_ntlm_core_mk_ntlmv2_resp(ntlmv2hash,
|
||||
result = Curl_ntlm_core_mk_ntlmv2_resp(ntlmv2hash,
|
||||
(unsigned char *)&entropy[0],
|
||||
ntlm, &ntlmv2resp, &ntresplen);
|
||||
if(res)
|
||||
return res;
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
ptr_ntresp = ntlmv2resp;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
|
||||
#if USE_NTLM2SESSION
|
||||
#if USE_NTRESPONSES && USE_NTLM2SESSION
|
||||
/* We don't support NTLM2 if we don't have USE_NTRESPONSES */
|
||||
if(ntlm->flags & NTLMFLAG_NEGOTIATE_NTLM2_KEY) {
|
||||
unsigned char ntbuffer[0x18];
|
||||
@ -792,13 +591,13 @@ CURLcode Curl_ntlm_create_type3_message(struct SessionHandle *data,
|
||||
memcpy(tmp, &ntlm->nonce[0], 8);
|
||||
memcpy(tmp + 8, entropy, 8);
|
||||
|
||||
Curl_ssl_md5sum(tmp, 16, md5sum, MD5_DIGEST_LENGTH);
|
||||
|
||||
/* We shall only use the first 8 bytes of md5sum, but the des
|
||||
code in Curl_ntlm_core_lm_resp only encrypt the first 8 bytes */
|
||||
if(CURLE_OUT_OF_MEMORY ==
|
||||
Curl_ntlm_core_mk_nt_hash(data, passwdp, ntbuffer))
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
result = Curl_ssl_md5sum(tmp, 16, md5sum, MD5_DIGEST_LENGTH);
|
||||
if(!result)
|
||||
/* We shall only use the first 8 bytes of md5sum, but the des code in
|
||||
Curl_ntlm_core_lm_resp only encrypt the first 8 bytes */
|
||||
result = Curl_ntlm_core_mk_nt_hash(data, passwdp, ntbuffer);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
Curl_ntlm_core_lm_resp(ntbuffer, md5sum, ntresp);
|
||||
|
||||
@ -815,14 +614,19 @@ CURLcode Curl_ntlm_create_type3_message(struct SessionHandle *data,
|
||||
unsigned char lmbuffer[0x18];
|
||||
|
||||
#if USE_NTRESPONSES
|
||||
if(CURLE_OUT_OF_MEMORY ==
|
||||
Curl_ntlm_core_mk_nt_hash(data, passwdp, ntbuffer))
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
result = Curl_ntlm_core_mk_nt_hash(data, passwdp, ntbuffer);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
Curl_ntlm_core_lm_resp(ntbuffer, &ntlm->nonce[0], ntresp);
|
||||
#endif
|
||||
|
||||
Curl_ntlm_core_mk_lm_hash(data, passwdp, lmbuffer);
|
||||
result = Curl_ntlm_core_mk_lm_hash(data, passwdp, lmbuffer);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
Curl_ntlm_core_lm_resp(lmbuffer, &ntlm->nonce[0], lmresp);
|
||||
|
||||
/* A safer but less compatible alternative is:
|
||||
* Curl_ntlm_core_lm_resp(ntbuffer, &ntlm->nonce[0], lmresp);
|
||||
* See http://davenport.sourceforge.net/ntlm.html#ntlmVersion2 */
|
||||
@ -954,7 +758,7 @@ CURLcode Curl_ntlm_create_type3_message(struct SessionHandle *data,
|
||||
ntlm_print_hex(stderr, (char *)&ntlmbuf[ntrespoff], ntresplen);
|
||||
});
|
||||
|
||||
Curl_safefree(ntlmv2resp);/* Free the dynamic buffer allocated for NTLMv2 */
|
||||
free(ntlmv2resp);/* Free the dynamic buffer allocated for NTLMv2 */
|
||||
|
||||
#endif
|
||||
|
||||
@ -997,14 +801,17 @@ CURLcode Curl_ntlm_create_type3_message(struct SessionHandle *data,
|
||||
size += hostlen;
|
||||
|
||||
/* Convert domain, user, and host to ASCII but leave the rest as-is */
|
||||
res = Curl_convert_to_network(data, (char *)&ntlmbuf[domoff],
|
||||
result = Curl_convert_to_network(data, (char *)&ntlmbuf[domoff],
|
||||
size - domoff);
|
||||
if(res)
|
||||
if(result)
|
||||
return CURLE_CONV_FAILED;
|
||||
|
||||
/* Return with binary blob encoded into base64 */
|
||||
return Curl_base64_encode(NULL, (char *)ntlmbuf, size, outptr, outlen);
|
||||
#endif
|
||||
result = Curl_base64_encode(NULL, (char *)ntlmbuf, size, outptr, outlen);
|
||||
|
||||
Curl_sasl_ntlm_cleanup(ntlm);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif /* USE_NTLM */
|
||||
#endif /* USE_NTLM && !USE_WINDOWS_SSPI */
|
||||
|
@ -26,40 +26,6 @@
|
||||
|
||||
#ifdef USE_NTLM
|
||||
|
||||
/* This is to generate a base64 encoded NTLM type-1 message */
|
||||
CURLcode Curl_ntlm_create_type1_message(const char *userp,
|
||||
const char *passwdp,
|
||||
struct ntlmdata *ntlm,
|
||||
char **outptr,
|
||||
size_t *outlen);
|
||||
|
||||
/* This is to generate a base64 encoded NTLM type-3 message */
|
||||
CURLcode Curl_ntlm_create_type3_message(struct SessionHandle *data,
|
||||
const char *userp,
|
||||
const char *passwdp,
|
||||
struct ntlmdata *ntlm,
|
||||
char **outptr,
|
||||
size_t *outlen);
|
||||
|
||||
/* This is to decode a NTLM type-2 message */
|
||||
CURLcode Curl_ntlm_decode_type2_message(struct SessionHandle *data,
|
||||
const char* header,
|
||||
struct ntlmdata* ntlm);
|
||||
|
||||
/* This is to decode target info received in NTLM type-2 message */
|
||||
CURLcode Curl_ntlm_decode_type2_target(struct SessionHandle *data,
|
||||
unsigned char* buffer,
|
||||
size_t size,
|
||||
struct ntlmdata* ntlm);
|
||||
|
||||
|
||||
/* This is to clean up the ntlm data structure */
|
||||
#ifdef USE_WINDOWS_SSPI
|
||||
void Curl_ntlm_sspi_cleanup(struct ntlmdata *ntlm);
|
||||
#else
|
||||
#define Curl_ntlm_sspi_cleanup(x)
|
||||
#endif
|
||||
|
||||
/* NTLM buffer fixed size, large enough for long user + host + domain */
|
||||
#define NTLM_BUFSIZE 1024
|
||||
|
||||
|
@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -22,7 +22,8 @@
|
||||
|
||||
#include "curl_setup.h"
|
||||
|
||||
#if defined(USE_NTLM) && defined(NTLM_WB_ENABLED)
|
||||
#if !defined(CURL_DISABLE_HTTP) && defined(USE_NTLM) && \
|
||||
defined(NTLM_WB_ENABLED)
|
||||
|
||||
/*
|
||||
* NTLM details:
|
||||
@ -50,12 +51,10 @@
|
||||
#include "curl_ntlm_wb.h"
|
||||
#include "url.h"
|
||||
#include "strerror.h"
|
||||
#include "curl_printf.h"
|
||||
|
||||
/* The last #include files should be: */
|
||||
#include "curl_memory.h"
|
||||
|
||||
#define _MPRINTF_REPLACE /* use our functions only */
|
||||
#include <curl/mprintf.h>
|
||||
|
||||
/* The last #include file should be: */
|
||||
#include "memdebug.h"
|
||||
|
||||
#if DEBUG_ME
|
||||
@ -106,9 +105,9 @@ void Curl_ntlm_wb_cleanup(struct connectdata *conn)
|
||||
conn->ntlm_auth_hlpr_pid = 0;
|
||||
}
|
||||
|
||||
Curl_safefree(conn->challenge_header);
|
||||
free(conn->challenge_header);
|
||||
conn->challenge_header = NULL;
|
||||
Curl_safefree(conn->response_header);
|
||||
free(conn->response_header);
|
||||
conn->response_header = NULL;
|
||||
}
|
||||
|
||||
@ -245,13 +244,13 @@ static CURLcode ntlm_wb_init(struct connectdata *conn, const char *userp)
|
||||
sclose(sockfds[1]);
|
||||
conn->ntlm_auth_hlpr_socket = sockfds[0];
|
||||
conn->ntlm_auth_hlpr_pid = child_pid;
|
||||
Curl_safefree(domain);
|
||||
Curl_safefree(ntlm_auth_alloc);
|
||||
free(domain);
|
||||
free(ntlm_auth_alloc);
|
||||
return CURLE_OK;
|
||||
|
||||
done:
|
||||
Curl_safefree(domain);
|
||||
Curl_safefree(ntlm_auth_alloc);
|
||||
free(domain);
|
||||
free(ntlm_auth_alloc);
|
||||
return CURLE_REMOTE_ACCESS_DENIED;
|
||||
}
|
||||
|
||||
@ -293,7 +292,7 @@ static CURLcode ntlm_wb_response(struct connectdata *conn,
|
||||
len_out += size;
|
||||
if(buf[len_out - 1] == '\n') {
|
||||
buf[len_out - 1] = '\0';
|
||||
goto wrfinish;
|
||||
break;
|
||||
}
|
||||
newbuf = realloc(buf, len_out + NTLM_BUFSIZE);
|
||||
if(!newbuf) {
|
||||
@ -302,13 +301,12 @@ static CURLcode ntlm_wb_response(struct connectdata *conn,
|
||||
}
|
||||
buf = newbuf;
|
||||
}
|
||||
goto done;
|
||||
wrfinish:
|
||||
|
||||
/* Samba/winbind installed but not configured */
|
||||
if(state == NTLMSTATE_TYPE1 &&
|
||||
len_out == 3 &&
|
||||
buf[0] == 'P' && buf[1] == 'W')
|
||||
return CURLE_REMOTE_ACCESS_DENIED;
|
||||
goto done;
|
||||
/* invalid response */
|
||||
if(len_out < 4)
|
||||
goto done;
|
||||
@ -391,12 +389,12 @@ CURLcode Curl_output_ntlm_wb(struct connectdata *conn,
|
||||
if(res)
|
||||
return res;
|
||||
|
||||
Curl_safefree(*allocuserpwd);
|
||||
free(*allocuserpwd);
|
||||
*allocuserpwd = aprintf("%sAuthorization: %s\r\n",
|
||||
proxy ? "Proxy-" : "",
|
||||
conn->response_header);
|
||||
DEBUG_OUT(fprintf(stderr, "**** Header %s\n ", *allocuserpwd));
|
||||
Curl_safefree(conn->response_header);
|
||||
free(conn->response_header);
|
||||
conn->response_header = NULL;
|
||||
break;
|
||||
case NTLMSTATE_TYPE2:
|
||||
@ -409,7 +407,7 @@ CURLcode Curl_output_ntlm_wb(struct connectdata *conn,
|
||||
if(res)
|
||||
return res;
|
||||
|
||||
Curl_safefree(*allocuserpwd);
|
||||
free(*allocuserpwd);
|
||||
*allocuserpwd = aprintf("%sAuthorization: %s\r\n",
|
||||
proxy ? "Proxy-" : "",
|
||||
conn->response_header);
|
||||
@ -421,10 +419,8 @@ CURLcode Curl_output_ntlm_wb(struct connectdata *conn,
|
||||
case NTLMSTATE_TYPE3:
|
||||
/* connection is already authenticated,
|
||||
* don't send a header in future requests */
|
||||
if(*allocuserpwd) {
|
||||
free(*allocuserpwd);
|
||||
*allocuserpwd=NULL;
|
||||
}
|
||||
authp->done = TRUE;
|
||||
break;
|
||||
}
|
||||
@ -432,4 +428,4 @@ CURLcode Curl_output_ntlm_wb(struct connectdata *conn,
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
#endif /* USE_NTLM && NTLM_WB_ENABLED */
|
||||
#endif /* !CURL_DISABLE_HTTP && USE_NTLM && NTLM_WB_ENABLED */
|
||||
|
@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -24,7 +24,8 @@
|
||||
|
||||
#include "curl_setup.h"
|
||||
|
||||
#if defined(USE_NTLM) && defined(NTLM_WB_ENABLED)
|
||||
#if !defined(CURL_DISABLE_HTTP) && defined(USE_NTLM) && \
|
||||
defined(NTLM_WB_ENABLED)
|
||||
|
||||
/* this is for creating ntlm header output by delegating challenge/response
|
||||
to Samba's winbind daemon helper ntlm_auth */
|
||||
@ -32,6 +33,6 @@ CURLcode Curl_output_ntlm_wb(struct connectdata *conn, bool proxy);
|
||||
|
||||
void Curl_ntlm_wb_cleanup(struct connectdata *conn);
|
||||
|
||||
#endif /* USE_NTLM && NTLM_WB_ENABLED */
|
||||
#endif /* !CURL_DISABLE_HTTP && USE_NTLM && NTLM_WB_ENABLED */
|
||||
|
||||
#endif /* HEADER_CURL_NTLM_WB_H */
|
||||
|
56
contrib/curl/lib/curl_printf.h
Normal file
56
contrib/curl/lib/curl_printf.h
Normal file
@ -0,0 +1,56 @@
|
||||
#ifndef HEADER_CURL_PRINTF_H
|
||||
#define HEADER_CURL_PRINTF_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* 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 header should be included by ALL code in libcurl that uses any
|
||||
* *rintf() functions.
|
||||
*/
|
||||
|
||||
#include <curl/mprintf.h>
|
||||
|
||||
# undef printf
|
||||
# undef fprintf
|
||||
# undef snprintf
|
||||
# undef vprintf
|
||||
# undef vfprintf
|
||||
# undef vsnprintf
|
||||
# undef aprintf
|
||||
# undef vaprintf
|
||||
# define printf curl_mprintf
|
||||
# define fprintf curl_mfprintf
|
||||
# define snprintf curl_msnprintf
|
||||
# define vprintf curl_mvprintf
|
||||
# define vfprintf curl_mvfprintf
|
||||
# define vsnprintf curl_mvsnprintf
|
||||
# define aprintf curl_maprintf
|
||||
# define vaprintf curl_mvaprintf
|
||||
|
||||
/* We define away the sprintf functions unconditonally since we don't want
|
||||
internal code to be using them, intentionally or by mistake!*/
|
||||
# undef sprintf
|
||||
# undef vsprintf
|
||||
# define sprintf sprintf_was_used
|
||||
# define vsprintf vsprintf_was_used
|
||||
|
||||
#endif /* HEADER_CURL_PRINTF_H */
|
@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2012 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 2012 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 2010, Howard Chu, <hyc@highlandsun.com>
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
@ -32,10 +32,6 @@
|
||||
#include "warnless.h"
|
||||
#include <curl/curl.h>
|
||||
#include <librtmp/rtmp.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"
|
||||
@ -49,7 +45,7 @@
|
||||
|
||||
#define DEF_BUFTIME (2*60*60*1000) /* 2 hours */
|
||||
|
||||
static CURLcode rtmp_setup(struct connectdata *conn);
|
||||
static CURLcode rtmp_setup_connection(struct connectdata *conn);
|
||||
static CURLcode rtmp_do(struct connectdata *conn, bool *done);
|
||||
static CURLcode rtmp_done(struct connectdata *conn, CURLcode, bool premature);
|
||||
static CURLcode rtmp_connect(struct connectdata *conn, bool *done);
|
||||
@ -64,7 +60,7 @@ static Curl_send rtmp_send;
|
||||
|
||||
const struct Curl_handler Curl_handler_rtmp = {
|
||||
"RTMP", /* scheme */
|
||||
rtmp_setup, /* setup_connection */
|
||||
rtmp_setup_connection, /* setup_connection */
|
||||
rtmp_do, /* do_it */
|
||||
rtmp_done, /* done */
|
||||
ZERO_NULL, /* do_more */
|
||||
@ -84,7 +80,7 @@ const struct Curl_handler Curl_handler_rtmp = {
|
||||
|
||||
const struct Curl_handler Curl_handler_rtmpt = {
|
||||
"RTMPT", /* scheme */
|
||||
rtmp_setup, /* setup_connection */
|
||||
rtmp_setup_connection, /* setup_connection */
|
||||
rtmp_do, /* do_it */
|
||||
rtmp_done, /* done */
|
||||
ZERO_NULL, /* do_more */
|
||||
@ -104,7 +100,7 @@ const struct Curl_handler Curl_handler_rtmpt = {
|
||||
|
||||
const struct Curl_handler Curl_handler_rtmpe = {
|
||||
"RTMPE", /* scheme */
|
||||
rtmp_setup, /* setup_connection */
|
||||
rtmp_setup_connection, /* setup_connection */
|
||||
rtmp_do, /* do_it */
|
||||
rtmp_done, /* done */
|
||||
ZERO_NULL, /* do_more */
|
||||
@ -124,7 +120,7 @@ const struct Curl_handler Curl_handler_rtmpe = {
|
||||
|
||||
const struct Curl_handler Curl_handler_rtmpte = {
|
||||
"RTMPTE", /* scheme */
|
||||
rtmp_setup, /* setup_connection */
|
||||
rtmp_setup_connection, /* setup_connection */
|
||||
rtmp_do, /* do_it */
|
||||
rtmp_done, /* done */
|
||||
ZERO_NULL, /* do_more */
|
||||
@ -144,7 +140,7 @@ const struct Curl_handler Curl_handler_rtmpte = {
|
||||
|
||||
const struct Curl_handler Curl_handler_rtmps = {
|
||||
"RTMPS", /* scheme */
|
||||
rtmp_setup, /* setup_connection */
|
||||
rtmp_setup_connection, /* setup_connection */
|
||||
rtmp_do, /* do_it */
|
||||
rtmp_done, /* done */
|
||||
ZERO_NULL, /* do_more */
|
||||
@ -164,7 +160,7 @@ const struct Curl_handler Curl_handler_rtmps = {
|
||||
|
||||
const struct Curl_handler Curl_handler_rtmpts = {
|
||||
"RTMPTS", /* scheme */
|
||||
rtmp_setup, /* setup_connection */
|
||||
rtmp_setup_connection, /* setup_connection */
|
||||
rtmp_do, /* do_it */
|
||||
rtmp_done, /* done */
|
||||
ZERO_NULL, /* do_more */
|
||||
@ -182,10 +178,9 @@ const struct Curl_handler Curl_handler_rtmpts = {
|
||||
PROTOPT_NONE /* flags*/
|
||||
};
|
||||
|
||||
static CURLcode rtmp_setup(struct connectdata *conn)
|
||||
static CURLcode rtmp_setup_connection(struct connectdata *conn)
|
||||
{
|
||||
RTMP *r = RTMP_Alloc();
|
||||
|
||||
if(!r)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
@ -202,7 +197,7 @@ static CURLcode rtmp_setup(struct connectdata *conn)
|
||||
static CURLcode rtmp_connect(struct connectdata *conn, bool *done)
|
||||
{
|
||||
RTMP *r = conn->proto.generic;
|
||||
SET_RCVTIMEO(tv,10);
|
||||
SET_RCVTIMEO(tv, 10);
|
||||
|
||||
r->m_sb.sb_socket = conn->sock[FIRSTSOCKET];
|
||||
|
||||
@ -217,7 +212,7 @@ static CURLcode rtmp_connect(struct connectdata *conn, bool *done)
|
||||
!(r->Link.protocol & RTMP_FEATURE_HTTP))
|
||||
r->Link.lFlags |= RTMP_LF_BUFX;
|
||||
|
||||
curlx_nonblock(r->m_sb.sb_socket, FALSE);
|
||||
(void)curlx_nonblock(r->m_sb.sb_socket, FALSE);
|
||||
setsockopt(r->m_sb.sb_socket, SOL_SOCKET, SO_RCVTIMEO,
|
||||
(char *)&tv, sizeof(tv));
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2012 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 2012 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -26,15 +26,18 @@
|
||||
|
||||
struct SessionHandle;
|
||||
struct connectdata;
|
||||
struct ntlmdata;
|
||||
|
||||
#if defined(USE_WINDOWS_SSPI)
|
||||
struct kerberos5data;
|
||||
#if !defined(CURL_DISABLE_CRYPTO_AUTH)
|
||||
struct digestdata;
|
||||
#endif
|
||||
|
||||
/* Authentication mechanism values */
|
||||
#define SASL_AUTH_NONE 0
|
||||
#define SASL_AUTH_ANY ~0U
|
||||
#if defined(USE_NTLM)
|
||||
struct ntlmdata;
|
||||
#endif
|
||||
|
||||
#if defined(USE_KERBEROS5)
|
||||
struct kerberos5data;
|
||||
#endif
|
||||
|
||||
/* Authentication mechanism flags */
|
||||
#define SASL_MECH_LOGIN (1 << 0)
|
||||
@ -46,6 +49,12 @@ struct kerberos5data;
|
||||
#define SASL_MECH_NTLM (1 << 6)
|
||||
#define SASL_MECH_XOAUTH2 (1 << 7)
|
||||
|
||||
/* Authentication mechanism values */
|
||||
#define SASL_AUTH_NONE 0
|
||||
#define SASL_AUTH_ANY ~0U
|
||||
#define SASL_AUTH_DEFAULT (SASL_AUTH_ANY & \
|
||||
~(SASL_MECH_EXTERNAL | SASL_MECH_XOAUTH2))
|
||||
|
||||
/* Authentication mechanism strings */
|
||||
#define SASL_MECH_STRING_LOGIN "LOGIN"
|
||||
#define SASL_MECH_STRING_PLAIN "PLAIN"
|
||||
@ -56,6 +65,70 @@ struct kerberos5data;
|
||||
#define SASL_MECH_STRING_NTLM "NTLM"
|
||||
#define SASL_MECH_STRING_XOAUTH2 "XOAUTH2"
|
||||
|
||||
#if !defined(CURL_DISABLE_CRYPTO_AUTH)
|
||||
#define DIGEST_MAX_VALUE_LENGTH 256
|
||||
#define DIGEST_MAX_CONTENT_LENGTH 1024
|
||||
#endif
|
||||
|
||||
enum {
|
||||
CURLDIGESTALGO_MD5,
|
||||
CURLDIGESTALGO_MD5SESS
|
||||
};
|
||||
|
||||
/* SASL machine states */
|
||||
typedef enum {
|
||||
SASL_STOP,
|
||||
SASL_PLAIN,
|
||||
SASL_LOGIN,
|
||||
SASL_LOGIN_PASSWD,
|
||||
SASL_EXTERNAL,
|
||||
SASL_CRAMMD5,
|
||||
SASL_DIGESTMD5,
|
||||
SASL_DIGESTMD5_RESP,
|
||||
SASL_NTLM,
|
||||
SASL_NTLM_TYPE2MSG,
|
||||
SASL_GSSAPI,
|
||||
SASL_GSSAPI_TOKEN,
|
||||
SASL_GSSAPI_NO_DATA,
|
||||
SASL_XOAUTH2,
|
||||
SASL_CANCEL,
|
||||
SASL_FINAL
|
||||
} saslstate;
|
||||
|
||||
/* Progress indicator */
|
||||
typedef enum {
|
||||
SASL_IDLE,
|
||||
SASL_INPROGRESS,
|
||||
SASL_DONE
|
||||
} saslprogress;
|
||||
|
||||
/* Protocol dependent SASL parameters */
|
||||
struct SASLproto {
|
||||
const char *service; /* The service name */
|
||||
int contcode; /* Code to receive when continuation is expected */
|
||||
int finalcode; /* Code to receive upon authentication success */
|
||||
size_t maxirlen; /* Maximum initial response length */
|
||||
CURLcode (*sendauth)(struct connectdata *conn,
|
||||
const char *mech, const char *ir);
|
||||
/* Send authentication command */
|
||||
CURLcode (*sendcont)(struct connectdata *conn, const char *contauth);
|
||||
/* Send authentication continuation */
|
||||
void (*getmessage)(char *buffer, char **outptr);
|
||||
/* Get SASL response message */
|
||||
};
|
||||
|
||||
/* Per-connection parameters */
|
||||
struct SASL {
|
||||
const struct SASLproto *params; /* Protocol dependent parameters */
|
||||
saslstate state; /* Current machine state */
|
||||
unsigned int authmechs; /* Accepted authentication mechanisms */
|
||||
unsigned int prefmech; /* Preferred authentication mechanism */
|
||||
unsigned int authused; /* Auth mechanism used for the connection */
|
||||
bool resetprefs; /* For URL auth option parsing. */
|
||||
bool mutual_auth; /* Mutual authentication enabled (GSSAPI only) */
|
||||
bool force_ir; /* Protocol always supports initial response */
|
||||
};
|
||||
|
||||
/* This is used to test whether the line starts with the given mechanism */
|
||||
#define sasl_mech_equal(line, wordlen, mech) \
|
||||
(wordlen == (sizeof(mech) - 1) / sizeof(char) && \
|
||||
@ -68,29 +141,14 @@ char *Curl_sasl_build_spn(const char *service, const char *instance);
|
||||
TCHAR *Curl_sasl_build_spn(const char *service, const char *instance);
|
||||
#endif
|
||||
|
||||
/* This is used to generate a base64 encoded PLAIN authentication message */
|
||||
CURLcode Curl_sasl_create_plain_message(struct SessionHandle *data,
|
||||
const char *userp,
|
||||
const char *passwdp,
|
||||
char **outptr, size_t *outlen);
|
||||
|
||||
/* This is used to generate a base64 encoded LOGIN authentication message
|
||||
containing either the user name or password details */
|
||||
CURLcode Curl_sasl_create_login_message(struct SessionHandle *data,
|
||||
const char *valuep, char **outptr,
|
||||
size_t *outlen);
|
||||
#if defined(HAVE_GSSAPI)
|
||||
char *Curl_sasl_build_gssapi_spn(const char *service, const char *instance);
|
||||
#endif
|
||||
|
||||
#ifndef CURL_DISABLE_CRYPTO_AUTH
|
||||
/* This is used to decode a base64 encoded CRAM-MD5 challange message */
|
||||
CURLcode Curl_sasl_decode_cram_md5_message(const char *chlg64, char **outptr,
|
||||
size_t *outlen);
|
||||
|
||||
/* This is used to generate a base64 encoded CRAM-MD5 response message */
|
||||
CURLcode Curl_sasl_create_cram_md5_message(struct SessionHandle *data,
|
||||
const char *chlg,
|
||||
const char *user,
|
||||
const char *passwdp,
|
||||
char **outptr, size_t *outlen);
|
||||
/* This is used to extract the realm from a challenge message */
|
||||
int Curl_sasl_digest_get_pair(const char *str, char *value, char *content,
|
||||
const char **endptr);
|
||||
|
||||
/* This is used to generate a base64 encoded DIGEST-MD5 response message */
|
||||
CURLcode Curl_sasl_create_digest_md5_message(struct SessionHandle *data,
|
||||
@ -99,6 +157,22 @@ CURLcode Curl_sasl_create_digest_md5_message(struct SessionHandle *data,
|
||||
const char *passwdp,
|
||||
const char *service,
|
||||
char **outptr, size_t *outlen);
|
||||
|
||||
/* This is used to decode a HTTP DIGEST challenge message */
|
||||
CURLcode Curl_sasl_decode_digest_http_message(const char *chlg,
|
||||
struct digestdata *digest);
|
||||
|
||||
/* This is used to generate a HTTP DIGEST response message */
|
||||
CURLcode Curl_sasl_create_digest_http_message(struct SessionHandle *data,
|
||||
const char *userp,
|
||||
const char *passwdp,
|
||||
const unsigned char *request,
|
||||
const unsigned char *uri,
|
||||
struct digestdata *digest,
|
||||
char **outptr, size_t *outlen);
|
||||
|
||||
/* This is used to clean up the digest specific data */
|
||||
void Curl_sasl_digest_cleanup(struct digestdata *digest);
|
||||
#endif
|
||||
|
||||
#ifdef USE_NTLM
|
||||
@ -121,9 +195,12 @@ CURLcode Curl_sasl_create_ntlm_type3_message(struct SessionHandle *data,
|
||||
struct ntlmdata *ntlm,
|
||||
char **outptr, size_t *outlen);
|
||||
|
||||
/* This is used to clean up the ntlm specific data */
|
||||
void Curl_sasl_ntlm_cleanup(struct ntlmdata *ntlm);
|
||||
|
||||
#endif /* USE_NTLM */
|
||||
|
||||
#if defined(USE_WINDOWS_SSPI)
|
||||
#if defined(USE_KERBEROS5)
|
||||
/* This is used to generate a base64 encoded GSSAPI (Kerberos V5) user token
|
||||
message */
|
||||
CURLcode Curl_sasl_create_gssapi_user_message(struct SessionHandle *data,
|
||||
@ -142,17 +219,35 @@ CURLcode Curl_sasl_create_gssapi_security_message(struct SessionHandle *data,
|
||||
struct kerberos5data *krb5,
|
||||
char **outptr,
|
||||
size_t *outlen);
|
||||
#endif
|
||||
|
||||
/* This is used to generate a base64 encoded XOAUTH2 authentication message
|
||||
containing the user name and bearer token */
|
||||
CURLcode Curl_sasl_create_xoauth2_message(struct SessionHandle *data,
|
||||
const char *user,
|
||||
const char *bearer,
|
||||
char **outptr, size_t *outlen);
|
||||
/* This is used to clean up the gssapi specific data */
|
||||
void Curl_sasl_gssapi_cleanup(struct kerberos5data *krb5);
|
||||
#endif /* USE_KERBEROS5 */
|
||||
|
||||
/* This is used to cleanup any libraries or curl modules used by the sasl
|
||||
functions */
|
||||
void Curl_sasl_cleanup(struct connectdata *conn, unsigned int authused);
|
||||
|
||||
/* Convert a mechanism name to a token */
|
||||
unsigned int Curl_sasl_decode_mech(const char *ptr,
|
||||
size_t maxlen, size_t *len);
|
||||
|
||||
/* Parse the URL login options */
|
||||
CURLcode Curl_sasl_parse_url_auth_option(struct SASL *sasl,
|
||||
const char *value, size_t len);
|
||||
|
||||
/* Initializes an SASL structure */
|
||||
void Curl_sasl_init(struct SASL *sasl, const struct SASLproto *params);
|
||||
|
||||
/* Check if we have enough auth data and capabilities to authenticate */
|
||||
bool Curl_sasl_can_authenticate(struct SASL *sasl, struct connectdata *conn);
|
||||
|
||||
/* Calculate the required login details for SASL authentication */
|
||||
CURLcode Curl_sasl_start(struct SASL *sasl, struct connectdata *conn,
|
||||
bool force_ir, saslprogress *progress);
|
||||
|
||||
/* Continue an SASL authentication */
|
||||
CURLcode Curl_sasl_continue(struct SASL *sasl, struct connectdata *conn,
|
||||
int code, saslprogress *progress);
|
||||
|
||||
#endif /* HEADER_CURL_SASL_H */
|
||||
|
392
contrib/curl/lib/curl_sasl_gssapi.c
Normal file
392
contrib/curl/lib/curl_sasl_gssapi.c
Normal file
@ -0,0 +1,392 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2014 - 2015, Steve Holme, <steve_holme@hotmail.com>.
|
||||
* Copyright (C) 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* 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.
|
||||
*
|
||||
* RFC4752 The Kerberos V5 ("GSSAPI") SASL Mechanism
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include "curl_setup.h"
|
||||
|
||||
#if defined(HAVE_GSSAPI) && defined(USE_KERBEROS5)
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
||||
#include "curl_sasl.h"
|
||||
#include "urldata.h"
|
||||
#include "curl_base64.h"
|
||||
#include "curl_gssapi.h"
|
||||
#include "sendf.h"
|
||||
#include "curl_printf.h"
|
||||
|
||||
/* The last #include files should be: */
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
/*
|
||||
* Curl_sasl_build_gssapi_spn()
|
||||
*
|
||||
* This is used to build a SPN string in the format service@instance.
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* service [in] - The service type such as www, smtp, pop or imap.
|
||||
* instance [in] - The host name or realm.
|
||||
*
|
||||
* Returns a pointer to the newly allocated SPN.
|
||||
*/
|
||||
char *Curl_sasl_build_gssapi_spn(const char *service, const char *instance)
|
||||
{
|
||||
/* Generate and return our SPN */
|
||||
return aprintf("%s@%s", service, instance);
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_sasl_create_gssapi_user_message()
|
||||
*
|
||||
* This is used to generate an already encoded GSSAPI (Kerberos V5) user token
|
||||
* message ready for sending to the recipient.
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* data [in] - The session handle.
|
||||
* userp [in] - The user name.
|
||||
* passdwp [in] - The user's password.
|
||||
* service [in] - The service type such as www, smtp, pop or imap.
|
||||
* mutual_auth [in] - Flag specifing whether or not mutual authentication
|
||||
* is enabled.
|
||||
* chlg64 [in] - Pointer to the optional base64 encoded challenge
|
||||
* message.
|
||||
* krb5 [in/out] - The gssapi data struct being used and modified.
|
||||
* outptr [in/out] - The address where a pointer to newly allocated memory
|
||||
* holding the result will be stored upon completion.
|
||||
* outlen [out] - The length of the output message.
|
||||
*
|
||||
* Returns CURLE_OK on success.
|
||||
*/
|
||||
CURLcode Curl_sasl_create_gssapi_user_message(struct SessionHandle *data,
|
||||
const char *userp,
|
||||
const char *passwdp,
|
||||
const char *service,
|
||||
const bool mutual_auth,
|
||||
const char *chlg64,
|
||||
struct kerberos5data *krb5,
|
||||
char **outptr, size_t *outlen)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
size_t chlglen = 0;
|
||||
unsigned char *chlg = NULL;
|
||||
OM_uint32 gss_status;
|
||||
OM_uint32 gss_major_status;
|
||||
OM_uint32 gss_minor_status;
|
||||
gss_buffer_desc spn_token = GSS_C_EMPTY_BUFFER;
|
||||
gss_buffer_desc input_token = GSS_C_EMPTY_BUFFER;
|
||||
gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER;
|
||||
|
||||
(void) userp;
|
||||
(void) passwdp;
|
||||
|
||||
if(krb5->context == GSS_C_NO_CONTEXT) {
|
||||
/* Generate our SPN */
|
||||
char *spn = Curl_sasl_build_gssapi_spn(service,
|
||||
data->easy_conn->host.name);
|
||||
if(!spn)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
/* Populate the SPN structure */
|
||||
spn_token.value = spn;
|
||||
spn_token.length = strlen(spn);
|
||||
|
||||
/* Import the SPN */
|
||||
gss_major_status = gss_import_name(&gss_minor_status, &spn_token,
|
||||
GSS_C_NT_HOSTBASED_SERVICE, &krb5->spn);
|
||||
if(GSS_ERROR(gss_major_status)) {
|
||||
Curl_gss_log_error(data, gss_minor_status, "gss_import_name() failed: ");
|
||||
|
||||
free(spn);
|
||||
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
free(spn);
|
||||
}
|
||||
else {
|
||||
/* Decode the base-64 encoded challenge message */
|
||||
if(strlen(chlg64) && *chlg64 != '=') {
|
||||
result = Curl_base64_decode(chlg64, &chlg, &chlglen);
|
||||
if(result)
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Ensure we have a valid challenge message */
|
||||
if(!chlg) {
|
||||
infof(data, "GSSAPI handshake failure (empty challenge message)\n");
|
||||
|
||||
return CURLE_BAD_CONTENT_ENCODING;
|
||||
}
|
||||
|
||||
/* Setup the challenge "input" security buffer */
|
||||
input_token.value = chlg;
|
||||
input_token.length = chlglen;
|
||||
}
|
||||
|
||||
gss_major_status = Curl_gss_init_sec_context(data,
|
||||
&gss_minor_status,
|
||||
&krb5->context,
|
||||
krb5->spn,
|
||||
&Curl_krb5_mech_oid,
|
||||
GSS_C_NO_CHANNEL_BINDINGS,
|
||||
&input_token,
|
||||
&output_token,
|
||||
mutual_auth,
|
||||
NULL);
|
||||
|
||||
free(input_token.value);
|
||||
|
||||
if(GSS_ERROR(gss_major_status)) {
|
||||
if(output_token.value)
|
||||
gss_release_buffer(&gss_status, &output_token);
|
||||
|
||||
Curl_gss_log_error(data, gss_minor_status,
|
||||
"gss_init_sec_context() failed: ");
|
||||
|
||||
return CURLE_RECV_ERROR;
|
||||
}
|
||||
|
||||
if(output_token.value && output_token.length) {
|
||||
/* Base64 encode the response */
|
||||
result = Curl_base64_encode(data, (char *) output_token.value,
|
||||
output_token.length, outptr, outlen);
|
||||
|
||||
gss_release_buffer(&gss_status, &output_token);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_sasl_create_gssapi_security_message()
|
||||
*
|
||||
* This is used to generate an already encoded GSSAPI (Kerberos V5) security
|
||||
* token message ready for sending to the recipient.
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* data [in] - The session handle.
|
||||
* chlg64 [in] - Pointer to the optional base64 encoded challenge message.
|
||||
* krb5 [in/out] - The gssapi data struct being used and modified.
|
||||
* outptr [in/out] - The address where a pointer to newly allocated memory
|
||||
* holding the result will be stored upon completion.
|
||||
* outlen [out] - The length of the output message.
|
||||
*
|
||||
* Returns CURLE_OK on success.
|
||||
*/
|
||||
CURLcode Curl_sasl_create_gssapi_security_message(struct SessionHandle *data,
|
||||
const char *chlg64,
|
||||
struct kerberos5data *krb5,
|
||||
char **outptr,
|
||||
size_t *outlen)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
size_t chlglen = 0;
|
||||
size_t messagelen = 0;
|
||||
unsigned char *chlg = NULL;
|
||||
unsigned char *message = NULL;
|
||||
OM_uint32 gss_status;
|
||||
OM_uint32 gss_major_status;
|
||||
OM_uint32 gss_minor_status;
|
||||
gss_buffer_desc input_token = GSS_C_EMPTY_BUFFER;
|
||||
gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER;
|
||||
unsigned int indata = 0;
|
||||
unsigned int outdata = 0;
|
||||
gss_qop_t qop = GSS_C_QOP_DEFAULT;
|
||||
unsigned int sec_layer = 0;
|
||||
unsigned int max_size = 0;
|
||||
gss_name_t username = GSS_C_NO_NAME;
|
||||
gss_buffer_desc username_token;
|
||||
|
||||
/* Decode the base-64 encoded input message */
|
||||
if(strlen(chlg64) && *chlg64 != '=') {
|
||||
result = Curl_base64_decode(chlg64, &chlg, &chlglen);
|
||||
if(result)
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Ensure we have a valid challenge message */
|
||||
if(!chlg) {
|
||||
infof(data, "GSSAPI handshake failure (empty security message)\n");
|
||||
|
||||
return CURLE_BAD_CONTENT_ENCODING;
|
||||
}
|
||||
|
||||
/* Get the fully qualified username back from the context */
|
||||
gss_major_status = gss_inquire_context(&gss_minor_status, krb5->context,
|
||||
&username, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL);
|
||||
if(GSS_ERROR(gss_major_status)) {
|
||||
Curl_gss_log_error(data, gss_minor_status,
|
||||
"gss_inquire_context() failed: ");
|
||||
|
||||
free(chlg);
|
||||
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
/* Convert the username from internal format to a displayable token */
|
||||
gss_major_status = gss_display_name(&gss_minor_status, username,
|
||||
&username_token, NULL);
|
||||
if(GSS_ERROR(gss_major_status)) {
|
||||
Curl_gss_log_error(data, gss_minor_status, "gss_display_name() failed: ");
|
||||
|
||||
free(chlg);
|
||||
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
/* Setup the challenge "input" security buffer */
|
||||
input_token.value = chlg;
|
||||
input_token.length = chlglen;
|
||||
|
||||
/* Decrypt the inbound challenge and obtain the qop */
|
||||
gss_major_status = gss_unwrap(&gss_minor_status, krb5->context, &input_token,
|
||||
&output_token, NULL, &qop);
|
||||
if(GSS_ERROR(gss_major_status)) {
|
||||
Curl_gss_log_error(data, gss_minor_status, "gss_unwrap() failed: ");
|
||||
|
||||
gss_release_buffer(&gss_status, &username_token);
|
||||
free(chlg);
|
||||
|
||||
return CURLE_BAD_CONTENT_ENCODING;
|
||||
}
|
||||
|
||||
/* Not 4 octets long so fail as per RFC4752 Section 3.1 */
|
||||
if(output_token.length != 4) {
|
||||
infof(data, "GSSAPI handshake failure (invalid security data)\n");
|
||||
|
||||
gss_release_buffer(&gss_status, &username_token);
|
||||
free(chlg);
|
||||
|
||||
return CURLE_BAD_CONTENT_ENCODING;
|
||||
}
|
||||
|
||||
/* Copy the data out and free the challenge as it is not required anymore */
|
||||
memcpy(&indata, output_token.value, 4);
|
||||
gss_release_buffer(&gss_status, &output_token);
|
||||
free(chlg);
|
||||
|
||||
/* Extract the security layer */
|
||||
sec_layer = indata & 0x000000FF;
|
||||
if(!(sec_layer & GSSAUTH_P_NONE)) {
|
||||
infof(data, "GSSAPI handshake failure (invalid security layer)\n");
|
||||
|
||||
gss_release_buffer(&gss_status, &username_token);
|
||||
|
||||
return CURLE_BAD_CONTENT_ENCODING;
|
||||
}
|
||||
|
||||
/* Extract the maximum message size the server can receive */
|
||||
max_size = ntohl(indata & 0xFFFFFF00);
|
||||
if(max_size > 0) {
|
||||
/* The server has told us it supports a maximum receive buffer, however, as
|
||||
we don't require one unless we are encrypting data, we tell the server
|
||||
our receive buffer is zero. */
|
||||
max_size = 0;
|
||||
}
|
||||
|
||||
/* Allocate our message */
|
||||
messagelen = sizeof(outdata) + username_token.length + 1;
|
||||
message = malloc(messagelen);
|
||||
if(!message) {
|
||||
gss_release_buffer(&gss_status, &username_token);
|
||||
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
/* Populate the message with the security layer, client supported receive
|
||||
message size and authorization identity including the 0x00 based
|
||||
terminator. Note: Dispite RFC4752 Section 3.1 stating "The authorization
|
||||
identity is not terminated with the zero-valued (%x00) octet." it seems
|
||||
necessary to include it. */
|
||||
outdata = htonl(max_size) | sec_layer;
|
||||
memcpy(message, &outdata, sizeof(outdata));
|
||||
memcpy(message + sizeof(outdata), username_token.value,
|
||||
username_token.length);
|
||||
message[messagelen - 1] = '\0';
|
||||
|
||||
/* Free the username token as it is not required anymore */
|
||||
gss_release_buffer(&gss_status, &username_token);
|
||||
|
||||
/* Setup the "authentication data" security buffer */
|
||||
input_token.value = message;
|
||||
input_token.length = messagelen;
|
||||
|
||||
/* Encrypt the data */
|
||||
gss_major_status = gss_wrap(&gss_minor_status, krb5->context, 0,
|
||||
GSS_C_QOP_DEFAULT, &input_token, NULL,
|
||||
&output_token);
|
||||
if(GSS_ERROR(gss_major_status)) {
|
||||
Curl_gss_log_error(data, gss_minor_status, "gss_wrap() failed: ");
|
||||
|
||||
free(message);
|
||||
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
/* Base64 encode the response */
|
||||
result = Curl_base64_encode(data, (char *) output_token.value,
|
||||
output_token.length, outptr, outlen);
|
||||
|
||||
/* Free the output buffer */
|
||||
gss_release_buffer(&gss_status, &output_token);
|
||||
|
||||
/* Free the message buffer */
|
||||
free(message);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_sasl_gssapi_cleanup()
|
||||
*
|
||||
* This is used to clean up the gssapi specific data.
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* krb5 [in/out] - The kerberos 5 data struct being cleaned up.
|
||||
*
|
||||
*/
|
||||
void Curl_sasl_gssapi_cleanup(struct kerberos5data *krb5)
|
||||
{
|
||||
OM_uint32 minor_status;
|
||||
|
||||
/* Free our security context */
|
||||
if(krb5->context != GSS_C_NO_CONTEXT) {
|
||||
gss_delete_sec_context(&minor_status, &krb5->context, GSS_C_NO_BUFFER);
|
||||
krb5->context = GSS_C_NO_CONTEXT;
|
||||
}
|
||||
|
||||
/* Free the SPN */
|
||||
if(krb5->spn != GSS_C_NO_NAME) {
|
||||
gss_release_name(&minor_status, &krb5->spn);
|
||||
krb5->spn = GSS_C_NO_NAME;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* HAVE_GSSAPI && USE_KERBEROS5 */
|
File diff suppressed because it is too large
Load Diff
@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -30,7 +30,7 @@ struct Curl_sec_client_mech {
|
||||
void (*end)(void *);
|
||||
int (*check_prot)(void *, int);
|
||||
int (*overhead)(void *, int, int);
|
||||
int (*encode)(void *, const void*, int, int, void**, struct connectdata *);
|
||||
int (*encode)(void *, const void*, int, int, void**);
|
||||
int (*decode)(void *, void*, int, int, struct connectdata *);
|
||||
};
|
||||
|
||||
|
@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -78,6 +78,14 @@
|
||||
# include "config-vxworks.h"
|
||||
#endif
|
||||
|
||||
#ifdef __linux__
|
||||
# include "config-linux.h"
|
||||
#endif
|
||||
|
||||
#ifdef __APPLE__ && __MACH__
|
||||
# include "config-osx.h"
|
||||
#endif
|
||||
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
/* ================================================================ */
|
||||
@ -190,6 +198,9 @@
|
||||
# ifndef CURL_DISABLE_GOPHER
|
||||
# define CURL_DISABLE_GOPHER
|
||||
# endif
|
||||
# ifndef CURL_DISABLE_SMB
|
||||
# define CURL_DISABLE_SMB
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
@ -601,26 +612,38 @@ 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) || defined(USE_AXTLS) || \
|
||||
#if defined(USE_GNUTLS) || defined(USE_OPENSSL) || defined(USE_NSS) || \
|
||||
defined(USE_POLARSSL) || defined(USE_AXTLS) || \
|
||||
defined(USE_CYASSL) || defined(USE_SCHANNEL) || \
|
||||
defined(USE_DARWINSSL) || defined(USE_GSKIT)
|
||||
//#define USE_SSL /* SSL support has been enabled */
|
||||
#define USE_SSL /* SSL support has been enabled */
|
||||
#endif
|
||||
|
||||
/* Single point where USE_SPNEGO definition might be defined */
|
||||
#if !defined(CURL_DISABLE_CRYPTO_AUTH) && \
|
||||
(defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI))
|
||||
#define USE_SPNEGO
|
||||
#endif
|
||||
|
||||
/* Single point where USE_NTLM definition might be done */
|
||||
#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_NTLM) && \
|
||||
!defined(CURL_DISABLE_CRYPTO_AUTH)
|
||||
#if defined(USE_SSLEAY) || defined(USE_WINDOWS_SSPI) || \
|
||||
defined(USE_GNUTLS) || defined(USE_NSS) || defined(USE_DARWINSSL)
|
||||
/* Single point where USE_KERBEROS5 definition might be defined */
|
||||
#if !defined(CURL_DISABLE_CRYPTO_AUTH) && \
|
||||
(defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI))
|
||||
#define USE_KERBEROS5
|
||||
#endif
|
||||
|
||||
/* Single point where USE_NTLM definition might be defined */
|
||||
#if !defined(CURL_DISABLE_NTLM) && !defined(CURL_DISABLE_CRYPTO_AUTH)
|
||||
#if defined(USE_OPENSSL) || defined(USE_WINDOWS_SSPI) || \
|
||||
defined(USE_GNUTLS) || defined(USE_NSS) || defined(USE_DARWINSSL) || \
|
||||
defined(USE_OS400CRYPTO) || defined(USE_WIN32_CRYPTO)
|
||||
|
||||
#ifdef HAVE_BORINGSSL /* BoringSSL is not NTLM capable */
|
||||
#undef USE_NTLM
|
||||
#else
|
||||
#define USE_NTLM
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* non-configure builds may define CURL_WANTS_CA_BUNDLE_ENV */
|
||||
#if defined(CURL_WANTS_CA_BUNDLE_ENV) && !defined(CURL_CA_BUNDLE)
|
||||
@ -636,8 +659,10 @@ int netware_init(void);
|
||||
#if defined(__GNUC__) && ((__GNUC__ >= 3) || \
|
||||
((__GNUC__ == 2) && defined(__GNUC_MINOR__) && (__GNUC_MINOR__ >= 7)))
|
||||
# define UNUSED_PARAM __attribute__((__unused__))
|
||||
# define WARN_UNUSED_RESULT __attribute__((warn_unused_result))
|
||||
#else
|
||||
# define UNUSED_PARAM /*NOTHING*/
|
||||
# define WARN_UNUSED_RESULT
|
||||
#endif
|
||||
|
||||
/*
|
||||
@ -690,4 +715,24 @@ int netware_init(void);
|
||||
#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
|
||||
#endif
|
||||
|
||||
/* In Windows the default file mode is text but an application can override it.
|
||||
Therefore we specify it explicitly. https://github.com/bagder/curl/pull/258
|
||||
*/
|
||||
#if defined(WIN32) || defined(MSDOS)
|
||||
#define FOPEN_READTEXT "rt"
|
||||
#define FOPEN_WRITETEXT "wt"
|
||||
#elif defined(__CYGWIN__)
|
||||
/* Cygwin has specific behavior we need to address when WIN32 is not defined.
|
||||
https://cygwin.com/cygwin-ug-net/using-textbinary.html
|
||||
For write we want our output to have line endings of LF and be compatible with
|
||||
other Cygwin utilities. For read we want to handle input that may have line
|
||||
endings either CRLF or LF so 't' is appropriate.
|
||||
*/
|
||||
#define FOPEN_READTEXT "rt"
|
||||
#define FOPEN_WRITETEXT "w"
|
||||
#else
|
||||
#define FOPEN_READTEXT "r"
|
||||
#define FOPEN_WRITETEXT "w"
|
||||
#endif
|
||||
|
||||
#endif /* HEADER_CURL_SETUP_H */
|
||||
|
@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -25,17 +25,12 @@
|
||||
#ifdef USE_WINDOWS_SSPI
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
||||
#include "curl_sspi.h"
|
||||
|
||||
#define _MPRINTF_REPLACE /* use our functions only */
|
||||
#include <curl/mprintf.h>
|
||||
|
||||
#include "curl_memory.h"
|
||||
#include "curl_multibyte.h"
|
||||
#include "warnless.h"
|
||||
|
||||
/* The last #include file should be: */
|
||||
/* The last #include files should be: */
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
/* We use our own typedef here since some headers might lack these */
|
||||
@ -98,20 +93,25 @@ CURLcode Curl_sspi_global_init(void)
|
||||
osver.dwPlatformId == platformId)
|
||||
securityDll = TRUE;
|
||||
#else
|
||||
ULONGLONG majorVersionMask;
|
||||
ULONGLONG platformIdMask;
|
||||
ULONGLONG cm;
|
||||
OSVERSIONINFOEX osver;
|
||||
|
||||
memset(&osver, 0, sizeof(osver));
|
||||
osver.dwOSVersionInfoSize = sizeof(osver);
|
||||
osver.dwMajorVersion = majorVersion;
|
||||
osver.dwPlatformId = platformId;
|
||||
majorVersionMask = VerSetConditionMask(0, VER_MAJORVERSION, VER_EQUAL);
|
||||
platformIdMask = VerSetConditionMask(0, VER_PLATFORMID, VER_EQUAL);
|
||||
|
||||
cm = VerSetConditionMask(0, VER_MAJORVERSION, VER_EQUAL);
|
||||
cm = VerSetConditionMask(cm, VER_MINORVERSION, VER_GREATER_EQUAL);
|
||||
cm = VerSetConditionMask(cm, VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL);
|
||||
cm = VerSetConditionMask(cm, VER_SERVICEPACKMINOR, VER_GREATER_EQUAL);
|
||||
cm = VerSetConditionMask(cm, VER_PLATFORMID, VER_EQUAL);
|
||||
|
||||
/* Verify the major version number == 4 and platform id == WIN_NT */
|
||||
if(VerifyVersionInfo(&osver, VER_MAJORVERSION, majorVersionMask) &&
|
||||
VerifyVersionInfo(&osver, VER_PLATFORMID, platformIdMask))
|
||||
if(VerifyVersionInfo(&osver, (VER_MAJORVERSION | VER_MINORVERSION |
|
||||
VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR |
|
||||
VER_PLATFORMID),
|
||||
cm))
|
||||
securityDll = TRUE;
|
||||
#endif
|
||||
|
||||
@ -224,7 +224,7 @@ CURLcode Curl_create_sspi_identity(const char *userp, const char *passwdp,
|
||||
|
||||
Curl_unicodefree(useranddomain.tchar_ptr);
|
||||
|
||||
/* Setup ntlm identity's password and length */
|
||||
/* Setup the identity's password and length */
|
||||
passwd.tchar_ptr = Curl_convert_UTF8_to_tchar((char *)passwdp);
|
||||
if(!passwd.tchar_ptr)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
@ -43,6 +43,10 @@
|
||||
CURLcode Curl_sspi_global_init(void);
|
||||
void Curl_sspi_global_cleanup(void);
|
||||
|
||||
/* This is used to populate the domain in a SSPI identity structure */
|
||||
CURLcode Curl_override_sspi_http_realm(const char *chlg,
|
||||
SEC_WINNT_AUTH_IDENTITY *identity);
|
||||
|
||||
/* This is used to generate an SSPI identity structure */
|
||||
CURLcode Curl_create_sspi_identity(const char *userp, const char *passwdp,
|
||||
SEC_WINNT_AUTH_IDENTITY *identity);
|
||||
@ -51,11 +55,38 @@ CURLcode Curl_create_sspi_identity(const char *userp, const char *passwdp,
|
||||
void Curl_sspi_free_identity(SEC_WINNT_AUTH_IDENTITY *identity);
|
||||
|
||||
/* Forward-declaration of global variables defined in curl_sspi.c */
|
||||
|
||||
extern HMODULE s_hSecDll;
|
||||
extern PSecurityFunctionTable s_pSecFn;
|
||||
|
||||
/* Provide some definitions missing in old headers */
|
||||
#define SP_NAME_DIGEST "WDigest"
|
||||
#define SP_NAME_NTLM "NTLM"
|
||||
#define SP_NAME_NEGOTIATE "Negotiate"
|
||||
#define SP_NAME_KERBEROS "Kerberos"
|
||||
|
||||
#ifndef ISC_REQ_USE_HTTP_STYLE
|
||||
#define ISC_REQ_USE_HTTP_STYLE 0x01000000
|
||||
#endif
|
||||
|
||||
#ifndef ISC_RET_REPLAY_DETECT
|
||||
#define ISC_RET_REPLAY_DETECT 0x00000004
|
||||
#endif
|
||||
|
||||
#ifndef ISC_RET_SEQUENCE_DETECT
|
||||
#define ISC_RET_SEQUENCE_DETECT 0x00000008
|
||||
#endif
|
||||
|
||||
#ifndef ISC_RET_CONFIDENTIALITY
|
||||
#define ISC_RET_CONFIDENTIALITY 0x00000010
|
||||
#endif
|
||||
|
||||
#ifndef ISC_RET_ALLOCATED_MEMORY
|
||||
#define ISC_RET_ALLOCATED_MEMORY 0x00000100
|
||||
#endif
|
||||
|
||||
#ifndef ISC_RET_STREAM
|
||||
#define ISC_RET_STREAM 0x00008000
|
||||
#endif
|
||||
|
||||
#ifndef SEC_E_INSUFFICIENT_MEMORY
|
||||
# define SEC_E_INSUFFICIENT_MEMORY ((HRESULT)0x80090300L)
|
||||
@ -296,6 +327,10 @@ extern PSecurityFunctionTable s_pSecFn;
|
||||
# define SEC_I_SIGNATURE_NEEDED ((HRESULT)0x0009035CL)
|
||||
#endif
|
||||
|
||||
#ifndef CRYPT_E_REVOKED
|
||||
# define CRYPT_E_REVOKED ((HRESULT)0x80092010L)
|
||||
#endif
|
||||
|
||||
#ifdef UNICODE
|
||||
# define SECFLAG_WINNT_AUTH_IDENTITY \
|
||||
(unsigned long)SEC_WINNT_AUTH_IDENTITY_UNICODE
|
||||
|
@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -33,10 +33,6 @@
|
||||
#endif
|
||||
|
||||
#include "curl_threads.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"
|
||||
@ -77,8 +73,8 @@ curl_thread_t Curl_thread_create(unsigned int (*func) (void*), void *arg)
|
||||
return t;
|
||||
|
||||
err:
|
||||
Curl_safefree(t);
|
||||
Curl_safefree(ac);
|
||||
free(t);
|
||||
free(ac);
|
||||
return curl_thread_t_null;
|
||||
}
|
||||
|
||||
@ -123,7 +119,12 @@ void Curl_thread_destroy(curl_thread_t hnd)
|
||||
|
||||
int Curl_thread_join(curl_thread_t *hnd)
|
||||
{
|
||||
#if !defined(_WIN32_WINNT) || !defined(_WIN32_WINNT_VISTA) || \
|
||||
(_WIN32_WINNT < _WIN32_WINNT_VISTA)
|
||||
int ret = (WaitForSingleObject(*hnd, INFINITE) == WAIT_OBJECT_0);
|
||||
#else
|
||||
int ret = (WaitForSingleObjectEx(*hnd, INFINITE, FALSE) == WAIT_OBJECT_0);
|
||||
#endif
|
||||
|
||||
Curl_thread_destroy(*hnd);
|
||||
|
||||
|
@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -37,7 +37,12 @@
|
||||
# define curl_mutex_t CRITICAL_SECTION
|
||||
# define curl_thread_t HANDLE
|
||||
# define curl_thread_t_null (HANDLE)0
|
||||
# if !defined(_WIN32_WINNT) || !defined(_WIN32_WINNT_VISTA) || \
|
||||
(_WIN32_WINNT < _WIN32_WINNT_VISTA)
|
||||
# define Curl_mutex_init(m) InitializeCriticalSection(m)
|
||||
# else
|
||||
# define Curl_mutex_init(m) InitializeCriticalSectionEx(m, 0, 1)
|
||||
# endif
|
||||
# define Curl_mutex_acquire(m) EnterCriticalSection(m)
|
||||
# define Curl_mutex_release(m) LeaveCriticalSection(m)
|
||||
# define Curl_mutex_destroy(m) DeleteCriticalSection(m)
|
||||
|
@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2008, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -90,8 +90,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 transparent and
|
||||
easier to understand/patch. Undefine them first in case _MPRINTF_REPLACE
|
||||
is set. */
|
||||
easier to understand/patch. Undefine them first. */
|
||||
# undef printf
|
||||
# undef fprintf
|
||||
# undef sprintf
|
||||
|
@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -57,10 +57,6 @@
|
||||
#include "strequal.h"
|
||||
#include "dict.h"
|
||||
#include "rawstr.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"
|
||||
@ -101,7 +97,7 @@ static char *unescape_word(struct SessionHandle *data, const char *inputbuff)
|
||||
char *dictp;
|
||||
char *ptr;
|
||||
int len;
|
||||
char byte;
|
||||
char ch;
|
||||
int olen=0;
|
||||
|
||||
newp = curl_easy_unescape(data, inputbuff, 0, &len);
|
||||
@ -113,13 +109,13 @@ static char *unescape_word(struct SessionHandle *data, const char *inputbuff)
|
||||
/* According to RFC2229 section 2.2, these letters need to be escaped with
|
||||
\[letter] */
|
||||
for(ptr = newp;
|
||||
(byte = *ptr) != 0;
|
||||
(ch = *ptr) != 0;
|
||||
ptr++) {
|
||||
if((byte <= 32) || (byte == 127) ||
|
||||
(byte == '\'') || (byte == '\"') || (byte == '\\')) {
|
||||
if((ch <= 32) || (ch == 127) ||
|
||||
(ch == '\'') || (ch == '\"') || (ch == '\\')) {
|
||||
dictp[olen++] = '\\';
|
||||
}
|
||||
dictp[olen++] = byte;
|
||||
dictp[olen++] = ch;
|
||||
}
|
||||
dictp[olen]=0;
|
||||
}
|
||||
|
@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -60,7 +60,6 @@
|
||||
#include "hostip.h"
|
||||
#include "share.h"
|
||||
#include "strdup.h"
|
||||
#include "curl_memory.h"
|
||||
#include "progress.h"
|
||||
#include "easyif.h"
|
||||
#include "select.h"
|
||||
@ -74,11 +73,11 @@
|
||||
#include "conncache.h"
|
||||
#include "multiif.h"
|
||||
#include "sigpipe.h"
|
||||
#include "ssh.h"
|
||||
#include "curl_printf.h"
|
||||
|
||||
#define _MPRINTF_REPLACE /* use our functions only */
|
||||
#include <curl/mprintf.h>
|
||||
|
||||
/* The last #include file should be: */
|
||||
/* The last #include files should be: */
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
/* win32_cleanup() is for win32 socket cleanup functionality, the opposite
|
||||
@ -136,9 +135,9 @@ static CURLcode win32_init(void)
|
||||
|
||||
#ifdef USE_WINDOWS_SSPI
|
||||
{
|
||||
CURLcode err = Curl_sspi_global_init();
|
||||
if(err != CURLE_OK)
|
||||
return err;
|
||||
CURLcode result = Curl_sspi_global_init();
|
||||
if(result)
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -243,7 +242,7 @@ CURLcode curl_global_init(long flags)
|
||||
}
|
||||
|
||||
if(flags & CURL_GLOBAL_WIN32)
|
||||
if(win32_init() != CURLE_OK) {
|
||||
if(win32_init()) {
|
||||
DEBUGF(fprintf(stderr, "Error: win32_init failed\n"));
|
||||
return CURLE_FAILED_INIT;
|
||||
}
|
||||
@ -265,7 +264,7 @@ CURLcode curl_global_init(long flags)
|
||||
idna_init();
|
||||
#endif
|
||||
|
||||
if(Curl_resolver_global_init() != CURLE_OK) {
|
||||
if(Curl_resolver_global_init()) {
|
||||
DEBUGF(fprintf(stderr, "Error: resolver_global_init failed\n"));
|
||||
return CURLE_FAILED_INIT;
|
||||
}
|
||||
@ -293,7 +292,7 @@ CURLcode curl_global_init_mem(long flags, curl_malloc_callback m,
|
||||
curl_free_callback f, curl_realloc_callback r,
|
||||
curl_strdup_callback s, curl_calloc_callback c)
|
||||
{
|
||||
CURLcode code = CURLE_OK;
|
||||
CURLcode result = CURLE_OK;
|
||||
|
||||
/* Invalid input, return immediately */
|
||||
if(!m || !f || !r || !s || !c)
|
||||
@ -308,8 +307,8 @@ CURLcode curl_global_init_mem(long flags, curl_malloc_callback m,
|
||||
}
|
||||
|
||||
/* Call the actual init function first */
|
||||
code = curl_global_init(flags);
|
||||
if(code == CURLE_OK) {
|
||||
result = curl_global_init(flags);
|
||||
if(!result) {
|
||||
Curl_cmalloc = m;
|
||||
Curl_cfree = f;
|
||||
Curl_cstrdup = s;
|
||||
@ -317,7 +316,7 @@ CURLcode curl_global_init_mem(long flags, curl_malloc_callback m,
|
||||
Curl_ccalloc = c;
|
||||
}
|
||||
|
||||
return code;
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -357,13 +356,13 @@ void curl_global_cleanup(void)
|
||||
*/
|
||||
CURL *curl_easy_init(void)
|
||||
{
|
||||
CURLcode res;
|
||||
CURLcode result;
|
||||
struct SessionHandle *data;
|
||||
|
||||
/* Make sure we inited the global SSL stuff */
|
||||
if(!initialized) {
|
||||
res = curl_global_init(CURL_GLOBAL_DEFAULT);
|
||||
if(res) {
|
||||
result = curl_global_init(CURL_GLOBAL_DEFAULT);
|
||||
if(result) {
|
||||
/* something in the global init failed, return nothing */
|
||||
DEBUGF(fprintf(stderr, "Error: curl_global_init failed\n"));
|
||||
return NULL;
|
||||
@ -371,8 +370,8 @@ CURL *curl_easy_init(void)
|
||||
}
|
||||
|
||||
/* We use curl_open() with undefined URL so far */
|
||||
res = Curl_open(&data);
|
||||
if(res != CURLE_OK) {
|
||||
result = Curl_open(&data);
|
||||
if(result) {
|
||||
DEBUGF(fprintf(stderr, "Error: Curl_open failed\n"));
|
||||
return NULL;
|
||||
}
|
||||
@ -390,17 +389,17 @@ CURLcode curl_easy_setopt(CURL *curl, CURLoption tag, ...)
|
||||
{
|
||||
va_list arg;
|
||||
struct SessionHandle *data = curl;
|
||||
CURLcode ret;
|
||||
CURLcode result;
|
||||
|
||||
if(!curl)
|
||||
return CURLE_BAD_FUNCTION_ARGUMENT;
|
||||
|
||||
va_start(arg, tag);
|
||||
|
||||
ret = Curl_setopt(data, tag, arg);
|
||||
result = Curl_setopt(data, tag, arg);
|
||||
|
||||
va_end(arg);
|
||||
return ret;
|
||||
return result;
|
||||
}
|
||||
|
||||
#ifdef CURLDEBUG
|
||||
@ -490,6 +489,10 @@ static int events_socket(CURL *easy, /* easy handle */
|
||||
struct events *ev = userp;
|
||||
struct socketmonitor *m;
|
||||
struct socketmonitor *prev=NULL;
|
||||
|
||||
#if defined(CURL_DISABLE_VERBOSE_STRINGS)
|
||||
(void) easy;
|
||||
#endif
|
||||
(void)socketp;
|
||||
|
||||
m = ev->list;
|
||||
@ -570,7 +573,7 @@ static CURLcode wait_or_timeout(struct Curl_multi *multi, struct events *ev)
|
||||
{
|
||||
bool done = FALSE;
|
||||
CURLMcode mcode;
|
||||
CURLcode rc = CURLE_OK;
|
||||
CURLcode result = CURLE_OK;
|
||||
|
||||
while(!done) {
|
||||
CURLMsg *msg;
|
||||
@ -630,6 +633,9 @@ static CURLcode wait_or_timeout(struct Curl_multi *multi, struct events *ev)
|
||||
ev->ms += curlx_tvdiff(after, before);
|
||||
|
||||
}
|
||||
else
|
||||
return CURLE_RECV_ERROR;
|
||||
|
||||
if(mcode)
|
||||
return CURLE_URL_MALFORMAT; /* TODO: return a proper error! */
|
||||
|
||||
@ -637,12 +643,12 @@ static CURLcode wait_or_timeout(struct Curl_multi *multi, struct events *ev)
|
||||
second argument */
|
||||
msg = curl_multi_info_read(multi, &pollrc);
|
||||
if(msg) {
|
||||
rc = msg->data.result;
|
||||
result = msg->data.result;
|
||||
done = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return rc;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@ -668,7 +674,7 @@ static CURLcode easy_transfer(CURLM *multi)
|
||||
{
|
||||
bool done = FALSE;
|
||||
CURLMcode mcode = CURLM_OK;
|
||||
CURLcode code = CURLE_OK;
|
||||
CURLcode result = CURLE_OK;
|
||||
struct timeval before;
|
||||
int without_fds = 0; /* count number of consecutive returns from
|
||||
curl_multi_wait() without any filedescriptors */
|
||||
@ -683,7 +689,7 @@ static CURLcode easy_transfer(CURLM *multi)
|
||||
if(mcode == CURLM_OK) {
|
||||
if(ret == -1) {
|
||||
/* poll() failed not on EINTR, indicate a network problem */
|
||||
code = CURLE_RECV_ERROR;
|
||||
result = CURLE_RECV_ERROR;
|
||||
break;
|
||||
}
|
||||
else if(ret == 0) {
|
||||
@ -714,7 +720,7 @@ static CURLcode easy_transfer(CURLM *multi)
|
||||
int rc;
|
||||
CURLMsg *msg = curl_multi_info_read(multi, &rc);
|
||||
if(msg) {
|
||||
code = msg->data.result;
|
||||
result = msg->data.result;
|
||||
done = TRUE;
|
||||
}
|
||||
}
|
||||
@ -728,7 +734,7 @@ static CURLcode easy_transfer(CURLM *multi)
|
||||
CURLE_BAD_FUNCTION_ARGUMENT;
|
||||
}
|
||||
|
||||
return code;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@ -753,7 +759,7 @@ static CURLcode easy_perform(struct SessionHandle *data, bool events)
|
||||
{
|
||||
CURLM *multi;
|
||||
CURLMcode mcode;
|
||||
CURLcode code = CURLE_OK;
|
||||
CURLcode result = CURLE_OK;
|
||||
SIGPIPE_VARIABLE(pipe_st);
|
||||
|
||||
if(!data)
|
||||
@ -794,7 +800,7 @@ static CURLcode easy_perform(struct SessionHandle *data, bool events)
|
||||
data->multi = multi;
|
||||
|
||||
/* run the transfer */
|
||||
code = events ? easy_events(multi) : easy_transfer(multi);
|
||||
result = events ? easy_events(multi) : easy_transfer(multi);
|
||||
|
||||
/* ignoring the return code isn't nice, but atm we can't really handle
|
||||
a failure here, room for future improvement! */
|
||||
@ -803,7 +809,7 @@ static CURLcode easy_perform(struct SessionHandle *data, bool events)
|
||||
sigpipe_restore(&pipe_st);
|
||||
|
||||
/* The multi handle is kept alive, owned by the easy handle */
|
||||
return code;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@ -854,16 +860,16 @@ CURLcode curl_easy_getinfo(CURL *curl, CURLINFO info, ...)
|
||||
{
|
||||
va_list arg;
|
||||
void *paramp;
|
||||
CURLcode ret;
|
||||
CURLcode result;
|
||||
struct SessionHandle *data = (struct SessionHandle *)curl;
|
||||
|
||||
va_start(arg, info);
|
||||
paramp = va_arg(arg, void *);
|
||||
|
||||
ret = Curl_getinfo(data, info, paramp);
|
||||
result = Curl_getinfo(data, info, paramp);
|
||||
|
||||
va_end(arg);
|
||||
return ret;
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -890,7 +896,7 @@ CURL *curl_easy_duphandle(CURL *incurl)
|
||||
outcurl->state.headersize = HEADERSIZE;
|
||||
|
||||
/* copy all userdefined values */
|
||||
if(Curl_dupset(outcurl, data) != CURLE_OK)
|
||||
if(Curl_dupset(outcurl, data))
|
||||
goto fail;
|
||||
|
||||
/* the connection cache is setup on demand */
|
||||
@ -936,7 +942,7 @@ CURL *curl_easy_duphandle(CURL *incurl)
|
||||
|
||||
/* Clone the resolver handle, if present, for the new handle */
|
||||
if(Curl_resolver_duphandle(&outcurl->state.resolver,
|
||||
data->state.resolver) != CURLE_OK)
|
||||
data->state.resolver))
|
||||
goto fail;
|
||||
|
||||
Curl_convert_setup(outcurl);
|
||||
@ -1018,73 +1024,15 @@ CURLcode curl_easy_pause(CURL *curl, int action)
|
||||
/* we have a buffer for sending that we now seem to be able to deliver
|
||||
since the receive pausing is lifted! */
|
||||
|
||||
/* get the pointer, type and length in local copies since the function may
|
||||
return PAUSE again and then we'll get a new copy allocted and stored in
|
||||
/* get the pointer in local copy since the function may return PAUSE
|
||||
again and then we'll get a new copy allocted and stored in
|
||||
the tempwrite variables */
|
||||
char *tempwrite = data->state.tempwrite;
|
||||
char *freewrite = tempwrite; /* store this pointer to free it later */
|
||||
size_t tempsize = data->state.tempwritesize;
|
||||
int temptype = data->state.tempwritetype;
|
||||
size_t chunklen;
|
||||
|
||||
/* clear tempwrite here just to make sure it gets cleared if there's no
|
||||
further use of it, and make sure we don't clear it after the function
|
||||
invoke as it may have been set to a new value by then */
|
||||
data->state.tempwrite = NULL;
|
||||
|
||||
/* since the write callback API is define to never exceed
|
||||
CURL_MAX_WRITE_SIZE bytes in a single call, and since we may in fact
|
||||
have more data than that in our buffer here, we must loop sending the
|
||||
data in multiple calls until there's no data left or we get another
|
||||
pause returned.
|
||||
|
||||
A tricky part is that the function we call will "buffer" the data
|
||||
itself when it pauses on a particular buffer, so we may need to do some
|
||||
extra trickery if we get a pause return here.
|
||||
*/
|
||||
do {
|
||||
chunklen = (tempsize > CURL_MAX_WRITE_SIZE)?CURL_MAX_WRITE_SIZE:tempsize;
|
||||
|
||||
result = Curl_client_write(data->easy_conn,
|
||||
temptype, tempwrite, chunklen);
|
||||
if(result)
|
||||
/* failures abort the loop at once */
|
||||
break;
|
||||
|
||||
if(data->state.tempwrite && (tempsize - chunklen)) {
|
||||
/* Ouch, the reading is again paused and the block we send is now
|
||||
"cached". If this is the final chunk we can leave it like this, but
|
||||
if we have more chunks that are cached after this, we need to free
|
||||
the newly cached one and put back a version that is truly the entire
|
||||
contents that is saved for later
|
||||
*/
|
||||
char *newptr;
|
||||
|
||||
/* note that tempsize is still the size as before the callback was
|
||||
used, and thus the whole piece of data to keep */
|
||||
newptr = realloc(data->state.tempwrite, tempsize);
|
||||
|
||||
if(!newptr) {
|
||||
free(data->state.tempwrite); /* free old area */
|
||||
data->state.tempwrite = NULL;
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
/* tempwrite will be freed further down */
|
||||
break;
|
||||
}
|
||||
data->state.tempwrite = newptr; /* store new pointer */
|
||||
memcpy(newptr, tempwrite, tempsize);
|
||||
data->state.tempwritesize = tempsize; /* store new size */
|
||||
/* tempwrite will be freed further down */
|
||||
break; /* go back to pausing until further notice */
|
||||
}
|
||||
else {
|
||||
tempsize -= chunklen; /* left after the call above */
|
||||
tempwrite += chunklen; /* advance the pointer */
|
||||
}
|
||||
|
||||
} while((result == CURLE_OK) && tempsize);
|
||||
|
||||
free(freewrite); /* this is unconditionally no longer used */
|
||||
result = Curl_client_chop_write(data->easy_conn, data->state.tempwritetype,
|
||||
tempwrite, data->state.tempwritesize);
|
||||
free(tempwrite);
|
||||
}
|
||||
|
||||
/* if there's no error and we're not pausing both directions, we want
|
||||
@ -1129,20 +1077,20 @@ static CURLcode easy_connection(struct SessionHandle *data,
|
||||
CURLcode curl_easy_recv(CURL *curl, void *buffer, size_t buflen, size_t *n)
|
||||
{
|
||||
curl_socket_t sfd;
|
||||
CURLcode ret;
|
||||
CURLcode result;
|
||||
ssize_t n1;
|
||||
struct connectdata *c;
|
||||
struct SessionHandle *data = (struct SessionHandle *)curl;
|
||||
|
||||
ret = easy_connection(data, &sfd, &c);
|
||||
if(ret)
|
||||
return ret;
|
||||
result = easy_connection(data, &sfd, &c);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
*n = 0;
|
||||
ret = Curl_read(c, sfd, buffer, buflen, &n1);
|
||||
result = Curl_read(c, sfd, buffer, buflen, &n1);
|
||||
|
||||
if(ret != CURLE_OK)
|
||||
return ret;
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
*n = (size_t)n1;
|
||||
|
||||
@ -1157,26 +1105,26 @@ CURLcode curl_easy_send(CURL *curl, const void *buffer, size_t buflen,
|
||||
size_t *n)
|
||||
{
|
||||
curl_socket_t sfd;
|
||||
CURLcode ret;
|
||||
CURLcode result;
|
||||
ssize_t n1;
|
||||
struct connectdata *c = NULL;
|
||||
struct SessionHandle *data = (struct SessionHandle *)curl;
|
||||
|
||||
ret = easy_connection(data, &sfd, &c);
|
||||
if(ret)
|
||||
return ret;
|
||||
result = easy_connection(data, &sfd, &c);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
*n = 0;
|
||||
ret = Curl_write(c, sfd, buffer, buflen, &n1);
|
||||
result = Curl_write(c, sfd, buffer, buflen, &n1);
|
||||
|
||||
if(n1 == -1)
|
||||
return CURLE_SEND_ERROR;
|
||||
|
||||
/* detect EAGAIN */
|
||||
if((CURLE_OK == ret) && (0 == n1))
|
||||
if(!result && !n1)
|
||||
return CURLE_AGAIN;
|
||||
|
||||
*n = (size_t)n1;
|
||||
|
||||
return ret;
|
||||
return result;
|
||||
}
|
||||
|
@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -27,16 +27,14 @@
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
||||
#include "curl_memory.h"
|
||||
#include "urldata.h"
|
||||
#include "warnless.h"
|
||||
#include "non-ascii.h"
|
||||
#include "escape.h"
|
||||
#include "curl_printf.h"
|
||||
|
||||
#define _MPRINTF_REPLACE /* use our functions only */
|
||||
#include <curl/mprintf.h>
|
||||
|
||||
/* The last #include file should be: */
|
||||
/* The last #include files should be: */
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
/* Portable character check (remember EBCDIC). Do not use isalnum() because
|
||||
@ -87,7 +85,7 @@ char *curl_easy_escape(CURL *handle, const char *string, int inlength)
|
||||
size_t newlen = alloc;
|
||||
size_t strindex=0;
|
||||
size_t length;
|
||||
CURLcode res;
|
||||
CURLcode result;
|
||||
|
||||
ns = malloc(alloc);
|
||||
if(!ns)
|
||||
@ -115,8 +113,8 @@ char *curl_easy_escape(CURL *handle, const char *string, int inlength)
|
||||
}
|
||||
}
|
||||
|
||||
res = Curl_convert_to_network(handle, &in, 1);
|
||||
if(res) {
|
||||
result = Curl_convert_to_network(handle, &in, 1);
|
||||
if(result) {
|
||||
/* Curl_convert_to_network calls failf if unsuccessful */
|
||||
free(ns);
|
||||
return NULL;
|
||||
@ -152,7 +150,7 @@ CURLcode Curl_urldecode(struct SessionHandle *data,
|
||||
unsigned char in;
|
||||
size_t strindex=0;
|
||||
unsigned long hex;
|
||||
CURLcode res;
|
||||
CURLcode result;
|
||||
|
||||
if(!ns)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
@ -172,16 +170,17 @@ CURLcode Curl_urldecode(struct SessionHandle *data,
|
||||
|
||||
in = curlx_ultouc(hex); /* this long is never bigger than 255 anyway */
|
||||
|
||||
res = Curl_convert_from_network(data, &in, 1);
|
||||
if(res) {
|
||||
result = Curl_convert_from_network(data, &in, 1);
|
||||
if(result) {
|
||||
/* Curl_convert_from_network calls failf if unsuccessful */
|
||||
free(ns);
|
||||
return res;
|
||||
return result;
|
||||
}
|
||||
|
||||
string+=2;
|
||||
alloc-=2;
|
||||
}
|
||||
|
||||
if(reject_ctrl && (in < 0x20)) {
|
||||
free(ns);
|
||||
return CURLE_URL_MALFORMAT;
|
||||
@ -228,6 +227,5 @@ char *curl_easy_unescape(CURL *handle, const char *string, int length,
|
||||
the library's memory system */
|
||||
void curl_free(void *p)
|
||||
{
|
||||
if(p)
|
||||
free(p);
|
||||
}
|
||||
|
@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -59,14 +59,12 @@
|
||||
#include "getinfo.h"
|
||||
#include "transfer.h"
|
||||
#include "url.h"
|
||||
#include "curl_memory.h"
|
||||
#include "parsedate.h" /* for the week day and month names */
|
||||
#include "warnless.h"
|
||||
#include "curl_printf.h"
|
||||
|
||||
#define _MPRINTF_REPLACE /* use our functions only */
|
||||
#include <curl/mprintf.h>
|
||||
|
||||
/* The last #include file should be: */
|
||||
/* The last #include files should be: */
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
#if defined(WIN32) || defined(MSDOS) || defined(__EMX__) || \
|
||||
@ -196,8 +194,9 @@ static CURLcode file_connect(struct connectdata *conn, bool *done)
|
||||
int i;
|
||||
char *actual_path;
|
||||
#endif
|
||||
int real_path_len;
|
||||
|
||||
real_path = curl_easy_unescape(data, data->state.path, 0, NULL);
|
||||
real_path = curl_easy_unescape(data, data->state.path, 0, &real_path_len);
|
||||
if(!real_path)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
@ -222,16 +221,23 @@ static CURLcode file_connect(struct connectdata *conn, bool *done)
|
||||
(actual_path[2] == ':' || actual_path[2] == '|')) {
|
||||
actual_path[2] = ':';
|
||||
actual_path++;
|
||||
real_path_len--;
|
||||
}
|
||||
|
||||
/* change path separators from '/' to '\\' for DOS, Windows and OS/2 */
|
||||
for(i=0; actual_path[i] != '\0'; ++i)
|
||||
for(i=0; i < real_path_len; ++i)
|
||||
if(actual_path[i] == '/')
|
||||
actual_path[i] = '\\';
|
||||
else if(!actual_path[i]) /* binary zero */
|
||||
return CURLE_URL_MALFORMAT;
|
||||
|
||||
fd = open_readonly(actual_path, O_RDONLY|O_BINARY);
|
||||
file->path = actual_path;
|
||||
#else
|
||||
if(memchr(real_path, 0, real_path_len))
|
||||
/* binary zeroes indicate foul play */
|
||||
return CURLE_URL_MALFORMAT;
|
||||
|
||||
fd = open_readonly(real_path, O_RDONLY);
|
||||
file->path = real_path;
|
||||
#endif
|
||||
@ -295,7 +301,7 @@ static CURLcode file_upload(struct connectdata *conn)
|
||||
const char *dir = strchr(file->path, DIRSEP);
|
||||
int fd;
|
||||
int mode;
|
||||
CURLcode res=CURLE_OK;
|
||||
CURLcode result = CURLE_OK;
|
||||
struct SessionHandle *data = conn->data;
|
||||
char *buf = data->state.buffer;
|
||||
size_t nread;
|
||||
@ -309,8 +315,6 @@ static CURLcode file_upload(struct connectdata *conn)
|
||||
* Since FILE: doesn't do the full init, we need to provide some extra
|
||||
* assignments here.
|
||||
*/
|
||||
conn->fread_func = data->set.fread_func;
|
||||
conn->fread_in = data->set.in;
|
||||
conn->data->req.upload_fromhere = buf;
|
||||
|
||||
if(!dir)
|
||||
@ -351,10 +355,10 @@ static CURLcode file_upload(struct connectdata *conn)
|
||||
data->state.resume_from = (curl_off_t)file_stat.st_size;
|
||||
}
|
||||
|
||||
while(res == CURLE_OK) {
|
||||
while(!result) {
|
||||
int readcount;
|
||||
res = Curl_fillreadbuffer(conn, BUFSIZE, &readcount);
|
||||
if(res)
|
||||
result = Curl_fillreadbuffer(conn, BUFSIZE, &readcount);
|
||||
if(result)
|
||||
break;
|
||||
|
||||
if(readcount <= 0) /* fix questionable compare error. curlvms */
|
||||
@ -381,7 +385,7 @@ static CURLcode file_upload(struct connectdata *conn)
|
||||
/* write the data to the target */
|
||||
nwrite = write(fd, buf2, nread);
|
||||
if(nwrite != nread) {
|
||||
res = CURLE_SEND_ERROR;
|
||||
result = CURLE_SEND_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -390,16 +394,16 @@ static CURLcode file_upload(struct connectdata *conn)
|
||||
Curl_pgrsSetUploadCounter(data, bytecount);
|
||||
|
||||
if(Curl_pgrsUpdate(conn))
|
||||
res = CURLE_ABORTED_BY_CALLBACK;
|
||||
result = CURLE_ABORTED_BY_CALLBACK;
|
||||
else
|
||||
res = Curl_speedcheck(data, now);
|
||||
result = Curl_speedcheck(data, now);
|
||||
}
|
||||
if(!res && Curl_pgrsUpdate(conn))
|
||||
res = CURLE_ABORTED_BY_CALLBACK;
|
||||
if(!result && Curl_pgrsUpdate(conn))
|
||||
result = CURLE_ABORTED_BY_CALLBACK;
|
||||
|
||||
close(fd);
|
||||
|
||||
return res;
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -417,7 +421,7 @@ static CURLcode file_do(struct connectdata *conn, bool *done)
|
||||
are supported. This means that files on remotely mounted directories
|
||||
(via NFS, Samba, NT sharing) can be accessed through a file:// URL
|
||||
*/
|
||||
CURLcode res = CURLE_OK;
|
||||
CURLcode result = CURLE_OK;
|
||||
struct_stat statbuf; /* struct_stat instead of struct stat just to allow the
|
||||
Windows version to have a different struct without
|
||||
having to redefine the simple word 'stat' */
|
||||
@ -464,7 +468,6 @@ static CURLcode file_do(struct connectdata *conn, bool *done)
|
||||
information. Which for FILE can't be much more than the file size and
|
||||
date. */
|
||||
if(data->set.opt_no_body && data->set.include_header && fstated) {
|
||||
CURLcode result;
|
||||
snprintf(buf, sizeof(data->state.buffer),
|
||||
"Content-Length: %" CURL_FORMAT_CURL_OFF_T "\r\n", expected_size);
|
||||
result = Curl_client_write(conn, CLIENTWRITE_BOTH, buf, 0);
|
||||
@ -546,7 +549,7 @@ static CURLcode file_do(struct connectdata *conn, bool *done)
|
||||
|
||||
Curl_pgrsTime(data, TIMER_STARTTRANSFER);
|
||||
|
||||
while(res == CURLE_OK) {
|
||||
while(!result) {
|
||||
/* Don't fill a whole buffer if we want less than all data */
|
||||
size_t bytestoread =
|
||||
(expected_size < CURL_OFF_T_C(BUFSIZE) - CURL_OFF_T_C(1)) ?
|
||||
@ -563,21 +566,21 @@ static CURLcode file_do(struct connectdata *conn, bool *done)
|
||||
bytecount += nread;
|
||||
expected_size -= nread;
|
||||
|
||||
res = Curl_client_write(conn, CLIENTWRITE_BODY, buf, nread);
|
||||
if(res)
|
||||
return res;
|
||||
result = Curl_client_write(conn, CLIENTWRITE_BODY, buf, nread);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
Curl_pgrsSetDownloadCounter(data, bytecount);
|
||||
|
||||
if(Curl_pgrsUpdate(conn))
|
||||
res = CURLE_ABORTED_BY_CALLBACK;
|
||||
result = CURLE_ABORTED_BY_CALLBACK;
|
||||
else
|
||||
res = Curl_speedcheck(data, now);
|
||||
result = Curl_speedcheck(data, now);
|
||||
}
|
||||
if(Curl_pgrsUpdate(conn))
|
||||
res = CURLE_ABORTED_BY_CALLBACK;
|
||||
result = CURLE_ABORTED_BY_CALLBACK;
|
||||
|
||||
return res;
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2010-2011, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 2010 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -24,10 +24,6 @@
|
||||
|
||||
#include "strdup.h"
|
||||
#include "fileinfo.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"
|
||||
|
@ -1,54 +0,0 @@
|
||||
#!/bin/sh
|
||||
# ***************************************************************************
|
||||
# * _ _ ____ _
|
||||
# * 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.
|
||||
# *
|
||||
# ***************************************************************************
|
||||
# This shell script creates a fresh ca-bundle.crt file for use with libcurl.
|
||||
# It extracts all ca certs it finds in the local Firefox database and converts
|
||||
# them all into PEM format.
|
||||
#
|
||||
db=`ls -1d $HOME/.mozilla/firefox/*default`
|
||||
out=$1
|
||||
|
||||
if test -z "$out"; then
|
||||
out="ca-bundle.crt" # use a sensible default
|
||||
fi
|
||||
|
||||
currentdate=`date`
|
||||
|
||||
cat >$out <<EOF
|
||||
##
|
||||
## Bundle of CA Root Certificates
|
||||
##
|
||||
## Converted at: ${currentdate}
|
||||
## These were converted from the local Firefox directory by the db2pem script.
|
||||
##
|
||||
EOF
|
||||
|
||||
|
||||
certutil -L -h 'Builtin Object Token' -d $db | \
|
||||
grep ' *[CcGTPpu]*,[CcGTPpu]*,[CcGTPpu]* *$' | \
|
||||
sed -e 's/ *[CcGTPpu]*,[CcGTPpu]*,[CcGTPpu]* *$//' -e 's/\(.*\)/"\1"/' | \
|
||||
sort | \
|
||||
while read nickname; \
|
||||
do echo $nickname | sed -e "s/Builtin Object Token://g"; \
|
||||
eval certutil -d $db -L -n "$nickname" -a ; \
|
||||
done >> $out
|
||||
|
@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -24,7 +24,7 @@
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
||||
#if !defined(CURL_DISABLE_HTTP) || defined(USE_SSLEAY)
|
||||
#ifndef CURL_DISABLE_HTTP
|
||||
|
||||
#if defined(HAVE_LIBGEN_H) && defined(HAVE_BASENAME)
|
||||
#include <libgen.h>
|
||||
@ -34,19 +34,14 @@
|
||||
#include "formdata.h"
|
||||
#include "vtls/vtls.h"
|
||||
#include "strequal.h"
|
||||
#include "curl_memory.h"
|
||||
#include "sendf.h"
|
||||
#include "strdup.h"
|
||||
#include "curl_printf.h"
|
||||
|
||||
#define _MPRINTF_REPLACE /* use our functions only */
|
||||
#include <curl/mprintf.h>
|
||||
|
||||
/* The last #include file should be: */
|
||||
/* The last #include files should be: */
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
#endif /* !defined(CURL_DISABLE_HTTP) || defined(USE_SSLEAY) */
|
||||
|
||||
#ifndef CURL_DISABLE_HTTP
|
||||
|
||||
#ifndef HAVE_BASENAME
|
||||
static char *Curl_basename(char *path);
|
||||
#define basename(x) Curl_basename((x))
|
||||
@ -212,46 +207,6 @@ static const char *ContentTypeForFilename(const char *filename,
|
||||
return contenttype;
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
*
|
||||
* memdup()
|
||||
*
|
||||
* Copies the 'source' data to a newly allocated buffer buffer (that is
|
||||
* returned). Uses buffer_length if not null, else uses strlen to determine
|
||||
* the length of the buffer to be copied
|
||||
*
|
||||
* Returns the new pointer or NULL on failure.
|
||||
*
|
||||
***************************************************************************/
|
||||
static char *memdup(const char *src, size_t buffer_length)
|
||||
{
|
||||
size_t length;
|
||||
bool add = FALSE;
|
||||
char *buffer;
|
||||
|
||||
if(buffer_length)
|
||||
length = buffer_length;
|
||||
else if(src) {
|
||||
length = strlen(src);
|
||||
add = TRUE;
|
||||
}
|
||||
else
|
||||
/* no length and a NULL src pointer! */
|
||||
return strdup("");
|
||||
|
||||
buffer = malloc(length+add);
|
||||
if(!buffer)
|
||||
return NULL; /* fail */
|
||||
|
||||
memcpy(buffer, src, length);
|
||||
|
||||
/* if length unknown do null termination */
|
||||
if(add)
|
||||
buffer[length] = '\0';
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
*
|
||||
* FormAdd()
|
||||
@ -460,7 +415,7 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
|
||||
else {
|
||||
form = AddFormInfo(fname, NULL, current_form);
|
||||
if(!form) {
|
||||
Curl_safefree(fname);
|
||||
free(fname);
|
||||
return_value = CURL_FORMADD_MEMORY;
|
||||
}
|
||||
else {
|
||||
@ -549,7 +504,7 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
|
||||
else {
|
||||
form = AddFormInfo(NULL, type, current_form);
|
||||
if(!form) {
|
||||
Curl_safefree(type);
|
||||
free(type);
|
||||
return_value = CURL_FORMADD_MEMORY;
|
||||
}
|
||||
else {
|
||||
@ -583,7 +538,7 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
|
||||
/* this "cast increases required alignment of target type" but
|
||||
we consider it OK anyway */
|
||||
struct curl_slist* list = array_state?
|
||||
(struct curl_slist*)array_value:
|
||||
(struct curl_slist*)(void*)array_value:
|
||||
va_arg(params, struct curl_slist*);
|
||||
|
||||
if(current_form->contentheader)
|
||||
@ -682,9 +637,12 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
|
||||
(form == first_form) ) {
|
||||
/* Note that there's small risk that form->name is NULL here if the
|
||||
app passed in a bad combo, so we better check for that first. */
|
||||
if(form->name)
|
||||
if(form->name) {
|
||||
/* copy name (without strdup; possibly contains null characters) */
|
||||
form->name = memdup(form->name, form->namelength);
|
||||
form->name = Curl_memdup(form->name, form->namelength?
|
||||
form->namelength:
|
||||
strlen(form->name)+1);
|
||||
}
|
||||
if(!form->name) {
|
||||
return_value = CURL_FORMADD_MEMORY;
|
||||
break;
|
||||
@ -693,9 +651,11 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
|
||||
}
|
||||
if(!(form->flags & (HTTPPOST_FILENAME | HTTPPOST_READFILE |
|
||||
HTTPPOST_PTRCONTENTS | HTTPPOST_PTRBUFFER |
|
||||
HTTPPOST_CALLBACK)) ) {
|
||||
HTTPPOST_CALLBACK)) && form->value) {
|
||||
/* copy value (without strdup; possibly contains null characters) */
|
||||
form->value = memdup(form->value, form->contentslength);
|
||||
form->value = Curl_memdup(form->value, form->contentslength?
|
||||
form->contentslength:
|
||||
strlen(form->value)+1);
|
||||
if(!form->value) {
|
||||
return_value = CURL_FORMADD_MEMORY;
|
||||
break;
|
||||
@ -751,7 +711,7 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
|
||||
now by the httppost linked list */
|
||||
while(first_form) {
|
||||
FormInfo *ptr = first_form->more;
|
||||
Curl_safefree(first_form);
|
||||
free(first_form);
|
||||
first_form = ptr;
|
||||
}
|
||||
|
||||
@ -796,7 +756,7 @@ curl_off_t VmsRealFileSize(const char * name,
|
||||
int ret_stat;
|
||||
FILE * file;
|
||||
|
||||
file = fopen(name, "r");
|
||||
file = fopen(name, "r"); /* VMS */
|
||||
if(file == NULL)
|
||||
return 0;
|
||||
|
||||
@ -954,13 +914,13 @@ void Curl_formclean(struct FormData **form_ptr)
|
||||
int curl_formget(struct curl_httppost *form, void *arg,
|
||||
curl_formget_callback append)
|
||||
{
|
||||
CURLcode rc;
|
||||
CURLcode result;
|
||||
curl_off_t size;
|
||||
struct FormData *data, *ptr;
|
||||
|
||||
rc = Curl_getformdata(NULL, &data, form, NULL, &size);
|
||||
if(rc != CURLE_OK)
|
||||
return (int)rc;
|
||||
result = Curl_getformdata(NULL, &data, form, NULL, &size);
|
||||
if(result)
|
||||
return (int)result;
|
||||
|
||||
for(ptr = data; ptr; ptr = ptr->next) {
|
||||
if((ptr->type == FORM_FILE) || (ptr->type == FORM_CALLBACK)) {
|
||||
@ -1009,18 +969,15 @@ void curl_formfree(struct curl_httppost *form)
|
||||
next=form->next; /* the following form line */
|
||||
|
||||
/* recurse to sub-contents */
|
||||
if(form->more)
|
||||
curl_formfree(form->more);
|
||||
|
||||
if(!(form->flags & HTTPPOST_PTRNAME) && form->name)
|
||||
if(!(form->flags & HTTPPOST_PTRNAME))
|
||||
free(form->name); /* free the name */
|
||||
if(!(form->flags &
|
||||
(HTTPPOST_PTRCONTENTS|HTTPPOST_BUFFER|HTTPPOST_CALLBACK)) &&
|
||||
form->contents)
|
||||
(HTTPPOST_PTRCONTENTS|HTTPPOST_BUFFER|HTTPPOST_CALLBACK))
|
||||
)
|
||||
free(form->contents); /* free the contents */
|
||||
if(form->contenttype)
|
||||
free(form->contenttype); /* free the content type */
|
||||
if(form->showfilename)
|
||||
free(form->showfilename); /* free the faked file name */
|
||||
free(form); /* free the struct */
|
||||
|
||||
@ -1111,7 +1068,7 @@ static CURLcode formdata_add_filename(const struct curl_httppost *file,
|
||||
/* filename need be escaped */
|
||||
filename_escaped = malloc(strlen(filename)*2+1);
|
||||
if(!filename_escaped) {
|
||||
Curl_safefree(filebasename);
|
||||
free(filebasename);
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
p0 = filename_escaped;
|
||||
@ -1127,8 +1084,8 @@ static CURLcode formdata_add_filename(const struct curl_httppost *file,
|
||||
result = AddFormDataf(form, size,
|
||||
"; filename=\"%s\"",
|
||||
filename);
|
||||
Curl_safefree(filename_escaped);
|
||||
Curl_safefree(filebasename);
|
||||
free(filename_escaped);
|
||||
free(filebasename);
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -1178,7 +1135,7 @@ CURLcode Curl_getformdata(struct SessionHandle *data,
|
||||
boundary);
|
||||
|
||||
if(result) {
|
||||
Curl_safefree(boundary);
|
||||
free(boundary);
|
||||
return result;
|
||||
}
|
||||
/* we DO NOT include that line in the total size of the POST, since it'll be
|
||||
@ -1221,7 +1178,7 @@ CURLcode Curl_getformdata(struct SessionHandle *data,
|
||||
/* If used, this is a link to more file names, we must then do
|
||||
the magic to include several files with the same field name */
|
||||
|
||||
Curl_safefree(fileboundary);
|
||||
free(fileboundary);
|
||||
fileboundary = formboundary(data);
|
||||
if(!fileboundary) {
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
@ -1369,22 +1326,20 @@ CURLcode Curl_getformdata(struct SessionHandle *data,
|
||||
} while((post = post->next) != NULL); /* for each field */
|
||||
|
||||
/* end-boundary for everything */
|
||||
if(CURLE_OK == result)
|
||||
result = AddFormDataf(&form, &size,
|
||||
"\r\n--%s--\r\n",
|
||||
boundary);
|
||||
if(!result)
|
||||
result = AddFormDataf(&form, &size, "\r\n--%s--\r\n", boundary);
|
||||
|
||||
if(result) {
|
||||
Curl_formclean(&firstform);
|
||||
Curl_safefree(fileboundary);
|
||||
Curl_safefree(boundary);
|
||||
free(fileboundary);
|
||||
free(boundary);
|
||||
return result;
|
||||
}
|
||||
|
||||
*sizep = size;
|
||||
|
||||
Curl_safefree(fileboundary);
|
||||
Curl_safefree(boundary);
|
||||
free(fileboundary);
|
||||
free(boundary);
|
||||
|
||||
*finalform = firstform;
|
||||
|
||||
@ -1430,7 +1385,7 @@ static FILE * vmsfopenread(const char *file, const char *mode) {
|
||||
case FAB$C_VAR:
|
||||
case FAB$C_VFC:
|
||||
case FAB$C_STMCR:
|
||||
return fopen(file, "r");
|
||||
return fopen(file, "r"); /* VMS */
|
||||
break;
|
||||
default:
|
||||
return fopen(file, "r", "rfm=stmlf", "ctx=stm");
|
||||
|
@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -77,9 +77,7 @@
|
||||
#include "warnless.h"
|
||||
#include "http_proxy.h"
|
||||
#include "non-ascii.h"
|
||||
|
||||
#define _MPRINTF_REPLACE /* use our functions only */
|
||||
#include <curl/mprintf.h>
|
||||
#include "curl_printf.h"
|
||||
|
||||
#include "curl_memory.h"
|
||||
/* The last #include file should be: */
|
||||
@ -157,7 +155,7 @@ static CURLcode ftp_dophase_done(struct connectdata *conn,
|
||||
bool connected);
|
||||
|
||||
/* easy-to-use macro: */
|
||||
#define PPSENDF(x,y,z) if((result = Curl_pp_sendf(x,y,z)) != CURLE_OK) \
|
||||
#define PPSENDF(x,y,z) if((result = Curl_pp_sendf(x,y,z))) \
|
||||
return result
|
||||
|
||||
|
||||
@ -285,19 +283,17 @@ static void freedirs(struct ftp_conn *ftpc)
|
||||
int i;
|
||||
if(ftpc->dirs) {
|
||||
for(i=0; i < ftpc->dirdepth; i++) {
|
||||
if(ftpc->dirs[i]) {
|
||||
free(ftpc->dirs[i]);
|
||||
ftpc->dirs[i]=NULL;
|
||||
}
|
||||
}
|
||||
free(ftpc->dirs);
|
||||
ftpc->dirs = NULL;
|
||||
ftpc->dirdepth = 0;
|
||||
}
|
||||
if(ftpc->file) {
|
||||
free(ftpc->file);
|
||||
ftpc->file = NULL;
|
||||
}
|
||||
Curl_safefree(ftpc->file);
|
||||
|
||||
/* no longer of any use */
|
||||
Curl_safefree(ftpc->newhost);
|
||||
}
|
||||
|
||||
/* Returns non-zero if the given string contains CR (\r) or LF (\n),
|
||||
@ -344,9 +340,12 @@ static CURLcode AcceptServerConnect(struct connectdata *conn)
|
||||
return CURLE_FTP_PORT_FAILED;
|
||||
}
|
||||
infof(data, "Connection accepted from server\n");
|
||||
/* when this happens within the DO state it is important that we mark us as
|
||||
not needing DO_MORE anymore */
|
||||
conn->bits.do_more = FALSE;
|
||||
|
||||
conn->sock[SECONDARYSOCKET] = s;
|
||||
curlx_nonblock(s, TRUE); /* enable non-blocking */
|
||||
(void)curlx_nonblock(s, TRUE); /* enable non-blocking */
|
||||
conn->sock_accepted[SECONDARYSOCKET] = TRUE;
|
||||
|
||||
if(data->set.fsockopt) {
|
||||
@ -541,7 +540,7 @@ static CURLcode AllowServerConnect(struct connectdata *conn, bool *connected)
|
||||
{
|
||||
struct SessionHandle *data = conn->data;
|
||||
long timeout_ms;
|
||||
CURLcode ret = CURLE_OK;
|
||||
CURLcode result = CURLE_OK;
|
||||
|
||||
*connected = FALSE;
|
||||
infof(data, "Preparing for accepting server on data port\n");
|
||||
@ -557,22 +556,22 @@ static CURLcode AllowServerConnect(struct connectdata *conn, bool *connected)
|
||||
}
|
||||
|
||||
/* see if the connection request is already here */
|
||||
ret = ReceivedServerConnect(conn, connected);
|
||||
if(ret)
|
||||
return ret;
|
||||
result = ReceivedServerConnect(conn, connected);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
if(*connected) {
|
||||
ret = AcceptServerConnect(conn);
|
||||
if(ret)
|
||||
return ret;
|
||||
result = AcceptServerConnect(conn);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
ret = InitiateTransfer(conn);
|
||||
if(ret)
|
||||
return ret;
|
||||
result = InitiateTransfer(conn);
|
||||
if(result)
|
||||
return result;
|
||||
}
|
||||
else {
|
||||
/* Add timeout to multi handle and break out of the loop */
|
||||
if(ret == CURLE_OK && *connected == FALSE) {
|
||||
if(!result && *connected == FALSE) {
|
||||
if(data->set.accepttimeout > 0)
|
||||
Curl_expire(data, data->set.accepttimeout);
|
||||
else
|
||||
@ -580,7 +579,7 @@ static CURLcode AllowServerConnect(struct connectdata *conn, bool *connected)
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
return result;
|
||||
}
|
||||
|
||||
/* macro to check for a three-digit ftp status code at the start of the
|
||||
@ -821,12 +820,19 @@ static void _state(struct connectdata *conn,
|
||||
)
|
||||
{
|
||||
struct ftp_conn *ftpc = &conn->proto.ftpc;
|
||||
#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
|
||||
|
||||
#if defined(DEBUGBUILD)
|
||||
|
||||
#if defined(CURL_DISABLE_VERBOSE_STRINGS)
|
||||
(void) lineno;
|
||||
#else
|
||||
if(ftpc->state != newstate)
|
||||
infof(conn->data, "FTP %p (line %d) state change from %s to %s\n",
|
||||
(void *)ftpc, lineno, ftp_state_names[ftpc->state],
|
||||
ftp_state_names[newstate]);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
ftpc->state = newstate;
|
||||
}
|
||||
|
||||
@ -1072,8 +1078,9 @@ static CURLcode ftp_state_use_port(struct connectdata *conn,
|
||||
|
||||
if(*addr != '\0') {
|
||||
/* attempt to get the address of the given interface name */
|
||||
switch(Curl_if2ip(conn->ip_addr->ai_family, conn->scope, addr,
|
||||
hbuf, sizeof(hbuf))) {
|
||||
switch(Curl_if2ip(conn->ip_addr->ai_family,
|
||||
Curl_ipv6_scope(conn->ip_addr->ai_addr),
|
||||
conn->scope_id, addr, hbuf, sizeof(hbuf))) {
|
||||
case IF2IP_NOT_FOUND:
|
||||
/* not an interface, use the given string as host name instead */
|
||||
host = addr;
|
||||
@ -1097,7 +1104,7 @@ static CURLcode ftp_state_use_port(struct connectdata *conn,
|
||||
if(getsockname(conn->sock[FIRSTSOCKET], sa, &sslen)) {
|
||||
failf(data, "getsockname() failed: %s",
|
||||
Curl_strerror(conn, SOCKERRNO) );
|
||||
Curl_safefree(addr);
|
||||
free(addr);
|
||||
return CURLE_FTP_PORT_FAILED;
|
||||
}
|
||||
switch(sa->sa_family) {
|
||||
@ -1129,11 +1136,11 @@ static CURLcode ftp_state_use_port(struct connectdata *conn,
|
||||
|
||||
if(res == NULL) {
|
||||
failf(data, "failed to resolve the address provided to PORT: %s", host);
|
||||
Curl_safefree(addr);
|
||||
free(addr);
|
||||
return CURLE_FTP_PORT_FAILED;
|
||||
}
|
||||
|
||||
Curl_safefree(addr);
|
||||
free(addr);
|
||||
host = NULL;
|
||||
|
||||
/* step 2, create a socket for the requested address */
|
||||
@ -1246,10 +1253,10 @@ static CURLcode ftp_state_use_port(struct connectdata *conn,
|
||||
continue;
|
||||
|
||||
if((PORT == fcmd) && sa->sa_family != AF_INET)
|
||||
/* PORT is ipv4 only */
|
||||
/* PORT is IPv4 only */
|
||||
continue;
|
||||
|
||||
switch (sa->sa_family) {
|
||||
switch(sa->sa_family) {
|
||||
case AF_INET:
|
||||
port = ntohs(sa4->sin_port);
|
||||
break;
|
||||
@ -1487,13 +1494,13 @@ static CURLcode ftp_state_list(struct connectdata *conn)
|
||||
The other ftp_filemethods will CWD into dir/dir/ first and
|
||||
then just do LIST (in that case: nothing to do here)
|
||||
*/
|
||||
char *cmd,*lstArg,*slashPos;
|
||||
char *cmd, *lstArg, *slashPos;
|
||||
|
||||
lstArg = NULL;
|
||||
if((data->set.ftp_filemethod == FTPFILE_NOCWD) &&
|
||||
data->state.path &&
|
||||
data->state.path[0] &&
|
||||
strchr(data->state.path,'/')) {
|
||||
strchr(data->state.path, '/')) {
|
||||
|
||||
lstArg = strdup(data->state.path);
|
||||
if(!lstArg)
|
||||
@ -1503,7 +1510,7 @@ static CURLcode ftp_state_list(struct connectdata *conn)
|
||||
if(lstArg[strlen(lstArg) - 1] != '/') {
|
||||
|
||||
/* chop off the file part if format is dir/dir/file */
|
||||
slashPos = strrchr(lstArg,'/');
|
||||
slashPos = strrchr(lstArg, '/');
|
||||
if(slashPos)
|
||||
*(slashPos+1) = '\0';
|
||||
}
|
||||
@ -1517,19 +1524,16 @@ static CURLcode ftp_state_list(struct connectdata *conn)
|
||||
lstArg? lstArg: "" );
|
||||
|
||||
if(!cmd) {
|
||||
if(lstArg)
|
||||
free(lstArg);
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
result = Curl_pp_sendf(&conn->proto.ftpc.pp, "%s", cmd);
|
||||
|
||||
if(lstArg)
|
||||
free(lstArg);
|
||||
|
||||
free(cmd);
|
||||
|
||||
if(result != CURLE_OK)
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
state(conn, FTP_LIST);
|
||||
@ -1669,8 +1673,8 @@ static CURLcode ftp_state_ul_setup(struct connectdata *conn,
|
||||
BUFSIZE : curlx_sotouz(data->state.resume_from - passed);
|
||||
|
||||
size_t actuallyread =
|
||||
conn->fread_func(data->state.buffer, 1, readthisamountnow,
|
||||
conn->fread_in);
|
||||
data->set.fread_func(data->state.buffer, 1, readthisamountnow,
|
||||
data->set.in);
|
||||
|
||||
passed += actuallyread;
|
||||
if((actuallyread == 0) || (actuallyread > readthisamountnow)) {
|
||||
@ -1807,6 +1811,13 @@ static CURLcode ftp_state_quote(struct connectdata *conn,
|
||||
static CURLcode ftp_epsv_disable(struct connectdata *conn)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
|
||||
if(conn->bits.ipv6) {
|
||||
/* We can't disable EPSV when doing IPv6, so this is instead a fail */
|
||||
failf(conn->data, "Failed EPSV attempt, exiting\n");
|
||||
return CURLE_FTP_WEIRD_SERVER_REPLY;
|
||||
}
|
||||
|
||||
infof(conn->data, "Failed EPSV attempt. Disabling EPSV\n");
|
||||
/* disable it for next transfer */
|
||||
conn->bits.ftp_use_epsv = FALSE;
|
||||
@ -1828,9 +1839,15 @@ static CURLcode proxy_magic(struct connectdata *conn,
|
||||
bool *magicdone)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
struct SessionHandle *data=conn->data;
|
||||
struct SessionHandle *data = conn->data;
|
||||
|
||||
#if defined(CURL_DISABLE_PROXY)
|
||||
(void) newhost;
|
||||
(void) newport;
|
||||
#endif
|
||||
|
||||
*magicdone = FALSE;
|
||||
|
||||
switch(conn->proxytype) {
|
||||
case CURLPROXY_SOCKS5:
|
||||
case CURLPROXY_SOCKS5_HOSTNAME:
|
||||
@ -1873,7 +1890,7 @@ static CURLcode proxy_magic(struct connectdata *conn,
|
||||
memset(&http_proxy, 0, sizeof(http_proxy));
|
||||
data->req.protop = &http_proxy;
|
||||
|
||||
result = Curl_proxyCONNECT(conn, SECONDARYSOCKET, newhost, newport);
|
||||
result = Curl_proxyCONNECT(conn, SECONDARYSOCKET, newhost, newport, TRUE);
|
||||
|
||||
data->req.protop = ftp_save;
|
||||
|
||||
@ -1888,9 +1905,26 @@ static CURLcode proxy_magic(struct connectdata *conn,
|
||||
else
|
||||
*magicdone = TRUE;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static char *control_address(struct connectdata *conn)
|
||||
{
|
||||
/* Returns the control connection IP address.
|
||||
If a proxy tunnel is used, returns the original host name instead, because
|
||||
the effective control connection address is the proxy address,
|
||||
not the ftp host. */
|
||||
if(conn->bits.tunnel_proxy ||
|
||||
conn->proxytype == CURLPROXY_SOCKS5 ||
|
||||
conn->proxytype == CURLPROXY_SOCKS5_HOSTNAME ||
|
||||
conn->proxytype == CURLPROXY_SOCKS4 ||
|
||||
conn->proxytype == CURLPROXY_SOCKS4A)
|
||||
return conn->host.name;
|
||||
|
||||
return conn->ip_addr_str;
|
||||
}
|
||||
|
||||
static CURLcode ftp_state_pasv_resp(struct connectdata *conn,
|
||||
int ftpcode)
|
||||
{
|
||||
@ -1902,6 +1936,9 @@ static CURLcode ftp_state_pasv_resp(struct connectdata *conn,
|
||||
unsigned short connectport; /* the local port connect() should use! */
|
||||
char *str=&data->state.buffer[4]; /* start on the first letter */
|
||||
|
||||
/* if we come here again, make sure the former name is cleared */
|
||||
Curl_safefree(ftpc->newhost);
|
||||
|
||||
if((ftpc->count1 == 0) &&
|
||||
(ftpcode == 229)) {
|
||||
/* positive EPSV response */
|
||||
@ -1933,19 +1970,9 @@ static CURLcode ftp_state_pasv_resp(struct connectdata *conn,
|
||||
}
|
||||
if(ptr) {
|
||||
ftpc->newport = (unsigned short)(num & 0xffff);
|
||||
|
||||
if(conn->bits.tunnel_proxy ||
|
||||
conn->proxytype == CURLPROXY_SOCKS5 ||
|
||||
conn->proxytype == CURLPROXY_SOCKS5_HOSTNAME ||
|
||||
conn->proxytype == CURLPROXY_SOCKS4 ||
|
||||
conn->proxytype == CURLPROXY_SOCKS4A)
|
||||
/* proxy tunnel -> use other host info because ip_addr_str is the
|
||||
proxy address not the ftp host */
|
||||
snprintf(ftpc->newhost, sizeof(ftpc->newhost), "%s",
|
||||
conn->host.name);
|
||||
else
|
||||
/* use the same IP we are already connected to */
|
||||
snprintf(ftpc->newhost, NEWHOST_BUFSIZE, "%s", conn->ip_addr_str);
|
||||
ftpc->newhost = strdup(control_address(conn));
|
||||
if(!ftpc->newhost)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -1986,26 +2013,19 @@ static CURLcode ftp_state_pasv_resp(struct connectdata *conn,
|
||||
|
||||
/* we got OK from server */
|
||||
if(data->set.ftp_skip_ip) {
|
||||
/* told to ignore the remotely given IP but instead use the one we used
|
||||
/* told to ignore the remotely given IP but instead use the host we used
|
||||
for the control connection */
|
||||
infof(data, "Skips %d.%d.%d.%d for data connection, uses %s instead\n",
|
||||
infof(data, "Skip %d.%d.%d.%d for data connection, re-use %s instead\n",
|
||||
ip[0], ip[1], ip[2], ip[3],
|
||||
conn->ip_addr_str);
|
||||
if(conn->bits.tunnel_proxy ||
|
||||
conn->proxytype == CURLPROXY_SOCKS5 ||
|
||||
conn->proxytype == CURLPROXY_SOCKS5_HOSTNAME ||
|
||||
conn->proxytype == CURLPROXY_SOCKS4 ||
|
||||
conn->proxytype == CURLPROXY_SOCKS4A)
|
||||
/* proxy tunnel -> use other host info because ip_addr_str is the
|
||||
proxy address not the ftp host */
|
||||
snprintf(ftpc->newhost, sizeof(ftpc->newhost), "%s", conn->host.name);
|
||||
else
|
||||
snprintf(ftpc->newhost, sizeof(ftpc->newhost), "%s",
|
||||
conn->ip_addr_str);
|
||||
conn->host.name);
|
||||
ftpc->newhost = strdup(control_address(conn));
|
||||
}
|
||||
else
|
||||
snprintf(ftpc->newhost, sizeof(ftpc->newhost),
|
||||
"%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);
|
||||
ftpc->newhost = aprintf("%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);
|
||||
|
||||
if(!ftpc->newhost)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
ftpc->newport = (unsigned short)(((port[0]<<8) + port[1]) & 0xffff);
|
||||
}
|
||||
else if(ftpc->count1 == 0) {
|
||||
@ -2056,9 +2076,8 @@ static CURLcode ftp_state_pasv_resp(struct connectdata *conn,
|
||||
conn->bits.tcpconnect[SECONDARYSOCKET] = FALSE;
|
||||
result = Curl_connecthost(conn, addr);
|
||||
|
||||
Curl_resolv_unlock(data, addr); /* we're done using this address */
|
||||
|
||||
if(result) {
|
||||
Curl_resolv_unlock(data, addr); /* we're done using this address */
|
||||
if(ftpc->count1 == 0 && ftpcode == 229)
|
||||
return ftp_epsv_disable(conn);
|
||||
|
||||
@ -2074,8 +2093,9 @@ static CURLcode ftp_state_pasv_resp(struct connectdata *conn,
|
||||
|
||||
if(data->set.verbose)
|
||||
/* this just dumps information about this second connection */
|
||||
ftp_pasv_verbose(conn, conn->ip_addr, ftpc->newhost, connectport);
|
||||
ftp_pasv_verbose(conn, addr->addr, ftpc->newhost, connectport);
|
||||
|
||||
Curl_resolv_unlock(data, addr); /* we're done using this address */
|
||||
conn->bits.do_more = TRUE;
|
||||
state(conn, FTP_STOP); /* this phase is completed */
|
||||
|
||||
@ -2090,7 +2110,9 @@ static CURLcode ftp_state_port_resp(struct connectdata *conn,
|
||||
ftpport fcmd = (ftpport)ftpc->count1;
|
||||
CURLcode result = CURLE_OK;
|
||||
|
||||
if(ftpcode != 200) {
|
||||
/* The FTP spec tells a positive response should have code 200.
|
||||
Be more permissive here to tolerate deviant servers. */
|
||||
if(ftpcode / 100 != 2) {
|
||||
/* the command failed */
|
||||
|
||||
if(EPRT == fcmd) {
|
||||
@ -2714,7 +2736,7 @@ static CURLcode ftp_statemach_act(struct connectdata *conn)
|
||||
set a valid level */
|
||||
Curl_sec_request_prot(conn, data->set.str[STRING_KRB_LEVEL]);
|
||||
|
||||
if(Curl_sec_login(conn) != CURLE_OK)
|
||||
if(Curl_sec_login(conn))
|
||||
infof(data, "Logging in with password in cleartext!\n");
|
||||
else
|
||||
infof(data, "Authentication successful\n");
|
||||
@ -2765,7 +2787,7 @@ static CURLcode ftp_statemach_act(struct connectdata *conn)
|
||||
if((ftpcode == 234) || (ftpcode == 334)) {
|
||||
/* Curl_ssl_connect is BLOCKING */
|
||||
result = Curl_ssl_connect(conn, FIRSTSOCKET);
|
||||
if(CURLE_OK == result) {
|
||||
if(!result) {
|
||||
conn->ssl[SECONDARYSOCKET].use = FALSE; /* clear-text data */
|
||||
result = ftp_state_user(conn);
|
||||
}
|
||||
@ -2907,7 +2929,7 @@ static CURLcode ftp_statemach_act(struct connectdata *conn)
|
||||
if(!ftpc->server_os && dir[0] != '/') {
|
||||
|
||||
result = Curl_pp_sendf(&ftpc->pp, "%s", "SYST");
|
||||
if(result != CURLE_OK) {
|
||||
if(result) {
|
||||
free(dir);
|
||||
return result;
|
||||
}
|
||||
@ -2960,7 +2982,7 @@ static CURLcode ftp_statemach_act(struct connectdata *conn)
|
||||
if(strequal(os, "OS/400")) {
|
||||
/* Force OS400 name format 1. */
|
||||
result = Curl_pp_sendf(&ftpc->pp, "%s", "SITE NAMEFMT 1");
|
||||
if(result != CURLE_OK) {
|
||||
if(result) {
|
||||
free(os);
|
||||
return result;
|
||||
}
|
||||
@ -3254,7 +3276,6 @@ static CURLcode ftp_done(struct connectdata *conn, CURLcode status,
|
||||
}
|
||||
|
||||
/* now store a copy of the directory we are in */
|
||||
if(ftpc->prevpath)
|
||||
free(ftpc->prevpath);
|
||||
|
||||
if(data->set.wildcardmatch) {
|
||||
@ -3304,7 +3325,7 @@ static CURLcode ftp_done(struct connectdata *conn, CURLcode status,
|
||||
/* shut down the socket to inform the server we're done */
|
||||
|
||||
#ifdef _WIN32_WCE
|
||||
shutdown(conn->sock[SECONDARYSOCKET],2); /* SD_BOTH */
|
||||
shutdown(conn->sock[SECONDARYSOCKET], 2); /* SD_BOTH */
|
||||
#endif
|
||||
|
||||
if(conn->sock[SECONDARYSOCKET] != CURL_SOCKET_BAD) {
|
||||
@ -3627,7 +3648,7 @@ static CURLcode ftp_do_more(struct connectdata *conn, int *completep)
|
||||
if(conn->tunnel_state[SECONDARYSOCKET] == TUNNEL_CONNECT) {
|
||||
/* As we're in TUNNEL_CONNECT state now, we know the proxy name and port
|
||||
aren't used so we blank their arguments. TODO: make this nicer */
|
||||
result = Curl_proxyCONNECT(conn, SECONDARYSOCKET, NULL, 0);
|
||||
result = Curl_proxyCONNECT(conn, SECONDARYSOCKET, NULL, 0, FALSE);
|
||||
|
||||
return result;
|
||||
}
|
||||
@ -3702,6 +3723,12 @@ static CURLcode ftp_do_more(struct connectdata *conn, int *completep)
|
||||
return result;
|
||||
|
||||
result = ftp_multi_statemach(conn, &complete);
|
||||
if(ftpc->wait_data_conn)
|
||||
/* if we reach the end of the FTP state machine here, *complete will be
|
||||
TRUE but so is ftpc->wait_data_conn, which says we need to wait for
|
||||
the data connection and therefore we're not actually complete */
|
||||
*completep = 0;
|
||||
else
|
||||
*completep = (int)complete;
|
||||
}
|
||||
else {
|
||||
@ -3736,7 +3763,7 @@ static CURLcode ftp_do_more(struct connectdata *conn, int *completep)
|
||||
return result;
|
||||
}
|
||||
|
||||
if((result == CURLE_OK) && (ftp->transfer != FTPTRANSFER_BODY))
|
||||
if(!result && (ftp->transfer != FTPTRANSFER_BODY))
|
||||
/* no data to transfer. FIX: it feels like a kludge to have this here
|
||||
too! */
|
||||
Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
|
||||
@ -3801,7 +3828,7 @@ static void wc_data_dtor(void *ptr)
|
||||
struct ftp_wc_tmpdata *tmp = ptr;
|
||||
if(tmp)
|
||||
Curl_ftp_parselist_data_free(&tmp->parser);
|
||||
Curl_safefree(tmp);
|
||||
free(tmp);
|
||||
}
|
||||
|
||||
static CURLcode init_wc_data(struct connectdata *conn)
|
||||
@ -3809,7 +3836,7 @@ static CURLcode init_wc_data(struct connectdata *conn)
|
||||
char *last_slash;
|
||||
char *path = conn->data->state.path;
|
||||
struct WildcardData *wildcard = &(conn->data->wildcard);
|
||||
CURLcode ret = CURLE_OK;
|
||||
CURLcode result = CURLE_OK;
|
||||
struct ftp_wc_tmpdata *ftp_tmp;
|
||||
|
||||
last_slash = strrchr(conn->data->state.path, '/');
|
||||
@ -3817,8 +3844,8 @@ static CURLcode init_wc_data(struct connectdata *conn)
|
||||
last_slash++;
|
||||
if(last_slash[0] == '\0') {
|
||||
wildcard->state = CURLWC_CLEAN;
|
||||
ret = ftp_parse_url_path(conn);
|
||||
return ret;
|
||||
result = ftp_parse_url_path(conn);
|
||||
return result;
|
||||
}
|
||||
else {
|
||||
wildcard->pattern = strdup(last_slash);
|
||||
@ -3836,8 +3863,8 @@ static CURLcode init_wc_data(struct connectdata *conn)
|
||||
}
|
||||
else { /* only list */
|
||||
wildcard->state = CURLWC_CLEAN;
|
||||
ret = ftp_parse_url_path(conn);
|
||||
return ret;
|
||||
result = ftp_parse_url_path(conn);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@ -3855,7 +3882,7 @@ static CURLcode init_wc_data(struct connectdata *conn)
|
||||
ftp_tmp->parser = Curl_ftp_parselist_data_alloc();
|
||||
if(!ftp_tmp->parser) {
|
||||
Curl_safefree(wildcard->pattern);
|
||||
Curl_safefree(ftp_tmp);
|
||||
free(ftp_tmp);
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
@ -3867,13 +3894,13 @@ static CURLcode init_wc_data(struct connectdata *conn)
|
||||
conn->data->set.ftp_filemethod = FTPFILE_MULTICWD;
|
||||
|
||||
/* try to parse ftp url */
|
||||
ret = ftp_parse_url_path(conn);
|
||||
if(ret) {
|
||||
result = ftp_parse_url_path(conn);
|
||||
if(result) {
|
||||
Curl_safefree(wildcard->pattern);
|
||||
wildcard->tmp_dtor(wildcard->tmp);
|
||||
wildcard->tmp_dtor = ZERO_NULL;
|
||||
wildcard->tmp = NULL;
|
||||
return ret;
|
||||
return result;
|
||||
}
|
||||
|
||||
wildcard->path = strdup(conn->data->state.path);
|
||||
@ -3902,16 +3929,16 @@ static CURLcode init_wc_data(struct connectdata *conn)
|
||||
static CURLcode wc_statemach(struct connectdata *conn)
|
||||
{
|
||||
struct WildcardData * const wildcard = &(conn->data->wildcard);
|
||||
CURLcode ret = CURLE_OK;
|
||||
CURLcode result = CURLE_OK;
|
||||
|
||||
switch (wildcard->state) {
|
||||
case CURLWC_INIT:
|
||||
ret = init_wc_data(conn);
|
||||
result = init_wc_data(conn);
|
||||
if(wildcard->state == CURLWC_CLEAN)
|
||||
/* only listing! */
|
||||
break;
|
||||
else
|
||||
wildcard->state = ret ? CURLWC_ERROR : CURLWC_MATCHING;
|
||||
wildcard->state = result ? CURLWC_ERROR : CURLWC_MATCHING;
|
||||
break;
|
||||
|
||||
case CURLWC_MATCHING: {
|
||||
@ -3975,10 +4002,9 @@ static CURLcode wc_statemach(struct connectdata *conn)
|
||||
if(finfo->flags & CURLFINFOFLAG_KNOWN_SIZE)
|
||||
ftpc->known_filesize = finfo->size;
|
||||
|
||||
ret = ftp_parse_url_path(conn);
|
||||
if(ret) {
|
||||
return ret;
|
||||
}
|
||||
result = ftp_parse_url_path(conn);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
/* we don't need the Curl_fileinfo of first file anymore */
|
||||
Curl_llist_remove(wildcard->filelist, wildcard->filelist->head, NULL);
|
||||
@ -4002,11 +4028,11 @@ static CURLcode wc_statemach(struct connectdata *conn)
|
||||
|
||||
case CURLWC_CLEAN: {
|
||||
struct ftp_wc_tmpdata *ftp_tmp = wildcard->tmp;
|
||||
ret = CURLE_OK;
|
||||
if(ftp_tmp) {
|
||||
ret = Curl_ftp_parselist_geterror(ftp_tmp->parser);
|
||||
}
|
||||
wildcard->state = ret ? CURLWC_ERROR : CURLWC_DONE;
|
||||
result = CURLE_OK;
|
||||
if(ftp_tmp)
|
||||
result = Curl_ftp_parselist_geterror(ftp_tmp->parser);
|
||||
|
||||
wildcard->state = result ? CURLWC_ERROR : CURLWC_DONE;
|
||||
} break;
|
||||
|
||||
case CURLWC_DONE:
|
||||
@ -4014,7 +4040,7 @@ static CURLcode wc_statemach(struct connectdata *conn)
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
return result;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
@ -4028,31 +4054,31 @@ static CURLcode wc_statemach(struct connectdata *conn)
|
||||
*/
|
||||
static CURLcode ftp_do(struct connectdata *conn, bool *done)
|
||||
{
|
||||
CURLcode retcode = CURLE_OK;
|
||||
CURLcode result = CURLE_OK;
|
||||
struct ftp_conn *ftpc = &conn->proto.ftpc;
|
||||
|
||||
*done = FALSE; /* default to false */
|
||||
ftpc->wait_data_conn = FALSE; /* default to no such wait */
|
||||
|
||||
if(conn->data->set.wildcardmatch) {
|
||||
retcode = wc_statemach(conn);
|
||||
result = wc_statemach(conn);
|
||||
if(conn->data->wildcard.state == CURLWC_SKIP ||
|
||||
conn->data->wildcard.state == CURLWC_DONE) {
|
||||
/* do not call ftp_regular_transfer */
|
||||
return CURLE_OK;
|
||||
}
|
||||
if(retcode) /* error, loop or skipping the file */
|
||||
return retcode;
|
||||
if(result) /* error, loop or skipping the file */
|
||||
return result;
|
||||
}
|
||||
else { /* no wildcard FSM needed */
|
||||
retcode = ftp_parse_url_path(conn);
|
||||
if(retcode)
|
||||
return retcode;
|
||||
result = ftp_parse_url_path(conn);
|
||||
if(result)
|
||||
return result;
|
||||
}
|
||||
|
||||
retcode = ftp_regular_transfer(conn, done);
|
||||
result = ftp_regular_transfer(conn, done);
|
||||
|
||||
return retcode;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@ -4064,7 +4090,7 @@ CURLcode Curl_ftpsendf(struct connectdata *conn,
|
||||
char s[SBUF_SIZE];
|
||||
size_t write_len;
|
||||
char *sptr=s;
|
||||
CURLcode res = CURLE_OK;
|
||||
CURLcode result = CURLE_OK;
|
||||
#ifdef HAVE_GSSAPI
|
||||
enum protection_level data_sec = conn->data_prot;
|
||||
#endif
|
||||
@ -4079,23 +4105,23 @@ CURLcode Curl_ftpsendf(struct connectdata *conn,
|
||||
|
||||
bytes_written=0;
|
||||
|
||||
res = Curl_convert_to_network(conn->data, s, write_len);
|
||||
result = Curl_convert_to_network(conn->data, s, write_len);
|
||||
/* Curl_convert_to_network calls failf if unsuccessful */
|
||||
if(res)
|
||||
return(res);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
for(;;) {
|
||||
#ifdef HAVE_GSSAPI
|
||||
conn->data_prot = PROT_CMD;
|
||||
#endif
|
||||
res = Curl_write(conn, conn->sock[FIRSTSOCKET], sptr, write_len,
|
||||
result = Curl_write(conn, conn->sock[FIRSTSOCKET], sptr, write_len,
|
||||
&bytes_written);
|
||||
#ifdef HAVE_GSSAPI
|
||||
DEBUGASSERT(data_sec > PROT_NONE && data_sec < PROT_LAST);
|
||||
conn->data_prot = data_sec;
|
||||
#endif
|
||||
|
||||
if(CURLE_OK != res)
|
||||
if(result)
|
||||
break;
|
||||
|
||||
if(conn->data->set.verbose)
|
||||
@ -4110,7 +4136,7 @@ CURLcode Curl_ftpsendf(struct connectdata *conn,
|
||||
break;
|
||||
}
|
||||
|
||||
return res;
|
||||
return result;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
@ -4181,14 +4207,10 @@ static CURLcode ftp_disconnect(struct connectdata *conn, bool dead_connection)
|
||||
}
|
||||
|
||||
freedirs(ftpc);
|
||||
if(ftpc->prevpath) {
|
||||
free(ftpc->prevpath);
|
||||
ftpc->prevpath = NULL;
|
||||
}
|
||||
if(ftpc->server_os) {
|
||||
free(ftpc->server_os);
|
||||
ftpc->server_os = NULL;
|
||||
}
|
||||
|
||||
Curl_pp_disconnect(pp);
|
||||
|
||||
@ -4470,8 +4492,8 @@ CURLcode ftp_regular_transfer(struct connectdata *conn,
|
||||
|
||||
Curl_pgrsSetUploadCounter(data, 0);
|
||||
Curl_pgrsSetDownloadCounter(data, 0);
|
||||
Curl_pgrsSetUploadSize(data, 0);
|
||||
Curl_pgrsSetDownloadSize(data, 0);
|
||||
Curl_pgrsSetUploadSize(data, -1);
|
||||
Curl_pgrsSetDownloadSize(data, -1);
|
||||
|
||||
ftpc->ctl_valid = TRUE; /* starts good */
|
||||
|
||||
@ -4479,7 +4501,7 @@ CURLcode ftp_regular_transfer(struct connectdata *conn,
|
||||
&connected, /* have we connected after PASV/PORT */
|
||||
dophase_done); /* all commands in the DO-phase done? */
|
||||
|
||||
if(CURLE_OK == result) {
|
||||
if(!result) {
|
||||
|
||||
if(!*dophase_done)
|
||||
/* the DO phase has not completed yet */
|
||||
|
@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -147,10 +147,9 @@ struct ftp_conn {
|
||||
curl_off_t known_filesize; /* file size is different from -1, if wildcard
|
||||
LIST parsing was done and wc_statemach set
|
||||
it */
|
||||
/* newhost must be able to hold a full IP-style address in ASCII, which
|
||||
in the IPv6 case means 5*8-1 = 39 letters */
|
||||
#define NEWHOST_BUFSIZE 48
|
||||
char newhost[NEWHOST_BUFSIZE]; /* this is the pair to connect the DATA... */
|
||||
/* newhost is the (allocated) IP addr or host name to connect the data
|
||||
connection to */
|
||||
char *newhost; /* this is the pair to connect the DATA... */
|
||||
unsigned short newport; /* connection to */
|
||||
|
||||
};
|
||||
|
@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -23,13 +23,13 @@
|
||||
/**
|
||||
* Now implemented:
|
||||
*
|
||||
* 1) UNIX version 1
|
||||
* 1) Unix version 1
|
||||
* drwxr-xr-x 1 user01 ftp 512 Jan 29 23:32 prog
|
||||
* 2) UNIX version 2
|
||||
* 2) Unix version 2
|
||||
* drwxr-xr-x 1 user01 ftp 512 Jan 29 1997 prog
|
||||
* 3) UNIX version 3
|
||||
* 3) Unix version 3
|
||||
* drwxr-xr-x 1 1 1 512 Jan 29 23:32 prog
|
||||
* 4) UNIX symlink
|
||||
* 4) Unix symlink
|
||||
* lrwxr-xr-x 1 user01 ftp 512 Jan 29 23:32 prog -> prog2000
|
||||
* 5) DOS style
|
||||
* 01-29-97 11:32PM <DIR> prog
|
||||
@ -49,10 +49,6 @@
|
||||
#include "ftp.h"
|
||||
#include "ftplistparser.h"
|
||||
#include "curl_fnmatch.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"
|
||||
@ -191,7 +187,6 @@ struct ftp_parselist_data *Curl_ftp_parselist_data_alloc(void)
|
||||
|
||||
void Curl_ftp_parselist_data_free(struct ftp_parselist_data **pl_data)
|
||||
{
|
||||
if(*pl_data)
|
||||
free(*pl_data);
|
||||
*pl_data = NULL;
|
||||
}
|
||||
@ -365,7 +360,7 @@ size_t Curl_ftp_parselist(char *buffer, size_t size, size_t nmemb,
|
||||
struct ftp_parselist_data *parser = tmpdata->parser;
|
||||
struct curl_fileinfo *finfo;
|
||||
unsigned long i = 0;
|
||||
CURLcode rc;
|
||||
CURLcode result;
|
||||
|
||||
if(parser->error) { /* error in previous call */
|
||||
/* scenario:
|
||||
@ -758,9 +753,9 @@ size_t Curl_ftp_parselist(char *buffer, size_t size, size_t nmemb,
|
||||
finfo->b_data[parser->item_offset + parser->item_length - 1] = 0;
|
||||
parser->offsets.filename = parser->item_offset;
|
||||
parser->state.UNIX.main = PL_UNIX_FILETYPE;
|
||||
rc = ftp_pl_insert_finfo(conn, finfo);
|
||||
if(rc) {
|
||||
PL_ERROR(conn, rc);
|
||||
result = ftp_pl_insert_finfo(conn, finfo);
|
||||
if(result) {
|
||||
PL_ERROR(conn, result);
|
||||
return bufflen;
|
||||
}
|
||||
}
|
||||
@ -770,9 +765,9 @@ size_t Curl_ftp_parselist(char *buffer, size_t size, size_t nmemb,
|
||||
finfo->b_data[parser->item_offset + parser->item_length] = 0;
|
||||
parser->offsets.filename = parser->item_offset;
|
||||
parser->state.UNIX.main = PL_UNIX_FILETYPE;
|
||||
rc = ftp_pl_insert_finfo(conn, finfo);
|
||||
if(rc) {
|
||||
PL_ERROR(conn, rc);
|
||||
result = ftp_pl_insert_finfo(conn, finfo);
|
||||
if(result) {
|
||||
PL_ERROR(conn, result);
|
||||
return bufflen;
|
||||
}
|
||||
}
|
||||
@ -866,9 +861,9 @@ size_t Curl_ftp_parselist(char *buffer, size_t size, size_t nmemb,
|
||||
else if(c == '\n') {
|
||||
finfo->b_data[parser->item_offset + parser->item_length - 1] = 0;
|
||||
parser->offsets.symlink_target = parser->item_offset;
|
||||
rc = ftp_pl_insert_finfo(conn, finfo);
|
||||
if(rc) {
|
||||
PL_ERROR(conn, rc);
|
||||
result = ftp_pl_insert_finfo(conn, finfo);
|
||||
if(result) {
|
||||
PL_ERROR(conn, result);
|
||||
return bufflen;
|
||||
}
|
||||
parser->state.UNIX.main = PL_UNIX_FILETYPE;
|
||||
@ -878,9 +873,9 @@ size_t Curl_ftp_parselist(char *buffer, size_t size, size_t nmemb,
|
||||
if(c == '\n') {
|
||||
finfo->b_data[parser->item_offset + parser->item_length - 1] = 0;
|
||||
parser->offsets.symlink_target = parser->item_offset;
|
||||
rc = ftp_pl_insert_finfo(conn, finfo);
|
||||
if(rc) {
|
||||
PL_ERROR(conn, rc);
|
||||
result = ftp_pl_insert_finfo(conn, finfo);
|
||||
if(result) {
|
||||
PL_ERROR(conn, result);
|
||||
return bufflen;
|
||||
}
|
||||
parser->state.UNIX.main = PL_UNIX_FILETYPE;
|
||||
@ -1011,9 +1006,9 @@ size_t Curl_ftp_parselist(char *buffer, size_t size, size_t nmemb,
|
||||
parser->offsets.filename = parser->item_offset;
|
||||
finfo->b_data[finfo->b_used - 1] = 0;
|
||||
parser->offsets.filename = parser->item_offset;
|
||||
rc = ftp_pl_insert_finfo(conn, finfo);
|
||||
if(rc) {
|
||||
PL_ERROR(conn, rc);
|
||||
result = ftp_pl_insert_finfo(conn, finfo);
|
||||
if(result) {
|
||||
PL_ERROR(conn, result);
|
||||
return bufflen;
|
||||
}
|
||||
parser->state.NT.main = PL_WINNT_DATE;
|
||||
@ -1023,9 +1018,9 @@ size_t Curl_ftp_parselist(char *buffer, size_t size, size_t nmemb,
|
||||
case PL_WINNT_FILENAME_WINEOL:
|
||||
if(c == '\n') {
|
||||
parser->offsets.filename = parser->item_offset;
|
||||
rc = ftp_pl_insert_finfo(conn, finfo);
|
||||
if(rc) {
|
||||
PL_ERROR(conn, rc);
|
||||
result = ftp_pl_insert_finfo(conn, finfo);
|
||||
if(result) {
|
||||
PL_ERROR(conn, result);
|
||||
return bufflen;
|
||||
}
|
||||
parser->state.NT.main = PL_WINNT_DATE;
|
||||
@ -1041,7 +1036,7 @@ size_t Curl_ftp_parselist(char *buffer, size_t size, size_t nmemb,
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return bufflen+1;
|
||||
return bufflen + 1;
|
||||
}
|
||||
|
||||
i++;
|
||||
|
@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -27,12 +27,12 @@
|
||||
#include "urldata.h"
|
||||
#include "getinfo.h"
|
||||
|
||||
#include "curl_memory.h"
|
||||
#include "vtls/vtls.h"
|
||||
#include "connect.h" /* Curl_getconnectinfo() */
|
||||
#include "progress.h"
|
||||
|
||||
/* Make this the last #include */
|
||||
/* The last #include files should be: */
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
/*
|
||||
@ -42,7 +42,7 @@
|
||||
CURLcode Curl_initinfo(struct SessionHandle *data)
|
||||
{
|
||||
struct Progress *pro = &data->progress;
|
||||
struct PureInfo *info =&data->info;
|
||||
struct PureInfo *info = &data->info;
|
||||
|
||||
pro->t_nslookup = 0;
|
||||
pro->t_connect = 0;
|
||||
@ -58,7 +58,6 @@ CURLcode Curl_initinfo(struct SessionHandle *data)
|
||||
info->filetime = -1; /* -1 is an illegal time and thus means unknown */
|
||||
info->timecond = FALSE;
|
||||
|
||||
if(info->contenttype)
|
||||
free(info->contenttype);
|
||||
info->contenttype = NULL;
|
||||
|
||||
@ -114,8 +113,9 @@ static CURLcode getinfo_char(struct SessionHandle *data, CURLINFO info,
|
||||
break;
|
||||
|
||||
default:
|
||||
return CURLE_BAD_FUNCTION_ARGUMENT;
|
||||
return CURLE_UNKNOWN_OPTION;
|
||||
}
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
@ -200,8 +200,9 @@ static CURLcode getinfo_long(struct SessionHandle *data, CURLINFO info,
|
||||
break;
|
||||
|
||||
default:
|
||||
return CURLE_BAD_FUNCTION_ARGUMENT;
|
||||
return CURLE_UNKNOWN_OPTION;
|
||||
}
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
@ -252,8 +253,9 @@ static CURLcode getinfo_double(struct SessionHandle *data, CURLINFO info,
|
||||
break;
|
||||
|
||||
default:
|
||||
return CURLE_BAD_FUNCTION_ARGUMENT;
|
||||
return CURLE_UNKNOWN_OPTION;
|
||||
}
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
@ -261,8 +263,8 @@ static CURLcode getinfo_slist(struct SessionHandle *data, CURLINFO info,
|
||||
struct curl_slist **param_slistp)
|
||||
{
|
||||
union {
|
||||
struct curl_certinfo * to_certinfo;
|
||||
struct curl_slist * to_slist;
|
||||
struct curl_certinfo *to_certinfo;
|
||||
struct curl_slist *to_slist;
|
||||
} ptr;
|
||||
|
||||
switch(info) {
|
||||
@ -288,7 +290,7 @@ static CURLcode getinfo_slist(struct SessionHandle *data, CURLINFO info,
|
||||
void *internals = NULL;
|
||||
|
||||
*tsip = tsi;
|
||||
tsi->backend = CURLSSLBACKEND_NONE;
|
||||
tsi->backend = Curl_ssl_backend();
|
||||
tsi->internals = NULL;
|
||||
|
||||
if(!conn)
|
||||
@ -303,7 +305,7 @@ static CURLcode getinfo_slist(struct SessionHandle *data, CURLINFO info,
|
||||
break; /* no SSL session found */
|
||||
|
||||
/* Return the TLS session information from the relevant backend */
|
||||
#ifdef USE_SSLEAY
|
||||
#ifdef USE_OPENSSL
|
||||
internals = conn->ssl[sockindex].ctx;
|
||||
#endif
|
||||
#ifdef USE_GNUTLS
|
||||
@ -312,41 +314,62 @@ static CURLcode getinfo_slist(struct SessionHandle *data, CURLINFO info,
|
||||
#ifdef USE_NSS
|
||||
internals = conn->ssl[sockindex].handle;
|
||||
#endif
|
||||
#ifdef USE_QSOSSL
|
||||
internals = conn->ssl[sockindex].handle;
|
||||
#endif
|
||||
#ifdef USE_GSKIT
|
||||
internals = conn->ssl[sockindex].handle;
|
||||
#endif
|
||||
if(internals) {
|
||||
tsi->backend = Curl_ssl_backend();
|
||||
tsi->internals = internals;
|
||||
}
|
||||
/* NOTE: For other SSL backends, it is not immediately clear what data
|
||||
to return from 'struct ssl_connect_data'; thus, for now we keep the
|
||||
backend as CURLSSLBACKEND_NONE in those cases, which should be
|
||||
interpreted as "not supported" */
|
||||
to return from 'struct ssl_connect_data'; thus we keep 'internals' to
|
||||
NULL which should be interpreted as "not supported" */
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return CURLE_BAD_FUNCTION_ARGUMENT;
|
||||
return CURLE_UNKNOWN_OPTION;
|
||||
}
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
static CURLcode getinfo_socket(struct SessionHandle *data, CURLINFO info,
|
||||
curl_socket_t *param_socketp)
|
||||
{
|
||||
curl_socket_t sockfd;
|
||||
|
||||
switch(info) {
|
||||
case CURLINFO_ACTIVESOCKET:
|
||||
sockfd = Curl_getconnectinfo(data, NULL);
|
||||
|
||||
/* note: this is not a good conversion for systems with 64 bit sockets and
|
||||
32 bit longs */
|
||||
if(sockfd != CURL_SOCKET_BAD)
|
||||
*param_socketp = sockfd;
|
||||
else
|
||||
/* this interface is documented to return -1 in case of badness, which
|
||||
may not be the same as the CURL_SOCKET_BAD value */
|
||||
*param_socketp = -1;
|
||||
break;
|
||||
default:
|
||||
return CURLE_UNKNOWN_OPTION;
|
||||
}
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
CURLcode Curl_getinfo(struct SessionHandle *data, CURLINFO info, ...)
|
||||
{
|
||||
va_list arg;
|
||||
long *param_longp=NULL;
|
||||
double *param_doublep=NULL;
|
||||
char **param_charp=NULL;
|
||||
struct curl_slist **param_slistp=NULL;
|
||||
long *param_longp = NULL;
|
||||
double *param_doublep = NULL;
|
||||
char **param_charp = NULL;
|
||||
struct curl_slist **param_slistp = NULL;
|
||||
curl_socket_t *param_socketp = NULL;
|
||||
int type;
|
||||
/* default return code is to error out! */
|
||||
CURLcode ret = CURLE_BAD_FUNCTION_ARGUMENT;
|
||||
CURLcode result = CURLE_UNKNOWN_OPTION;
|
||||
|
||||
if(!data)
|
||||
return ret;
|
||||
return result;
|
||||
|
||||
va_start(arg, info);
|
||||
|
||||
@ -354,28 +377,34 @@ CURLcode Curl_getinfo(struct SessionHandle *data, CURLINFO info, ...)
|
||||
switch(type) {
|
||||
case CURLINFO_STRING:
|
||||
param_charp = va_arg(arg, char **);
|
||||
if(NULL != param_charp)
|
||||
ret = getinfo_char(data, info, param_charp);
|
||||
if(param_charp)
|
||||
result = getinfo_char(data, info, param_charp);
|
||||
break;
|
||||
case CURLINFO_LONG:
|
||||
param_longp = va_arg(arg, long *);
|
||||
if(NULL != param_longp)
|
||||
ret = getinfo_long(data, info, param_longp);
|
||||
if(param_longp)
|
||||
result = getinfo_long(data, info, param_longp);
|
||||
break;
|
||||
case CURLINFO_DOUBLE:
|
||||
param_doublep = va_arg(arg, double *);
|
||||
if(NULL != param_doublep)
|
||||
ret = getinfo_double(data, info, param_doublep);
|
||||
if(param_doublep)
|
||||
result = getinfo_double(data, info, param_doublep);
|
||||
break;
|
||||
case CURLINFO_SLIST:
|
||||
param_slistp = va_arg(arg, struct curl_slist **);
|
||||
if(NULL != param_slistp)
|
||||
ret = getinfo_slist(data, info, param_slistp);
|
||||
if(param_slistp)
|
||||
result = getinfo_slist(data, info, param_slistp);
|
||||
break;
|
||||
case CURLINFO_SOCKET:
|
||||
param_socketp = va_arg(arg, curl_socket_t *);
|
||||
if(param_socketp)
|
||||
result = getinfo_socket(data, info, param_socketp);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
va_end(arg);
|
||||
return ret;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -36,10 +36,6 @@
|
||||
#include "select.h"
|
||||
#include "url.h"
|
||||
#include "warnless.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"
|
||||
@ -87,16 +83,18 @@ static CURLcode gopher_do(struct connectdata *conn, bool *done)
|
||||
char *sel;
|
||||
char *sel_org = NULL;
|
||||
ssize_t amount, k;
|
||||
int len;
|
||||
|
||||
*done = TRUE; /* unconditionally */
|
||||
|
||||
/* Create selector. Degenerate cases: / and /1 => convert to "" */
|
||||
if(strlen(path) <= 2)
|
||||
if(strlen(path) <= 2) {
|
||||
sel = (char *)"";
|
||||
len = (int)strlen(sel);
|
||||
}
|
||||
else {
|
||||
char *newp;
|
||||
size_t j, i;
|
||||
int len;
|
||||
|
||||
/* Otherwise, drop / and the first character (i.e., item type) ... */
|
||||
newp = path;
|
||||
@ -117,14 +115,14 @@ static CURLcode gopher_do(struct connectdata *conn, bool *done)
|
||||
|
||||
/* We use Curl_write instead of Curl_sendf to make sure the entire buffer is
|
||||
sent, which could be sizeable with long selectors. */
|
||||
k = curlx_uztosz(strlen(sel));
|
||||
k = curlx_uztosz(len);
|
||||
|
||||
for(;;) {
|
||||
result = Curl_write(conn, sockfd, sel, k, &amount);
|
||||
if(CURLE_OK == result) { /* Which may not have written it all! */
|
||||
if(!result) { /* Which may not have written it all! */
|
||||
result = Curl_client_write(conn, CLIENTWRITE_HEADER, sel, amount);
|
||||
if(result) {
|
||||
Curl_safefree(sel_org);
|
||||
free(sel_org);
|
||||
return result;
|
||||
}
|
||||
k -= amount;
|
||||
@ -134,7 +132,7 @@ static CURLcode gopher_do(struct connectdata *conn, bool *done)
|
||||
}
|
||||
else {
|
||||
failf(data, "Failed sending Gopher request");
|
||||
Curl_safefree(sel_org);
|
||||
free(sel_org);
|
||||
return result;
|
||||
}
|
||||
/* Don't busyloop. The entire loop thing is a work-around as it causes a
|
||||
@ -149,12 +147,12 @@ static CURLcode gopher_do(struct connectdata *conn, bool *done)
|
||||
Curl_socket_ready(CURL_SOCKET_BAD, sockfd, 100);
|
||||
}
|
||||
|
||||
Curl_safefree(sel_org);
|
||||
free(sel_org);
|
||||
|
||||
/* We can use Curl_sendf to send the terminal \r\n relatively safely and
|
||||
save allocing another string/doing another _write loop. */
|
||||
result = Curl_sendf(sockfd, conn, "\r\n");
|
||||
if(result != CURLE_OK) {
|
||||
if(result) {
|
||||
failf(data, "Failed sending Gopher request");
|
||||
return result;
|
||||
}
|
||||
|
@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -24,10 +24,6 @@
|
||||
|
||||
#include "hash.h"
|
||||
#include "llist.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"
|
||||
@ -93,32 +89,6 @@ Curl_hash_init(struct curl_hash *h,
|
||||
}
|
||||
}
|
||||
|
||||
struct curl_hash *
|
||||
Curl_hash_alloc(int slots,
|
||||
hash_function hfunc,
|
||||
comp_function comparator,
|
||||
curl_hash_dtor dtor)
|
||||
{
|
||||
struct curl_hash *h;
|
||||
|
||||
if(!slots || !hfunc || !comparator ||!dtor) {
|
||||
return NULL; /* failure */
|
||||
}
|
||||
|
||||
h = malloc(sizeof(struct curl_hash));
|
||||
if(h) {
|
||||
if(Curl_hash_init(h, slots, hfunc, comparator, dtor)) {
|
||||
/* failure */
|
||||
free(h);
|
||||
h = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return h;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static struct curl_hash_element *
|
||||
mk_hash_element(const void *key, size_t key_len, const void *p)
|
||||
{
|
||||
@ -242,8 +212,11 @@ Curl_hash_apply(curl_hash *h, void *user,
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Destroys all the entries in the given hash and resets its attributes,
|
||||
* prepping the given hash for [static|dynamic] deallocation.
|
||||
*/
|
||||
void
|
||||
Curl_hash_clean(struct curl_hash *h)
|
||||
Curl_hash_destroy(struct curl_hash *h)
|
||||
{
|
||||
int i;
|
||||
|
||||
@ -257,6 +230,17 @@ Curl_hash_clean(struct curl_hash *h)
|
||||
h->slots = 0;
|
||||
}
|
||||
|
||||
/* Removes all the entries in the given hash.
|
||||
*
|
||||
* @unittest: 1602
|
||||
*/
|
||||
void
|
||||
Curl_hash_clean(struct curl_hash *h)
|
||||
{
|
||||
Curl_hash_clean_with_criterium(h, NULL, NULL);
|
||||
}
|
||||
|
||||
/* Cleans all entries that pass the comp function criteria. */
|
||||
void
|
||||
Curl_hash_clean_with_criterium(struct curl_hash *h, void *user,
|
||||
int (*comp)(void *, void *))
|
||||
@ -276,7 +260,7 @@ Curl_hash_clean_with_criterium(struct curl_hash *h, void *user,
|
||||
struct curl_hash_element *he = le->ptr;
|
||||
lnext = le->next;
|
||||
/* ask the callback function if we shall remove this entry or not */
|
||||
if(comp(user, he->ptr)) {
|
||||
if(comp == NULL || comp(user, he->ptr)) {
|
||||
Curl_llist_remove(list, le, (void *) h);
|
||||
--h->size; /* one less entry in the hash now */
|
||||
}
|
||||
@ -285,17 +269,6 @@ Curl_hash_clean_with_criterium(struct curl_hash *h, void *user,
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Curl_hash_destroy(struct curl_hash *h)
|
||||
{
|
||||
if(!h)
|
||||
return;
|
||||
|
||||
Curl_hash_clean(h);
|
||||
|
||||
free(h);
|
||||
}
|
||||
|
||||
size_t Curl_hash_str(void* key, size_t key_length, size_t slots_num)
|
||||
{
|
||||
const char* key_str = (const char *) key;
|
||||
@ -310,16 +283,11 @@ size_t Curl_hash_str(void* key, size_t key_length, size_t slots_num)
|
||||
return (h % slots_num);
|
||||
}
|
||||
|
||||
size_t Curl_str_key_compare(void*k1, size_t key1_len, void*k2, size_t key2_len)
|
||||
size_t Curl_str_key_compare(void *k1, size_t key1_len,
|
||||
void *k2, size_t key2_len)
|
||||
{
|
||||
char *key1 = (char *)k1;
|
||||
char *key2 = (char *)k2;
|
||||
|
||||
if(key1_len == key2_len &&
|
||||
*key1 == *key2 &&
|
||||
memcmp(key1, key2, key1_len) == 0) {
|
||||
if((key1_len == key2_len) && !memcmp(k1, k2, key1_len))
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -74,22 +74,16 @@ int Curl_hash_init(struct curl_hash *h,
|
||||
comp_function comparator,
|
||||
curl_hash_dtor dtor);
|
||||
|
||||
struct curl_hash *Curl_hash_alloc(int slots,
|
||||
hash_function hfunc,
|
||||
comp_function comparator,
|
||||
curl_hash_dtor dtor);
|
||||
|
||||
void *Curl_hash_add(struct curl_hash *h, void *key, size_t key_len, void *p);
|
||||
int Curl_hash_delete(struct curl_hash *h, void *key, size_t key_len);
|
||||
void *Curl_hash_pick(struct curl_hash *, void * key, size_t key_len);
|
||||
void Curl_hash_apply(struct curl_hash *h, void *user,
|
||||
void (*cb)(void *user, void *ptr));
|
||||
int Curl_hash_count(struct curl_hash *h);
|
||||
void Curl_hash_destroy(struct curl_hash *h);
|
||||
void Curl_hash_clean(struct curl_hash *h);
|
||||
void Curl_hash_clean_with_criterium(struct curl_hash *h, void *user,
|
||||
int (*comp)(void *, void *));
|
||||
void Curl_hash_destroy(struct curl_hash *h);
|
||||
|
||||
size_t Curl_hash_str(void* key, size_t key_length, size_t slots_num);
|
||||
size_t Curl_str_key_compare(void*k1, size_t key1_len, void*k2,
|
||||
size_t key2_len);
|
||||
|
@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -27,10 +27,6 @@
|
||||
#ifndef CURL_DISABLE_CRYPTO_AUTH
|
||||
|
||||
#include "curl_hmac.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"
|
||||
|
@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -47,10 +47,6 @@
|
||||
#include "share.h"
|
||||
#include "strerror.h"
|
||||
#include "url.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"
|
||||
@ -75,7 +71,7 @@ CURLcode Curl_addrinfo_callback(struct connectdata *conn,
|
||||
struct Curl_addrinfo *ai)
|
||||
{
|
||||
struct Curl_dns_entry *dns = NULL;
|
||||
CURLcode rc = CURLE_OK;
|
||||
CURLcode result = CURLE_OK;
|
||||
|
||||
conn->async.status = status;
|
||||
|
||||
@ -92,14 +88,14 @@ CURLcode Curl_addrinfo_callback(struct connectdata *conn,
|
||||
if(!dns) {
|
||||
/* failed to store, cleanup and return error */
|
||||
Curl_freeaddrinfo(ai);
|
||||
rc = CURLE_OUT_OF_MEMORY;
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
if(data->share)
|
||||
Curl_share_unlock(data, CURL_LOCK_DATA_DNS);
|
||||
}
|
||||
else {
|
||||
rc = CURLE_OUT_OF_MEMORY;
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
|
||||
@ -110,9 +106,9 @@ CURLcode Curl_addrinfo_callback(struct connectdata *conn,
|
||||
async struct */
|
||||
conn->async.done = TRUE;
|
||||
|
||||
/* ipv4: The input hostent struct will be freed by ares when we return from
|
||||
/* IPv4: The input hostent struct will be freed by ares when we return from
|
||||
this function */
|
||||
return rc;
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Call this function after Curl_connect() has returned async=TRUE and
|
||||
@ -123,21 +119,21 @@ CURLcode Curl_addrinfo_callback(struct connectdata *conn,
|
||||
CURLcode Curl_async_resolved(struct connectdata *conn,
|
||||
bool *protocol_done)
|
||||
{
|
||||
CURLcode code;
|
||||
CURLcode result;
|
||||
|
||||
if(conn->async.dns) {
|
||||
conn->dns_entry = conn->async.dns;
|
||||
conn->async.dns = NULL;
|
||||
}
|
||||
|
||||
code = Curl_setup_conn(conn, protocol_done);
|
||||
result = Curl_setup_conn(conn, protocol_done);
|
||||
|
||||
if(code)
|
||||
if(result)
|
||||
/* We're not allowed to return failure with memory left allocated
|
||||
in the connectdata struct, free those here */
|
||||
Curl_disconnect(conn, FALSE); /* close the connection */
|
||||
|
||||
return code;
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -22,8 +22,7 @@
|
||||
|
||||
#include "curl_setup.h"
|
||||
|
||||
#if defined(USE_SSLEAY) || defined(USE_AXTLS) || defined(USE_QSOSSL) || \
|
||||
defined(USE_GSKIT)
|
||||
#if defined(USE_OPENSSL) || defined(USE_AXTLS) || defined(USE_GSKIT)
|
||||
/* these backends use functions from this file */
|
||||
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
@ -145,4 +144,4 @@ int Curl_cert_hostcheck(const char *match_pattern, const char *hostname)
|
||||
return res;
|
||||
}
|
||||
|
||||
#endif /* SSLEAY or AXTLS or QSOSSL or GSKIT */
|
||||
#endif /* OPENSSL or AXTLS or GSKIT */
|
||||
|
@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -56,10 +56,7 @@
|
||||
#include "url.h"
|
||||
#include "inet_ntop.h"
|
||||
#include "warnless.h"
|
||||
|
||||
#define _MPRINTF_REPLACE /* use our functions only */
|
||||
#include <curl/mprintf.h>
|
||||
|
||||
#include "curl_printf.h"
|
||||
#include "curl_memory.h"
|
||||
/* The last #include file should be: */
|
||||
#include "memdebug.h"
|
||||
@ -98,8 +95,8 @@
|
||||
* hostip.c - method-independent resolver functions and utility functions
|
||||
* hostasyn.c - functions for asynchronous name resolves
|
||||
* hostsyn.c - functions for synchronous name resolves
|
||||
* hostip4.c - ipv4-specific functions
|
||||
* hostip6.c - ipv6-specific functions
|
||||
* hostip4.c - IPv4 specific functions
|
||||
* hostip6.c - IPv6 specific functions
|
||||
*
|
||||
* The two asynchronous name resolver backends are implemented in:
|
||||
* asyn-ares.c - functions for ares-using name resolves
|
||||
@ -140,11 +137,7 @@ struct curl_hash *Curl_global_host_cache_init(void)
|
||||
void Curl_global_host_cache_dtor(void)
|
||||
{
|
||||
if(host_cache_initialized) {
|
||||
/* first make sure that any custom "CURLOPT_RESOLVE" names are
|
||||
cleared off */
|
||||
Curl_hostcache_clean(NULL, &hostname_cache);
|
||||
/* then free the remaining hash completely */
|
||||
Curl_hash_clean(&hostname_cache);
|
||||
Curl_hash_destroy(&hostname_cache);
|
||||
host_cache_initialized = 0;
|
||||
}
|
||||
}
|
||||
@ -237,7 +230,8 @@ hostcache_timestamp_remove(void *datap, void *hc)
|
||||
(struct hostcache_prune_data *) datap;
|
||||
struct Curl_dns_entry *c = (struct Curl_dns_entry *) hc;
|
||||
|
||||
return !c->inuse && (data->now - c->timestamp >= data->cache_timeout);
|
||||
return (0 != c->timestamp)
|
||||
&& (data->now - c->timestamp >= data->cache_timeout);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -283,34 +277,6 @@ void Curl_hostcache_prune(struct SessionHandle *data)
|
||||
Curl_share_unlock(data, CURL_LOCK_DATA_DNS);
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if the entry should be pruned. Assumes a locked cache.
|
||||
*/
|
||||
static int
|
||||
remove_entry_if_stale(struct SessionHandle *data, struct Curl_dns_entry *dns)
|
||||
{
|
||||
struct hostcache_prune_data user;
|
||||
|
||||
if(!dns || (data->set.dns_cache_timeout == -1) || !data->dns.hostcache ||
|
||||
dns->inuse)
|
||||
/* cache forever means never prune, and NULL hostcache means we can't do
|
||||
it, if it still is in use then we leave it */
|
||||
return 0;
|
||||
|
||||
time(&user.now);
|
||||
user.cache_timeout = data->set.dns_cache_timeout;
|
||||
|
||||
if(!hostcache_timestamp_remove(&user,dns) )
|
||||
return 0;
|
||||
|
||||
Curl_hash_clean_with_criterium(data->dns.hostcache,
|
||||
(void *) &user,
|
||||
hostcache_timestamp_remove);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
#ifdef HAVE_SIGSETJMP
|
||||
/* Beware this is a global and unique instance. This is used to store the
|
||||
return address that we can jump back to from inside a signal handler. This
|
||||
@ -318,6 +284,82 @@ remove_entry_if_stale(struct SessionHandle *data, struct Curl_dns_entry *dns)
|
||||
sigjmp_buf curl_jmpenv;
|
||||
#endif
|
||||
|
||||
/* lookup address, returns entry if found and not stale */
|
||||
static struct Curl_dns_entry *
|
||||
fetch_addr(struct connectdata *conn,
|
||||
const char *hostname,
|
||||
int port)
|
||||
{
|
||||
char *entry_id = NULL;
|
||||
struct Curl_dns_entry *dns = NULL;
|
||||
size_t entry_len;
|
||||
struct SessionHandle *data = conn->data;
|
||||
|
||||
/* Create an entry id, based upon the hostname and port */
|
||||
entry_id = create_hostcache_id(hostname, port);
|
||||
/* If we can't create the entry id, fail */
|
||||
if(!entry_id)
|
||||
return dns;
|
||||
|
||||
entry_len = strlen(entry_id);
|
||||
|
||||
/* See if its already in our dns cache */
|
||||
dns = Curl_hash_pick(data->dns.hostcache, entry_id, entry_len+1);
|
||||
|
||||
if(dns && (data->set.dns_cache_timeout != -1)) {
|
||||
/* See whether the returned entry is stale. Done before we release lock */
|
||||
struct hostcache_prune_data user;
|
||||
|
||||
time(&user.now);
|
||||
user.cache_timeout = data->set.dns_cache_timeout;
|
||||
|
||||
if(hostcache_timestamp_remove(&user, dns)) {
|
||||
infof(data, "Hostname in DNS cache was stale, zapped\n");
|
||||
dns = NULL; /* the memory deallocation is being handled by the hash */
|
||||
Curl_hash_delete(data->dns.hostcache, entry_id, entry_len+1);
|
||||
}
|
||||
}
|
||||
|
||||
/* free the allocated entry_id again */
|
||||
free(entry_id);
|
||||
|
||||
return dns;
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_fetch_addr() fetches a 'Curl_dns_entry' already in the DNS cache.
|
||||
*
|
||||
* Curl_resolv() checks initially and multi_runsingle() checks each time
|
||||
* it discovers the handle in the state WAITRESOLVE whether the hostname
|
||||
* has already been resolved and the address has already been stored in
|
||||
* the DNS cache. This short circuits waiting for a lot of pending
|
||||
* lookups for the same hostname requested by different handles.
|
||||
*
|
||||
* Returns the Curl_dns_entry entry pointer or NULL if not in the cache.
|
||||
*
|
||||
* The returned data *MUST* be "unlocked" with Curl_resolv_unlock() after
|
||||
* use, or we'll leak memory!
|
||||
*/
|
||||
struct Curl_dns_entry *
|
||||
Curl_fetch_addr(struct connectdata *conn,
|
||||
const char *hostname,
|
||||
int port)
|
||||
{
|
||||
struct SessionHandle *data = conn->data;
|
||||
struct Curl_dns_entry *dns = NULL;
|
||||
|
||||
if(data->share)
|
||||
Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE);
|
||||
|
||||
dns = fetch_addr(conn, hostname, port);
|
||||
|
||||
if(dns) dns->inuse++; /* we use it! */
|
||||
|
||||
if(data->share)
|
||||
Curl_share_unlock(data, CURL_LOCK_DATA_DNS);
|
||||
|
||||
return dns;
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_cache_addr() stores a 'Curl_addrinfo' struct in the DNS cache.
|
||||
@ -353,11 +395,11 @@ Curl_cache_addr(struct SessionHandle *data,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
dns->inuse = 0; /* init to not used */
|
||||
dns->inuse = 1; /* the cache has the first reference */
|
||||
dns->addr = addr; /* this is the address(es) */
|
||||
time(&dns->timestamp);
|
||||
if(dns->timestamp == 0)
|
||||
dns->timestamp = 1; /* zero indicates that entry isn't in hash table */
|
||||
dns->timestamp = 1; /* zero indicates CURLOPT_RESOLVE entry */
|
||||
|
||||
/* Store the resolved data in our DNS cache. */
|
||||
dns2 = Curl_hash_add(data->dns.hostcache, entry_id, entry_len+1,
|
||||
@ -403,41 +445,20 @@ int Curl_resolv(struct connectdata *conn,
|
||||
int port,
|
||||
struct Curl_dns_entry **entry)
|
||||
{
|
||||
char *entry_id = NULL;
|
||||
struct Curl_dns_entry *dns = NULL;
|
||||
size_t entry_len;
|
||||
struct SessionHandle *data = conn->data;
|
||||
CURLcode result;
|
||||
int rc = CURLRESOLV_ERROR; /* default to failure */
|
||||
|
||||
*entry = NULL;
|
||||
|
||||
/* Create an entry id, based upon the hostname and port */
|
||||
entry_id = create_hostcache_id(hostname, port);
|
||||
/* If we can't create the entry id, fail */
|
||||
if(!entry_id)
|
||||
return rc;
|
||||
|
||||
entry_len = strlen(entry_id);
|
||||
|
||||
if(data->share)
|
||||
Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE);
|
||||
|
||||
/* See if its already in our dns cache */
|
||||
dns = Curl_hash_pick(data->dns.hostcache, entry_id, entry_len+1);
|
||||
|
||||
/* free the allocated entry_id again */
|
||||
free(entry_id);
|
||||
|
||||
infof(data, "Hostname was %sfound in DNS cache\n", dns?"":"NOT ");
|
||||
|
||||
/* See whether the returned entry is stale. Done before we release lock */
|
||||
if(remove_entry_if_stale(data, dns)) {
|
||||
infof(data, "Hostname in DNS cache was stale, zapped\n");
|
||||
dns = NULL; /* the memory deallocation is being handled by the hash */
|
||||
}
|
||||
dns = fetch_addr(conn, hostname, port);
|
||||
|
||||
if(dns) {
|
||||
infof(data, "Hostname %s was found in DNS cache\n", hostname);
|
||||
dns->inuse++; /* we use it! */
|
||||
rc = CURLRESOLV_RESOLVED;
|
||||
}
|
||||
@ -586,6 +607,19 @@ int Curl_resolv_timeout(struct connectdata *conn,
|
||||
we want to wait less than one second we must bail out already now. */
|
||||
return CURLRESOLV_TIMEDOUT;
|
||||
|
||||
/* This allows us to time-out from the name resolver, as the timeout
|
||||
will generate a signal and we will siglongjmp() from that here.
|
||||
This technique has problems (see alarmfunc).
|
||||
This should be the last thing we do before calling Curl_resolv(),
|
||||
as otherwise we'd have to worry about variables that get modified
|
||||
before we invoke Curl_resolv() (and thus use "volatile"). */
|
||||
if(sigsetjmp(curl_jmpenv, 1)) {
|
||||
/* this is coming from a siglongjmp() after an alarm signal */
|
||||
failf(data, "name lookup timed out");
|
||||
rc = CURLRESOLV_ERROR;
|
||||
goto clean_up;
|
||||
}
|
||||
else {
|
||||
/*************************************************************
|
||||
* Set signal handler to catch SIGALRM
|
||||
* Store the old value to be able to set it back later!
|
||||
@ -611,18 +645,6 @@ int Curl_resolv_timeout(struct connectdata *conn,
|
||||
/* alarm() makes a signal get sent when the timeout fires off, and that
|
||||
will abort system calls */
|
||||
prev_alarm = alarm(curlx_sltoui(timeout/1000L));
|
||||
|
||||
/* This allows us to time-out from the name resolver, as the timeout
|
||||
will generate a signal and we will siglongjmp() from that here.
|
||||
This technique has problems (see alarmfunc).
|
||||
This should be the last thing we do before calling Curl_resolv(),
|
||||
as otherwise we'd have to worry about variables that get modified
|
||||
before we invoke Curl_resolv() (and thus use "volatile"). */
|
||||
if(sigsetjmp(curl_jmpenv, 1)) {
|
||||
/* this is coming from a siglongjmp() after an alarm signal */
|
||||
failf(data, "name lookup timed out");
|
||||
rc = CURLRESOLV_ERROR;
|
||||
goto clean_up;
|
||||
}
|
||||
|
||||
#else
|
||||
@ -695,54 +717,37 @@ clean_up:
|
||||
*/
|
||||
void Curl_resolv_unlock(struct SessionHandle *data, struct Curl_dns_entry *dns)
|
||||
{
|
||||
DEBUGASSERT(dns && (dns->inuse>0));
|
||||
|
||||
if(data && data->share)
|
||||
Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE);
|
||||
|
||||
dns->inuse--;
|
||||
/* only free if nobody is using AND it is not in hostcache (timestamp ==
|
||||
0) */
|
||||
if(dns->inuse == 0 && dns->timestamp == 0) {
|
||||
Curl_freeaddrinfo(dns->addr);
|
||||
free(dns);
|
||||
}
|
||||
freednsentry(dns);
|
||||
|
||||
if(data && data->share)
|
||||
Curl_share_unlock(data, CURL_LOCK_DATA_DNS);
|
||||
}
|
||||
|
||||
/*
|
||||
* File-internal: free a cache dns entry.
|
||||
* File-internal: release cache dns entry reference, free if inuse drops to 0
|
||||
*/
|
||||
static void freednsentry(void *freethis)
|
||||
{
|
||||
struct Curl_dns_entry *p = (struct Curl_dns_entry *) freethis;
|
||||
struct Curl_dns_entry *dns = (struct Curl_dns_entry *) freethis;
|
||||
DEBUGASSERT(dns && (dns->inuse>0));
|
||||
|
||||
/* mark the entry as not in hostcache */
|
||||
p->timestamp = 0;
|
||||
if(p->inuse == 0) {
|
||||
Curl_freeaddrinfo(p->addr);
|
||||
free(p);
|
||||
dns->inuse--;
|
||||
if(dns->inuse == 0) {
|
||||
Curl_freeaddrinfo(dns->addr);
|
||||
free(dns);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_mk_dnscache() creates a new DNS cache and returns the handle for it.
|
||||
* Curl_mk_dnscache() inits a new DNS cache and returns success/failure.
|
||||
*/
|
||||
struct curl_hash *Curl_mk_dnscache(void)
|
||||
int Curl_mk_dnscache(struct curl_hash *hash)
|
||||
{
|
||||
return Curl_hash_alloc(7, Curl_hash_str, Curl_str_key_compare, freednsentry);
|
||||
}
|
||||
|
||||
static int hostcache_inuse(void *data, void *hc)
|
||||
{
|
||||
struct Curl_dns_entry *c = (struct Curl_dns_entry *) hc;
|
||||
|
||||
if(c->inuse == 1)
|
||||
Curl_resolv_unlock(data, c);
|
||||
|
||||
return 1; /* free all entries */
|
||||
return Curl_hash_init(hash, 7, Curl_hash_str, Curl_str_key_compare,
|
||||
freednsentry);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -755,11 +760,13 @@ static int hostcache_inuse(void *data, void *hc)
|
||||
void Curl_hostcache_clean(struct SessionHandle *data,
|
||||
struct curl_hash *hash)
|
||||
{
|
||||
/* Entries added to the hostcache with the CURLOPT_RESOLVE function are
|
||||
* still present in the cache with the inuse counter set to 1. Detect them
|
||||
* and cleanup!
|
||||
*/
|
||||
Curl_hash_clean_with_criterium(hash, data, hostcache_inuse);
|
||||
if(data && data->share)
|
||||
Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE);
|
||||
|
||||
Curl_hash_clean(hash);
|
||||
|
||||
if(data && data->share)
|
||||
Curl_share_unlock(data, CURL_LOCK_DATA_DNS);
|
||||
}
|
||||
|
||||
|
||||
@ -774,18 +781,52 @@ CURLcode Curl_loadhostpairs(struct SessionHandle *data)
|
||||
if(!hostp->data)
|
||||
continue;
|
||||
if(hostp->data[0] == '-') {
|
||||
/* TODO: mark an entry for removal */
|
||||
char *entry_id;
|
||||
size_t entry_len;
|
||||
|
||||
if(2 != sscanf(hostp->data + 1, "%255[^:]:%d", hostname, &port)) {
|
||||
infof(data, "Couldn't parse CURLOPT_RESOLVE removal entry '%s'!\n",
|
||||
hostp->data);
|
||||
continue;
|
||||
}
|
||||
else if(3 == sscanf(hostp->data, "%255[^:]:%d:%255s", hostname, &port,
|
||||
address)) {
|
||||
|
||||
/* Create an entry id, based upon the hostname and port */
|
||||
entry_id = create_hostcache_id(hostname, port);
|
||||
/* If we can't create the entry id, fail */
|
||||
if(!entry_id) {
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
entry_len = strlen(entry_id);
|
||||
|
||||
if(data->share)
|
||||
Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE);
|
||||
|
||||
/* delete entry, ignore if it didn't exist */
|
||||
Curl_hash_delete(data->dns.hostcache, entry_id, entry_len+1);
|
||||
|
||||
if(data->share)
|
||||
Curl_share_unlock(data, CURL_LOCK_DATA_DNS);
|
||||
|
||||
/* free the allocated entry_id again */
|
||||
free(entry_id);
|
||||
}
|
||||
else {
|
||||
struct Curl_dns_entry *dns;
|
||||
Curl_addrinfo *addr;
|
||||
char *entry_id;
|
||||
size_t entry_len;
|
||||
|
||||
if(3 != sscanf(hostp->data, "%255[^:]:%d:%255s", hostname, &port,
|
||||
address)) {
|
||||
infof(data, "Couldn't parse CURLOPT_RESOLVE entry '%s'!\n",
|
||||
hostp->data);
|
||||
continue;
|
||||
}
|
||||
|
||||
addr = Curl_str2addr(address, port);
|
||||
if(!addr) {
|
||||
infof(data, "Resolve %s found illegal!\n", hostp->data);
|
||||
infof(data, "Address in '%s' found illegal!\n", hostp->data);
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -808,9 +849,16 @@ CURLcode Curl_loadhostpairs(struct SessionHandle *data)
|
||||
/* free the allocated entry_id again */
|
||||
free(entry_id);
|
||||
|
||||
if(!dns)
|
||||
if(!dns) {
|
||||
/* if not in the cache already, put this host in the cache */
|
||||
dns = Curl_cache_addr(data, addr, hostname, port);
|
||||
if(dns) {
|
||||
dns->timestamp = 0; /* mark as added by CURLOPT_RESOLVE */
|
||||
/* release the returned reference; the cache itself will keep the
|
||||
* entry alive: */
|
||||
dns->inuse--;
|
||||
}
|
||||
}
|
||||
else
|
||||
/* this is a duplicate, free it again */
|
||||
Curl_freeaddrinfo(addr);
|
||||
|
@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -65,11 +65,10 @@ void Curl_global_host_cache_dtor(void);
|
||||
|
||||
struct Curl_dns_entry {
|
||||
Curl_addrinfo *addr;
|
||||
/* timestamp == 0 -- entry not in hostcache
|
||||
timestamp != 0 -- entry is in hostcache */
|
||||
/* timestamp == 0 -- CURLOPT_RESOLVE entry, doesn't timeout */
|
||||
time_t timestamp;
|
||||
long inuse; /* use-counter, make very sure you decrease this
|
||||
when you're done using the address you received */
|
||||
/* use-counter, use Curl_resolv_unlock to release reference */
|
||||
long inuse;
|
||||
};
|
||||
|
||||
/*
|
||||
@ -92,7 +91,7 @@ int Curl_resolv_timeout(struct connectdata *conn, const char *hostname,
|
||||
|
||||
#ifdef CURLRES_IPV6
|
||||
/*
|
||||
* Curl_ipv6works() returns TRUE if ipv6 seems to work.
|
||||
* Curl_ipv6works() returns TRUE if IPv6 seems to work.
|
||||
*/
|
||||
bool Curl_ipv6works(void);
|
||||
#else
|
||||
@ -125,8 +124,8 @@ void Curl_resolv_unlock(struct SessionHandle *data,
|
||||
/* for debugging purposes only: */
|
||||
void Curl_scan_cache_used(void *user, void *ptr);
|
||||
|
||||
/* make a new dns cache and return the handle */
|
||||
struct curl_hash *Curl_mk_dnscache(void);
|
||||
/* init a new dns cache and return success */
|
||||
int Curl_mk_dnscache(struct curl_hash *hash);
|
||||
|
||||
/* prune old entries from the DNS cache */
|
||||
void Curl_hostcache_prune(struct SessionHandle *data);
|
||||
@ -171,6 +170,18 @@ CURLcode Curl_addrinfo_callback(struct connectdata *conn,
|
||||
const char *Curl_printable_address(const Curl_addrinfo *ip,
|
||||
char *buf, size_t bufsize);
|
||||
|
||||
/*
|
||||
* Curl_fetch_addr() fetches a 'Curl_dns_entry' already in the DNS cache.
|
||||
*
|
||||
* Returns the Curl_dns_entry entry pointer or NULL if not in the cache.
|
||||
*
|
||||
* The returned data *MUST* be "unlocked" with Curl_resolv_unlock() after
|
||||
* use, or we'll leak memory!
|
||||
*/
|
||||
struct Curl_dns_entry *
|
||||
Curl_fetch_addr(struct connectdata *conn,
|
||||
const char *hostname,
|
||||
int port);
|
||||
/*
|
||||
* Curl_cache_addr() stores a 'Curl_addrinfo' struct in the DNS cache.
|
||||
*
|
||||
|
@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -48,18 +48,15 @@
|
||||
#include "strerror.h"
|
||||
#include "url.h"
|
||||
#include "inet_pton.h"
|
||||
|
||||
#define _MPRINTF_REPLACE /* use our functions only */
|
||||
#include <curl/mprintf.h>
|
||||
|
||||
#include "curl_printf.h"
|
||||
#include "curl_memory.h"
|
||||
/* The last #include file should be: */
|
||||
#include "memdebug.h"
|
||||
|
||||
/***********************************************************************
|
||||
* Only for plain-ipv4 builds
|
||||
* Only for plain IPv4 builds
|
||||
**********************************************************************/
|
||||
#ifdef CURLRES_IPV4 /* plain ipv4 code coming up */
|
||||
#ifdef CURLRES_IPV4 /* plain IPv4 code coming up */
|
||||
/*
|
||||
* Curl_ipvalid() checks what CURL_IPRESOLVE_* requirements that might've
|
||||
* been set and returns TRUE if they are OK.
|
||||
@ -67,7 +64,7 @@
|
||||
bool Curl_ipvalid(struct connectdata *conn)
|
||||
{
|
||||
if(conn->ip_version == CURL_IPRESOLVE_V6)
|
||||
/* an ipv6 address was requested and we can't get/use one */
|
||||
/* An IPv6 address was requested and we can't get/use one */
|
||||
return FALSE;
|
||||
|
||||
return TRUE; /* OK, proceed */
|
||||
@ -76,7 +73,7 @@ bool Curl_ipvalid(struct connectdata *conn)
|
||||
#ifdef CURLRES_SYNCH
|
||||
|
||||
/*
|
||||
* Curl_getaddrinfo() - the ipv4 synchronous version.
|
||||
* Curl_getaddrinfo() - the IPv4 synchronous version.
|
||||
*
|
||||
* The original code to this function was from the Dancer source code, written
|
||||
* by Bjorn Reese, it has since been patched and modified considerably.
|
||||
|
@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -49,16 +49,13 @@
|
||||
#include "url.h"
|
||||
#include "inet_pton.h"
|
||||
#include "connect.h"
|
||||
|
||||
#define _MPRINTF_REPLACE /* use our functions only */
|
||||
#include <curl/mprintf.h>
|
||||
|
||||
#include "curl_printf.h"
|
||||
#include "curl_memory.h"
|
||||
/* The last #include file should be: */
|
||||
#include "memdebug.h"
|
||||
|
||||
/***********************************************************************
|
||||
* Only for ipv6-enabled builds
|
||||
* Only for IPv6-enabled builds
|
||||
**********************************************************************/
|
||||
#ifdef CURLRES_IPV6
|
||||
|
||||
@ -97,7 +94,7 @@ int curl_dogetnameinfo(GETNAMEINFO_QUAL_ARG1 GETNAMEINFO_TYPE_ARG1 sa,
|
||||
#endif /* defined(CURLDEBUG) && defined(HAVE_GETNAMEINFO) */
|
||||
|
||||
/*
|
||||
* Curl_ipv6works() returns TRUE if ipv6 seems to work.
|
||||
* Curl_ipv6works() returns TRUE if IPv6 seems to work.
|
||||
*/
|
||||
bool Curl_ipv6works(void)
|
||||
{
|
||||
@ -109,7 +106,7 @@ bool Curl_ipv6works(void)
|
||||
/* probe to see if we have a working IPv6 stack */
|
||||
curl_socket_t s = socket(PF_INET6, SOCK_DGRAM, 0);
|
||||
if(s == CURL_SOCKET_BAD)
|
||||
/* an ipv6 address was requested but we can't get/use one */
|
||||
/* an IPv6 address was requested but we can't get/use one */
|
||||
ipv6_works = 0;
|
||||
else {
|
||||
ipv6_works = 1;
|
||||
@ -152,7 +149,7 @@ static void dump_addrinfo(struct connectdata *conn, const Curl_addrinfo *ai)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Curl_getaddrinfo() when built ipv6-enabled (non-threading and
|
||||
* Curl_getaddrinfo() when built IPv6-enabled (non-threading and
|
||||
* non-ares version).
|
||||
*
|
||||
* Returns name information about the given hostname and port number. If
|
||||
@ -192,7 +189,7 @@ Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
|
||||
}
|
||||
|
||||
if((pf != PF_INET) && !Curl_ipv6works())
|
||||
/* the stack seems to be a non-ipv6 one */
|
||||
/* The stack seems to be a non-IPv6 one */
|
||||
pf = PF_INET;
|
||||
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
|
@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -47,10 +47,6 @@
|
||||
#include "share.h"
|
||||
#include "strerror.h"
|
||||
#include "url.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"
|
||||
|
@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -63,7 +63,6 @@
|
||||
#include "share.h"
|
||||
#include "hostip.h"
|
||||
#include "http.h"
|
||||
#include "curl_memory.h"
|
||||
#include "select.h"
|
||||
#include "parsedate.h" /* for the week day and month names */
|
||||
#include "strtoofft.h"
|
||||
@ -73,15 +72,14 @@
|
||||
#include "http_proxy.h"
|
||||
#include "warnless.h"
|
||||
#include "non-ascii.h"
|
||||
#include "bundles.h"
|
||||
#include "conncache.h"
|
||||
#include "pipeline.h"
|
||||
#include "http2.h"
|
||||
#include "connect.h"
|
||||
#include "curl_printf.h"
|
||||
|
||||
#define _MPRINTF_REPLACE /* use our functions only */
|
||||
#include <curl/mprintf.h>
|
||||
|
||||
/* The last #include file should be: */
|
||||
/* The last #include files should be: */
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
/*
|
||||
@ -155,12 +153,18 @@ CURLcode Curl_http_setup_conn(struct connectdata *conn)
|
||||
{
|
||||
/* allocate the HTTP-specific struct for the SessionHandle, only to survive
|
||||
during this request */
|
||||
struct HTTP *http;
|
||||
DEBUGASSERT(conn->data->req.protop == NULL);
|
||||
|
||||
conn->data->req.protop = calloc(1, sizeof(struct HTTP));
|
||||
if(!conn->data->req.protop)
|
||||
http = calloc(1, sizeof(struct HTTP));
|
||||
if(!http)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
conn->data->req.protop = http;
|
||||
|
||||
Curl_http2_setup_conn(conn);
|
||||
Curl_http2_setup_req(conn->data);
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
@ -279,7 +283,7 @@ static CURLcode http_output_basic(struct connectdata *conn, bool proxy)
|
||||
char **userp;
|
||||
const char *user;
|
||||
const char *pwd;
|
||||
CURLcode error;
|
||||
CURLcode result;
|
||||
|
||||
if(proxy) {
|
||||
userp = &conn->allocptr.proxyuserpwd;
|
||||
@ -294,16 +298,16 @@ static CURLcode http_output_basic(struct connectdata *conn, bool proxy)
|
||||
|
||||
snprintf(data->state.buffer, sizeof(data->state.buffer), "%s:%s", user, pwd);
|
||||
|
||||
error = Curl_base64_encode(data,
|
||||
result = Curl_base64_encode(data,
|
||||
data->state.buffer, strlen(data->state.buffer),
|
||||
&authorization, &size);
|
||||
if(error)
|
||||
return error;
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
if(!authorization)
|
||||
return CURLE_REMOTE_ACCESS_DENIED;
|
||||
|
||||
Curl_safefree(*userp);
|
||||
free(*userp);
|
||||
*userp = aprintf("%sAuthorization: Basic %s\r\n",
|
||||
proxy?"Proxy-":"",
|
||||
authorization);
|
||||
@ -392,16 +396,21 @@ static CURLcode http_perhapsrewind(struct connectdata *conn)
|
||||
|
||||
bytessent = http->writebytecount;
|
||||
|
||||
if(conn->bits.authneg)
|
||||
if(conn->bits.authneg) {
|
||||
/* This is a state where we are known to be negotiating and we don't send
|
||||
any data then. */
|
||||
expectsend = 0;
|
||||
}
|
||||
else if(!conn->bits.protoconnstart) {
|
||||
/* HTTP CONNECT in progress: there is no body */
|
||||
expectsend = 0;
|
||||
}
|
||||
else {
|
||||
/* figure out how much data we are expected to send */
|
||||
switch(data->set.httpreq) {
|
||||
case HTTPREQ_POST:
|
||||
if(data->set.postfieldsize != -1)
|
||||
expectsend = data->set.postfieldsize;
|
||||
if(data->state.infilesize != -1)
|
||||
expectsend = data->state.infilesize;
|
||||
else if(data->set.postfields)
|
||||
expectsend = (curl_off_t)strlen(data->set.postfields);
|
||||
break;
|
||||
@ -420,6 +429,7 @@ static CURLcode http_perhapsrewind(struct connectdata *conn)
|
||||
conn->bits.rewindaftersend = FALSE; /* default */
|
||||
|
||||
if((expectsend == -1) || (expectsend > bytessent)) {
|
||||
#if defined(USE_NTLM)
|
||||
/* There is still data left to send */
|
||||
if((data->state.authproxy.picked == CURLAUTH_NTLM) ||
|
||||
(data->state.authhost.picked == CURLAUTH_NTLM) ||
|
||||
@ -439,6 +449,7 @@ static CURLcode http_perhapsrewind(struct connectdata *conn)
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
if(conn->bits.close)
|
||||
/* this is already marked to get closed */
|
||||
return CURLE_OK;
|
||||
@ -447,9 +458,9 @@ static CURLcode http_perhapsrewind(struct connectdata *conn)
|
||||
CURL_FORMAT_CURL_OFF_T " bytes\n",
|
||||
(curl_off_t)(expectsend - bytessent));
|
||||
}
|
||||
#endif
|
||||
|
||||
/* This is not NTLM or many bytes left to send: close
|
||||
*/
|
||||
/* This is not NTLM or many bytes left to send: close */
|
||||
connclose(conn, "Mid-auth HTTP and much data left to send");
|
||||
data->req.size = 0; /* don't download any more than 0 bytes */
|
||||
|
||||
@ -476,7 +487,7 @@ CURLcode Curl_http_auth_act(struct connectdata *conn)
|
||||
struct SessionHandle *data = conn->data;
|
||||
bool pickhost = FALSE;
|
||||
bool pickproxy = FALSE;
|
||||
CURLcode code = CURLE_OK;
|
||||
CURLcode result = CURLE_OK;
|
||||
|
||||
if(100 <= data->req.httpcode && 199 >= data->req.httpcode)
|
||||
/* this is a transient response code, ignore */
|
||||
@ -512,9 +523,9 @@ CURLcode Curl_http_auth_act(struct connectdata *conn)
|
||||
if((data->set.httpreq != HTTPREQ_GET) &&
|
||||
(data->set.httpreq != HTTPREQ_HEAD) &&
|
||||
!conn->bits.rewindaftersend) {
|
||||
code = http_perhapsrewind(conn);
|
||||
if(code)
|
||||
return code;
|
||||
result = http_perhapsrewind(conn);
|
||||
if(result)
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@ -536,10 +547,10 @@ CURLcode Curl_http_auth_act(struct connectdata *conn)
|
||||
if(http_should_fail(conn)) {
|
||||
failf (data, "The requested URL returned error: %d",
|
||||
data->req.httpcode);
|
||||
code = CURLE_HTTP_RETURNED_ERROR;
|
||||
result = CURLE_HTTP_RETURNED_ERROR;
|
||||
}
|
||||
|
||||
return code;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@ -554,9 +565,11 @@ output_auth_headers(struct connectdata *conn,
|
||||
const char *path,
|
||||
bool proxy)
|
||||
{
|
||||
struct SessionHandle *data = conn->data;
|
||||
const char *auth=NULL;
|
||||
const char *auth = NULL;
|
||||
CURLcode result = CURLE_OK;
|
||||
#if defined(USE_SPNEGO) || !defined(CURL_DISABLE_VERBOSE_STRINGS)
|
||||
struct SessionHandle *data = conn->data;
|
||||
#endif
|
||||
#ifdef USE_SPNEGO
|
||||
struct negotiatedata *negdata = proxy?
|
||||
&data->state.proxyneg:&data->state.negotiate;
|
||||
@ -672,7 +685,7 @@ Curl_http_output_auth(struct connectdata *conn,
|
||||
|
||||
if((conn->bits.httpproxy && conn->bits.proxy_user_passwd) ||
|
||||
conn->bits.user_passwd)
|
||||
/* continue please */ ;
|
||||
/* continue please */;
|
||||
else {
|
||||
authhost->done = TRUE;
|
||||
authproxy->done = TRUE;
|
||||
@ -773,14 +786,13 @@ CURLcode Curl_http_input_auth(struct connectdata *conn, bool proxy,
|
||||
while(*auth) {
|
||||
#ifdef USE_SPNEGO
|
||||
if(checkprefix("Negotiate", auth)) {
|
||||
int neg;
|
||||
*availp |= CURLAUTH_NEGOTIATE;
|
||||
authp->avail |= CURLAUTH_NEGOTIATE;
|
||||
|
||||
if(authp->picked == CURLAUTH_NEGOTIATE) {
|
||||
if(negdata->state == GSS_AUTHSENT || negdata->state == GSS_AUTHNONE) {
|
||||
neg = Curl_input_negotiate(conn, proxy, auth);
|
||||
if(neg == 0) {
|
||||
CURLcode result = Curl_input_negotiate(conn, proxy, auth);
|
||||
if(!result) {
|
||||
DEBUGASSERT(!data->req.newurl);
|
||||
data->req.newurl = strdup(data->change.url);
|
||||
if(!data->req.newurl)
|
||||
@ -804,9 +816,8 @@ CURLcode Curl_http_input_auth(struct connectdata *conn, bool proxy,
|
||||
if(authp->picked == CURLAUTH_NTLM ||
|
||||
authp->picked == CURLAUTH_NTLM_WB) {
|
||||
/* NTLM authentication is picked and activated */
|
||||
CURLcode ntlm =
|
||||
Curl_input_ntlm(conn, proxy, auth);
|
||||
if(CURLE_OK == ntlm) {
|
||||
CURLcode result = Curl_input_ntlm(conn, proxy, auth);
|
||||
if(!result) {
|
||||
data->state.authproblem = FALSE;
|
||||
#ifdef NTLM_WB_ENABLED
|
||||
if(authp->picked == CURLAUTH_NTLM_WB) {
|
||||
@ -844,7 +855,7 @@ CURLcode Curl_http_input_auth(struct connectdata *conn, bool proxy,
|
||||
infof(data, "Ignoring duplicate digest auth header.\n");
|
||||
}
|
||||
else {
|
||||
CURLdigest dig;
|
||||
CURLcode result;
|
||||
*availp |= CURLAUTH_DIGEST;
|
||||
authp->avail |= CURLAUTH_DIGEST;
|
||||
|
||||
@ -852,9 +863,8 @@ CURLcode Curl_http_input_auth(struct connectdata *conn, bool proxy,
|
||||
* authentication isn't activated yet, as we need to store the
|
||||
* incoming data from this header in case we are gonna use
|
||||
* Digest. */
|
||||
dig = Curl_input_digest(conn, proxy, auth);
|
||||
|
||||
if(CURLDIGEST_FINE != dig) {
|
||||
result = Curl_input_digest(conn, proxy, auth);
|
||||
if(result) {
|
||||
infof(data, "Authentication problem. Ignoring this.\n");
|
||||
data->state.authproblem = TRUE;
|
||||
}
|
||||
@ -991,8 +1001,8 @@ static size_t readmoredata(char *buffer,
|
||||
/* move backup data into focus and continue on that */
|
||||
http->postdata = http->backup.postdata;
|
||||
http->postsize = http->backup.postsize;
|
||||
conn->fread_func = http->backup.fread_func;
|
||||
conn->fread_in = http->backup.fread_in;
|
||||
conn->data->set.fread_func = http->backup.fread_func;
|
||||
conn->data->set.in = http->backup.fread_in;
|
||||
|
||||
http->sending++; /* move one step up */
|
||||
|
||||
@ -1022,6 +1032,16 @@ Curl_send_buffer *Curl_add_buffer_init(void)
|
||||
return calloc(1, sizeof(Curl_send_buffer));
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_add_buffer_free() frees all associated resources.
|
||||
*/
|
||||
void Curl_add_buffer_free(Curl_send_buffer *buff)
|
||||
{
|
||||
if(buff) /* deal with NULL input */
|
||||
free(buff->buffer);
|
||||
free(buff);
|
||||
}
|
||||
|
||||
/*
|
||||
* Curl_add_buffer_send() sends a header buffer and frees all associated
|
||||
* memory. Body data may be appended to the header data if desired.
|
||||
@ -1041,7 +1061,7 @@ CURLcode Curl_add_buffer_send(Curl_send_buffer *in,
|
||||
|
||||
{
|
||||
ssize_t amount;
|
||||
CURLcode res;
|
||||
CURLcode result;
|
||||
char *ptr;
|
||||
size_t size;
|
||||
struct HTTP *http = conn->data->req.protop;
|
||||
@ -1064,14 +1084,12 @@ CURLcode Curl_add_buffer_send(Curl_send_buffer *in,
|
||||
|
||||
DEBUGASSERT(size > included_body_bytes);
|
||||
|
||||
res = Curl_convert_to_network(conn->data, ptr, headersize);
|
||||
result = Curl_convert_to_network(conn->data, ptr, headersize);
|
||||
/* Curl_convert_to_network calls failf if unsuccessful */
|
||||
if(res) {
|
||||
if(result) {
|
||||
/* conversion failed, free memory and return to the caller */
|
||||
if(in->buffer)
|
||||
free(in->buffer);
|
||||
free(in);
|
||||
return res;
|
||||
Curl_add_buffer_free(in);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@ -1096,9 +1114,9 @@ CURLcode Curl_add_buffer_send(Curl_send_buffer *in,
|
||||
else
|
||||
sendsize = size;
|
||||
|
||||
res = Curl_write(conn, sockfd, ptr, sendsize, &amount);
|
||||
result = Curl_write(conn, sockfd, ptr, sendsize, &amount);
|
||||
|
||||
if(CURLE_OK == res) {
|
||||
if(!result) {
|
||||
/*
|
||||
* Note that we may not send the entire chunk at once, and we have a set
|
||||
* number of data bytes at the end of the big buffer (out of which we may
|
||||
@ -1139,14 +1157,14 @@ CURLcode Curl_add_buffer_send(Curl_send_buffer *in,
|
||||
ptr = in->buffer + amount;
|
||||
|
||||
/* backup the currently set pointers */
|
||||
http->backup.fread_func = conn->fread_func;
|
||||
http->backup.fread_in = conn->fread_in;
|
||||
http->backup.fread_func = conn->data->set.fread_func;
|
||||
http->backup.fread_in = conn->data->set.in;
|
||||
http->backup.postdata = http->postdata;
|
||||
http->backup.postsize = http->postsize;
|
||||
|
||||
/* set the new pointers for the request-sending */
|
||||
conn->fread_func = (curl_read_callback)readmoredata;
|
||||
conn->fread_in = (void *)conn;
|
||||
conn->data->set.fread_func = (curl_read_callback)readmoredata;
|
||||
conn->data->set.in = (void *)conn;
|
||||
http->postdata = ptr;
|
||||
http->postsize = (curl_off_t)size;
|
||||
|
||||
@ -1169,14 +1187,12 @@ CURLcode Curl_add_buffer_send(Curl_send_buffer *in,
|
||||
*/
|
||||
return CURLE_SEND_ERROR;
|
||||
else
|
||||
conn->writechannel_inuse = FALSE;
|
||||
Curl_pipeline_leave_write(conn);
|
||||
}
|
||||
}
|
||||
if(in->buffer)
|
||||
free(in->buffer);
|
||||
free(in);
|
||||
Curl_add_buffer_free(in);
|
||||
|
||||
return res;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@ -1197,7 +1213,6 @@ CURLcode Curl_add_bufferf(Curl_send_buffer *in, const char *fmt, ...)
|
||||
return result;
|
||||
}
|
||||
/* If we failed, we cleanup the whole buffer and return error */
|
||||
if(in->buffer)
|
||||
free(in->buffer);
|
||||
free(in);
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
@ -1378,7 +1393,7 @@ static CURLcode https_connecting(struct connectdata *conn, bool *done)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(USE_SSLEAY) || defined(USE_GNUTLS) || defined(USE_SCHANNEL) || \
|
||||
#if defined(USE_OPENSSL) || defined(USE_GNUTLS) || defined(USE_SCHANNEL) || \
|
||||
defined(USE_DARWINSSL) || defined(USE_POLARSSL) || defined(USE_NSS)
|
||||
/* This function is for OpenSSL, GnuTLS, darwinssl, schannel and polarssl only.
|
||||
It should be made to query the generic SSL layer instead. */
|
||||
@ -1417,7 +1432,7 @@ static int https_getsock(struct connectdata *conn,
|
||||
return GETSOCK_BLANK;
|
||||
}
|
||||
#endif /* USE_SSL */
|
||||
#endif /* USE_SSLEAY || USE_GNUTLS || USE_SCHANNEL */
|
||||
#endif /* USE_OPENSSL || USE_GNUTLS || USE_SCHANNEL */
|
||||
|
||||
/*
|
||||
* Curl_http_done() gets called from Curl_done() after a single HTTP request
|
||||
@ -1428,19 +1443,26 @@ CURLcode Curl_http_done(struct connectdata *conn,
|
||||
CURLcode status, bool premature)
|
||||
{
|
||||
struct SessionHandle *data = conn->data;
|
||||
struct HTTP *http =data->req.protop;
|
||||
struct HTTP *http = data->req.protop;
|
||||
#ifdef USE_NGHTTP2
|
||||
struct http_conn *httpc = &conn->proto.httpc;
|
||||
#endif
|
||||
|
||||
Curl_unencode_cleanup(conn);
|
||||
|
||||
#ifdef USE_SPNEGO
|
||||
if(data->state.proxyneg.state == GSS_AUTHSENT ||
|
||||
data->state.negotiate.state == GSS_AUTHSENT)
|
||||
data->state.negotiate.state == GSS_AUTHSENT) {
|
||||
/* add forbid re-use if http-code != 401/407 as a WA only needed for
|
||||
* 401/407 that signal auth failure (empty) otherwise state will be RECV
|
||||
* with current code */
|
||||
if((data->req.httpcode != 401) && (data->req.httpcode != 407))
|
||||
connclose(conn, "Negotiate transfer completed");
|
||||
Curl_cleanup_negotiate(data);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* set the proper values (possibly modified on POST) */
|
||||
conn->fread_func = data->set.fread_func; /* restore */
|
||||
conn->fread_in = data->set.in; /* restore */
|
||||
conn->seek_func = data->set.seek_func; /* restore */
|
||||
conn->seek_client = data->set.seek_client; /* restore */
|
||||
|
||||
@ -1448,13 +1470,27 @@ CURLcode Curl_http_done(struct connectdata *conn,
|
||||
return CURLE_OK;
|
||||
|
||||
if(http->send_buffer) {
|
||||
Curl_send_buffer *buff = http->send_buffer;
|
||||
|
||||
free(buff->buffer);
|
||||
free(buff);
|
||||
Curl_add_buffer_free(http->send_buffer);
|
||||
http->send_buffer = NULL; /* clear the pointer */
|
||||
}
|
||||
|
||||
#ifdef USE_NGHTTP2
|
||||
if(http->header_recvbuf) {
|
||||
DEBUGF(infof(data, "free header_recvbuf!!\n"));
|
||||
Curl_add_buffer_free(http->header_recvbuf);
|
||||
http->header_recvbuf = NULL; /* clear the pointer */
|
||||
for(; http->push_headers_used > 0; --http->push_headers_used) {
|
||||
free(http->push_headers[http->push_headers_used - 1]);
|
||||
}
|
||||
free(http->push_headers);
|
||||
http->push_headers = NULL;
|
||||
}
|
||||
if(http->stream_id) {
|
||||
nghttp2_session_set_stream_user_data(httpc->h2, http->stream_id, 0);
|
||||
http->stream_id = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
if(HTTPREQ_POST_FORM == data->set.httpreq) {
|
||||
data->req.bytecount = http->readbytecount + http->writebytecount;
|
||||
|
||||
@ -1468,8 +1504,8 @@ CURLcode Curl_http_done(struct connectdata *conn,
|
||||
else if(HTTPREQ_PUT == data->set.httpreq)
|
||||
data->req.bytecount = http->readbytecount + http->writebytecount;
|
||||
|
||||
if(status != CURLE_OK)
|
||||
return (status);
|
||||
if(status)
|
||||
return status;
|
||||
|
||||
if(!premature && /* this check is pointless when DONE is called before the
|
||||
entire operation is complete */
|
||||
@ -1517,10 +1553,11 @@ static CURLcode expect100(struct SessionHandle *data,
|
||||
const char *ptr;
|
||||
data->state.expect100header = FALSE; /* default to false unless it is set
|
||||
to TRUE below */
|
||||
if(use_http_1_1plus(data, conn)) {
|
||||
/* if not doing HTTP 1.0 or disabled explicitly, we add a Expect:
|
||||
100-continue to the headers which actually speeds up post operations
|
||||
(as there is one packet coming back from the web server) */
|
||||
if(use_http_1_1plus(data, conn) &&
|
||||
(conn->httpversion != 20)) {
|
||||
/* if not doing HTTP 1.0 or version 2, or disabled explicitly, we add an
|
||||
Expect: 100-continue to the headers which actually speeds up post
|
||||
operations (as there is one packet coming back from the web server) */
|
||||
ptr = Curl_checkheaders(conn, "Expect:");
|
||||
if(ptr) {
|
||||
data->state.expect100header =
|
||||
@ -1529,7 +1566,7 @@ static CURLcode expect100(struct SessionHandle *data,
|
||||
else {
|
||||
result = Curl_add_bufferf(req_buffer,
|
||||
"Expect: 100-continue\r\n");
|
||||
if(result == CURLE_OK)
|
||||
if(!result)
|
||||
data->state.expect100header = TRUE;
|
||||
}
|
||||
}
|
||||
@ -1659,10 +1696,8 @@ CURLcode Curl_add_timecondition(struct SessionHandle *data,
|
||||
{
|
||||
const struct tm *tm;
|
||||
char *buf = data->state.buffer;
|
||||
CURLcode result = CURLE_OK;
|
||||
struct tm keeptime;
|
||||
|
||||
result = Curl_gmtime(data->set.timevalue, &keeptime);
|
||||
CURLcode result = Curl_gmtime(data->set.timevalue, &keeptime);
|
||||
if(result) {
|
||||
failf(data, "Invalid TIMEVALUE");
|
||||
return result;
|
||||
@ -1713,8 +1748,8 @@ CURLcode Curl_add_timecondition(struct SessionHandle *data,
|
||||
*/
|
||||
CURLcode Curl_http(struct connectdata *conn, bool *done)
|
||||
{
|
||||
struct SessionHandle *data=conn->data;
|
||||
CURLcode result=CURLE_OK;
|
||||
struct SessionHandle *data = conn->data;
|
||||
CURLcode result = CURLE_OK;
|
||||
struct HTTP *http;
|
||||
const char *ppath = data->state.path;
|
||||
bool paste_ftp_userpwd = FALSE;
|
||||
@ -1724,7 +1759,9 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
||||
const char *ptr;
|
||||
const char *request;
|
||||
Curl_HttpReq httpreq = data->set.httpreq;
|
||||
#if !defined(CURL_DISABLE_COOKIES)
|
||||
char *addcookies = NULL;
|
||||
#endif
|
||||
curl_off_t included_body = 0;
|
||||
const char *httpstring;
|
||||
Curl_send_buffer *req_buffer;
|
||||
@ -1738,8 +1775,9 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
||||
|
||||
if(conn->httpversion < 20) { /* unless the connection is re-used and already
|
||||
http2 */
|
||||
switch (conn->negnpn) {
|
||||
case NPN_HTTP2:
|
||||
switch(conn->negnpn) {
|
||||
case CURL_HTTP_VERSION_2_0:
|
||||
conn->httpversion = 20; /* we know we're on HTTP/2 now */
|
||||
result = Curl_http2_init(conn);
|
||||
if(result)
|
||||
return result;
|
||||
@ -1748,11 +1786,11 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
result = Curl_http2_switched(conn);
|
||||
result = Curl_http2_switched(conn, NULL, 0);
|
||||
if(result)
|
||||
return result;
|
||||
break;
|
||||
case NPN_HTTP1_1:
|
||||
case CURL_HTTP_VERSION_1_1:
|
||||
/* continue with HTTP/1.1 when explicitly requested */
|
||||
break;
|
||||
default:
|
||||
@ -1770,8 +1808,6 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
||||
http = data->req.protop;
|
||||
|
||||
if(!data->state.this_is_a_follow) {
|
||||
/* this is not a followed location, get the original host name */
|
||||
if(data->state.first_host)
|
||||
/* Free to avoid leaking memory on multiple requests*/
|
||||
free(data->state.first_host);
|
||||
|
||||
@ -1817,7 +1853,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
||||
it might have been used in the proxy connect, but if we have got a header
|
||||
with the user-agent string specified, we erase the previously made string
|
||||
here. */
|
||||
if(Curl_checkheaders(conn, "User-Agent:") && conn->allocptr.uagent) {
|
||||
if(Curl_checkheaders(conn, "User-Agent:")) {
|
||||
free(conn->allocptr.uagent);
|
||||
conn->allocptr.uagent=NULL;
|
||||
}
|
||||
@ -1846,8 +1882,10 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
||||
else
|
||||
conn->allocptr.ref = NULL;
|
||||
|
||||
#if !defined(CURL_DISABLE_COOKIES)
|
||||
if(data->set.str[STRING_COOKIE] && !Curl_checkheaders(conn, "Cookie:"))
|
||||
addcookies = data->set.str[STRING_COOKIE];
|
||||
#endif
|
||||
|
||||
if(!Curl_checkheaders(conn, "Accept-Encoding:") &&
|
||||
data->set.str[STRING_ENCODING]) {
|
||||
@ -1958,6 +1996,13 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
||||
}
|
||||
#endif
|
||||
|
||||
if(strcmp("Host:", ptr)) {
|
||||
conn->allocptr.host = aprintf("%s\r\n", ptr);
|
||||
if(!conn->allocptr.host)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
else
|
||||
/* when clearing the header */
|
||||
conn->allocptr.host = NULL;
|
||||
}
|
||||
else {
|
||||
@ -2153,7 +2198,6 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
||||
if(((httpreq == HTTPREQ_GET) || (httpreq == HTTPREQ_HEAD)) &&
|
||||
!Curl_checkheaders(conn, "Range:")) {
|
||||
/* if a line like this was already allocated, free the previous one */
|
||||
if(conn->allocptr.rangeline)
|
||||
free(conn->allocptr.rangeline);
|
||||
conn->allocptr.rangeline = aprintf("Range: bytes=%s\r\n",
|
||||
data->state.range);
|
||||
@ -2162,7 +2206,6 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
||||
!Curl_checkheaders(conn, "Content-Range:")) {
|
||||
|
||||
/* if a line like this was already allocated, free the previous one */
|
||||
if(conn->allocptr.rangeline)
|
||||
free(conn->allocptr.rangeline);
|
||||
|
||||
if(data->set.set_resume_from < 0) {
|
||||
@ -2227,11 +2270,11 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
||||
Curl_add_bufferf(req_buffer,
|
||||
"%s" /* ftp typecode (;type=x) */
|
||||
" HTTP/%s\r\n" /* HTTP version */
|
||||
"%s" /* host */
|
||||
"%s" /* proxyuserpwd */
|
||||
"%s" /* userpwd */
|
||||
"%s" /* range */
|
||||
"%s" /* user agent */
|
||||
"%s" /* host */
|
||||
"%s" /* accept */
|
||||
"%s" /* TE: */
|
||||
"%s" /* accept-encoding */
|
||||
@ -2241,6 +2284,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
||||
|
||||
ftp_typecode,
|
||||
httpstring,
|
||||
(conn->allocptr.host?conn->allocptr.host:""),
|
||||
conn->allocptr.proxyuserpwd?
|
||||
conn->allocptr.proxyuserpwd:"",
|
||||
conn->allocptr.userpwd?conn->allocptr.userpwd:"",
|
||||
@ -2250,7 +2294,6 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
||||
*data->set.str[STRING_USERAGENT] &&
|
||||
conn->allocptr.uagent)?
|
||||
conn->allocptr.uagent:"",
|
||||
(conn->allocptr.host?conn->allocptr.host:""),
|
||||
http->p_accept?http->p_accept:"",
|
||||
conn->allocptr.te?conn->allocptr.te:"",
|
||||
(data->set.str[STRING_ENCODING] &&
|
||||
@ -2266,18 +2309,26 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
||||
te
|
||||
);
|
||||
|
||||
/*
|
||||
* Free userpwd now --- cannot reuse this for Negotiate and possibly NTLM
|
||||
* with basic and digest, it will be freed anyway by the next request
|
||||
*/
|
||||
/* clear userpwd to avoid re-using credentials from re-used connections */
|
||||
Curl_safefree(conn->allocptr.userpwd);
|
||||
|
||||
Curl_safefree (conn->allocptr.userpwd);
|
||||
conn->allocptr.userpwd = NULL;
|
||||
/*
|
||||
* Free proxyuserpwd for Negotiate/NTLM. Cannot reuse as it is associated
|
||||
* with the connection and shouldn't be repeated over it either.
|
||||
*/
|
||||
switch (data->state.authproxy.picked) {
|
||||
case CURLAUTH_NEGOTIATE:
|
||||
case CURLAUTH_NTLM:
|
||||
case CURLAUTH_NTLM_WB:
|
||||
Curl_safefree(conn->allocptr.proxyuserpwd);
|
||||
break;
|
||||
}
|
||||
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
if(!(conn->handler->flags&PROTOPT_SSL) &&
|
||||
conn->httpversion != 20 &&
|
||||
(data->set.httpversion == CURL_HTTP_VERSION_2_0)) {
|
||||
/* append HTTP2 upgrade magic stuff to the HTTP request if it isn't done
|
||||
over SSL */
|
||||
@ -2322,17 +2373,16 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
||||
}
|
||||
Curl_cookie_freelist(store, FALSE); /* free the cookie list */
|
||||
}
|
||||
if(addcookies && (CURLE_OK == result)) {
|
||||
if(addcookies && !result) {
|
||||
if(!count)
|
||||
result = Curl_add_bufferf(req_buffer, "Cookie: ");
|
||||
if(CURLE_OK == result) {
|
||||
result = Curl_add_bufferf(req_buffer, "%s%s",
|
||||
count?"; ":"",
|
||||
if(!result) {
|
||||
result = Curl_add_bufferf(req_buffer, "%s%s", count?"; ":"",
|
||||
addcookies);
|
||||
count++;
|
||||
}
|
||||
}
|
||||
if(count && (CURLE_OK == result))
|
||||
if(count && !result)
|
||||
result = Curl_add_buffer(req_buffer, "\r\n", 2);
|
||||
|
||||
if(result)
|
||||
@ -2351,7 +2401,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
||||
return result;
|
||||
|
||||
http->postdata = NULL; /* nothing to post at this point */
|
||||
Curl_pgrsSetUploadSize(data, 0); /* upload size is 0 atm */
|
||||
Curl_pgrsSetUploadSize(data, -1); /* upload size is unknown atm */
|
||||
|
||||
/* If 'authdone' is FALSE, we must not set the write socket index to the
|
||||
Curl_transfer() call below, as we're not ready to actually upload any
|
||||
@ -2384,14 +2434,14 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
||||
|
||||
/* Get the currently set callback function pointer and store that in the
|
||||
form struct since we might want the actual user-provided callback later
|
||||
on. The conn->fread_func pointer itself will be changed for the
|
||||
on. The data->set.fread_func pointer itself will be changed for the
|
||||
multipart case to the function that returns a multipart formatted
|
||||
stream. */
|
||||
http->form.fread_func = conn->fread_func;
|
||||
http->form.fread_func = data->set.fread_func;
|
||||
|
||||
/* Set the read function to read from the generated form data */
|
||||
conn->fread_func = (curl_read_callback)Curl_FormReader;
|
||||
conn->fread_in = &http->form;
|
||||
data->set.fread_func = (curl_read_callback)Curl_FormReader;
|
||||
data->set.in = &http->form;
|
||||
|
||||
http->sending = HTTPSEND_BODY;
|
||||
|
||||
@ -2511,8 +2561,8 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
||||
postsize = 0;
|
||||
else {
|
||||
/* figure out the size of the postfields */
|
||||
postsize = (data->set.postfieldsize != -1)?
|
||||
data->set.postfieldsize:
|
||||
postsize = (data->state.infilesize != -1)?
|
||||
data->state.infilesize:
|
||||
(data->set.postfields? (curl_off_t)strlen(data->set.postfields):-1);
|
||||
}
|
||||
|
||||
@ -2584,17 +2634,16 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
||||
if(postsize) {
|
||||
/* Append the POST data chunky-style */
|
||||
result = Curl_add_bufferf(req_buffer, "%x\r\n", (int)postsize);
|
||||
if(CURLE_OK == result) {
|
||||
if(!result) {
|
||||
result = Curl_add_buffer(req_buffer, data->set.postfields,
|
||||
(size_t)postsize);
|
||||
if(CURLE_OK == result)
|
||||
if(!result)
|
||||
result = Curl_add_buffer(req_buffer, "\r\n", 2);
|
||||
included_body = postsize + 2;
|
||||
}
|
||||
}
|
||||
if(CURLE_OK == result)
|
||||
result = Curl_add_buffer(req_buffer,
|
||||
"\x30\x0d\x0a\x0d\x0a", 5);
|
||||
if(!result)
|
||||
result = Curl_add_buffer(req_buffer, "\x30\x0d\x0a\x0d\x0a", 5);
|
||||
/* 0 CR LF CR LF */
|
||||
included_body += 5;
|
||||
}
|
||||
@ -2610,8 +2659,8 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
||||
|
||||
http->sending = HTTPSEND_BODY;
|
||||
|
||||
conn->fread_func = (curl_read_callback)readmoredata;
|
||||
conn->fread_in = (void *)conn;
|
||||
data->set.fread_func = (curl_read_callback)readmoredata;
|
||||
data->set.in = (void *)conn;
|
||||
|
||||
/* set the upload size to the progress meter */
|
||||
Curl_pgrsSetUploadSize(data, http->postsize);
|
||||
@ -2636,7 +2685,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
|
||||
return result;
|
||||
}
|
||||
|
||||
else if(data->set.postfieldsize) {
|
||||
else if(data->state.infilesize) {
|
||||
/* set the upload size to the progress meter */
|
||||
Curl_pgrsSetUploadSize(data, postsize?postsize:-1);
|
||||
|
||||
@ -2997,10 +3046,12 @@ CURLcode Curl_http_readwrite_headers(struct SessionHandle *data,
|
||||
infof(data, "Received 101\n");
|
||||
k->upgr101 = UPGR101_RECEIVED;
|
||||
|
||||
/* switch to http2 now */
|
||||
result = Curl_http2_switched(conn);
|
||||
/* switch to http2 now. The bytes after response headers
|
||||
are also processed here, otherwise they are lost. */
|
||||
result = Curl_http2_switched(conn, k->str, *nread);
|
||||
if(result)
|
||||
return result;
|
||||
*nread = 0;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@ -3025,6 +3076,19 @@ CURLcode Curl_http_readwrite_headers(struct SessionHandle *data,
|
||||
}
|
||||
}
|
||||
|
||||
/* At this point we have some idea about the fate of the connection.
|
||||
If we are closing the connection it may result auth failure. */
|
||||
#if defined(USE_NTLM)
|
||||
if(conn->bits.close &&
|
||||
(((data->req.httpcode == 401) &&
|
||||
(conn->ntlm.state == NTLMSTATE_TYPE2)) ||
|
||||
((data->req.httpcode == 407) &&
|
||||
(conn->proxyntlm.state == NTLMSTATE_TYPE2)))) {
|
||||
infof(data, "Connection closure while negotiating auth (HTTP 1.0?)\n");
|
||||
data->state.authproblem = TRUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* When all the headers have been parsed, see if we should give
|
||||
* up and return an error.
|
||||
@ -3121,6 +3185,16 @@ CURLcode Curl_http_readwrite_headers(struct SessionHandle *data,
|
||||
*/
|
||||
if(data->set.opt_no_body)
|
||||
*stop_reading = TRUE;
|
||||
#ifndef CURL_DISABLE_RTSP
|
||||
else if((conn->handler->protocol & CURLPROTO_RTSP) &&
|
||||
(data->set.rtspreq == RTSPREQ_DESCRIBE) &&
|
||||
(k->size <= -1))
|
||||
/* Respect section 4.4 of rfc2326: If the Content-Length header is
|
||||
absent, a length 0 must be assumed. It will prevent libcurl from
|
||||
hanging on DECRIBE request that got refused for whatever
|
||||
reason */
|
||||
*stop_reading = TRUE;
|
||||
#endif
|
||||
else {
|
||||
/* If we know the expected size of this document, we set the
|
||||
maximum download size to the size of the expected
|
||||
@ -3203,13 +3277,26 @@ CURLcode Curl_http_readwrite_headers(struct SessionHandle *data,
|
||||
#endif /* CURL_DOES_CONVERSIONS */
|
||||
|
||||
if(conn->handler->protocol & PROTO_FAMILY_HTTP) {
|
||||
/*
|
||||
* https://tools.ietf.org/html/rfc7230#section-3.1.2
|
||||
*
|
||||
* The reponse code is always a three-digit number in HTTP as the spec
|
||||
* says. We try to allow any number here, but we cannot make
|
||||
* guarantees on future behaviors since it isn't within the protocol.
|
||||
*/
|
||||
nc = sscanf(HEADER1,
|
||||
" HTTP/%d.%d %3d",
|
||||
" HTTP/%d.%d %d",
|
||||
&httpversion_major,
|
||||
&conn->httpversion,
|
||||
&k->httpcode);
|
||||
if(nc==3) {
|
||||
conn->httpversion += 10 * httpversion_major;
|
||||
|
||||
if(k->upgr101 == UPGR101_RECEIVED) {
|
||||
/* supposedly upgraded to http2 now */
|
||||
if(conn->httpversion != 20)
|
||||
infof(data, "Lying server, not serving HTTP/2\n");
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* this is the real world, not a Nirvana
|
||||
@ -3287,20 +3374,25 @@ CURLcode Curl_http_readwrite_headers(struct SessionHandle *data,
|
||||
infof(data, "HTTP 1.0, assume close after body\n");
|
||||
connclose(conn, "HTTP/1.0 close after body");
|
||||
}
|
||||
else if(conn->httpversion == 20 ||
|
||||
(k->upgr101 == UPGR101_REQUESTED && k->httpcode == 101)) {
|
||||
DEBUGF(infof(data, "HTTP/2 found, allow multiplexing\n"));
|
||||
|
||||
/* HTTP/2 cannot blacklist multiplexing since it is a core
|
||||
functionality of the protocol */
|
||||
conn->bundle->multiuse = BUNDLE_MULTIPLEX;
|
||||
}
|
||||
else if(conn->httpversion >= 11 &&
|
||||
!conn->bits.close) {
|
||||
struct connectbundle *cb_ptr;
|
||||
|
||||
/* If HTTP version is >= 1.1 and connection is persistent
|
||||
server supports pipelining. */
|
||||
DEBUGF(infof(data,
|
||||
"HTTP 1.1 or later with persistent connection, "
|
||||
"pipelining supported\n"));
|
||||
/* Activate pipelining if needed */
|
||||
cb_ptr = conn->bundle;
|
||||
if(cb_ptr) {
|
||||
if(conn->bundle) {
|
||||
if(!Curl_pipeline_site_blacklisted(data, conn))
|
||||
cb_ptr->server_supports_pipelining = TRUE;
|
||||
conn->bundle->multiuse = BUNDLE_PIPELINING;
|
||||
}
|
||||
}
|
||||
|
||||
@ -3379,14 +3471,17 @@ CURLcode Curl_http_readwrite_headers(struct SessionHandle *data,
|
||||
}
|
||||
}
|
||||
else if(checkprefix("Server:", k->p)) {
|
||||
if(conn->httpversion < 20) {
|
||||
/* only do this for non-h2 servers */
|
||||
char *server_name = Curl_copy_header_value(k->p);
|
||||
|
||||
/* Turn off pipelining if the server version is blacklisted */
|
||||
if(conn->bundle && conn->bundle->server_supports_pipelining) {
|
||||
if(conn->bundle && (conn->bundle->multiuse == BUNDLE_PIPELINING)) {
|
||||
if(Curl_pipeline_server_blacklisted(data, server_name))
|
||||
conn->bundle->server_supports_pipelining = FALSE;
|
||||
conn->bundle->multiuse = BUNDLE_NO_MULTIUSE;
|
||||
}
|
||||
free(server_name);
|
||||
}
|
||||
Curl_safefree(server_name);
|
||||
}
|
||||
else if((conn->httpversion == 10) &&
|
||||
conn->bits.httpproxy &&
|
||||
@ -3483,14 +3578,6 @@ CURLcode Curl_http_readwrite_headers(struct SessionHandle *data,
|
||||
k->auto_decoding = GZIP;
|
||||
start += 6;
|
||||
}
|
||||
else if(checkprefix("compress", start)) {
|
||||
k->auto_decoding = COMPRESS;
|
||||
start += 8;
|
||||
}
|
||||
else if(checkprefix("x-compress", start)) {
|
||||
k->auto_decoding = COMPRESS;
|
||||
start += 10;
|
||||
}
|
||||
else
|
||||
/* unknown! */
|
||||
break;
|
||||
@ -3523,9 +3610,6 @@ CURLcode Curl_http_readwrite_headers(struct SessionHandle *data,
|
||||
else if(checkprefix("gzip", start)
|
||||
|| checkprefix("x-gzip", start))
|
||||
k->auto_decoding = GZIP;
|
||||
else if(checkprefix("compress", start)
|
||||
|| checkprefix("x-compress", start))
|
||||
k->auto_decoding = COMPRESS;
|
||||
}
|
||||
else if(checkprefix("Content-Range:", k->p)) {
|
||||
/* Content-Range: bytes [num]-
|
||||
@ -3591,7 +3675,7 @@ CURLcode Curl_http_readwrite_headers(struct SessionHandle *data,
|
||||
|
||||
result = Curl_http_input_auth(conn, proxy, auth);
|
||||
|
||||
Curl_safefree(auth);
|
||||
free(auth);
|
||||
|
||||
if(result)
|
||||
return result;
|
||||
|
@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -60,6 +60,7 @@ struct Curl_send_buffer {
|
||||
typedef struct Curl_send_buffer Curl_send_buffer;
|
||||
|
||||
Curl_send_buffer *Curl_add_buffer_init(void);
|
||||
void Curl_add_buffer_free(Curl_send_buffer *buff);
|
||||
CURLcode Curl_add_bufferf(Curl_send_buffer *in, const char *fmt, ...);
|
||||
CURLcode Curl_add_buffer(Curl_send_buffer *in, const void *inptr, size_t size);
|
||||
CURLcode Curl_add_buffer_send(Curl_send_buffer *in,
|
||||
@ -152,42 +153,69 @@ struct HTTP {
|
||||
|
||||
void *send_buffer; /* used if the request couldn't be sent in one chunk,
|
||||
points to an allocated send_buffer struct */
|
||||
|
||||
#ifdef USE_NGHTTP2
|
||||
/*********** for HTTP/2 we store stream-local data here *************/
|
||||
int32_t stream_id; /* stream we are interested in */
|
||||
|
||||
bool bodystarted;
|
||||
/* We store non-final and final response headers here, per-stream */
|
||||
Curl_send_buffer *header_recvbuf;
|
||||
size_t nread_header_recvbuf; /* number of bytes in header_recvbuf fed into
|
||||
upper layer */
|
||||
int status_code; /* HTTP status code */
|
||||
const uint8_t *pausedata; /* pointer to data received in on_data_chunk */
|
||||
size_t pauselen; /* the number of bytes left in data */
|
||||
bool closed; /* TRUE on HTTP2 stream close */
|
||||
uint32_t error_code; /* HTTP/2 error code */
|
||||
|
||||
char *mem; /* points to a buffer in memory to store received data */
|
||||
size_t len; /* size of the buffer 'mem' points to */
|
||||
size_t memlen; /* size of data copied to mem */
|
||||
|
||||
const uint8_t *upload_mem; /* points to a buffer to read from */
|
||||
size_t upload_len; /* size of the buffer 'upload_mem' points to */
|
||||
curl_off_t upload_left; /* number of bytes left to upload */
|
||||
|
||||
char **push_headers; /* allocated array */
|
||||
size_t push_headers_used; /* number of entries filled in */
|
||||
size_t push_headers_alloc; /* number of entries allocated */
|
||||
#endif
|
||||
};
|
||||
|
||||
typedef int (*sending)(void); /* Curl_send */
|
||||
typedef int (*recving)(void); /* Curl_recv */
|
||||
|
||||
#ifdef USE_NGHTTP2
|
||||
/* h2 settings for this connection */
|
||||
struct h2settings {
|
||||
uint32_t max_concurrent_streams;
|
||||
bool enable_push;
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
struct http_conn {
|
||||
#ifdef USE_NGHTTP2
|
||||
#define H2_BINSETTINGS_LEN 80
|
||||
nghttp2_session *h2;
|
||||
uint8_t binsettings[H2_BINSETTINGS_LEN];
|
||||
size_t binlen; /* length of the binsettings data */
|
||||
char *mem; /* points to a buffer in memory to store */
|
||||
size_t len; /* size of the buffer 'mem' points to */
|
||||
bool bodystarted;
|
||||
sending send_underlying; /* underlying send Curl_send callback */
|
||||
recving recv_underlying; /* underlying recv Curl_recv callback */
|
||||
bool closed; /* TRUE on HTTP2 stream close */
|
||||
Curl_send_buffer *header_recvbuf; /* store response headers. We
|
||||
store non-final and final
|
||||
response headers into it. */
|
||||
size_t nread_header_recvbuf; /* number of bytes in header_recvbuf
|
||||
fed into upper layer */
|
||||
int32_t stream_id; /* stream we are interested in */
|
||||
const uint8_t *data; /* pointer to data chunk, received in
|
||||
on_data_chunk */
|
||||
size_t datalen; /* the number of bytes left in data */
|
||||
char *inbuf; /* buffer to receive data from underlying socket */
|
||||
size_t inbuflen; /* number of bytes filled in inbuf */
|
||||
size_t nread_inbuf; /* number of bytes read from in inbuf */
|
||||
/* We need separate buffer for transmission and reception because we
|
||||
may call nghttp2_session_send() after the
|
||||
nghttp2_session_mem_recv() but mem buffer is still not full. In
|
||||
this case, we wrongly sends the content of mem buffer if we share
|
||||
them for both cases. */
|
||||
const uint8_t *upload_mem; /* points to a buffer to read from */
|
||||
size_t upload_len; /* size of the buffer 'upload_mem' points to */
|
||||
size_t upload_left; /* number of bytes left to upload */
|
||||
int status_code; /* HTTP status code */
|
||||
int32_t pause_stream_id; /* stream ID which paused
|
||||
nghttp2_session_mem_recv */
|
||||
|
||||
/* this is a hash of all individual streams (SessionHandle structs) */
|
||||
struct h2settings settings;
|
||||
#else
|
||||
int unused; /* prevent a compiler warning */
|
||||
#endif
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -26,6 +26,11 @@
|
||||
|
||||
#ifdef USE_NGHTTP2
|
||||
#include "http.h"
|
||||
|
||||
/* value for MAX_CONCURRENT_STREAMS we use until we get an updated setting
|
||||
from the peer */
|
||||
#define DEFAULT_MAX_CONCURRENT_STREAMS 13
|
||||
|
||||
/*
|
||||
* Store nghttp2 version info in this buffer, Prefix with a space. Return
|
||||
* total length written.
|
||||
@ -37,13 +42,19 @@ CURLcode Curl_http2_send_request(struct connectdata *conn);
|
||||
CURLcode Curl_http2_request_upgrade(Curl_send_buffer *req,
|
||||
struct connectdata *conn);
|
||||
CURLcode Curl_http2_setup(struct connectdata *conn);
|
||||
CURLcode Curl_http2_switched(struct connectdata *conn);
|
||||
CURLcode Curl_http2_switched(struct connectdata *conn,
|
||||
const char *data, size_t nread);
|
||||
/* called from Curl_http_setup_conn */
|
||||
void Curl_http2_setup_conn(struct connectdata *conn);
|
||||
void Curl_http2_setup_req(struct SessionHandle *data);
|
||||
#else /* USE_NGHTTP2 */
|
||||
#define Curl_http2_init(x) CURLE_UNSUPPORTED_PROTOCOL
|
||||
#define Curl_http2_send_request(x) CURLE_UNSUPPORTED_PROTOCOL
|
||||
#define Curl_http2_request_upgrade(x,y) CURLE_UNSUPPORTED_PROTOCOL
|
||||
#define Curl_http2_setup(x) CURLE_UNSUPPORTED_PROTOCOL
|
||||
#define Curl_http2_switched(x) CURLE_UNSUPPORTED_PROTOCOL
|
||||
#define Curl_http2_switched(x,y,z) CURLE_UNSUPPORTED_PROTOCOL
|
||||
#define Curl_http2_setup_conn(x)
|
||||
#define Curl_http2_setup_req(x)
|
||||
#endif
|
||||
|
||||
#endif /* HEADER_CURL_HTTP2_H */
|
||||
|
@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -29,15 +29,12 @@
|
||||
|
||||
#include "content_encoding.h"
|
||||
#include "http.h"
|
||||
#include "curl_memory.h"
|
||||
#include "non-ascii.h" /* for Curl_convert_to_network prototype */
|
||||
#include "strtoofft.h"
|
||||
#include "warnless.h"
|
||||
|
||||
#define _MPRINTF_REPLACE /* use our functions only */
|
||||
#include <curl/mprintf.h>
|
||||
|
||||
/* The last #include file should be: */
|
||||
/* The last #include files should be: */
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
/*
|
||||
@ -158,7 +155,7 @@ CHUNKcode Curl_httpchunk_read(struct connectdata *conn,
|
||||
if(result) {
|
||||
/* Curl_convert_from_network calls failf if unsuccessful */
|
||||
/* Treat it as a bad hex character */
|
||||
return CHUNKE_ILLEGAL_HEX ;
|
||||
return CHUNKE_ILLEGAL_HEX;
|
||||
}
|
||||
|
||||
ch->datasize=curlx_strtoofft(ch->hexbuffer, &endptr, 16);
|
||||
@ -221,7 +218,6 @@ CHUNKcode Curl_httpchunk_read(struct connectdata *conn,
|
||||
(ssize_t)piece);
|
||||
break;
|
||||
|
||||
case COMPRESS:
|
||||
default:
|
||||
failf (conn->data,
|
||||
"Unrecognized content encoding type. "
|
||||
|
@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -26,94 +26,14 @@
|
||||
|
||||
#include "urldata.h"
|
||||
#include "rawstr.h"
|
||||
#include "curl_base64.h"
|
||||
#include "curl_md5.h"
|
||||
#include "curl_sasl.h"
|
||||
#include "http_digest.h"
|
||||
#include "strtok.h"
|
||||
#include "curl_printf.h"
|
||||
|
||||
/* The last #include files should be: */
|
||||
#include "curl_memory.h"
|
||||
#include "vtls/vtls.h" /* for Curl_rand() */
|
||||
#include "non-ascii.h" /* included for Curl_convert_... prototypes */
|
||||
#include "warnless.h"
|
||||
|
||||
#define _MPRINTF_REPLACE /* use our functions only */
|
||||
#include <curl/mprintf.h>
|
||||
|
||||
/* The last #include file should be: */
|
||||
#include "memdebug.h"
|
||||
|
||||
#define MAX_VALUE_LENGTH 256
|
||||
#define MAX_CONTENT_LENGTH 1024
|
||||
|
||||
static void digest_cleanup_one(struct digestdata *dig);
|
||||
|
||||
/*
|
||||
* Return 0 on success and then the buffers are filled in fine.
|
||||
*
|
||||
* Non-zero means failure to parse.
|
||||
*/
|
||||
static int get_pair(const char *str, char *value, char *content,
|
||||
const char **endptr)
|
||||
{
|
||||
int c;
|
||||
bool starts_with_quote = FALSE;
|
||||
bool escape = FALSE;
|
||||
|
||||
for(c=MAX_VALUE_LENGTH-1; (*str && (*str != '=') && c--); )
|
||||
*value++ = *str++;
|
||||
*value=0;
|
||||
|
||||
if('=' != *str++)
|
||||
/* eek, no match */
|
||||
return 1;
|
||||
|
||||
if('\"' == *str) {
|
||||
/* this starts with a quote so it must end with one as well! */
|
||||
str++;
|
||||
starts_with_quote = TRUE;
|
||||
}
|
||||
|
||||
for(c=MAX_CONTENT_LENGTH-1; *str && c--; str++) {
|
||||
switch(*str) {
|
||||
case '\\':
|
||||
if(!escape) {
|
||||
/* possibly the start of an escaped quote */
|
||||
escape = TRUE;
|
||||
*content++ = '\\'; /* even though this is an escape character, we still
|
||||
store it as-is in the target buffer */
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
case ',':
|
||||
if(!starts_with_quote) {
|
||||
/* this signals the end of the content if we didn't get a starting
|
||||
quote and then we do "sloppy" parsing */
|
||||
c=0; /* the end */
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
case '\r':
|
||||
case '\n':
|
||||
/* end of string */
|
||||
c=0;
|
||||
continue;
|
||||
case '\"':
|
||||
if(!escape && starts_with_quote) {
|
||||
/* end of string */
|
||||
c=0;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
escape = FALSE;
|
||||
*content++ = *str;
|
||||
}
|
||||
*content=0;
|
||||
|
||||
*endptr = str;
|
||||
|
||||
return 0; /* all is fine! */
|
||||
}
|
||||
|
||||
/* Test example headers:
|
||||
|
||||
WWW-Authenticate: Digest realm="testrealm", nonce="1053604598"
|
||||
@ -121,177 +41,31 @@ Proxy-Authenticate: Digest realm="testrealm", nonce="1053604598"
|
||||
|
||||
*/
|
||||
|
||||
CURLdigest Curl_input_digest(struct connectdata *conn,
|
||||
CURLcode Curl_input_digest(struct connectdata *conn,
|
||||
bool proxy,
|
||||
const char *header) /* rest of the *-authenticate:
|
||||
header */
|
||||
{
|
||||
char *token = NULL;
|
||||
char *tmp = NULL;
|
||||
bool foundAuth = FALSE;
|
||||
bool foundAuthInt = FALSE;
|
||||
struct SessionHandle *data=conn->data;
|
||||
bool before = FALSE; /* got a nonce before */
|
||||
struct digestdata *d;
|
||||
struct SessionHandle *data = conn->data;
|
||||
|
||||
/* Point to the correct struct with this */
|
||||
struct digestdata *digest;
|
||||
|
||||
if(proxy) {
|
||||
d = &data->state.proxydigest;
|
||||
digest = &data->state.proxydigest;
|
||||
}
|
||||
else {
|
||||
d = &data->state.digest;
|
||||
digest = &data->state.digest;
|
||||
}
|
||||
|
||||
if(checkprefix("Digest", header)) {
|
||||
if(!checkprefix("Digest", header))
|
||||
return CURLE_BAD_CONTENT_ENCODING;
|
||||
|
||||
header += strlen("Digest");
|
||||
|
||||
/* If we already have received a nonce, keep that in mind */
|
||||
if(d->nonce)
|
||||
before = TRUE;
|
||||
|
||||
/* clear off any former leftovers and init to defaults */
|
||||
digest_cleanup_one(d);
|
||||
|
||||
for(;;) {
|
||||
char value[MAX_VALUE_LENGTH];
|
||||
char content[MAX_CONTENT_LENGTH];
|
||||
|
||||
while(*header && ISSPACE(*header))
|
||||
header++;
|
||||
|
||||
/* extract a value=content pair */
|
||||
if(!get_pair(header, value, content, &header)) {
|
||||
if(Curl_raw_equal(value, "nonce")) {
|
||||
d->nonce = strdup(content);
|
||||
if(!d->nonce)
|
||||
return CURLDIGEST_NOMEM;
|
||||
}
|
||||
else if(Curl_raw_equal(value, "stale")) {
|
||||
if(Curl_raw_equal(content, "true")) {
|
||||
d->stale = TRUE;
|
||||
d->nc = 1; /* we make a new nonce now */
|
||||
}
|
||||
}
|
||||
else if(Curl_raw_equal(value, "realm")) {
|
||||
d->realm = strdup(content);
|
||||
if(!d->realm)
|
||||
return CURLDIGEST_NOMEM;
|
||||
}
|
||||
else if(Curl_raw_equal(value, "opaque")) {
|
||||
d->opaque = strdup(content);
|
||||
if(!d->opaque)
|
||||
return CURLDIGEST_NOMEM;
|
||||
}
|
||||
else if(Curl_raw_equal(value, "qop")) {
|
||||
char *tok_buf;
|
||||
/* tokenize the list and choose auth if possible, use a temporary
|
||||
clone of the buffer since strtok_r() ruins it */
|
||||
tmp = strdup(content);
|
||||
if(!tmp)
|
||||
return CURLDIGEST_NOMEM;
|
||||
token = strtok_r(tmp, ",", &tok_buf);
|
||||
while(token != NULL) {
|
||||
if(Curl_raw_equal(token, "auth")) {
|
||||
foundAuth = TRUE;
|
||||
}
|
||||
else if(Curl_raw_equal(token, "auth-int")) {
|
||||
foundAuthInt = TRUE;
|
||||
}
|
||||
token = strtok_r(NULL, ",", &tok_buf);
|
||||
}
|
||||
free(tmp);
|
||||
/*select only auth o auth-int. Otherwise, ignore*/
|
||||
if(foundAuth) {
|
||||
d->qop = strdup("auth");
|
||||
if(!d->qop)
|
||||
return CURLDIGEST_NOMEM;
|
||||
}
|
||||
else if(foundAuthInt) {
|
||||
d->qop = strdup("auth-int");
|
||||
if(!d->qop)
|
||||
return CURLDIGEST_NOMEM;
|
||||
}
|
||||
}
|
||||
else if(Curl_raw_equal(value, "algorithm")) {
|
||||
d->algorithm = strdup(content);
|
||||
if(!d->algorithm)
|
||||
return CURLDIGEST_NOMEM;
|
||||
if(Curl_raw_equal(content, "MD5-sess"))
|
||||
d->algo = CURLDIGESTALGO_MD5SESS;
|
||||
else if(Curl_raw_equal(content, "MD5"))
|
||||
d->algo = CURLDIGESTALGO_MD5;
|
||||
else
|
||||
return CURLDIGEST_BADALGO;
|
||||
}
|
||||
else {
|
||||
/* unknown specifier, ignore it! */
|
||||
}
|
||||
}
|
||||
else
|
||||
break; /* we're done here */
|
||||
|
||||
/* pass all additional spaces here */
|
||||
while(*header && ISSPACE(*header))
|
||||
header++;
|
||||
if(',' == *header)
|
||||
/* allow the list to be comma-separated */
|
||||
header++;
|
||||
}
|
||||
/* We had a nonce since before, and we got another one now without
|
||||
'stale=true'. This means we provided bad credentials in the previous
|
||||
request */
|
||||
if(before && !d->stale)
|
||||
return CURLDIGEST_BAD;
|
||||
|
||||
/* We got this header without a nonce, that's a bad Digest line! */
|
||||
if(!d->nonce)
|
||||
return CURLDIGEST_BAD;
|
||||
}
|
||||
else
|
||||
/* else not a digest, get out */
|
||||
return CURLDIGEST_NONE;
|
||||
|
||||
return CURLDIGEST_FINE;
|
||||
}
|
||||
|
||||
/* convert md5 chunk to RFC2617 (section 3.1.3) -suitable ascii string*/
|
||||
static void md5_to_ascii(unsigned char *source, /* 16 bytes */
|
||||
unsigned char *dest) /* 33 bytes */
|
||||
{
|
||||
int i;
|
||||
for(i=0; i<16; i++)
|
||||
snprintf((char *)&dest[i*2], 3, "%02x", source[i]);
|
||||
}
|
||||
|
||||
/* Perform quoted-string escaping as described in RFC2616 and its errata */
|
||||
static char *string_quoted(const char *source)
|
||||
{
|
||||
char *dest, *d;
|
||||
const char *s = source;
|
||||
size_t n = 1; /* null terminator */
|
||||
|
||||
/* Calculate size needed */
|
||||
while(*s) {
|
||||
++n;
|
||||
if(*s == '"' || *s == '\\') {
|
||||
++n;
|
||||
}
|
||||
++s;
|
||||
}
|
||||
|
||||
dest = malloc(n);
|
||||
if(dest) {
|
||||
s = source;
|
||||
d = dest;
|
||||
while(*s) {
|
||||
if(*s == '"' || *s == '\\') {
|
||||
*d++ = '\\';
|
||||
}
|
||||
*d++ = *s++;
|
||||
}
|
||||
*d = 0;
|
||||
}
|
||||
|
||||
return dest;
|
||||
return Curl_sasl_decode_digest_http_message(header, digest);
|
||||
}
|
||||
|
||||
CURLcode Curl_output_digest(struct connectdata *conn,
|
||||
@ -299,49 +73,35 @@ CURLcode Curl_output_digest(struct connectdata *conn,
|
||||
const unsigned char *request,
|
||||
const unsigned char *uripath)
|
||||
{
|
||||
/* We have a Digest setup for this, use it! Now, to get all the details for
|
||||
this sorted out, I must urge you dear friend to read up on the RFC2617
|
||||
section 3.2.2, */
|
||||
size_t urilen;
|
||||
unsigned char md5buf[16]; /* 16 bytes/128 bits */
|
||||
unsigned char request_digest[33];
|
||||
unsigned char *md5this;
|
||||
unsigned char ha1[33];/* 32 digits and 1 zero byte */
|
||||
unsigned char ha2[33];/* 32 digits and 1 zero byte */
|
||||
char cnoncebuf[33];
|
||||
char *cnonce = NULL;
|
||||
size_t cnonce_sz = 0;
|
||||
char *tmp = NULL;
|
||||
CURLcode result;
|
||||
struct SessionHandle *data = conn->data;
|
||||
unsigned char *path;
|
||||
char *tmp;
|
||||
char *response;
|
||||
size_t len;
|
||||
bool have_chlg;
|
||||
|
||||
/* Point to the address of the pointer that holds the string to send to the
|
||||
server, which is for a plain host or for a HTTP proxy */
|
||||
char **allocuserpwd;
|
||||
size_t userlen;
|
||||
|
||||
/* Point to the name and password for this */
|
||||
const char *userp;
|
||||
char *userp_quoted;
|
||||
const char *passwdp;
|
||||
|
||||
/* Point to the correct struct with this */
|
||||
struct digestdata *digest;
|
||||
struct auth *authp;
|
||||
|
||||
struct SessionHandle *data = conn->data;
|
||||
struct digestdata *d;
|
||||
CURLcode rc;
|
||||
/* The CURL_OUTPUT_DIGEST_CONV macro below is for non-ASCII machines.
|
||||
It converts digest text to ASCII so the MD5 will be correct for
|
||||
what ultimately goes over the network.
|
||||
*/
|
||||
#define CURL_OUTPUT_DIGEST_CONV(a, b) \
|
||||
rc = Curl_convert_to_network(a, (char *)b, strlen((const char*)b)); \
|
||||
if(rc != CURLE_OK) { \
|
||||
free(b); \
|
||||
return rc; \
|
||||
}
|
||||
|
||||
if(proxy) {
|
||||
d = &data->state.proxydigest;
|
||||
digest = &data->state.proxydigest;
|
||||
allocuserpwd = &conn->allocptr.proxyuserpwd;
|
||||
userp = conn->proxyuser;
|
||||
passwdp = conn->proxypasswd;
|
||||
authp = &data->state.authproxy;
|
||||
}
|
||||
else {
|
||||
d = &data->state.digest;
|
||||
digest = &data->state.digest;
|
||||
allocuserpwd = &conn->allocptr.userpwd;
|
||||
userp = conn->user;
|
||||
passwdp = conn->passwd;
|
||||
@ -352,75 +112,21 @@ CURLcode Curl_output_digest(struct connectdata *conn,
|
||||
|
||||
/* not set means empty */
|
||||
if(!userp)
|
||||
userp="";
|
||||
userp = "";
|
||||
|
||||
if(!passwdp)
|
||||
passwdp="";
|
||||
passwdp = "";
|
||||
|
||||
if(!d->nonce) {
|
||||
#if defined(USE_WINDOWS_SSPI)
|
||||
have_chlg = digest->input_token ? TRUE : FALSE;
|
||||
#else
|
||||
have_chlg = digest->nonce ? TRUE : FALSE;
|
||||
#endif
|
||||
|
||||
if(!have_chlg) {
|
||||
authp->done = FALSE;
|
||||
return CURLE_OK;
|
||||
}
|
||||
authp->done = TRUE;
|
||||
|
||||
if(!d->nc)
|
||||
d->nc = 1;
|
||||
|
||||
if(!d->cnonce) {
|
||||
snprintf(cnoncebuf, sizeof(cnoncebuf), "%08x%08x%08x%08x",
|
||||
Curl_rand(data), Curl_rand(data),
|
||||
Curl_rand(data), Curl_rand(data));
|
||||
rc = Curl_base64_encode(data, cnoncebuf, strlen(cnoncebuf),
|
||||
&cnonce, &cnonce_sz);
|
||||
if(rc)
|
||||
return rc;
|
||||
d->cnonce = cnonce;
|
||||
}
|
||||
|
||||
/*
|
||||
if the algorithm is "MD5" or unspecified (which then defaults to MD5):
|
||||
|
||||
A1 = unq(username-value) ":" unq(realm-value) ":" passwd
|
||||
|
||||
if the algorithm is "MD5-sess" then:
|
||||
|
||||
A1 = H( unq(username-value) ":" unq(realm-value) ":" passwd )
|
||||
":" unq(nonce-value) ":" unq(cnonce-value)
|
||||
*/
|
||||
|
||||
md5this = (unsigned char *)
|
||||
aprintf("%s:%s:%s", userp, d->realm, passwdp);
|
||||
if(!md5this)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
CURL_OUTPUT_DIGEST_CONV(data, md5this); /* convert on non-ASCII machines */
|
||||
Curl_md5it(md5buf, md5this);
|
||||
Curl_safefree(md5this);
|
||||
md5_to_ascii(md5buf, ha1);
|
||||
|
||||
if(d->algo == CURLDIGESTALGO_MD5SESS) {
|
||||
/* nonce and cnonce are OUTSIDE the hash */
|
||||
tmp = aprintf("%s:%s:%s", ha1, d->nonce, d->cnonce);
|
||||
if(!tmp)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
CURL_OUTPUT_DIGEST_CONV(data, tmp); /* convert on non-ASCII machines */
|
||||
Curl_md5it(md5buf, (unsigned char *)tmp);
|
||||
Curl_safefree(tmp);
|
||||
md5_to_ascii(md5buf, ha1);
|
||||
}
|
||||
|
||||
/*
|
||||
If the "qop" directive's value is "auth" or is unspecified, then A2 is:
|
||||
|
||||
A2 = Method ":" digest-uri-value
|
||||
|
||||
If the "qop" value is "auth-int", then A2 is:
|
||||
|
||||
A2 = Method ":" digest-uri-value ":" H(entity-body)
|
||||
|
||||
(The "Method" value is the HTTP request method as specified in section
|
||||
5.1.1 of RFC 2616)
|
||||
*/
|
||||
|
||||
/* So IE browsers < v7 cut off the URI part at the query part when they
|
||||
evaluate the MD5 and some (IIS?) servers work with them so we may need to
|
||||
@ -435,164 +141,39 @@ CURLcode Curl_output_digest(struct connectdata *conn,
|
||||
http://www.fngtps.com/2006/09/http-authentication
|
||||
*/
|
||||
|
||||
if(authp->iestyle && ((tmp = strchr((char *)uripath, '?')) != NULL))
|
||||
urilen = tmp - (char *)uripath;
|
||||
if(authp->iestyle && ((tmp = strchr((char *)uripath, '?')) != NULL)) {
|
||||
size_t urilen = tmp - (char *)uripath;
|
||||
|
||||
path = (unsigned char *) aprintf("%.*s", urilen, uripath);
|
||||
}
|
||||
else
|
||||
urilen = strlen((char *)uripath);
|
||||
path = (unsigned char *) strdup((char *) uripath);
|
||||
|
||||
md5this = (unsigned char *)aprintf("%s:%.*s", request, urilen, uripath);
|
||||
|
||||
if(d->qop && Curl_raw_equal(d->qop, "auth-int")) {
|
||||
/* We don't support auth-int for PUT or POST at the moment.
|
||||
TODO: replace md5 of empty string with entity-body for PUT/POST */
|
||||
unsigned char *md5this2 = (unsigned char *)
|
||||
aprintf("%s:%s", md5this, "d41d8cd98f00b204e9800998ecf8427e");
|
||||
Curl_safefree(md5this);
|
||||
md5this = md5this2;
|
||||
}
|
||||
|
||||
if(!md5this)
|
||||
if(!path)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
CURL_OUTPUT_DIGEST_CONV(data, md5this); /* convert on non-ASCII machines */
|
||||
Curl_md5it(md5buf, md5this);
|
||||
Curl_safefree(md5this);
|
||||
md5_to_ascii(md5buf, ha2);
|
||||
result = Curl_sasl_create_digest_http_message(data, userp, passwdp, request,
|
||||
path, digest, &response, &len);
|
||||
free(path);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
if(d->qop) {
|
||||
md5this = (unsigned char *)aprintf("%s:%s:%08x:%s:%s:%s",
|
||||
ha1,
|
||||
d->nonce,
|
||||
d->nc,
|
||||
d->cnonce,
|
||||
d->qop,
|
||||
ha2);
|
||||
}
|
||||
else {
|
||||
md5this = (unsigned char *)aprintf("%s:%s:%s",
|
||||
ha1,
|
||||
d->nonce,
|
||||
ha2);
|
||||
}
|
||||
if(!md5this)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
CURL_OUTPUT_DIGEST_CONV(data, md5this); /* convert on non-ASCII machines */
|
||||
Curl_md5it(md5buf, md5this);
|
||||
Curl_safefree(md5this);
|
||||
md5_to_ascii(md5buf, request_digest);
|
||||
|
||||
/* for test case 64 (snooped from a Mozilla 1.3a request)
|
||||
|
||||
Authorization: Digest username="testuser", realm="testrealm", \
|
||||
nonce="1053604145", uri="/64", response="c55f7f30d83d774a3d2dcacf725abaca"
|
||||
|
||||
Digest parameters are all quoted strings. Username which is provided by
|
||||
the user will need double quotes and backslashes within it escaped. For
|
||||
the other fields, this shouldn't be an issue. realm, nonce, and opaque
|
||||
are copied as is from the server, escapes and all. cnonce is generated
|
||||
with web-safe characters. uri is already percent encoded. nc is 8 hex
|
||||
characters. algorithm and qop with standard values only contain web-safe
|
||||
chracters.
|
||||
*/
|
||||
userp_quoted = string_quoted(userp);
|
||||
if(!userp_quoted)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
if(d->qop) {
|
||||
*allocuserpwd =
|
||||
aprintf( "%sAuthorization: Digest "
|
||||
"username=\"%s\", "
|
||||
"realm=\"%s\", "
|
||||
"nonce=\"%s\", "
|
||||
"uri=\"%.*s\", "
|
||||
"cnonce=\"%s\", "
|
||||
"nc=%08x, "
|
||||
"qop=%s, "
|
||||
"response=\"%s\"",
|
||||
proxy?"Proxy-":"",
|
||||
userp_quoted,
|
||||
d->realm,
|
||||
d->nonce,
|
||||
urilen, uripath, /* this is the PATH part of the URL */
|
||||
d->cnonce,
|
||||
d->nc,
|
||||
d->qop,
|
||||
request_digest);
|
||||
|
||||
if(Curl_raw_equal(d->qop, "auth"))
|
||||
d->nc++; /* The nc (from RFC) has to be a 8 hex digit number 0 padded
|
||||
which tells to the server how many times you are using the
|
||||
same nonce in the qop=auth mode. */
|
||||
}
|
||||
else {
|
||||
*allocuserpwd =
|
||||
aprintf( "%sAuthorization: Digest "
|
||||
"username=\"%s\", "
|
||||
"realm=\"%s\", "
|
||||
"nonce=\"%s\", "
|
||||
"uri=\"%.*s\", "
|
||||
"response=\"%s\"",
|
||||
proxy?"Proxy-":"",
|
||||
userp_quoted,
|
||||
d->realm,
|
||||
d->nonce,
|
||||
urilen, uripath, /* this is the PATH part of the URL */
|
||||
request_digest);
|
||||
}
|
||||
Curl_safefree(userp_quoted);
|
||||
*allocuserpwd = aprintf("%sAuthorization: Digest %s\r\n",
|
||||
proxy ? "Proxy-" : "",
|
||||
response);
|
||||
free(response);
|
||||
if(!*allocuserpwd)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
/* Add optional fields */
|
||||
if(d->opaque) {
|
||||
/* append opaque */
|
||||
tmp = aprintf("%s, opaque=\"%s\"", *allocuserpwd, d->opaque);
|
||||
if(!tmp)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
free(*allocuserpwd);
|
||||
*allocuserpwd = tmp;
|
||||
}
|
||||
|
||||
if(d->algorithm) {
|
||||
/* append algorithm */
|
||||
tmp = aprintf("%s, algorithm=\"%s\"", *allocuserpwd, d->algorithm);
|
||||
if(!tmp)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
free(*allocuserpwd);
|
||||
*allocuserpwd = tmp;
|
||||
}
|
||||
|
||||
/* append CRLF + zero (3 bytes) to the userpwd header */
|
||||
userlen = strlen(*allocuserpwd);
|
||||
tmp = realloc(*allocuserpwd, userlen + 3);
|
||||
if(!tmp)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
strcpy(&tmp[userlen], "\r\n"); /* append the data */
|
||||
*allocuserpwd = tmp;
|
||||
authp->done = TRUE;
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
static void digest_cleanup_one(struct digestdata *d)
|
||||
{
|
||||
Curl_safefree(d->nonce);
|
||||
Curl_safefree(d->cnonce);
|
||||
Curl_safefree(d->realm);
|
||||
Curl_safefree(d->opaque);
|
||||
Curl_safefree(d->qop);
|
||||
Curl_safefree(d->algorithm);
|
||||
|
||||
d->nc = 0;
|
||||
d->algo = CURLDIGESTALGO_MD5; /* default algorithm */
|
||||
d->stale = FALSE; /* default means normal, not stale */
|
||||
}
|
||||
|
||||
|
||||
void Curl_digest_cleanup(struct SessionHandle *data)
|
||||
{
|
||||
digest_cleanup_one(&data->state.digest);
|
||||
digest_cleanup_one(&data->state.proxydigest);
|
||||
Curl_sasl_digest_cleanup(&data->state.digest);
|
||||
Curl_sasl_digest_cleanup(&data->state.proxydigest);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -23,23 +23,8 @@
|
||||
***************************************************************************/
|
||||
#include "curl_setup.h"
|
||||
|
||||
typedef enum {
|
||||
CURLDIGEST_NONE, /* not a digest */
|
||||
CURLDIGEST_BAD, /* a digest, but one we don't like */
|
||||
CURLDIGEST_BADALGO, /* unsupported algorithm requested */
|
||||
CURLDIGEST_NOMEM,
|
||||
CURLDIGEST_FINE, /* a digest we act on */
|
||||
|
||||
CURLDIGEST_LAST /* last entry in this enum, don't use */
|
||||
} CURLdigest;
|
||||
|
||||
enum {
|
||||
CURLDIGESTALGO_MD5,
|
||||
CURLDIGESTALGO_MD5SESS
|
||||
};
|
||||
|
||||
/* this is for digest header input */
|
||||
CURLdigest Curl_input_digest(struct connectdata *conn,
|
||||
CURLcode Curl_input_digest(struct connectdata *conn,
|
||||
bool proxy, const char *header);
|
||||
|
||||
/* this is for creating digest header output */
|
||||
|
@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -22,13 +22,7 @@
|
||||
|
||||
#include "curl_setup.h"
|
||||
|
||||
#ifdef HAVE_GSSAPI
|
||||
#ifdef HAVE_OLD_GSSMIT
|
||||
#define GSS_C_NT_HOSTBASED_SERVICE gss_nt_service_name
|
||||
#define NCOMPAT 1
|
||||
#endif
|
||||
|
||||
#ifndef CURL_DISABLE_HTTP
|
||||
#if defined(HAVE_GSSAPI) && !defined(CURL_DISABLE_HTTP) && defined(USE_SPNEGO)
|
||||
|
||||
#include "urldata.h"
|
||||
#include "sendf.h"
|
||||
@ -36,97 +30,63 @@
|
||||
#include "rawstr.h"
|
||||
#include "curl_base64.h"
|
||||
#include "http_negotiate.h"
|
||||
#include "curl_memory.h"
|
||||
#include "curl_sasl.h"
|
||||
#include "url.h"
|
||||
#include "curl_printf.h"
|
||||
|
||||
#define _MPRINTF_REPLACE /* use our functions only */
|
||||
#include <curl/mprintf.h>
|
||||
|
||||
/* The last #include file should be: */
|
||||
/* The last #include files should be: */
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
static int
|
||||
get_gss_name(struct connectdata *conn, bool proxy, gss_name_t *server)
|
||||
{
|
||||
OM_uint32 major_status, minor_status;
|
||||
gss_buffer_desc token = GSS_C_EMPTY_BUFFER;
|
||||
char name[2048];
|
||||
const char* service = "HTTP";
|
||||
|
||||
token.length = strlen(service) + 1 + strlen(proxy ? conn->proxy.name :
|
||||
conn->host.name) + 1;
|
||||
if(token.length + 1 > sizeof(name))
|
||||
return EMSGSIZE;
|
||||
|
||||
snprintf(name, sizeof(name), "%s@%s", service, proxy ? conn->proxy.name :
|
||||
conn->host.name);
|
||||
|
||||
token.value = (void *) name;
|
||||
major_status = gss_import_name(&minor_status,
|
||||
&token,
|
||||
GSS_C_NT_HOSTBASED_SERVICE,
|
||||
server);
|
||||
|
||||
return GSS_ERROR(major_status) ? -1 : 0;
|
||||
}
|
||||
|
||||
static void
|
||||
log_gss_error(struct connectdata *conn, OM_uint32 error_status,
|
||||
const char *prefix)
|
||||
{
|
||||
OM_uint32 maj_stat, min_stat;
|
||||
OM_uint32 msg_ctx = 0;
|
||||
gss_buffer_desc status_string;
|
||||
char buf[1024];
|
||||
size_t len;
|
||||
|
||||
snprintf(buf, sizeof(buf), "%s", prefix);
|
||||
len = strlen(buf);
|
||||
do {
|
||||
maj_stat = gss_display_status(&min_stat,
|
||||
error_status,
|
||||
GSS_C_MECH_CODE,
|
||||
GSS_C_NO_OID,
|
||||
&msg_ctx,
|
||||
&status_string);
|
||||
if(sizeof(buf) > len + status_string.length + 1) {
|
||||
snprintf(buf + len, sizeof(buf) - len,
|
||||
": %s", (char*) status_string.value);
|
||||
len += status_string.length;
|
||||
}
|
||||
gss_release_buffer(&min_stat, &status_string);
|
||||
} while(!GSS_ERROR(maj_stat) && msg_ctx != 0);
|
||||
|
||||
infof(conn->data, "%s\n", buf);
|
||||
}
|
||||
|
||||
/* 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,
|
||||
CURLcode Curl_input_negotiate(struct connectdata *conn, bool proxy,
|
||||
const char *header)
|
||||
{
|
||||
struct SessionHandle *data = conn->data;
|
||||
struct negotiatedata *neg_ctx = proxy?&data->state.proxyneg:
|
||||
&data->state.negotiate;
|
||||
OM_uint32 major_status, minor_status, discard_st;
|
||||
gss_buffer_desc spn_token = GSS_C_EMPTY_BUFFER;
|
||||
gss_buffer_desc input_token = GSS_C_EMPTY_BUFFER;
|
||||
gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER;
|
||||
int ret;
|
||||
size_t len;
|
||||
size_t rawlen = 0;
|
||||
CURLcode error;
|
||||
CURLcode result;
|
||||
|
||||
if(neg_ctx->context && neg_ctx->status == GSS_S_COMPLETE) {
|
||||
/* We finished successfully our part of authentication, but server
|
||||
* rejected it (since we're again here). Exit with an error since we
|
||||
* can't invent anything better */
|
||||
Curl_cleanup_negotiate(data);
|
||||
return -1;
|
||||
return CURLE_LOGIN_DENIED;
|
||||
}
|
||||
|
||||
if(neg_ctx->server_name == NULL &&
|
||||
(ret = get_gss_name(conn, proxy, &neg_ctx->server_name)))
|
||||
return ret;
|
||||
if(!neg_ctx->server_name) {
|
||||
/* Generate our SPN */
|
||||
char *spn = Curl_sasl_build_gssapi_spn(
|
||||
proxy ? data->set.str[STRING_PROXY_SERVICE_NAME] :
|
||||
data->set.str[STRING_SERVICE_NAME],
|
||||
proxy ? conn->proxy.name : conn->host.name);
|
||||
if(!spn)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
/* Populate the SPN structure */
|
||||
spn_token.value = spn;
|
||||
spn_token.length = strlen(spn);
|
||||
|
||||
/* Import the SPN */
|
||||
major_status = gss_import_name(&minor_status, &spn_token,
|
||||
GSS_C_NT_HOSTBASED_SERVICE,
|
||||
&neg_ctx->server_name);
|
||||
if(GSS_ERROR(major_status)) {
|
||||
Curl_gss_log_error(data, minor_status, "gss_import_name() failed: ");
|
||||
|
||||
free(spn);
|
||||
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
free(spn);
|
||||
}
|
||||
|
||||
header += strlen("Negotiate");
|
||||
while(*header && ISSPACE(*header))
|
||||
@ -134,10 +94,17 @@ int Curl_input_negotiate(struct connectdata *conn, bool proxy,
|
||||
|
||||
len = strlen(header);
|
||||
if(len > 0) {
|
||||
error = Curl_base64_decode(header,
|
||||
(unsigned char **)&input_token.value, &rawlen);
|
||||
if(error || rawlen == 0)
|
||||
return -1;
|
||||
result = Curl_base64_decode(header, (unsigned char **)&input_token.value,
|
||||
&rawlen);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
if(!rawlen) {
|
||||
infof(data, "Negotiate handshake failure (empty challenge message)\n");
|
||||
|
||||
return CURLE_BAD_CONTENT_ENCODING;
|
||||
}
|
||||
|
||||
input_token.length = rawlen;
|
||||
|
||||
DEBUGASSERT(input_token.value != NULL);
|
||||
@ -151,6 +118,7 @@ int Curl_input_negotiate(struct connectdata *conn, bool proxy,
|
||||
GSS_C_NO_CHANNEL_BINDINGS,
|
||||
&input_token,
|
||||
&output_token,
|
||||
TRUE,
|
||||
NULL);
|
||||
Curl_safefree(input_token.value);
|
||||
|
||||
@ -158,20 +126,21 @@ int Curl_input_negotiate(struct connectdata *conn, bool proxy,
|
||||
if(GSS_ERROR(major_status)) {
|
||||
if(output_token.value)
|
||||
gss_release_buffer(&discard_st, &output_token);
|
||||
log_gss_error(conn, minor_status, "gss_init_sec_context() failed: ");
|
||||
return -1;
|
||||
Curl_gss_log_error(conn->data, minor_status,
|
||||
"gss_init_sec_context() failed: ");
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
if(!output_token.value || !output_token.length) {
|
||||
if(output_token.value)
|
||||
gss_release_buffer(&discard_st, &output_token);
|
||||
return -1;
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
neg_ctx->output_token = output_token;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
CURLcode Curl_output_negotiate(struct connectdata *conn, bool proxy)
|
||||
{
|
||||
@ -180,18 +149,18 @@ CURLcode Curl_output_negotiate(struct connectdata *conn, bool proxy)
|
||||
char *encoded = NULL;
|
||||
size_t len = 0;
|
||||
char *userp;
|
||||
CURLcode error;
|
||||
CURLcode result;
|
||||
OM_uint32 discard_st;
|
||||
|
||||
error = Curl_base64_encode(conn->data,
|
||||
result = Curl_base64_encode(conn->data,
|
||||
neg_ctx->output_token.value,
|
||||
neg_ctx->output_token.length,
|
||||
&encoded, &len);
|
||||
if(error) {
|
||||
if(result) {
|
||||
gss_release_buffer(&discard_st, &neg_ctx->output_token);
|
||||
neg_ctx->output_token.value = NULL;
|
||||
neg_ctx->output_token.length = 0;
|
||||
return error;
|
||||
return result;
|
||||
}
|
||||
|
||||
if(!encoded || !len) {
|
||||
@ -212,7 +181,7 @@ CURLcode Curl_output_negotiate(struct connectdata *conn, bool proxy)
|
||||
conn->allocptr.userpwd = userp;
|
||||
}
|
||||
|
||||
Curl_safefree(encoded);
|
||||
free(encoded);
|
||||
|
||||
return (userp == NULL) ? CURLE_OUT_OF_MEMORY : CURLE_OK;
|
||||
}
|
||||
@ -238,6 +207,4 @@ void Curl_cleanup_negotiate(struct SessionHandle *data)
|
||||
cleanup(&data->state.proxyneg);
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
#endif
|
||||
#endif /* HAVE_GSSAPI && !CURL_DISABLE_HTTP && USE_SPNEGO */
|
||||
|
@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -25,7 +25,7 @@
|
||||
#ifdef USE_SPNEGO
|
||||
|
||||
/* this is for Negotiate header input */
|
||||
int Curl_input_negotiate(struct connectdata *conn, bool proxy,
|
||||
CURLcode Curl_input_negotiate(struct connectdata *conn, bool proxy,
|
||||
const char *header);
|
||||
|
||||
/* this is for creating Negotiate header output */
|
||||
|
@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -33,30 +33,27 @@
|
||||
#include "curl_base64.h"
|
||||
#include "curl_sasl.h"
|
||||
#include "http_negotiate.h"
|
||||
#include "curl_memory.h"
|
||||
#include "curl_multibyte.h"
|
||||
#include "curl_printf.h"
|
||||
|
||||
#define _MPRINTF_REPLACE /* use our functions only */
|
||||
#include <curl/mprintf.h>
|
||||
|
||||
/* The last #include file should be: */
|
||||
/* The last #include files should be: */
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
/* 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,
|
||||
CURLcode Curl_input_negotiate(struct connectdata *conn, bool proxy,
|
||||
const char *header)
|
||||
{
|
||||
struct SessionHandle *data = conn->data;
|
||||
BYTE *input_token = NULL;
|
||||
SecBufferDesc out_buff_desc;
|
||||
SecBuffer out_sec_buff;
|
||||
SecBufferDesc in_buff_desc;
|
||||
SecBuffer in_sec_buff;
|
||||
unsigned long context_attributes;
|
||||
TimeStamp lifetime;
|
||||
int ret;
|
||||
SECURITY_STATUS status;
|
||||
unsigned long attrs;
|
||||
TimeStamp expiry; /* For Windows 9x compatibility of SSPI calls */
|
||||
size_t len = 0, input_token_len = 0;
|
||||
CURLcode error;
|
||||
CURLcode result;
|
||||
|
||||
/* Point to the username and password */
|
||||
const char *userp;
|
||||
@ -68,12 +65,12 @@ int Curl_input_negotiate(struct connectdata *conn, bool proxy,
|
||||
if(proxy) {
|
||||
userp = conn->proxyuser;
|
||||
passwdp = conn->proxypasswd;
|
||||
neg_ctx = &conn->data->state.proxyneg;
|
||||
neg_ctx = &data->state.proxyneg;
|
||||
}
|
||||
else {
|
||||
userp = conn->user;
|
||||
passwdp = conn->passwd;
|
||||
neg_ctx = &conn->data->state.negotiate;
|
||||
neg_ctx = &data->state.negotiate;
|
||||
}
|
||||
|
||||
/* Not set means empty */
|
||||
@ -87,34 +84,36 @@ int Curl_input_negotiate(struct connectdata *conn, bool proxy,
|
||||
/* We finished successfully our part of authentication, but server
|
||||
* rejected it (since we're again here). Exit with an error since we
|
||||
* can't invent anything better */
|
||||
Curl_cleanup_negotiate(conn->data);
|
||||
return -1;
|
||||
Curl_cleanup_negotiate(data);
|
||||
return CURLE_LOGIN_DENIED;
|
||||
}
|
||||
|
||||
if(!neg_ctx->server_name) {
|
||||
/* Check proxy auth requested but no given proxy name */
|
||||
if(proxy && !conn->proxy.name)
|
||||
return -1;
|
||||
return CURLE_BAD_FUNCTION_ARGUMENT;
|
||||
|
||||
/* Generate our SPN */
|
||||
neg_ctx->server_name = Curl_sasl_build_spn("HTTP",
|
||||
proxy ? conn->proxy.name :
|
||||
conn->host.name);
|
||||
neg_ctx->server_name = Curl_sasl_build_spn(
|
||||
proxy ? data->set.str[STRING_PROXY_SERVICE_NAME] :
|
||||
data->set.str[STRING_SERVICE_NAME],
|
||||
proxy ? conn->proxy.name : conn->host.name);
|
||||
if(!neg_ctx->server_name)
|
||||
return -1;
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
if(!neg_ctx->output_token) {
|
||||
PSecPkgInfo SecurityPackage;
|
||||
ret = s_pSecFn->QuerySecurityPackageInfo((TCHAR *) TEXT("Negotiate"),
|
||||
status = s_pSecFn->QuerySecurityPackageInfo((TCHAR *)
|
||||
TEXT(SP_NAME_NEGOTIATE),
|
||||
&SecurityPackage);
|
||||
if(ret != SEC_E_OK)
|
||||
return -1;
|
||||
if(status != SEC_E_OK)
|
||||
return CURLE_NOT_BUILT_IN;
|
||||
|
||||
/* 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 = malloc(neg_ctx->max_token_length);
|
||||
neg_ctx->token_max = SecurityPackage->cbMaxToken;
|
||||
neg_ctx->output_token = malloc(neg_ctx->token_max);
|
||||
s_pSecFn->FreeContextBuffer(SecurityPackage);
|
||||
}
|
||||
|
||||
@ -129,7 +128,7 @@ int Curl_input_negotiate(struct connectdata *conn, bool proxy,
|
||||
if(neg_ctx->context) {
|
||||
/* The server rejected our authentication and hasn't suppled any more
|
||||
negotiation mechanisms */
|
||||
return -1;
|
||||
return CURLE_LOGIN_DENIED;
|
||||
}
|
||||
|
||||
/* We have to acquire credentials and allocate memory for the context */
|
||||
@ -137,13 +136,13 @@ int Curl_input_negotiate(struct connectdata *conn, bool proxy,
|
||||
neg_ctx->context = malloc(sizeof(CtxtHandle));
|
||||
|
||||
if(!neg_ctx->credentials || !neg_ctx->context)
|
||||
return -1;
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
if(userp && *userp) {
|
||||
/* Populate our identity structure */
|
||||
error = Curl_create_sspi_identity(userp, passwdp, &neg_ctx->identity);
|
||||
if(error)
|
||||
return -1;
|
||||
result = Curl_create_sspi_identity(userp, passwdp, &neg_ctx->identity);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
/* Allow proper cleanup of the identity structure */
|
||||
neg_ctx->p_identity = &neg_ctx->identity;
|
||||
@ -155,19 +154,26 @@ int Curl_input_negotiate(struct connectdata *conn, bool proxy,
|
||||
/* Acquire our credientials handle */
|
||||
neg_ctx->status =
|
||||
s_pSecFn->AcquireCredentialsHandle(NULL,
|
||||
(TCHAR *) TEXT("Negotiate"),
|
||||
(TCHAR *) TEXT(SP_NAME_NEGOTIATE),
|
||||
SECPKG_CRED_OUTBOUND, NULL,
|
||||
neg_ctx->p_identity, NULL, NULL,
|
||||
neg_ctx->credentials, &lifetime);
|
||||
neg_ctx->credentials, &expiry);
|
||||
if(neg_ctx->status != SEC_E_OK)
|
||||
return -1;
|
||||
return CURLE_LOGIN_DENIED;
|
||||
}
|
||||
else {
|
||||
error = Curl_base64_decode(header,
|
||||
result = Curl_base64_decode(header,
|
||||
(unsigned char **)&input_token,
|
||||
&input_token_len);
|
||||
if(error || !input_token_len)
|
||||
return -1;
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
if(!input_token_len) {
|
||||
infof(data,
|
||||
"Negotiate handshake failure (empty challenge message)\n");
|
||||
|
||||
return CURLE_BAD_CONTENT_ENCODING;
|
||||
}
|
||||
}
|
||||
|
||||
/* Setup the "output" security buffer */
|
||||
@ -176,7 +182,7 @@ int Curl_input_negotiate(struct connectdata *conn, bool proxy,
|
||||
out_buff_desc.pBuffers = &out_sec_buff;
|
||||
out_sec_buff.BufferType = SECBUFFER_TOKEN;
|
||||
out_sec_buff.pvBuffer = neg_ctx->output_token;
|
||||
out_sec_buff.cbBuffer = curlx_uztoul(neg_ctx->max_token_length);
|
||||
out_sec_buff.cbBuffer = curlx_uztoul(neg_ctx->token_max);
|
||||
|
||||
/* Setup the "input" security buffer if present */
|
||||
if(input_token) {
|
||||
@ -200,28 +206,27 @@ int Curl_input_negotiate(struct connectdata *conn, bool proxy,
|
||||
0,
|
||||
neg_ctx->context,
|
||||
&out_buff_desc,
|
||||
&context_attributes,
|
||||
&lifetime);
|
||||
&attrs,
|
||||
&expiry);
|
||||
|
||||
Curl_safefree(input_token);
|
||||
free(input_token);
|
||||
|
||||
if(GSS_ERROR(neg_ctx->status))
|
||||
return -1;
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
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;
|
||||
return CURLE_RECV_ERROR;
|
||||
}
|
||||
|
||||
neg_ctx->output_token_length = out_sec_buff.cbBuffer;
|
||||
|
||||
return 0;
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
|
||||
CURLcode Curl_output_negotiate(struct connectdata *conn, bool proxy)
|
||||
{
|
||||
struct negotiatedata *neg_ctx = proxy?&conn->data->state.proxyneg:
|
||||
@ -258,25 +263,30 @@ CURLcode Curl_output_negotiate(struct connectdata *conn, bool proxy)
|
||||
|
||||
static void cleanup(struct negotiatedata *neg_ctx)
|
||||
{
|
||||
/* Free our security context */
|
||||
if(neg_ctx->context) {
|
||||
s_pSecFn->DeleteSecurityContext(neg_ctx->context);
|
||||
free(neg_ctx->context);
|
||||
neg_ctx->context = NULL;
|
||||
}
|
||||
|
||||
/* Free our credentials handle */
|
||||
if(neg_ctx->credentials) {
|
||||
s_pSecFn->FreeCredentialsHandle(neg_ctx->credentials);
|
||||
free(neg_ctx->credentials);
|
||||
neg_ctx->credentials = NULL;
|
||||
}
|
||||
|
||||
neg_ctx->max_token_length = 0;
|
||||
Curl_safefree(neg_ctx->output_token);
|
||||
|
||||
Curl_safefree(neg_ctx->server_name);
|
||||
|
||||
/* Free our identity */
|
||||
Curl_sspi_free_identity(neg_ctx->p_identity);
|
||||
neg_ctx->p_identity = NULL;
|
||||
|
||||
/* Free the SPN and output token */
|
||||
Curl_safefree(neg_ctx->server_name);
|
||||
Curl_safefree(neg_ctx->output_token);
|
||||
|
||||
/* Reset any variables */
|
||||
neg_ctx->token_max = 0;
|
||||
}
|
||||
|
||||
void Curl_cleanup_negotiate(struct SessionHandle *data)
|
||||
|
@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -35,10 +35,7 @@
|
||||
#include "progress.h"
|
||||
#include "non-ascii.h"
|
||||
#include "connect.h"
|
||||
|
||||
#define _MPRINTF_REPLACE /* use our functions only */
|
||||
#include <curl/mprintf.h>
|
||||
|
||||
#include "curl_printf.h"
|
||||
#include "curlx.h"
|
||||
|
||||
#include "curl_memory.h"
|
||||
@ -71,10 +68,11 @@ CURLcode Curl_proxy_connect(struct connectdata *conn)
|
||||
conn->data->req.protop = &http_proxy;
|
||||
connkeep(conn, "HTTP proxy CONNECT");
|
||||
result = Curl_proxyCONNECT(conn, FIRSTSOCKET,
|
||||
conn->host.name, conn->remote_port);
|
||||
conn->host.name, conn->remote_port, FALSE);
|
||||
conn->data->req.protop = prot_save;
|
||||
if(CURLE_OK != result)
|
||||
return result;
|
||||
Curl_safefree(conn->allocptr.proxyuserpwd);
|
||||
#else
|
||||
return CURLE_NOT_BUILT_IN;
|
||||
#endif
|
||||
@ -87,12 +85,16 @@ CURLcode Curl_proxy_connect(struct connectdata *conn)
|
||||
* Curl_proxyCONNECT() requires that we're connected to a HTTP proxy. This
|
||||
* function will issue the necessary commands to get a seamless tunnel through
|
||||
* this proxy. After that, the socket can be used just as a normal socket.
|
||||
*
|
||||
* 'blocking' set to TRUE means that this function will do the entire CONNECT
|
||||
* + response in a blocking fashion. Should be avoided!
|
||||
*/
|
||||
|
||||
CURLcode Curl_proxyCONNECT(struct connectdata *conn,
|
||||
int sockindex,
|
||||
const char *hostname,
|
||||
int remote_port)
|
||||
int remote_port,
|
||||
bool blocking)
|
||||
{
|
||||
int subversion=0;
|
||||
struct SessionHandle *data=conn->data;
|
||||
@ -123,13 +125,11 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
|
||||
infof(data, "Establish HTTP proxy tunnel to %s:%hu\n",
|
||||
hostname, remote_port);
|
||||
|
||||
if(data->req.newurl) {
|
||||
/* This only happens if we've looped here due to authentication
|
||||
reasons, and we don't really use the newly cloned URL here
|
||||
then. Just free() it. */
|
||||
free(data->req.newurl);
|
||||
data->req.newurl = NULL;
|
||||
}
|
||||
|
||||
/* initialize a dynamic send-buffer */
|
||||
req_buffer = Curl_add_buffer_init();
|
||||
@ -139,7 +139,7 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
|
||||
|
||||
host_port = aprintf("%s:%hu", hostname, remote_port);
|
||||
if(!host_port) {
|
||||
free(req_buffer);
|
||||
Curl_add_buffer_free(req_buffer);
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
@ -148,7 +148,7 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
|
||||
|
||||
free(host_port);
|
||||
|
||||
if(CURLE_OK == result) {
|
||||
if(!result) {
|
||||
char *host=(char *)"";
|
||||
const char *proxyconn="";
|
||||
const char *useragent="";
|
||||
@ -159,7 +159,7 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
|
||||
hostname, conn->bits.ipv6_ip?"]":"",
|
||||
remote_port);
|
||||
if(!hostheader) {
|
||||
free(req_buffer);
|
||||
Curl_add_buffer_free(req_buffer);
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
@ -167,7 +167,7 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
|
||||
host = aprintf("Host: %s\r\n", hostheader);
|
||||
if(!host) {
|
||||
free(hostheader);
|
||||
free(req_buffer);
|
||||
Curl_add_buffer_free(req_buffer);
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
@ -197,14 +197,14 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
|
||||
free(host);
|
||||
free(hostheader);
|
||||
|
||||
if(CURLE_OK == result)
|
||||
if(!result)
|
||||
result = Curl_add_custom_headers(conn, TRUE, req_buffer);
|
||||
|
||||
if(CURLE_OK == result)
|
||||
if(!result)
|
||||
/* CRLF terminate the request */
|
||||
result = Curl_add_bufferf(req_buffer, "\r\n");
|
||||
|
||||
if(CURLE_OK == result) {
|
||||
if(!result) {
|
||||
/* Send the connect request to the proxy */
|
||||
/* BLOCKING */
|
||||
result =
|
||||
@ -216,7 +216,7 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
|
||||
failf(data, "Failed sending CONNECT to proxy");
|
||||
}
|
||||
|
||||
Curl_safefree(req_buffer);
|
||||
Curl_add_buffer_free(req_buffer);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
@ -229,6 +229,7 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
|
||||
return CURLE_RECV_ERROR;
|
||||
}
|
||||
|
||||
if(!blocking) {
|
||||
if(0 == Curl_socket_ready(tunnelsocket, CURL_SOCKET_BAD, 0))
|
||||
/* return so we'll be called again polling-style */
|
||||
return CURLE_OK;
|
||||
@ -236,6 +237,7 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
|
||||
DEBUGF(infof(data,
|
||||
"Read response immediately from proxy CONNECT\n"));
|
||||
}
|
||||
}
|
||||
|
||||
/* at this point, the tunnel_connecting phase is over. */
|
||||
|
||||
@ -252,7 +254,6 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
|
||||
|
||||
nread=0;
|
||||
perline=0;
|
||||
keepon=TRUE;
|
||||
|
||||
while((nread<BUFSIZE) && (keepon && !error)) {
|
||||
|
||||
@ -286,7 +287,7 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
|
||||
/* proxy auth was requested and there was proxy auth available,
|
||||
then deem this as "mere" proxy disconnect */
|
||||
conn->bits.proxy_connect_closed = TRUE;
|
||||
infof(data, "Proxy CONNECT connection closed");
|
||||
infof(data, "Proxy CONNECT connection closed\n");
|
||||
}
|
||||
else {
|
||||
error = SELECT_ERROR;
|
||||
@ -468,7 +469,7 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
|
||||
|
||||
result = Curl_http_input_auth(conn, proxy, auth);
|
||||
|
||||
Curl_safefree(auth);
|
||||
free(auth);
|
||||
|
||||
if(result)
|
||||
return result;
|
||||
@ -554,10 +555,13 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
|
||||
conn->bits.proxy_connect_closed = TRUE;
|
||||
infof(data, "Connect me again please\n");
|
||||
}
|
||||
else if(data->req.newurl) {
|
||||
/* this won't be used anymore for the CONNECT so free it now */
|
||||
else {
|
||||
free(data->req.newurl);
|
||||
data->req.newurl = NULL;
|
||||
/* failure, close this connection to avoid re-use */
|
||||
connclose(conn, "proxy CONNECT failure");
|
||||
Curl_closesocket(conn, conn->sock[sockindex]);
|
||||
conn->sock[sockindex] = CURL_SOCKET_BAD;
|
||||
}
|
||||
|
||||
/* to back to init state */
|
||||
|
@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -26,7 +26,8 @@
|
||||
/* ftp can use this as well */
|
||||
CURLcode Curl_proxyCONNECT(struct connectdata *conn,
|
||||
int tunnelsocket,
|
||||
const char *hostname, int remote_port);
|
||||
const char *hostname, int remote_port,
|
||||
bool blocking);
|
||||
|
||||
/* Default proxy timeout in milliseconds */
|
||||
#define PROXY_TIMEOUT (3600*1000)
|
||||
@ -34,7 +35,7 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
|
||||
CURLcode Curl_proxy_connect(struct connectdata *conn);
|
||||
|
||||
#else
|
||||
#define Curl_proxyCONNECT(x,y,z,w) CURLE_NOT_BUILT_IN
|
||||
#define Curl_proxyCONNECT(x,y,z,w,v) CURLE_NOT_BUILT_IN
|
||||
#define Curl_proxy_connect(x) CURLE_OK
|
||||
#endif
|
||||
|
||||
|
@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -35,8 +35,31 @@
|
||||
#include "memdebug.h"
|
||||
|
||||
#ifdef WANT_IDN_PROTOTYPES
|
||||
WINBASEAPI int WINAPI IdnToAscii(DWORD, const WCHAR *, int, WCHAR *, int);
|
||||
WINBASEAPI int WINAPI IdnToUnicode(DWORD, const WCHAR *, int, WCHAR *, int);
|
||||
# if defined(_SAL_VERSION)
|
||||
WINNORMALIZEAPI int WINAPI
|
||||
IdnToAscii(_In_ DWORD dwFlags,
|
||||
_In_reads_(cchUnicodeChar) LPCWSTR lpUnicodeCharStr,
|
||||
_In_ int cchUnicodeChar,
|
||||
_Out_writes_opt_(cchASCIIChar) LPWSTR lpASCIICharStr,
|
||||
_In_ int cchASCIIChar);
|
||||
WINNORMALIZEAPI int WINAPI
|
||||
IdnToUnicode(_In_ DWORD dwFlags,
|
||||
_In_reads_(cchASCIIChar) LPCWSTR lpASCIICharStr,
|
||||
_In_ int cchASCIIChar,
|
||||
_Out_writes_opt_(cchUnicodeChar) LPWSTR lpUnicodeCharStr,
|
||||
_In_ int cchUnicodeChar);
|
||||
# else
|
||||
WINBASEAPI int WINAPI IdnToAscii(DWORD dwFlags,
|
||||
const WCHAR *lpUnicodeCharStr,
|
||||
int cchUnicodeChar,
|
||||
WCHAR *lpASCIICharStr,
|
||||
int cchASCIIChar);
|
||||
WINBASEAPI int WINAPI IdnToUnicode(DWORD dwFlags,
|
||||
const WCHAR *lpASCIICharStr,
|
||||
int cchASCIIChar,
|
||||
WCHAR *lpUnicodeCharStr,
|
||||
int cchUnicodeChar);
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#define IDN_MAX_LENGTH 255
|
||||
|
@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -53,9 +53,7 @@
|
||||
#include "inet_ntop.h"
|
||||
#include "strequal.h"
|
||||
#include "if2ip.h"
|
||||
|
||||
#define _MPRINTF_REPLACE /* use our functions only */
|
||||
#include <curl/mprintf.h>
|
||||
#include "curl_printf.h"
|
||||
|
||||
#include "curl_memory.h"
|
||||
/* The last #include file should be: */
|
||||
@ -63,6 +61,38 @@
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
|
||||
/* Return the scope of the given address. */
|
||||
unsigned int Curl_ipv6_scope(const struct sockaddr *sa)
|
||||
{
|
||||
#ifndef ENABLE_IPV6
|
||||
(void) sa;
|
||||
#else
|
||||
if(sa->sa_family == AF_INET6) {
|
||||
const struct sockaddr_in6 * sa6 = (const struct sockaddr_in6 *)(void *) sa;
|
||||
const unsigned char * b = sa6->sin6_addr.s6_addr;
|
||||
unsigned short w = (unsigned short) ((b[0] << 8) | b[1]);
|
||||
|
||||
switch(w & 0xFFC0) {
|
||||
case 0xFE80:
|
||||
return IPV6_SCOPE_LINKLOCAL;
|
||||
case 0xFEC0:
|
||||
return IPV6_SCOPE_SITELOCAL;
|
||||
case 0x0000:
|
||||
w = b[1] | b[2] | b[3] | b[4] | b[5] | b[6] | b[7] | b[8] | b[9] |
|
||||
b[10] | b[11] | b[12] | b[13] | b[14];
|
||||
if(w || b[15] != 0x01)
|
||||
break;
|
||||
return IPV6_SCOPE_NODELOCAL;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return IPV6_SCOPE_GLOBAL;
|
||||
}
|
||||
|
||||
|
||||
#if defined(HAVE_GETIFADDRS)
|
||||
|
||||
bool Curl_if_is_interface_name(const char *interf)
|
||||
@ -84,47 +114,66 @@ bool Curl_if_is_interface_name(const char *interf)
|
||||
}
|
||||
|
||||
if2ip_result_t Curl_if2ip(int af, unsigned int remote_scope,
|
||||
const char *interf, char *buf, int buf_size)
|
||||
unsigned int remote_scope_id, const char *interf,
|
||||
char *buf, int buf_size)
|
||||
{
|
||||
struct ifaddrs *iface, *head;
|
||||
if2ip_result_t res = IF2IP_NOT_FOUND;
|
||||
|
||||
#ifndef ENABLE_IPV6
|
||||
(void) remote_scope;
|
||||
|
||||
#ifndef HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID
|
||||
(void) remote_scope_id;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
if(getifaddrs(&head) >= 0) {
|
||||
for(iface=head; iface != NULL; iface=iface->ifa_next) {
|
||||
for(iface = head; iface != NULL; iface=iface->ifa_next) {
|
||||
if(iface->ifa_addr != NULL) {
|
||||
if(iface->ifa_addr->sa_family == af) {
|
||||
if(curl_strequal(iface->ifa_name, interf)) {
|
||||
void *addr;
|
||||
char *ip;
|
||||
char scope[12]="";
|
||||
char scope[12] = "";
|
||||
char ipstr[64];
|
||||
#ifdef ENABLE_IPV6
|
||||
if(af == AF_INET6) {
|
||||
unsigned int scopeid = 0;
|
||||
addr = &((struct sockaddr_in6 *)iface->ifa_addr)->sin6_addr;
|
||||
#ifdef HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID
|
||||
/* Include the scope of this interface as part of the address */
|
||||
scopeid =
|
||||
((struct sockaddr_in6 *)iface->ifa_addr)->sin6_scope_id;
|
||||
#endif
|
||||
if(scopeid != remote_scope) {
|
||||
unsigned int ifscope = Curl_ipv6_scope(iface->ifa_addr);
|
||||
|
||||
if(ifscope != remote_scope) {
|
||||
/* We are interested only in interface addresses whose
|
||||
scope ID matches the remote address we want to
|
||||
connect to: global (0) for global, link-local for
|
||||
scope matches the remote address we want to
|
||||
connect to: global for global, link-local for
|
||||
link-local, etc... */
|
||||
if(res == IF2IP_NOT_FOUND) res = IF2IP_AF_NOT_SUPPORTED;
|
||||
continue;
|
||||
}
|
||||
|
||||
addr =
|
||||
&((struct sockaddr_in6 *)(void *)iface->ifa_addr)->sin6_addr;
|
||||
#ifdef HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID
|
||||
/* Include the scope of this interface as part of the address */
|
||||
scopeid = ((struct sockaddr_in6 *)(void *)iface->ifa_addr)
|
||||
->sin6_scope_id;
|
||||
|
||||
/* If given, scope id should match. */
|
||||
if(remote_scope_id && scopeid != remote_scope_id) {
|
||||
if(res == IF2IP_NOT_FOUND)
|
||||
res = IF2IP_AF_NOT_SUPPORTED;
|
||||
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
if(scopeid)
|
||||
snprintf(scope, sizeof(scope), "%%%u", scopeid);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
addr = &((struct sockaddr_in *)iface->ifa_addr)->sin_addr;
|
||||
addr =
|
||||
&((struct sockaddr_in *)(void *)iface->ifa_addr)->sin_addr;
|
||||
res = IF2IP_FOUND;
|
||||
ip = (char *) Curl_inet_ntop(af, addr, ipstr, sizeof(ipstr));
|
||||
snprintf(buf, buf_size, "%s%s", ip, scope);
|
||||
@ -137,8 +186,10 @@ if2ip_result_t Curl_if2ip(int af, unsigned int remote_scope,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
freeifaddrs(head);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
@ -149,12 +200,13 @@ bool Curl_if_is_interface_name(const char *interf)
|
||||
/* This is here just to support the old interfaces */
|
||||
char buf[256];
|
||||
|
||||
return (Curl_if2ip(AF_INET, 0, interf, buf, sizeof(buf)) ==
|
||||
return (Curl_if2ip(AF_INET, 0 /* unused */, 0, interf, buf, sizeof(buf)) ==
|
||||
IF2IP_NOT_FOUND) ? FALSE : TRUE;
|
||||
}
|
||||
|
||||
if2ip_result_t Curl_if2ip(int af, unsigned int remote_scope,
|
||||
const char *interf, char *buf, int buf_size)
|
||||
unsigned int remote_scope_id, const char *interf,
|
||||
char *buf, int buf_size)
|
||||
{
|
||||
struct ifreq req;
|
||||
struct in_addr in;
|
||||
@ -163,6 +215,7 @@ if2ip_result_t Curl_if2ip(int af, unsigned int remote_scope,
|
||||
size_t len;
|
||||
|
||||
(void)remote_scope;
|
||||
(void)remote_scope_id;
|
||||
|
||||
if(!interf || (af != AF_INET))
|
||||
return IF2IP_NOT_FOUND;
|
||||
@ -205,10 +258,12 @@ bool Curl_if_is_interface_name(const char *interf)
|
||||
}
|
||||
|
||||
if2ip_result_t Curl_if2ip(int af, unsigned int remote_scope,
|
||||
const char *interf, char *buf, int buf_size)
|
||||
unsigned int remote_scope_id, const char *interf,
|
||||
char *buf, int buf_size)
|
||||
{
|
||||
(void) af;
|
||||
(void) remote_scope;
|
||||
(void) remote_scope_id;
|
||||
(void) interf;
|
||||
(void) buf;
|
||||
(void) buf_size;
|
||||
|
@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -23,6 +23,14 @@
|
||||
***************************************************************************/
|
||||
#include "curl_setup.h"
|
||||
|
||||
/* IPv6 address scopes. */
|
||||
#define IPV6_SCOPE_GLOBAL 0 /* Global scope. */
|
||||
#define IPV6_SCOPE_LINKLOCAL 1 /* Link-local scope. */
|
||||
#define IPV6_SCOPE_SITELOCAL 2 /* Site-local scope (deprecated). */
|
||||
#define IPV6_SCOPE_NODELOCAL 3 /* Loopback. */
|
||||
|
||||
unsigned int Curl_ipv6_scope(const struct sockaddr *sa);
|
||||
|
||||
bool Curl_if_is_interface_name(const char *interf);
|
||||
|
||||
typedef enum {
|
||||
@ -32,7 +40,8 @@ typedef enum {
|
||||
} if2ip_result_t;
|
||||
|
||||
if2ip_result_t Curl_if2ip(int af, unsigned int remote_scope,
|
||||
const char *interf, char *buf, int buf_size);
|
||||
unsigned int remote_scope_id, const char *interf,
|
||||
char *buf, int buf_size);
|
||||
|
||||
#ifdef __INTERIX
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user