Merge pull request #342 from Blizzard/update-curl

Update to Curl 7.45.0
This commit is contained in:
Tom van Dijck 2015-12-15 09:29:22 -08:00
commit 760859825b
187 changed files with 17063 additions and 12884 deletions

View 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/

View File

@ -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()

View File

@ -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 */

View File

@ -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 */

View File

@ -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

View File

@ -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

View File

@ -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 */

View File

@ -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__ */

View File

@ -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;
}

View File

@ -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 */

View File

@ -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 */

View File

@ -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;
}

View File

@ -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"

View File

@ -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

View 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 */

View File

@ -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

View File

@ -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"

View File

@ -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. */

View File

@ -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 */

View File

@ -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 */

View File

@ -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

View File

@ -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 */

View File

@ -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;

View File

@ -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);

View File

@ -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

View File

@ -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.

View File

@ -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;

View File

@ -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()

View File

@ -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,

View 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 */

View File

@ -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 */

View 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 */

View 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 */

View File

@ -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"

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */

View File

@ -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

View File

@ -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"

View File

@ -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) */

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */

View File

@ -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

View File

@ -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 */

View File

@ -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 */

View 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 */

View File

@ -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

View File

@ -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 */

View 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

View File

@ -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 *);
};

View File

@ -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 */

View File

@ -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;

View File

@ -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

View File

@ -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);

View File

@ -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)

View File

@ -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

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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

View File

@ -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"

View File

@ -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

View File

@ -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");

View File

@ -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 */

View File

@ -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 */
};

View File

@ -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++;

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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);

View File

@ -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"

View File

@ -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;
}
/*

View File

@ -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 */

View File

@ -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);

View File

@ -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.
*

View File

@ -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.

View File

@ -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));

View File

@ -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"

View File

@ -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;

View File

@ -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

View File

@ -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 */

View File

@ -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. "

View File

@ -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

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */

View File

@ -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)

View File

@ -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 */

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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