mirror of
https://github.com/libgit2/libgit2.git
synced 2026-06-22 06:26:26 +00:00
Merge pull request #5974 from libgit2/ethomson/dlopen_ssl
Dynamically load OpenSSL (optionally)
This commit is contained in:
35
.github/workflows/nightly.yml
vendored
35
.github/workflows/nightly.yml
vendored
@@ -59,6 +59,14 @@ jobs:
|
||||
CMAKE_OPTIONS: -DTHREADSAFE=OFF -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON
|
||||
CMAKE_GENERATOR: Ninja
|
||||
os: ubuntu-latest
|
||||
- # Xenial, Clang, OpenSSL (dynamically loaded)
|
||||
container:
|
||||
name: xenial
|
||||
env:
|
||||
CC: clang
|
||||
CMAKE_OPTIONS: -DUSE_HTTPS=OpenSSL-Dynamic -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON
|
||||
CMAKE_GENERATOR: Ninja
|
||||
os: ubuntu-latest
|
||||
- # Focal, Clang 10, mbedTLS, MemorySanitizer
|
||||
container:
|
||||
name: focal
|
||||
@@ -115,6 +123,14 @@ jobs:
|
||||
PKG_CONFIG_PATH: /usr/local/lib/pkgconfig
|
||||
SKIP_NEGOTIATE_TESTS: true
|
||||
os: ubuntu-latest
|
||||
- # CentOS 7, OpenSSL (dynamically loaded)
|
||||
container:
|
||||
name: centos7
|
||||
env:
|
||||
CMAKE_OPTIONS: -DUSE_HTTPS=OpenSSL-Dynamic -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON
|
||||
PKG_CONFIG_PATH: /usr/local/lib/pkgconfig
|
||||
SKIP_NEGOTIATE_TESTS: true
|
||||
os: ubuntu-latest
|
||||
- # CentOS 8
|
||||
container:
|
||||
name: centos8
|
||||
@@ -124,6 +140,15 @@ jobs:
|
||||
SKIP_NEGOTIATE_TESTS: true
|
||||
SKIP_SSH_TESTS: true
|
||||
os: ubuntu-latest
|
||||
- # CentOS 8, OpenSSL (dynamically loaded)
|
||||
container:
|
||||
name: centos8
|
||||
env:
|
||||
CMAKE_OPTIONS: -DUSE_HTTPS=OpenSSL-Dynamic -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON
|
||||
PKG_CONFIG_PATH: /usr/local/lib/pkgconfig
|
||||
SKIP_NEGOTIATE_TESTS: true
|
||||
SKIP_SSH_TESTS: true
|
||||
os: ubuntu-latest
|
||||
- # macOS
|
||||
os: macos-10.15
|
||||
env:
|
||||
@@ -180,6 +205,16 @@ jobs:
|
||||
BUILD_PATH: D:\Temp\mingw32\bin;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Program Files (x86)\CMake\bin
|
||||
SKIP_SSH_TESTS: true
|
||||
SKIP_NEGOTIATE_TESTS: true
|
||||
- # Bionic, GCC, OpenSSL (dynamically loaded)
|
||||
container:
|
||||
name: bionic
|
||||
dockerfile: bionic
|
||||
env:
|
||||
CC: gcc
|
||||
CMAKE_GENERATOR: Ninja
|
||||
CMAKE_OPTIONS: -DUSE_HTTPS=OpenSSL-Dynamic -DDEPRECATE_HARD=ON -DUSE_LEAK_CHECKER=valgrind -DUSE_GSSAPI=ON
|
||||
RUN_INVASIVE_TESTS: true
|
||||
os: ubuntu-latest
|
||||
- # Bionic, x86, Clang, OpenSSL
|
||||
container:
|
||||
name: bionic-x86
|
||||
|
||||
110
COPYING
110
COPYING
@@ -420,7 +420,7 @@ The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
@@ -1019,3 +1019,111 @@ following restrictions are are met:
|
||||
THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
|
||||
WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Portions of the OpenSSL headers are included under the OpenSSL license:
|
||||
|
||||
Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
||||
All rights reserved.
|
||||
|
||||
This package is an SSL implementation written
|
||||
by Eric Young (eay@cryptsoft.com).
|
||||
The implementation was written so as to conform with Netscapes SSL.
|
||||
|
||||
This library is free for commercial and non-commercial use as long as
|
||||
the following conditions are aheared to. The following conditions
|
||||
apply to all code found in this distribution, be it the RC4, RSA,
|
||||
lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
included with this distribution is covered by the same copyright terms
|
||||
except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
|
||||
Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
the code are not to be removed.
|
||||
If this package is used in a product, Eric Young should be given attribution
|
||||
as the author of the parts of the library used.
|
||||
This can be in the form of a textual message at program startup or
|
||||
in documentation (online or textual) provided with the package.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
1. Redistributions of source code must retain the copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. All advertising materials mentioning features or use of this software
|
||||
must display the following acknowledgement:
|
||||
"This product includes cryptographic software written by
|
||||
Eric Young (eay@cryptsoft.com)"
|
||||
The word 'cryptographic' can be left out if the rouines from the library
|
||||
being used are not cryptographic related :-).
|
||||
4. If you include any Windows specific code (or a derivative thereof) from
|
||||
the apps directory (application code) you must include an acknowledgement:
|
||||
"This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGE.
|
||||
|
||||
The licence and distribution terms for any publically available version or
|
||||
derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
copied and put under another distribution licence
|
||||
[including the GNU Public Licence.]
|
||||
|
||||
====================================================================
|
||||
Copyright (c) 1998-2007 The OpenSSL Project. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in
|
||||
the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
|
||||
3. All advertising materials mentioning features or use of this
|
||||
software must display the following acknowledgment:
|
||||
"This product includes software developed by the OpenSSL Project
|
||||
for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
|
||||
|
||||
4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
endorse or promote products derived from this software without
|
||||
prior written permission. For written permission, please contact
|
||||
openssl-core@openssl.org.
|
||||
|
||||
5. Products derived from this software may not be called "OpenSSL"
|
||||
nor may "OpenSSL" appear in their names without prior written
|
||||
permission of the OpenSSL Project.
|
||||
|
||||
6. Redistributions of any form whatsoever must retain the following
|
||||
acknowledgment:
|
||||
"This product includes software developed by the OpenSSL Project
|
||||
for use in the OpenSSL Toolkit (http://www.openssl.org/)"
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
|
||||
@@ -108,6 +108,10 @@ IF(USE_HTTPS)
|
||||
LIST(APPEND LIBGIT2_PC_LIBS ${MBEDTLS_LIBRARIES})
|
||||
ELSEIF (USE_HTTPS STREQUAL "WinHTTP")
|
||||
# WinHTTP setup was handled in the WinHTTP-specific block above
|
||||
ELSEIF (USE_HTTPS STREQUAL "OpenSSL-Dynamic")
|
||||
SET(GIT_OPENSSL 1)
|
||||
SET(GIT_OPENSSL_DYNAMIC 1)
|
||||
LIST(APPEND LIBGIT2_LIBS dl)
|
||||
ELSE()
|
||||
MESSAGE(FATAL_ERROR "Asked for backend ${USE_HTTPS} but it wasn't found")
|
||||
ENDIF()
|
||||
|
||||
22
deps/ntlmclient/CMakeLists.txt
vendored
22
deps/ntlmclient/CMakeLists.txt
vendored
@@ -1,25 +1,37 @@
|
||||
FILE(GLOB SRC_NTLMCLIENT "ntlm.c" "unicode_builtin.c" "util.c")
|
||||
FILE(GLOB SRC_NTLMCLIENT "ntlm.c" "ntlm.h" "util.c" "util.h")
|
||||
LIST(SORT SRC_NTLMCLIENT)
|
||||
|
||||
ADD_DEFINITIONS(-DNTLM_STATIC=1)
|
||||
|
||||
DISABLE_WARNINGS(implicit-fallthrough)
|
||||
|
||||
IF(USE_ICONV)
|
||||
ADD_DEFINITIONS(-DUNICODE_ICONV=1)
|
||||
FILE(GLOB SRC_NTLMCLIENT_UNICODE "unicode_iconv.c" "unicode_iconv.h")
|
||||
ELSE()
|
||||
ADD_DEFINITIONS(-DUNICODE_BUILTIN=1)
|
||||
FILE(GLOB SRC_NTLMCLIENT_UNICODE "unicode_builtin.c" "unicode_builtin.h")
|
||||
ENDIF()
|
||||
|
||||
IF(USE_HTTPS STREQUAL "SecureTransport")
|
||||
ADD_DEFINITIONS(-DCRYPT_COMMONCRYPTO)
|
||||
SET(SRC_NTLMCLIENT_CRYPTO "crypt_commoncrypto.c")
|
||||
SET(SRC_NTLMCLIENT_CRYPTO "crypt_commoncrypto.c" "crypt_commoncrypto.h")
|
||||
# CC_MD4 has been deprecated in macOS 10.15.
|
||||
SET_SOURCE_FILES_PROPERTIES("crypt_commoncrypto.c" COMPILE_FLAGS "-Wno-deprecated")
|
||||
ELSEIF(USE_HTTPS STREQUAL "OpenSSL")
|
||||
ADD_DEFINITIONS(-DCRYPT_OPENSSL)
|
||||
INCLUDE_DIRECTORIES(${OPENSSL_INCLUDE_DIR})
|
||||
SET(SRC_NTLMCLIENT_CRYPTO "crypt_openssl.c")
|
||||
SET(SRC_NTLMCLIENT_CRYPTO "crypt_openssl.c" "crypt_openssl.h")
|
||||
ELSEIF(USE_HTTPS STREQUAL "OpenSSL-Dynamic")
|
||||
ADD_DEFINITIONS(-DCRYPT_OPENSSL)
|
||||
ADD_DEFINITIONS(-DCRYPT_OPENSSL_DYNAMIC)
|
||||
SET(SRC_NTLMCLIENT_CRYPTO "crypt_openssl.c" "crypt_openssl.h")
|
||||
ELSEIF(USE_HTTPS STREQUAL "mbedTLS")
|
||||
ADD_DEFINITIONS(-DCRYPT_MBEDTLS)
|
||||
INCLUDE_DIRECTORIES(${MBEDTLS_INCLUDE_DIR})
|
||||
SET(SRC_NTLMCLIENT_CRYPTO "crypt_mbedtls.c")
|
||||
SET(SRC_NTLMCLIENT_CRYPTO "crypt_mbedtls.c" "crypt_mbedtls.h")
|
||||
ELSE()
|
||||
MESSAGE(FATAL_ERROR "Unable to use libgit2's HTTPS backend (${USE_HTTPS}) for NTLM crypto")
|
||||
ENDIF()
|
||||
|
||||
ADD_LIBRARY(ntlmclient OBJECT ${SRC_NTLMCLIENT} ${SRC_NTLMCLIENT_CRYPTO})
|
||||
ADD_LIBRARY(ntlmclient OBJECT ${SRC_NTLMCLIENT} ${SRC_NTLMCLIENT_UNICODE} ${SRC_NTLMCLIENT_CRYPTO})
|
||||
|
||||
23
deps/ntlmclient/crypt.h
vendored
23
deps/ntlmclient/crypt.h
vendored
@@ -9,6 +9,9 @@
|
||||
#ifndef PRIVATE_CRYPT_COMMON_H__
|
||||
#define PRIVATE_CRYPT_COMMON_H__
|
||||
|
||||
#include "ntlmclient.h"
|
||||
#include "ntlm.h"
|
||||
|
||||
#if defined(CRYPT_OPENSSL)
|
||||
# include "crypt_openssl.h"
|
||||
#elif defined(CRYPT_MBEDTLS)
|
||||
@@ -25,40 +28,42 @@
|
||||
|
||||
typedef unsigned char ntlm_des_block[CRYPT_DES_BLOCKSIZE];
|
||||
|
||||
typedef struct ntlm_crypt_ctx ntlm_crypt_ctx;
|
||||
|
||||
extern bool ntlm_crypt_init(ntlm_client *ntlm);
|
||||
|
||||
extern bool ntlm_random_bytes(
|
||||
ntlm_client *ntlm,
|
||||
unsigned char *out,
|
||||
ntlm_client *ntlm,
|
||||
size_t len);
|
||||
|
||||
extern bool ntlm_des_encrypt(
|
||||
ntlm_des_block *out,
|
||||
ntlm_client *ntlm,
|
||||
ntlm_des_block *plaintext,
|
||||
ntlm_des_block *key);
|
||||
|
||||
extern bool ntlm_md4_digest(
|
||||
unsigned char out[CRYPT_MD4_DIGESTSIZE],
|
||||
ntlm_client *ntlm,
|
||||
const unsigned char *in,
|
||||
size_t in_len);
|
||||
|
||||
extern ntlm_hmac_ctx *ntlm_hmac_ctx_init(void);
|
||||
|
||||
extern bool ntlm_hmac_ctx_reset(ntlm_hmac_ctx *ctx);
|
||||
|
||||
extern bool ntlm_hmac_md5_init(
|
||||
ntlm_hmac_ctx *ctx,
|
||||
ntlm_client *ntlm,
|
||||
const unsigned char *key,
|
||||
size_t key_len);
|
||||
|
||||
extern bool ntlm_hmac_md5_update(
|
||||
ntlm_hmac_ctx *ctx,
|
||||
ntlm_client *ntlm,
|
||||
const unsigned char *data,
|
||||
size_t data_len);
|
||||
|
||||
extern bool ntlm_hmac_md5_final(
|
||||
unsigned char *out,
|
||||
size_t *out_len,
|
||||
ntlm_hmac_ctx *ctx);
|
||||
ntlm_client *ntlm);
|
||||
|
||||
extern void ntlm_hmac_ctx_free(ntlm_hmac_ctx *ctx);
|
||||
extern void ntlm_crypt_shutdown(ntlm_client *ntlm);
|
||||
|
||||
#endif /* PRIVATE_CRYPT_COMMON_H__ */
|
||||
|
||||
40
deps/ntlmclient/crypt_commoncrypto.c
vendored
40
deps/ntlmclient/crypt_commoncrypto.c
vendored
@@ -18,9 +18,15 @@
|
||||
#include "ntlm.h"
|
||||
#include "crypt.h"
|
||||
|
||||
bool ntlm_crypt_init(ntlm_client *ntlm)
|
||||
{
|
||||
memset(&ntlm->crypt_ctx, 0, sizeof(ntlm_crypt_ctx));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ntlm_random_bytes(
|
||||
ntlm_client *ntlm,
|
||||
unsigned char *out,
|
||||
ntlm_client *ntlm,
|
||||
size_t len)
|
||||
{
|
||||
int fd, ret;
|
||||
@@ -49,11 +55,14 @@ bool ntlm_random_bytes(
|
||||
|
||||
bool ntlm_des_encrypt(
|
||||
ntlm_des_block *out,
|
||||
ntlm_client *ntlm,
|
||||
ntlm_des_block *plaintext,
|
||||
ntlm_des_block *key)
|
||||
{
|
||||
size_t written;
|
||||
|
||||
NTLM_UNUSED(ntlm);
|
||||
|
||||
CCCryptorStatus result = CCCrypt(kCCEncrypt,
|
||||
kCCAlgorithmDES, kCCOptionECBMode,
|
||||
key, sizeof(ntlm_des_block), NULL,
|
||||
@@ -65,56 +74,47 @@ bool ntlm_des_encrypt(
|
||||
|
||||
bool ntlm_md4_digest(
|
||||
unsigned char out[CRYPT_MD4_DIGESTSIZE],
|
||||
ntlm_client *ntlm,
|
||||
const unsigned char *in,
|
||||
size_t in_len)
|
||||
{
|
||||
NTLM_UNUSED(ntlm);
|
||||
return !!CC_MD4(in, in_len, out);
|
||||
}
|
||||
|
||||
ntlm_hmac_ctx *ntlm_hmac_ctx_init(void)
|
||||
{
|
||||
return calloc(1, sizeof(ntlm_hmac_ctx));
|
||||
}
|
||||
|
||||
bool ntlm_hmac_ctx_reset(ntlm_hmac_ctx *ctx)
|
||||
{
|
||||
memset(ctx, 0, sizeof(ntlm_hmac_ctx));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ntlm_hmac_md5_init(
|
||||
ntlm_hmac_ctx *ctx,
|
||||
ntlm_client *ntlm,
|
||||
const unsigned char *key,
|
||||
size_t key_len)
|
||||
{
|
||||
CCHmacInit(&ctx->native, kCCHmacAlgMD5, key, key_len);
|
||||
CCHmacInit(&ntlm->crypt_ctx.hmac, kCCHmacAlgMD5, key, key_len);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ntlm_hmac_md5_update(
|
||||
ntlm_hmac_ctx *ctx,
|
||||
ntlm_client *ntlm,
|
||||
const unsigned char *data,
|
||||
size_t data_len)
|
||||
{
|
||||
CCHmacUpdate(&ctx->native, data, data_len);
|
||||
CCHmacUpdate(&ntlm->crypt_ctx.hmac, data, data_len);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ntlm_hmac_md5_final(
|
||||
unsigned char *out,
|
||||
size_t *out_len,
|
||||
ntlm_hmac_ctx *ctx)
|
||||
ntlm_client *ntlm)
|
||||
{
|
||||
if (*out_len < CRYPT_MD5_DIGESTSIZE)
|
||||
return false;
|
||||
|
||||
CCHmacFinal(&ctx->native, out);
|
||||
CCHmacFinal(&ntlm->crypt_ctx.hmac, out);
|
||||
|
||||
*out_len = CRYPT_MD5_DIGESTSIZE;
|
||||
return true;
|
||||
}
|
||||
|
||||
void ntlm_hmac_ctx_free(ntlm_hmac_ctx *ctx)
|
||||
void ntlm_crypt_shutdown(ntlm_client *ntlm)
|
||||
{
|
||||
free(ctx);
|
||||
NTLM_UNUSED(ntlm);
|
||||
}
|
||||
|
||||
6
deps/ntlmclient/crypt_commoncrypto.h
vendored
6
deps/ntlmclient/crypt_commoncrypto.h
vendored
@@ -11,8 +11,8 @@
|
||||
|
||||
#include <CommonCrypto/CommonCrypto.h>
|
||||
|
||||
typedef struct {
|
||||
CCHmacContext native;
|
||||
} ntlm_hmac_ctx;
|
||||
struct ntlm_crypt_ctx {
|
||||
CCHmacContext hmac;
|
||||
};
|
||||
|
||||
#endif /* PRIVATE_CRYPT_COMMONCRYPTO_H__ */
|
||||
|
||||
73
deps/ntlmclient/crypt_mbedtls.c
vendored
73
deps/ntlmclient/crypt_mbedtls.c
vendored
@@ -17,9 +17,24 @@
|
||||
#include "ntlm.h"
|
||||
#include "crypt.h"
|
||||
|
||||
bool ntlm_crypt_init(ntlm_client *ntlm)
|
||||
{
|
||||
const mbedtls_md_info_t *info = mbedtls_md_info_from_type(MBEDTLS_MD_MD5);
|
||||
|
||||
mbedtls_md_init(&ntlm->crypt_ctx.hmac);
|
||||
|
||||
if (mbedtls_md_setup(&ntlm->crypt_ctx.hmac, info, 1) != 0) {
|
||||
ntlm_client_set_errmsg(ntlm, "could not setup mbedtls digest");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool ntlm_random_bytes(
|
||||
ntlm_client *ntlm,
|
||||
unsigned char *out,
|
||||
ntlm_client *ntlm,
|
||||
size_t len)
|
||||
{
|
||||
mbedtls_ctr_drbg_context ctr_drbg;
|
||||
@@ -51,6 +66,7 @@ bool ntlm_random_bytes(
|
||||
|
||||
bool ntlm_des_encrypt(
|
||||
ntlm_des_block *out,
|
||||
ntlm_client *ntlm,
|
||||
ntlm_des_block *plaintext,
|
||||
ntlm_des_block *key)
|
||||
{
|
||||
@@ -60,8 +76,10 @@ bool ntlm_des_encrypt(
|
||||
mbedtls_des_init(&ctx);
|
||||
|
||||
if (mbedtls_des_setkey_enc(&ctx, *key) ||
|
||||
mbedtls_des_crypt_ecb(&ctx, *plaintext, *out))
|
||||
mbedtls_des_crypt_ecb(&ctx, *plaintext, *out)) {
|
||||
ntlm_client_set_errmsg(ntlm, "DES encryption failed");
|
||||
goto done;
|
||||
}
|
||||
|
||||
success = true;
|
||||
|
||||
@@ -72,11 +90,14 @@ done:
|
||||
|
||||
bool ntlm_md4_digest(
|
||||
unsigned char out[CRYPT_MD4_DIGESTSIZE],
|
||||
ntlm_client *ntlm,
|
||||
const unsigned char *in,
|
||||
size_t in_len)
|
||||
{
|
||||
mbedtls_md4_context ctx;
|
||||
|
||||
NTLM_UNUSED(ntlm);
|
||||
|
||||
mbedtls_md4_init(&ctx);
|
||||
mbedtls_md4_starts(&ctx);
|
||||
mbedtls_md4_update(&ctx, in, in_len);
|
||||
@@ -86,60 +107,40 @@ bool ntlm_md4_digest(
|
||||
return true;
|
||||
}
|
||||
|
||||
ntlm_hmac_ctx *ntlm_hmac_ctx_init(void)
|
||||
{
|
||||
ntlm_hmac_ctx *ctx;
|
||||
const mbedtls_md_info_t *info = mbedtls_md_info_from_type(MBEDTLS_MD_MD5);
|
||||
|
||||
if ((ctx = calloc(1, sizeof(ntlm_hmac_ctx))) == NULL)
|
||||
return NULL;
|
||||
|
||||
mbedtls_md_init(&ctx->mbed);
|
||||
|
||||
if (mbedtls_md_setup(&ctx->mbed, info, 1) != 0) {
|
||||
free(ctx);
|
||||
return false;
|
||||
}
|
||||
|
||||
return ctx;
|
||||
}
|
||||
|
||||
bool ntlm_hmac_ctx_reset(ntlm_hmac_ctx *ctx)
|
||||
{
|
||||
return !mbedtls_md_hmac_reset(&ctx->mbed);
|
||||
}
|
||||
|
||||
bool ntlm_hmac_md5_init(
|
||||
ntlm_hmac_ctx *ctx,
|
||||
ntlm_client *ntlm,
|
||||
const unsigned char *key,
|
||||
size_t key_len)
|
||||
{
|
||||
return !mbedtls_md_hmac_starts(&ctx->mbed, key, key_len);
|
||||
if (ntlm->crypt_ctx.hmac_initialized) {
|
||||
if (mbedtls_md_hmac_reset(&ntlm->crypt_ctx.hmac))
|
||||
return false;
|
||||
}
|
||||
|
||||
ntlm->crypt_ctx.hmac_initialized = !mbedtls_md_hmac_starts(&ntlm->crypt_ctx.hmac, key, key_len);
|
||||
return ntlm->crypt_ctx.hmac_initialized;
|
||||
}
|
||||
|
||||
bool ntlm_hmac_md5_update(
|
||||
ntlm_hmac_ctx *ctx,
|
||||
ntlm_client *ntlm,
|
||||
const unsigned char *in,
|
||||
size_t in_len)
|
||||
{
|
||||
return !mbedtls_md_hmac_update(&ctx->mbed, in, in_len);
|
||||
return !mbedtls_md_hmac_update(&ntlm->crypt_ctx.hmac, in, in_len);
|
||||
}
|
||||
|
||||
bool ntlm_hmac_md5_final(
|
||||
unsigned char *out,
|
||||
size_t *out_len,
|
||||
ntlm_hmac_ctx *ctx)
|
||||
ntlm_client *ntlm)
|
||||
{
|
||||
if (*out_len < CRYPT_MD5_DIGESTSIZE)
|
||||
return false;
|
||||
|
||||
return !mbedtls_md_hmac_finish(&ctx->mbed, out);
|
||||
return !mbedtls_md_hmac_finish(&ntlm->crypt_ctx.hmac, out);
|
||||
}
|
||||
|
||||
void ntlm_hmac_ctx_free(ntlm_hmac_ctx *ctx)
|
||||
void ntlm_crypt_shutdown(ntlm_client *ntlm)
|
||||
{
|
||||
if (ctx) {
|
||||
mbedtls_md_free(&ctx->mbed);
|
||||
free(ctx);
|
||||
}
|
||||
mbedtls_md_free(&ntlm->crypt_ctx.hmac);
|
||||
}
|
||||
|
||||
7
deps/ntlmclient/crypt_mbedtls.h
vendored
7
deps/ntlmclient/crypt_mbedtls.h
vendored
@@ -11,8 +11,9 @@
|
||||
|
||||
#include "mbedtls/md.h"
|
||||
|
||||
typedef struct {
|
||||
mbedtls_md_context_t mbed;
|
||||
} ntlm_hmac_ctx;
|
||||
struct ntlm_crypt_ctx {
|
||||
mbedtls_md_context_t hmac;
|
||||
unsigned int hmac_initialized : 1;
|
||||
};
|
||||
|
||||
#endif /* PRIVATE_CRYPT_MBEDTLS_H__ */
|
||||
|
||||
229
deps/ntlmclient/crypt_openssl.c
vendored
229
deps/ntlmclient/crypt_openssl.c
vendored
@@ -9,26 +9,166 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <openssl/rand.h>
|
||||
#include <openssl/des.h>
|
||||
#include <openssl/md4.h>
|
||||
#include <openssl/hmac.h>
|
||||
#include <openssl/err.h>
|
||||
#ifdef CRYPT_OPENSSL_DYNAMIC
|
||||
# include <dlfcn.h>
|
||||
#else
|
||||
# include <openssl/rand.h>
|
||||
# include <openssl/des.h>
|
||||
# include <openssl/md4.h>
|
||||
# include <openssl/hmac.h>
|
||||
# include <openssl/err.h>
|
||||
#endif
|
||||
|
||||
#include "ntlm.h"
|
||||
#include "compat.h"
|
||||
#include "util.h"
|
||||
#include "crypt.h"
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(CRYPT_OPENSSL_DYNAMIC)
|
||||
|
||||
static inline HMAC_CTX *HMAC_CTX_new(void)
|
||||
{
|
||||
return calloc(1, sizeof(HMAC_CTX));
|
||||
}
|
||||
|
||||
static inline int HMAC_CTX_reset(HMAC_CTX *ctx)
|
||||
{
|
||||
ntlm_memzero(ctx, sizeof(HMAC_CTX));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static inline void HMAC_CTX_free(HMAC_CTX *ctx)
|
||||
{
|
||||
free(ctx);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x10100000L || defined(CRYPT_OPENSSL_DYNAMIC)
|
||||
|
||||
static inline void HMAC_CTX_cleanup(HMAC_CTX *ctx)
|
||||
{
|
||||
NTLM_UNUSED(ctx);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef CRYPT_OPENSSL_DYNAMIC
|
||||
|
||||
static bool ntlm_crypt_init_functions(ntlm_client *ntlm)
|
||||
{
|
||||
void *handle;
|
||||
|
||||
if ((handle = dlopen("libssl.so.1.1", RTLD_NOW)) == NULL &&
|
||||
(handle = dlopen("libssl.1.1.dylib", RTLD_NOW)) == NULL &&
|
||||
(handle = dlopen("libssl.so.1.0.0", RTLD_NOW)) == NULL &&
|
||||
(handle = dlopen("libssl.1.0.0.dylib", RTLD_NOW)) == NULL &&
|
||||
(handle = dlopen("libssl.so.10", RTLD_NOW)) == NULL) {
|
||||
ntlm_client_set_errmsg(ntlm, "could not open libssl");
|
||||
return false;
|
||||
}
|
||||
|
||||
ntlm->crypt_ctx.des_set_key_fn = dlsym(handle, "DES_set_key");
|
||||
ntlm->crypt_ctx.des_ecb_encrypt_fn = dlsym(handle, "DES_ecb_encrypt");
|
||||
ntlm->crypt_ctx.err_get_error_fn = dlsym(handle, "ERR_get_error");
|
||||
ntlm->crypt_ctx.err_lib_error_string_fn = dlsym(handle, "ERR_lib_error_string");
|
||||
ntlm->crypt_ctx.evp_md5_fn = dlsym(handle, "EVP_md5");
|
||||
ntlm->crypt_ctx.hmac_ctx_new_fn = dlsym(handle, "HMAC_CTX_new");
|
||||
ntlm->crypt_ctx.hmac_ctx_free_fn = dlsym(handle, "HMAC_CTX_free");
|
||||
ntlm->crypt_ctx.hmac_ctx_reset_fn = dlsym(handle, "HMAC_CTX_reset");
|
||||
ntlm->crypt_ctx.hmac_init_ex_fn = dlsym(handle, "HMAC_Init_ex");
|
||||
ntlm->crypt_ctx.hmac_update_fn = dlsym(handle, "HMAC_Update");
|
||||
ntlm->crypt_ctx.hmac_final_fn = dlsym(handle, "HMAC_Final");
|
||||
ntlm->crypt_ctx.md4_fn = dlsym(handle, "MD4");
|
||||
ntlm->crypt_ctx.rand_bytes_fn = dlsym(handle, "RAND_bytes");
|
||||
|
||||
if (!ntlm->crypt_ctx.des_set_key_fn ||
|
||||
!ntlm->crypt_ctx.des_ecb_encrypt_fn ||
|
||||
!ntlm->crypt_ctx.err_get_error_fn ||
|
||||
!ntlm->crypt_ctx.err_lib_error_string_fn ||
|
||||
!ntlm->crypt_ctx.evp_md5_fn ||
|
||||
!ntlm->crypt_ctx.hmac_init_ex_fn ||
|
||||
!ntlm->crypt_ctx.hmac_update_fn ||
|
||||
!ntlm->crypt_ctx.hmac_final_fn ||
|
||||
!ntlm->crypt_ctx.md4_fn ||
|
||||
!ntlm->crypt_ctx.rand_bytes_fn) {
|
||||
ntlm_client_set_errmsg(ntlm, "could not load libssl functions");
|
||||
dlclose(handle);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Toggle legacy HMAC context functions */
|
||||
if (ntlm->crypt_ctx.hmac_ctx_new_fn &&
|
||||
ntlm->crypt_ctx.hmac_ctx_free_fn &&
|
||||
ntlm->crypt_ctx.hmac_ctx_reset_fn) {
|
||||
ntlm->crypt_ctx.hmac_ctx_cleanup_fn = HMAC_CTX_cleanup;
|
||||
} else {
|
||||
ntlm->crypt_ctx.hmac_ctx_cleanup_fn = dlsym(handle, "HMAC_CTX_cleanup");
|
||||
|
||||
if (!ntlm->crypt_ctx.hmac_ctx_cleanup_fn) {
|
||||
ntlm_client_set_errmsg(ntlm, "could not load legacy libssl functions");
|
||||
dlclose(handle);
|
||||
return false;
|
||||
}
|
||||
|
||||
ntlm->crypt_ctx.hmac_ctx_new_fn = HMAC_CTX_new;
|
||||
ntlm->crypt_ctx.hmac_ctx_free_fn = HMAC_CTX_free;
|
||||
ntlm->crypt_ctx.hmac_ctx_reset_fn = HMAC_CTX_reset;
|
||||
}
|
||||
|
||||
ntlm->crypt_ctx.openssl_handle = handle;
|
||||
return true;
|
||||
}
|
||||
|
||||
#else /* CRYPT_OPENSSL_DYNAMIC */
|
||||
|
||||
static bool ntlm_crypt_init_functions(ntlm_client *ntlm)
|
||||
{
|
||||
ntlm->crypt_ctx.des_set_key_fn = DES_set_key;
|
||||
ntlm->crypt_ctx.des_ecb_encrypt_fn = DES_ecb_encrypt;
|
||||
ntlm->crypt_ctx.err_get_error_fn = ERR_get_error;
|
||||
ntlm->crypt_ctx.err_lib_error_string_fn = ERR_lib_error_string;
|
||||
ntlm->crypt_ctx.evp_md5_fn = EVP_md5;
|
||||
ntlm->crypt_ctx.hmac_ctx_new_fn = HMAC_CTX_new;
|
||||
ntlm->crypt_ctx.hmac_ctx_free_fn = HMAC_CTX_free;
|
||||
ntlm->crypt_ctx.hmac_ctx_reset_fn = HMAC_CTX_reset;
|
||||
ntlm->crypt_ctx.hmac_ctx_cleanup_fn = HMAC_CTX_cleanup;
|
||||
ntlm->crypt_ctx.hmac_init_ex_fn = HMAC_Init_ex;
|
||||
ntlm->crypt_ctx.hmac_update_fn = HMAC_Update;
|
||||
ntlm->crypt_ctx.hmac_final_fn = HMAC_Final;
|
||||
ntlm->crypt_ctx.md4_fn = MD4;
|
||||
ntlm->crypt_ctx.rand_bytes_fn = RAND_bytes;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif /* CRYPT_OPENSSL_DYNAMIC */
|
||||
|
||||
bool ntlm_crypt_init(ntlm_client *ntlm)
|
||||
{
|
||||
if (!ntlm_crypt_init_functions(ntlm))
|
||||
return false;
|
||||
|
||||
ntlm->crypt_ctx.hmac = ntlm->crypt_ctx.hmac_ctx_new_fn();
|
||||
|
||||
if (ntlm->crypt_ctx.hmac == NULL) {
|
||||
ntlm_client_set_errmsg(ntlm, "out of memory");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ntlm_random_bytes(
|
||||
ntlm_client *ntlm,
|
||||
unsigned char *out,
|
||||
ntlm_client *ntlm,
|
||||
size_t len)
|
||||
{
|
||||
int rc = RAND_bytes(out, len);
|
||||
int rc = ntlm->crypt_ctx.rand_bytes_fn(out, len);
|
||||
|
||||
if (rc != 1) {
|
||||
ntlm_client_set_errmsg(ntlm, ERR_lib_error_string(ERR_get_error()));
|
||||
ntlm_client_set_errmsg(ntlm, ntlm->crypt_ctx.err_lib_error_string_fn(ntlm->crypt_ctx.err_get_error_fn()));
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -37,94 +177,81 @@ bool ntlm_random_bytes(
|
||||
|
||||
bool ntlm_des_encrypt(
|
||||
ntlm_des_block *out,
|
||||
ntlm_client *ntlm,
|
||||
ntlm_des_block *plaintext,
|
||||
ntlm_des_block *key)
|
||||
{
|
||||
DES_key_schedule keysched;
|
||||
|
||||
NTLM_UNUSED(ntlm);
|
||||
|
||||
memset(out, 0, sizeof(ntlm_des_block));
|
||||
|
||||
DES_set_key(key, &keysched);
|
||||
DES_ecb_encrypt(plaintext, out, &keysched, DES_ENCRYPT);
|
||||
ntlm->crypt_ctx.des_set_key_fn(key, &keysched);
|
||||
ntlm->crypt_ctx.des_ecb_encrypt_fn(plaintext, out, &keysched, DES_ENCRYPT);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ntlm_md4_digest(
|
||||
unsigned char out[CRYPT_MD4_DIGESTSIZE],
|
||||
ntlm_client *ntlm,
|
||||
const unsigned char *in,
|
||||
size_t in_len)
|
||||
{
|
||||
MD4(in, in_len, out);
|
||||
ntlm->crypt_ctx.md4_fn(in, in_len, out);
|
||||
return true;
|
||||
}
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||
static inline void HMAC_CTX_free(HMAC_CTX *ctx)
|
||||
{
|
||||
if (ctx)
|
||||
HMAC_CTX_cleanup(ctx);
|
||||
|
||||
free(ctx);
|
||||
}
|
||||
|
||||
static inline int HMAC_CTX_reset(HMAC_CTX *ctx)
|
||||
{
|
||||
HMAC_CTX_cleanup(ctx);
|
||||
ntlm_memzero(ctx, sizeof(HMAC_CTX));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static inline HMAC_CTX *HMAC_CTX_new(void)
|
||||
{
|
||||
return calloc(1, sizeof(HMAC_CTX));
|
||||
}
|
||||
#endif
|
||||
|
||||
ntlm_hmac_ctx *ntlm_hmac_ctx_init(void)
|
||||
{
|
||||
return HMAC_CTX_new();
|
||||
}
|
||||
|
||||
bool ntlm_hmac_ctx_reset(ntlm_hmac_ctx *ctx)
|
||||
{
|
||||
return HMAC_CTX_reset(ctx);
|
||||
}
|
||||
|
||||
bool ntlm_hmac_md5_init(
|
||||
ntlm_hmac_ctx *ctx,
|
||||
ntlm_client *ntlm,
|
||||
const unsigned char *key,
|
||||
size_t key_len)
|
||||
{
|
||||
return HMAC_Init_ex(ctx, key, key_len, EVP_md5(), NULL);
|
||||
const EVP_MD *md5 = ntlm->crypt_ctx.evp_md5_fn();
|
||||
|
||||
ntlm->crypt_ctx.hmac_ctx_cleanup_fn(ntlm->crypt_ctx.hmac);
|
||||
|
||||
return ntlm->crypt_ctx.hmac_ctx_reset_fn(ntlm->crypt_ctx.hmac) &&
|
||||
ntlm->crypt_ctx.hmac_init_ex_fn(ntlm->crypt_ctx.hmac, key, key_len, md5, NULL);
|
||||
}
|
||||
|
||||
bool ntlm_hmac_md5_update(
|
||||
ntlm_hmac_ctx *ctx,
|
||||
ntlm_client *ntlm,
|
||||
const unsigned char *in,
|
||||
size_t in_len)
|
||||
{
|
||||
return HMAC_Update(ctx, in, in_len);
|
||||
return ntlm->crypt_ctx.hmac_update_fn(ntlm->crypt_ctx.hmac, in, in_len);
|
||||
}
|
||||
|
||||
bool ntlm_hmac_md5_final(
|
||||
unsigned char *out,
|
||||
size_t *out_len,
|
||||
ntlm_hmac_ctx *ctx)
|
||||
ntlm_client *ntlm)
|
||||
{
|
||||
unsigned int len;
|
||||
|
||||
if (*out_len < CRYPT_MD5_DIGESTSIZE)
|
||||
return false;
|
||||
|
||||
if (!HMAC_Final(ctx, out, &len))
|
||||
if (!ntlm->crypt_ctx.hmac_final_fn(ntlm->crypt_ctx.hmac, out, &len))
|
||||
return false;
|
||||
|
||||
*out_len = len;
|
||||
return true;
|
||||
}
|
||||
|
||||
void ntlm_hmac_ctx_free(ntlm_hmac_ctx *ctx)
|
||||
void ntlm_crypt_shutdown(ntlm_client *ntlm)
|
||||
{
|
||||
HMAC_CTX_free(ctx);
|
||||
if (ntlm->crypt_ctx.hmac) {
|
||||
ntlm->crypt_ctx.hmac_ctx_cleanup_fn(ntlm->crypt_ctx.hmac);
|
||||
ntlm->crypt_ctx.hmac_ctx_free_fn(ntlm->crypt_ctx.hmac);
|
||||
}
|
||||
|
||||
#ifdef CRYPT_OPENSSL_DYNAMIC
|
||||
if (ntlm->crypt_ctx.openssl_handle)
|
||||
dlclose(ntlm->crypt_ctx.openssl_handle);
|
||||
#endif
|
||||
|
||||
memset(&ntlm->crypt_ctx, 0, sizeof(ntlm_crypt_ctx));
|
||||
}
|
||||
|
||||
83
deps/ntlmclient/crypt_openssl.h
vendored
83
deps/ntlmclient/crypt_openssl.h
vendored
@@ -9,13 +9,82 @@
|
||||
#ifndef PRIVATE_CRYPT_OPENSSL_H__
|
||||
#define PRIVATE_CRYPT_OPENSSL_H__
|
||||
|
||||
#include <openssl/hmac.h>
|
||||
|
||||
/* OpenSSL 1.1.0 uses opaque structs, we'll reuse these. */
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||
typedef struct hmac_ctx_st ntlm_hmac_ctx;
|
||||
#else
|
||||
# define ntlm_hmac_ctx HMAC_CTX
|
||||
#ifndef CRYPT_OPENSSL_DYNAMIC
|
||||
# include <openssl/des.h>
|
||||
# include <openssl/hmac.h>
|
||||
#endif
|
||||
|
||||
/* OpenSSL 1.1.0 uses opaque structs, we'll reuse these. */
|
||||
#if defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||
# define HMAC_CTX struct hmac_ctx_st
|
||||
#endif
|
||||
|
||||
#ifdef CRYPT_OPENSSL_DYNAMIC
|
||||
typedef unsigned char DES_cblock[8];
|
||||
typedef unsigned char const_DES_cblock[8];
|
||||
|
||||
typedef unsigned long DES_LONG;
|
||||
|
||||
typedef struct DES_ks {
|
||||
union {
|
||||
DES_cblock cblock;
|
||||
DES_LONG deslong[2];
|
||||
} ks[16];
|
||||
} DES_key_schedule;
|
||||
|
||||
#define DES_ENCRYPT 1
|
||||
|
||||
typedef void EVP_MD;
|
||||
typedef void ENGINE;
|
||||
typedef void EVP_PKEY_CTX;
|
||||
|
||||
#define HMAC_MAX_MD_CBLOCK 128
|
||||
|
||||
typedef struct env_md_ctx_st EVP_MD_CTX;
|
||||
struct env_md_ctx_st {
|
||||
const EVP_MD *digest;
|
||||
ENGINE *engine;
|
||||
unsigned long flags;
|
||||
void *md_data;
|
||||
EVP_PKEY_CTX *pctx;
|
||||
int (*update) (EVP_MD_CTX *ctx, const void *data, size_t count);
|
||||
};
|
||||
|
||||
typedef struct hmac_ctx_st {
|
||||
const EVP_MD *md;
|
||||
EVP_MD_CTX md_ctx;
|
||||
EVP_MD_CTX i_ctx;
|
||||
EVP_MD_CTX o_ctx;
|
||||
unsigned int key_length;
|
||||
unsigned char key[HMAC_MAX_MD_CBLOCK];
|
||||
} HMAC_CTX;
|
||||
#endif
|
||||
|
||||
struct ntlm_crypt_ctx {
|
||||
HMAC_CTX *hmac;
|
||||
|
||||
void *openssl_handle;
|
||||
|
||||
void (*des_ecb_encrypt_fn)(const_DES_cblock *input, DES_cblock *output, DES_key_schedule *ks, int enc);
|
||||
int (*des_set_key_fn)(const_DES_cblock *key, DES_key_schedule *schedule);
|
||||
|
||||
unsigned long (*err_get_error_fn)(void);
|
||||
const char *(*err_lib_error_string_fn)(unsigned long e);
|
||||
|
||||
const EVP_MD *(*evp_md5_fn)(void);
|
||||
|
||||
HMAC_CTX *(*hmac_ctx_new_fn)(void);
|
||||
int (*hmac_ctx_reset_fn)(HMAC_CTX *ctx);
|
||||
void (*hmac_ctx_free_fn)(HMAC_CTX *ctx);
|
||||
void (*hmac_ctx_cleanup_fn)(HMAC_CTX *ctx);
|
||||
|
||||
int (*hmac_init_ex_fn)(HMAC_CTX *ctx, const void *key, int key_len, const EVP_MD *md, ENGINE *impl);
|
||||
int (*hmac_update_fn)(HMAC_CTX *ctx, const unsigned char *data, size_t len);
|
||||
int (*hmac_final_fn)(HMAC_CTX *ctx, unsigned char *md, unsigned int *len);
|
||||
|
||||
unsigned char *(*md4_fn)(const unsigned char *d, size_t n, unsigned char *md);
|
||||
|
||||
int (*rand_bytes_fn)(unsigned char *buf, int num);
|
||||
};
|
||||
|
||||
#endif /* PRIVATE_CRYPT_OPENSSL_H__ */
|
||||
|
||||
266
deps/ntlmclient/ntlm.c
vendored
266
deps/ntlmclient/ntlm.c
vendored
@@ -9,7 +9,6 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <ctype.h>
|
||||
#include <unistd.h>
|
||||
@@ -24,6 +23,18 @@
|
||||
#include "compat.h"
|
||||
#include "util.h"
|
||||
|
||||
#define NTLM_ASSERT_ARG(expr) do { \
|
||||
if (!(expr)) \
|
||||
return NTLM_CLIENT_ERROR_INVALID_INPUT; \
|
||||
} while(0)
|
||||
|
||||
#define NTLM_ASSERT(ntlm, expr) do { \
|
||||
if (!(expr)) { \
|
||||
ntlm_client_set_errmsg(ntlm, "internal error: " #expr); \
|
||||
return -1; \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
unsigned char ntlm_client_signature[] = NTLM_SIGNATURE;
|
||||
|
||||
static bool supports_unicode(ntlm_client *ntlm)
|
||||
@@ -52,17 +63,20 @@ ntlm_client *ntlm_client_init(ntlm_client_flags flags)
|
||||
|
||||
ntlm->flags = flags;
|
||||
|
||||
if ((ntlm->hmac_ctx = ntlm_hmac_ctx_init()) == NULL ||
|
||||
(ntlm->unicode_ctx = ntlm_unicode_ctx_init(ntlm)) == NULL) {
|
||||
ntlm_hmac_ctx_free(ntlm->hmac_ctx);
|
||||
ntlm_unicode_ctx_free(ntlm->unicode_ctx);
|
||||
free(ntlm);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return ntlm;
|
||||
}
|
||||
|
||||
#define ENSURE_INITIALIZED(ntlm) \
|
||||
do { \
|
||||
if (!(ntlm)->unicode_initialized) \
|
||||
(ntlm)->unicode_initialized = ntlm_unicode_init((ntlm)); \
|
||||
if (!(ntlm)->crypt_initialized) \
|
||||
(ntlm)->crypt_initialized = ntlm_crypt_init((ntlm)); \
|
||||
if (!(ntlm)->unicode_initialized || \
|
||||
!(ntlm)->crypt_initialized) \
|
||||
return -1; \
|
||||
} while(0)
|
||||
|
||||
void ntlm_client_set_errmsg(ntlm_client *ntlm, const char *errmsg)
|
||||
{
|
||||
ntlm->state = NTLM_STATE_ERROR;
|
||||
@@ -71,7 +85,9 @@ void ntlm_client_set_errmsg(ntlm_client *ntlm, const char *errmsg)
|
||||
|
||||
const char *ntlm_client_errmsg(ntlm_client *ntlm)
|
||||
{
|
||||
assert(ntlm);
|
||||
if (!ntlm)
|
||||
return "internal error";
|
||||
|
||||
return ntlm->errmsg ? ntlm->errmsg : "no error";
|
||||
}
|
||||
|
||||
@@ -81,7 +97,7 @@ int ntlm_client_set_version(
|
||||
uint8_t minor,
|
||||
uint16_t build)
|
||||
{
|
||||
assert(ntlm);
|
||||
NTLM_ASSERT_ARG(ntlm);
|
||||
|
||||
ntlm->host_version.major = major;
|
||||
ntlm->host_version.minor = minor;
|
||||
@@ -93,20 +109,25 @@ int ntlm_client_set_version(
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define reset(ptr) do { free(ptr); ptr = NULL; } while(0)
|
||||
|
||||
static void free_hostname(ntlm_client *ntlm)
|
||||
{
|
||||
reset(ntlm->hostname);
|
||||
reset(ntlm->hostdomain);
|
||||
reset(ntlm->hostname_utf16);
|
||||
ntlm->hostname_utf16_len = 0;
|
||||
}
|
||||
|
||||
int ntlm_client_set_hostname(
|
||||
ntlm_client *ntlm,
|
||||
const char *hostname,
|
||||
const char *domain)
|
||||
{
|
||||
assert(ntlm);
|
||||
NTLM_ASSERT_ARG(ntlm);
|
||||
ENSURE_INITIALIZED(ntlm);
|
||||
|
||||
free(ntlm->hostname);
|
||||
free(ntlm->hostdomain);
|
||||
free(ntlm->hostname_utf16);
|
||||
|
||||
ntlm->hostname = NULL;
|
||||
ntlm->hostdomain = NULL;
|
||||
ntlm->hostname_utf16 = NULL;
|
||||
free_hostname(ntlm);
|
||||
|
||||
if (hostname && (ntlm->hostname = strdup(hostname)) == NULL) {
|
||||
ntlm_client_set_errmsg(ntlm, "out of memory");
|
||||
@@ -121,7 +142,7 @@ int ntlm_client_set_hostname(
|
||||
if (hostname && supports_unicode(ntlm) && !ntlm_unicode_utf8_to_16(
|
||||
&ntlm->hostname_utf16,
|
||||
&ntlm->hostname_utf16_len,
|
||||
ntlm->unicode_ctx,
|
||||
ntlm,
|
||||
hostname,
|
||||
strlen(hostname)))
|
||||
return -1;
|
||||
@@ -137,25 +158,20 @@ static void free_credentials(ntlm_client *ntlm)
|
||||
if (ntlm->password_utf16)
|
||||
ntlm_memzero(ntlm->password_utf16, ntlm->password_utf16_len);
|
||||
|
||||
free(ntlm->username);
|
||||
free(ntlm->username_upper);
|
||||
free(ntlm->userdomain);
|
||||
free(ntlm->password);
|
||||
reset(ntlm->username);
|
||||
reset(ntlm->username_upper);
|
||||
reset(ntlm->userdomain);
|
||||
reset(ntlm->password);
|
||||
|
||||
free(ntlm->username_utf16);
|
||||
free(ntlm->username_upper_utf16);
|
||||
free(ntlm->userdomain_utf16);
|
||||
free(ntlm->password_utf16);
|
||||
reset(ntlm->username_utf16);
|
||||
reset(ntlm->username_upper_utf16);
|
||||
reset(ntlm->userdomain_utf16);
|
||||
reset(ntlm->password_utf16);
|
||||
|
||||
ntlm->username = NULL;
|
||||
ntlm->username_upper = NULL;
|
||||
ntlm->userdomain = NULL;
|
||||
ntlm->password = NULL;
|
||||
|
||||
ntlm->username_utf16 = NULL;
|
||||
ntlm->username_upper_utf16 = NULL;
|
||||
ntlm->userdomain_utf16 = NULL;
|
||||
ntlm->password_utf16 = NULL;
|
||||
ntlm->username_utf16_len = 0;
|
||||
ntlm->username_upper_utf16_len = 0;
|
||||
ntlm->userdomain_utf16_len = 0;
|
||||
ntlm->password_utf16_len = 0;
|
||||
}
|
||||
|
||||
int ntlm_client_set_credentials(
|
||||
@@ -164,7 +180,8 @@ int ntlm_client_set_credentials(
|
||||
const char *domain,
|
||||
const char *password)
|
||||
{
|
||||
assert(ntlm);
|
||||
NTLM_ASSERT_ARG(ntlm);
|
||||
ENSURE_INITIALIZED(ntlm);
|
||||
|
||||
free_credentials(ntlm);
|
||||
|
||||
@@ -185,7 +202,7 @@ int ntlm_client_set_credentials(
|
||||
if (!ntlm_unicode_utf8_to_16(
|
||||
&ntlm->username_utf16,
|
||||
&ntlm->username_utf16_len,
|
||||
ntlm->unicode_ctx,
|
||||
ntlm,
|
||||
ntlm->username,
|
||||
strlen(ntlm->username)))
|
||||
return -1;
|
||||
@@ -193,7 +210,7 @@ int ntlm_client_set_credentials(
|
||||
if (!ntlm_unicode_utf8_to_16(
|
||||
&ntlm->username_upper_utf16,
|
||||
&ntlm->username_upper_utf16_len,
|
||||
ntlm->unicode_ctx,
|
||||
ntlm,
|
||||
ntlm->username_upper,
|
||||
strlen(ntlm->username_upper)))
|
||||
return -1;
|
||||
@@ -202,7 +219,7 @@ int ntlm_client_set_credentials(
|
||||
if (domain && supports_unicode(ntlm) && !ntlm_unicode_utf8_to_16(
|
||||
&ntlm->userdomain_utf16,
|
||||
&ntlm->userdomain_utf16_len,
|
||||
ntlm->unicode_ctx,
|
||||
ntlm,
|
||||
ntlm->userdomain,
|
||||
strlen(ntlm->userdomain)))
|
||||
return -1;
|
||||
@@ -212,7 +229,8 @@ int ntlm_client_set_credentials(
|
||||
|
||||
int ntlm_client_set_target(ntlm_client *ntlm, const char *target)
|
||||
{
|
||||
assert(ntlm);
|
||||
NTLM_ASSERT_ARG(ntlm);
|
||||
ENSURE_INITIALIZED(ntlm);
|
||||
|
||||
free(ntlm->target);
|
||||
free(ntlm->target_utf16);
|
||||
@@ -229,7 +247,7 @@ int ntlm_client_set_target(ntlm_client *ntlm, const char *target)
|
||||
if (supports_unicode(ntlm) && !ntlm_unicode_utf8_to_16(
|
||||
&ntlm->target_utf16,
|
||||
&ntlm->target_utf16_len,
|
||||
ntlm->unicode_ctx,
|
||||
ntlm,
|
||||
ntlm->target,
|
||||
strlen(ntlm->target)))
|
||||
return -1;
|
||||
@@ -240,14 +258,16 @@ int ntlm_client_set_target(ntlm_client *ntlm, const char *target)
|
||||
|
||||
int ntlm_client_set_nonce(ntlm_client *ntlm, uint64_t nonce)
|
||||
{
|
||||
assert(ntlm);
|
||||
NTLM_ASSERT_ARG(ntlm);
|
||||
|
||||
ntlm->nonce = nonce;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ntlm_client_set_timestamp(ntlm_client *ntlm, uint64_t timestamp)
|
||||
{
|
||||
assert(ntlm);
|
||||
NTLM_ASSERT_ARG(ntlm);
|
||||
|
||||
ntlm->timestamp = timestamp;
|
||||
return 0;
|
||||
}
|
||||
@@ -475,7 +495,7 @@ static inline bool read_string_unicode(
|
||||
size_t out_len;
|
||||
int ret = ntlm_unicode_utf16_to_8(out,
|
||||
&out_len,
|
||||
ntlm->unicode_ctx,
|
||||
ntlm,
|
||||
(char *)&message->buf[message->pos],
|
||||
string_len);
|
||||
|
||||
@@ -593,7 +613,9 @@ int ntlm_client_negotiate(
|
||||
size_t hostname_offset = 0;
|
||||
uint32_t flags = 0;
|
||||
|
||||
assert(out && out_len && ntlm);
|
||||
NTLM_ASSERT_ARG(out);
|
||||
NTLM_ASSERT_ARG(out_len);
|
||||
NTLM_ASSERT_ARG(ntlm);
|
||||
|
||||
*out = NULL;
|
||||
*out_len = 0;
|
||||
@@ -676,20 +698,22 @@ int ntlm_client_negotiate(
|
||||
return -1;
|
||||
|
||||
if (hostname_len > 0) {
|
||||
assert(hostname_offset == ntlm->negotiate.pos);
|
||||
NTLM_ASSERT(ntlm, hostname_offset == ntlm->negotiate.pos);
|
||||
|
||||
if (!write_buf(ntlm, &ntlm->negotiate,
|
||||
(const unsigned char *)ntlm->hostname, hostname_len))
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (domain_len > 0) {
|
||||
assert(domain_offset == ntlm->negotiate.pos);
|
||||
NTLM_ASSERT(ntlm, domain_offset == ntlm->negotiate.pos);
|
||||
|
||||
if (!write_buf(ntlm, &ntlm->negotiate,
|
||||
(const unsigned char *)ntlm->hostdomain, domain_len))
|
||||
return -1;
|
||||
}
|
||||
|
||||
assert(ntlm->negotiate.pos == ntlm->negotiate.len);
|
||||
NTLM_ASSERT(ntlm, ntlm->negotiate.pos == ntlm->negotiate.len);
|
||||
|
||||
ntlm->state = NTLM_STATE_CHALLENGE;
|
||||
|
||||
@@ -711,7 +735,10 @@ int ntlm_client_set_challenge(
|
||||
uint32_t name_offset, info_offset = 0;
|
||||
bool unicode, has_target_info = false;
|
||||
|
||||
assert(ntlm && (challenge_msg || !challenge_msg_len));
|
||||
NTLM_ASSERT_ARG(ntlm);
|
||||
NTLM_ASSERT_ARG(challenge_msg || !challenge_msg_len);
|
||||
|
||||
ENSURE_INITIALIZED(ntlm);
|
||||
|
||||
if (ntlm->state != NTLM_STATE_NEGOTIATE &&
|
||||
ntlm->state != NTLM_STATE_CHALLENGE) {
|
||||
@@ -940,6 +967,7 @@ static void des_key_from_password(
|
||||
|
||||
static inline bool generate_lm_hash(
|
||||
ntlm_des_block out[2],
|
||||
ntlm_client *ntlm,
|
||||
const char *password)
|
||||
{
|
||||
/* LM encrypts this known plaintext using the password as a key */
|
||||
@@ -968,8 +996,8 @@ static inline bool generate_lm_hash(
|
||||
des_key_from_password(&key1, keystr1, keystr1_len);
|
||||
des_key_from_password(&key2, keystr2, keystr2_len);
|
||||
|
||||
return ntlm_des_encrypt(&out[0], &plaintext, &key1) &&
|
||||
ntlm_des_encrypt(&out[1], &plaintext, &key2);
|
||||
return ntlm_des_encrypt(&out[0], ntlm, &plaintext, &key1) &&
|
||||
ntlm_des_encrypt(&out[1], ntlm, &plaintext, &key2);
|
||||
}
|
||||
|
||||
static void des_keys_from_lm_hash(ntlm_des_block out[3], ntlm_des_block lm_hash[2])
|
||||
@@ -994,16 +1022,16 @@ static bool generate_lm_response(ntlm_client *ntlm)
|
||||
ntlm_des_block *challenge = (ntlm_des_block *)&ntlm->challenge.nonce;
|
||||
|
||||
/* Generate the LM hash from the password */
|
||||
if (!generate_lm_hash(lm_hash, ntlm->password))
|
||||
if (!generate_lm_hash(lm_hash, ntlm, ntlm->password))
|
||||
return false;
|
||||
|
||||
/* Convert that LM hash to three DES keys */
|
||||
des_keys_from_lm_hash(key, lm_hash);
|
||||
|
||||
/* Finally, encrypt the challenge with each of these keys */
|
||||
if (!ntlm_des_encrypt(&lm_response[0], challenge, &key[0]) ||
|
||||
!ntlm_des_encrypt(&lm_response[1], challenge, &key[1]) ||
|
||||
!ntlm_des_encrypt(&lm_response[2], challenge, &key[2]))
|
||||
if (!ntlm_des_encrypt(&lm_response[0], ntlm, challenge, &key[0]) ||
|
||||
!ntlm_des_encrypt(&lm_response[1], ntlm, challenge, &key[1]) ||
|
||||
!ntlm_des_encrypt(&lm_response[2], ntlm, challenge, &key[2]))
|
||||
return false;
|
||||
|
||||
memcpy(&ntlm->lm_response[0], lm_response[0], 8);
|
||||
@@ -1022,12 +1050,13 @@ static bool generate_ntlm_hash(
|
||||
if (ntlm->password && !ntlm_unicode_utf8_to_16(
|
||||
&ntlm->password_utf16,
|
||||
&ntlm->password_utf16_len,
|
||||
ntlm->unicode_ctx,
|
||||
ntlm,
|
||||
ntlm->password,
|
||||
strlen(ntlm->password)))
|
||||
return false;
|
||||
|
||||
return ntlm_md4_digest(out,
|
||||
ntlm,
|
||||
(const unsigned char *)ntlm->password_utf16,
|
||||
ntlm->password_utf16_len);
|
||||
}
|
||||
@@ -1048,9 +1077,9 @@ static bool generate_ntlm_response(ntlm_client *ntlm)
|
||||
des_key_from_password(&key[2], &ntlm_hash[14], 2);
|
||||
|
||||
/* Finally, encrypt the challenge with each of these keys */
|
||||
if (!ntlm_des_encrypt(&ntlm_response[0], challenge, &key[0]) ||
|
||||
!ntlm_des_encrypt(&ntlm_response[1], challenge, &key[1]) ||
|
||||
!ntlm_des_encrypt(&ntlm_response[2], challenge, &key[2]))
|
||||
if (!ntlm_des_encrypt(&ntlm_response[0], ntlm, challenge, &key[0]) ||
|
||||
!ntlm_des_encrypt(&ntlm_response[1], ntlm, challenge, &key[1]) ||
|
||||
!ntlm_des_encrypt(&ntlm_response[2], ntlm, challenge, &key[2]))
|
||||
return false;
|
||||
|
||||
memcpy(&ntlm->ntlm_response[0], ntlm_response[0], 8);
|
||||
@@ -1081,16 +1110,15 @@ static bool generate_ntlm2_hash(
|
||||
target_len = ntlm->target_utf16_len;
|
||||
}
|
||||
|
||||
if (!ntlm_hmac_ctx_reset(ntlm->hmac_ctx) ||
|
||||
!ntlm_hmac_md5_init(ntlm->hmac_ctx, ntlm_hash, sizeof(ntlm_hash)) ||
|
||||
!ntlm_hmac_md5_update(ntlm->hmac_ctx, username, username_len) ||
|
||||
!ntlm_hmac_md5_update(ntlm->hmac_ctx, target, target_len) ||
|
||||
!ntlm_hmac_md5_final(out, &out_len, ntlm->hmac_ctx)) {
|
||||
if (!ntlm_hmac_md5_init(ntlm, ntlm_hash, sizeof(ntlm_hash)) ||
|
||||
!ntlm_hmac_md5_update(ntlm, username, username_len) ||
|
||||
!ntlm_hmac_md5_update(ntlm, target, target_len) ||
|
||||
!ntlm_hmac_md5_final(out, &out_len, ntlm)) {
|
||||
ntlm_client_set_errmsg(ntlm, "failed to create HMAC-MD5");
|
||||
return false;
|
||||
}
|
||||
|
||||
assert(out_len == NTLM_NTLM2_HASH_LEN);
|
||||
NTLM_ASSERT(ntlm, out_len == NTLM_NTLM2_HASH_LEN);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1103,18 +1131,15 @@ static bool generate_ntlm2_challengehash(
|
||||
{
|
||||
size_t out_len = 16;
|
||||
|
||||
if (!ntlm_hmac_ctx_reset(ntlm->hmac_ctx) ||
|
||||
!ntlm_hmac_md5_init(ntlm->hmac_ctx,
|
||||
ntlm2_hash, NTLM_NTLM2_HASH_LEN) ||
|
||||
!ntlm_hmac_md5_update(ntlm->hmac_ctx,
|
||||
(const unsigned char *)&ntlm->challenge.nonce, 8) ||
|
||||
!ntlm_hmac_md5_update(ntlm->hmac_ctx, blob, blob_len) ||
|
||||
!ntlm_hmac_md5_final(out, &out_len, ntlm->hmac_ctx)) {
|
||||
if (!ntlm_hmac_md5_init(ntlm, ntlm2_hash, NTLM_NTLM2_HASH_LEN) ||
|
||||
!ntlm_hmac_md5_update(ntlm, (const unsigned char *)&ntlm->challenge.nonce, 8) ||
|
||||
!ntlm_hmac_md5_update(ntlm, blob, blob_len) ||
|
||||
!ntlm_hmac_md5_final(out, &out_len, ntlm)) {
|
||||
ntlm_client_set_errmsg(ntlm, "failed to create HMAC-MD5");
|
||||
return false;
|
||||
}
|
||||
|
||||
assert(out_len == 16);
|
||||
NTLM_ASSERT(ntlm, out_len == 16);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1127,19 +1152,15 @@ static bool generate_lm2_response(ntlm_client *ntlm,
|
||||
|
||||
local_nonce = ntlm_htonll(ntlm->nonce);
|
||||
|
||||
if (!ntlm_hmac_ctx_reset(ntlm->hmac_ctx) ||
|
||||
!ntlm_hmac_md5_init(ntlm->hmac_ctx,
|
||||
ntlm2_hash, NTLM_NTLM2_HASH_LEN) ||
|
||||
!ntlm_hmac_md5_update(ntlm->hmac_ctx,
|
||||
(const unsigned char *)&ntlm->challenge.nonce, 8) ||
|
||||
!ntlm_hmac_md5_update(ntlm->hmac_ctx,
|
||||
(const unsigned char *)&local_nonce, 8) ||
|
||||
!ntlm_hmac_md5_final(lm2_challengehash, &lm2_len, ntlm->hmac_ctx)) {
|
||||
if (!ntlm_hmac_md5_init(ntlm, ntlm2_hash, NTLM_NTLM2_HASH_LEN) ||
|
||||
!ntlm_hmac_md5_update(ntlm, (const unsigned char *)&ntlm->challenge.nonce, 8) ||
|
||||
!ntlm_hmac_md5_update(ntlm, (const unsigned char *)&local_nonce, 8) ||
|
||||
!ntlm_hmac_md5_final(lm2_challengehash, &lm2_len, ntlm)) {
|
||||
ntlm_client_set_errmsg(ntlm, "failed to create HMAC-MD5");
|
||||
return false;
|
||||
}
|
||||
|
||||
assert(lm2_len == 16);
|
||||
NTLM_ASSERT(ntlm, lm2_len == 16);
|
||||
|
||||
memcpy(&ntlm->lm_response[0], lm2_challengehash, 16);
|
||||
memcpy(&ntlm->lm_response[16], &local_nonce, 8);
|
||||
@@ -1163,7 +1184,7 @@ static bool generate_nonce(ntlm_client *ntlm)
|
||||
if (ntlm->nonce)
|
||||
return true;
|
||||
|
||||
if (!ntlm_random_bytes(ntlm, buf, 8))
|
||||
if (!ntlm_random_bytes(buf, ntlm, 8))
|
||||
return false;
|
||||
|
||||
memcpy(&ntlm->nonce, buf, sizeof(uint64_t));
|
||||
@@ -1233,7 +1254,11 @@ int ntlm_client_response(
|
||||
uint32_t flags = 0;
|
||||
bool unicode;
|
||||
|
||||
assert(out && out_len && ntlm);
|
||||
NTLM_ASSERT_ARG(out);
|
||||
NTLM_ASSERT_ARG(out_len);
|
||||
NTLM_ASSERT_ARG(ntlm);
|
||||
|
||||
ENSURE_INITIALIZED(ntlm);
|
||||
|
||||
*out = NULL;
|
||||
*out_len = 0;
|
||||
@@ -1356,7 +1381,7 @@ int ntlm_client_response(
|
||||
!write_buf(ntlm, &ntlm->response, session, session_len))
|
||||
return -1;
|
||||
|
||||
assert(ntlm->response.pos == ntlm->response.len);
|
||||
NTLM_ASSERT(ntlm, ntlm->response.pos == ntlm->response.len);
|
||||
|
||||
ntlm->state = NTLM_STATE_COMPLETE;
|
||||
|
||||
@@ -1368,41 +1393,48 @@ int ntlm_client_response(
|
||||
|
||||
void ntlm_client_reset(ntlm_client *ntlm)
|
||||
{
|
||||
ntlm_client_flags flags;
|
||||
ntlm_hmac_ctx *hmac_ctx;
|
||||
ntlm_unicode_ctx *unicode_ctx;
|
||||
if (!ntlm)
|
||||
return;
|
||||
|
||||
assert(ntlm);
|
||||
ntlm->state = NTLM_STATE_NEGOTIATE;
|
||||
|
||||
free_hostname(ntlm);
|
||||
|
||||
memset(&ntlm->host_version, 0, sizeof(ntlm_version));
|
||||
|
||||
reset(ntlm->target);
|
||||
reset(ntlm->target_utf16);
|
||||
ntlm->target_utf16_len = 0;
|
||||
|
||||
free_credentials(ntlm);
|
||||
|
||||
ntlm->nonce = 0;
|
||||
ntlm->timestamp = 0;
|
||||
|
||||
memset(ntlm->lm_response, 0, NTLM_LM_RESPONSE_LEN);
|
||||
ntlm->lm_response_len = 0;
|
||||
|
||||
memset(ntlm->ntlm_response, 0, NTLM_NTLM_RESPONSE_LEN);
|
||||
ntlm->ntlm_response_len = 0;
|
||||
|
||||
reset(ntlm->ntlm2_response);
|
||||
ntlm->ntlm2_response_len = 0;
|
||||
|
||||
reset(ntlm->negotiate.buf);
|
||||
ntlm->negotiate.pos = 0;
|
||||
ntlm->negotiate.len = 0;
|
||||
|
||||
reset(ntlm->response.buf);
|
||||
ntlm->response.pos = 0;
|
||||
ntlm->response.len = 0;
|
||||
|
||||
free(ntlm->negotiate.buf);
|
||||
free(ntlm->challenge.target_info);
|
||||
free(ntlm->challenge.target);
|
||||
free(ntlm->challenge.target_domain);
|
||||
free(ntlm->challenge.target_domain_dns);
|
||||
free(ntlm->challenge.target_server);
|
||||
free(ntlm->challenge.target_server_dns);
|
||||
free(ntlm->response.buf);
|
||||
|
||||
free(ntlm->hostname);
|
||||
free(ntlm->hostname_utf16);
|
||||
free(ntlm->hostdomain);
|
||||
|
||||
free(ntlm->target);
|
||||
free(ntlm->target_utf16);
|
||||
|
||||
free(ntlm->ntlm2_response);
|
||||
|
||||
free_credentials(ntlm);
|
||||
|
||||
flags = ntlm->flags;
|
||||
hmac_ctx = ntlm->hmac_ctx;
|
||||
unicode_ctx = ntlm->unicode_ctx;
|
||||
|
||||
memset(ntlm, 0, sizeof(struct ntlm_client));
|
||||
|
||||
ntlm->flags = flags;
|
||||
ntlm->hmac_ctx = hmac_ctx;
|
||||
ntlm->unicode_ctx = unicode_ctx;
|
||||
memset(&ntlm->challenge, 0, sizeof(ntlm_challenge));
|
||||
}
|
||||
|
||||
void ntlm_client_free(ntlm_client *ntlm)
|
||||
@@ -1410,10 +1442,10 @@ void ntlm_client_free(ntlm_client *ntlm)
|
||||
if (!ntlm)
|
||||
return;
|
||||
|
||||
ntlm_client_reset(ntlm);
|
||||
ntlm_crypt_shutdown(ntlm);
|
||||
ntlm_unicode_shutdown(ntlm);
|
||||
|
||||
ntlm_hmac_ctx_free(ntlm->hmac_ctx);
|
||||
ntlm_unicode_ctx_free(ntlm->unicode_ctx);
|
||||
ntlm_client_reset(ntlm);
|
||||
|
||||
free(ntlm);
|
||||
}
|
||||
|
||||
26
deps/ntlmclient/ntlm.h
vendored
26
deps/ntlmclient/ntlm.h
vendored
@@ -14,6 +14,8 @@
|
||||
#include "crypt.h"
|
||||
#include "compat.h"
|
||||
|
||||
#define NTLM_UNUSED(x) ((void)(x))
|
||||
|
||||
#define NTLM_LM_RESPONSE_LEN 24
|
||||
#define NTLM_NTLM_RESPONSE_LEN 24
|
||||
#define NTLM_NTLM_HASH_LEN 16
|
||||
@@ -66,9 +68,11 @@ struct ntlm_client {
|
||||
|
||||
ntlm_state state;
|
||||
|
||||
/* crypto contexts */
|
||||
ntlm_hmac_ctx *hmac_ctx;
|
||||
ntlm_unicode_ctx *unicode_ctx;
|
||||
/* subsystem contexts */
|
||||
ntlm_crypt_ctx crypt_ctx;
|
||||
ntlm_unicode_ctx unicode_ctx;
|
||||
int crypt_initialized : 1,
|
||||
unicode_initialized : 1;
|
||||
|
||||
/* error message as set by the library */
|
||||
const char *errmsg;
|
||||
@@ -85,24 +89,24 @@ struct ntlm_client {
|
||||
char *password;
|
||||
|
||||
/* strings as converted to utf16 */
|
||||
char *hostname_utf16;
|
||||
char *target_utf16;
|
||||
char *username_utf16;
|
||||
char *username_upper_utf16;
|
||||
char *userdomain_utf16;
|
||||
char *hostname_utf16;
|
||||
char *password_utf16;
|
||||
|
||||
size_t hostname_utf16_len;
|
||||
size_t username_utf16_len;
|
||||
size_t username_upper_utf16_len;
|
||||
size_t userdomain_utf16_len;
|
||||
size_t password_utf16_len;
|
||||
size_t target_utf16_len;
|
||||
|
||||
/* timestamp and nonce; only for debugging */
|
||||
uint64_t nonce;
|
||||
uint64_t timestamp;
|
||||
|
||||
size_t username_utf16_len;
|
||||
size_t username_upper_utf16_len;
|
||||
size_t userdomain_utf16_len;
|
||||
size_t hostname_utf16_len;
|
||||
size_t password_utf16_len;
|
||||
size_t target_utf16_len;
|
||||
|
||||
unsigned char lm_response[NTLM_LM_RESPONSE_LEN];
|
||||
size_t lm_response_len;
|
||||
|
||||
|
||||
19
deps/ntlmclient/ntlmclient.h
vendored
19
deps/ntlmclient/ntlmclient.h
vendored
@@ -15,13 +15,26 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define NTLM_CLIENT_VERSION "0.0.1"
|
||||
#define NTLM_CLIENT_VERSION "0.9.0"
|
||||
#define NTLM_CLIENT_VERSION_MAJOR 0
|
||||
#define NTLM_CLIENT_VERSION_MINOR 0
|
||||
#define NTLM_CLIENT_VERSION_TEENY 1
|
||||
#define NTLM_CLIENT_VERSION_MINOR 9
|
||||
#define NTLM_CLIENT_VERSION_TEENY 0
|
||||
|
||||
typedef struct ntlm_client ntlm_client;
|
||||
|
||||
typedef enum {
|
||||
/**
|
||||
* An error occurred; more details are available by querying
|
||||
* `ntlm_client_errmsg`.
|
||||
*/
|
||||
NTLM_CLIENT_ERROR = -1,
|
||||
|
||||
/**
|
||||
* The input provided to the function is missing or invalid.
|
||||
*/
|
||||
NTLM_CLIENT_ERROR_INVALID_INPUT = -2,
|
||||
} ntlm_error_code;
|
||||
|
||||
/*
|
||||
* Flags for initializing the `ntlm_client` context. A combination of
|
||||
* these flags can be provided to `ntlm_client_init`.
|
||||
|
||||
14
deps/ntlmclient/unicode.h
vendored
14
deps/ntlmclient/unicode.h
vendored
@@ -11,26 +11,32 @@
|
||||
|
||||
#include "compat.h"
|
||||
|
||||
#ifdef UNICODE_ICONV
|
||||
# include "unicode_iconv.h"
|
||||
#elif UNICODE_BUILTIN
|
||||
# include "unicode_builtin.h"
|
||||
#endif
|
||||
|
||||
#define NTLM_UNICODE_MAX_LEN 2048
|
||||
|
||||
typedef struct ntlm_unicode_ctx ntlm_unicode_ctx;
|
||||
|
||||
extern ntlm_unicode_ctx *ntlm_unicode_ctx_init(ntlm_client *ntlm);
|
||||
extern bool ntlm_unicode_init(ntlm_client *ntlm);
|
||||
|
||||
bool ntlm_unicode_utf8_to_16(
|
||||
char **converted,
|
||||
size_t *converted_len,
|
||||
ntlm_unicode_ctx *ctx,
|
||||
ntlm_client *ntlm,
|
||||
const char *string,
|
||||
size_t string_len);
|
||||
|
||||
bool ntlm_unicode_utf16_to_8(
|
||||
char **converted,
|
||||
size_t *converted_len,
|
||||
ntlm_unicode_ctx *ctx,
|
||||
ntlm_client *ntlm,
|
||||
const char *string,
|
||||
size_t string_len);
|
||||
|
||||
extern void ntlm_unicode_ctx_free(ntlm_unicode_ctx *ctx);
|
||||
extern void ntlm_unicode_shutdown(ntlm_client *ntlm);
|
||||
|
||||
#endif /* PRIVATE_UNICODE_H__ */
|
||||
|
||||
43
deps/ntlmclient/unicode_builtin.c
vendored
43
deps/ntlmclient/unicode_builtin.c
vendored
@@ -13,10 +13,6 @@
|
||||
#include "unicode.h"
|
||||
#include "compat.h"
|
||||
|
||||
struct ntlm_unicode_ctx {
|
||||
ntlm_client *ntlm;
|
||||
};
|
||||
|
||||
typedef unsigned int UTF32; /* at least 32 bits */
|
||||
typedef unsigned short UTF16; /* at least 16 bits */
|
||||
typedef unsigned char UTF8; /* typically 8 bits */
|
||||
@@ -281,15 +277,10 @@ static ConversionResult ConvertUTF8toUTF16 (
|
||||
}
|
||||
|
||||
|
||||
ntlm_unicode_ctx *ntlm_unicode_ctx_init(ntlm_client *ntlm)
|
||||
bool ntlm_unicode_init(ntlm_client *ntlm)
|
||||
{
|
||||
ntlm_unicode_ctx *ctx;
|
||||
|
||||
if ((ctx = malloc(sizeof(ntlm_unicode_ctx))) == NULL)
|
||||
return NULL;
|
||||
|
||||
ctx->ntlm = ntlm;
|
||||
return ctx;
|
||||
NTLM_UNUSED(ntlm);
|
||||
return true;
|
||||
}
|
||||
|
||||
typedef enum {
|
||||
@@ -300,7 +291,7 @@ typedef enum {
|
||||
static inline bool unicode_builtin_encoding_convert(
|
||||
char **converted,
|
||||
size_t *converted_len,
|
||||
ntlm_unicode_ctx *ctx,
|
||||
ntlm_client *ntlm,
|
||||
const char *string,
|
||||
size_t string_len,
|
||||
unicode_builtin_encoding_direction direction)
|
||||
@@ -332,7 +323,7 @@ static inline bool unicode_builtin_encoding_convert(
|
||||
out_size = (out_size + 7) & ~7;
|
||||
|
||||
if ((out = malloc(out_size)) == NULL) {
|
||||
ntlm_client_set_errmsg(ctx->ntlm, "out of memory");
|
||||
ntlm_client_set_errmsg(ntlm, "out of memory");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -358,17 +349,17 @@ static inline bool unicode_builtin_encoding_convert(
|
||||
success = true;
|
||||
goto done;
|
||||
case sourceExhausted:
|
||||
ntlm_client_set_errmsg(ctx->ntlm,
|
||||
ntlm_client_set_errmsg(ntlm,
|
||||
"invalid unicode string; trailing data remains");
|
||||
goto done;
|
||||
case targetExhausted:
|
||||
break;
|
||||
case sourceIllegal:
|
||||
ntlm_client_set_errmsg(ctx->ntlm,
|
||||
ntlm_client_set_errmsg(ntlm,
|
||||
"invalid unicode string; trailing data remains");
|
||||
goto done;
|
||||
default:
|
||||
ntlm_client_set_errmsg(ctx->ntlm,
|
||||
ntlm_client_set_errmsg(ntlm,
|
||||
"unknown unicode conversion failure");
|
||||
goto done;
|
||||
}
|
||||
@@ -377,13 +368,12 @@ static inline bool unicode_builtin_encoding_convert(
|
||||
out_size = ((((out_size << 1) - (out_size >> 1)) + 7) & ~7);
|
||||
|
||||
if (out_size > NTLM_UNICODE_MAX_LEN) {
|
||||
ntlm_client_set_errmsg(ctx->ntlm,
|
||||
"unicode conversion too large");
|
||||
ntlm_client_set_errmsg(ntlm, "unicode conversion too large");
|
||||
goto done;
|
||||
}
|
||||
|
||||
if ((new_out = realloc(out, out_size)) == NULL) {
|
||||
ntlm_client_set_errmsg(ctx->ntlm, "out of memory");
|
||||
ntlm_client_set_errmsg(ntlm, "out of memory");
|
||||
goto done;
|
||||
}
|
||||
|
||||
@@ -419,27 +409,26 @@ done:
|
||||
bool ntlm_unicode_utf8_to_16(
|
||||
char **converted,
|
||||
size_t *converted_len,
|
||||
ntlm_unicode_ctx *ctx,
|
||||
ntlm_client *client,
|
||||
const char *string,
|
||||
size_t string_len)
|
||||
{
|
||||
return unicode_builtin_encoding_convert(converted, converted_len,
|
||||
ctx, string, string_len, unicode_builtin_utf8_to_16);
|
||||
client, string, string_len, unicode_builtin_utf8_to_16);
|
||||
}
|
||||
|
||||
bool ntlm_unicode_utf16_to_8(
|
||||
char **converted,
|
||||
size_t *converted_len,
|
||||
ntlm_unicode_ctx *ctx,
|
||||
ntlm_client *client,
|
||||
const char *string,
|
||||
size_t string_len)
|
||||
{
|
||||
return unicode_builtin_encoding_convert(converted, converted_len,
|
||||
ctx, string, string_len, unicode_builtin_utf16_to_8);
|
||||
client, string, string_len, unicode_builtin_utf16_to_8);
|
||||
}
|
||||
|
||||
void ntlm_unicode_ctx_free(ntlm_unicode_ctx *ctx)
|
||||
void ntlm_unicode_shutdown(ntlm_client *ntlm)
|
||||
{
|
||||
if (ctx)
|
||||
free(ctx);
|
||||
NTLM_UNUSED(ntlm);
|
||||
}
|
||||
|
||||
20
deps/ntlmclient/unicode_builtin.h
vendored
Normal file
20
deps/ntlmclient/unicode_builtin.h
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
* Copyright (c) Edward Thomson. All rights reserved.
|
||||
*
|
||||
* This file is part of ntlmclient, distributed under the MIT license.
|
||||
* For full terms and copyright information, and for third-party
|
||||
* copyright information, see the included LICENSE.txt file.
|
||||
*/
|
||||
|
||||
#ifndef PRIVATE_UNICODE_BUILTIN_H__
|
||||
#define PRIVATE_UNICODE_BUILTIN_H__
|
||||
|
||||
#include <locale.h>
|
||||
#include <iconv.h>
|
||||
|
||||
#include "ntlmclient.h"
|
||||
|
||||
struct ntlm_unicode_ctx {
|
||||
};
|
||||
|
||||
#endif /* PRIVATE_UNICODE_BUILTIN_H__ */
|
||||
80
deps/ntlmclient/unicode_iconv.c
vendored
80
deps/ntlmclient/unicode_iconv.c
vendored
@@ -16,43 +16,23 @@
|
||||
#include "ntlm.h"
|
||||
#include "compat.h"
|
||||
|
||||
struct ntlm_unicode_ctx {
|
||||
ntlm_client *ntlm;
|
||||
iconv_t utf8_to_16;
|
||||
iconv_t utf16_to_8;
|
||||
};
|
||||
|
||||
ntlm_unicode_ctx *ntlm_unicode_ctx_init(ntlm_client *ntlm)
|
||||
{
|
||||
ntlm_unicode_ctx *ctx;
|
||||
|
||||
if ((ctx = calloc(1, sizeof(ntlm_unicode_ctx))) == NULL)
|
||||
return NULL;
|
||||
|
||||
ctx->ntlm = ntlm;
|
||||
ctx->utf8_to_16 = (iconv_t)-1;
|
||||
ctx->utf16_to_8 = (iconv_t)-1;
|
||||
|
||||
return ctx;
|
||||
}
|
||||
|
||||
typedef enum {
|
||||
unicode_iconv_utf8_to_16,
|
||||
unicode_iconv_utf16_to_8
|
||||
} unicode_iconv_encoding_direction;
|
||||
|
||||
static inline bool unicode_iconv_init(ntlm_unicode_ctx *ctx)
|
||||
bool ntlm_unicode_init(ntlm_client *ntlm)
|
||||
{
|
||||
if (ctx->utf8_to_16 != (iconv_t)-1 || ctx->utf16_to_8 != (iconv_t)-1)
|
||||
return true;
|
||||
ntlm->unicode_ctx.utf8_to_16 = iconv_open("UTF-16LE", "UTF-8");
|
||||
ntlm->unicode_ctx.utf16_to_8 = iconv_open("UTF-8", "UTF-16LE");
|
||||
|
||||
if ((ctx->utf8_to_16 = iconv_open("UTF-16LE", "UTF-8")) == (iconv_t)-1 ||
|
||||
(ctx->utf16_to_8 = iconv_open("UTF-8", "UTF-16LE")) == (iconv_t)-1) {
|
||||
if (ntlm->unicode_ctx.utf8_to_16 == (iconv_t)-1 ||
|
||||
ntlm->unicode_ctx.utf16_to_8 == (iconv_t)-1) {
|
||||
if (errno == EINVAL)
|
||||
ntlm_client_set_errmsg(ctx->ntlm,
|
||||
ntlm_client_set_errmsg(ntlm,
|
||||
"iconv does not support UTF8 <-> UTF16 conversion");
|
||||
else
|
||||
ntlm_client_set_errmsg(ctx->ntlm, strerror(errno));
|
||||
ntlm_client_set_errmsg(ntlm, strerror(errno));
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -63,7 +43,7 @@ static inline bool unicode_iconv_init(ntlm_unicode_ctx *ctx)
|
||||
static inline bool unicode_iconv_encoding_convert(
|
||||
char **converted,
|
||||
size_t *converted_len,
|
||||
ntlm_unicode_ctx *ctx,
|
||||
ntlm_client *ntlm,
|
||||
const char *string,
|
||||
size_t string_len,
|
||||
unicode_iconv_encoding_direction direction)
|
||||
@@ -75,9 +55,6 @@ static inline bool unicode_iconv_encoding_convert(
|
||||
*converted = NULL;
|
||||
*converted_len = 0;
|
||||
|
||||
if (!unicode_iconv_init(ctx))
|
||||
return false;
|
||||
|
||||
/*
|
||||
* When translating UTF8 to UTF16, these strings are only used
|
||||
* internally, and we obey the given length, so we can simply
|
||||
@@ -86,11 +63,11 @@ static inline bool unicode_iconv_encoding_convert(
|
||||
* terminate and expect an extra byte for UTF8, two for UTF16.
|
||||
*/
|
||||
if (direction == unicode_iconv_utf8_to_16) {
|
||||
converter = ctx->utf8_to_16;
|
||||
converter = ntlm->unicode_ctx.utf8_to_16;
|
||||
out_size = (string_len * 2) + 2;
|
||||
nul_size = 2;
|
||||
} else {
|
||||
converter = ctx->utf16_to_8;
|
||||
converter = ntlm->unicode_ctx.utf16_to_8;
|
||||
out_size = (string_len / 2) + 1;
|
||||
nul_size = 1;
|
||||
}
|
||||
@@ -99,7 +76,7 @@ static inline bool unicode_iconv_encoding_convert(
|
||||
out_size = (out_size + 7) & ~7;
|
||||
|
||||
if ((out = malloc(out_size)) == NULL) {
|
||||
ntlm_client_set_errmsg(ctx->ntlm, "out of memory");
|
||||
ntlm_client_set_errmsg(ntlm, "out of memory");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -117,7 +94,7 @@ static inline bool unicode_iconv_encoding_convert(
|
||||
break;
|
||||
|
||||
if (ret == (size_t)-1 && errno != E2BIG) {
|
||||
ntlm_client_set_errmsg(ctx->ntlm, strerror(errno));
|
||||
ntlm_client_set_errmsg(ntlm, strerror(errno));
|
||||
goto on_error;
|
||||
}
|
||||
|
||||
@@ -125,13 +102,12 @@ static inline bool unicode_iconv_encoding_convert(
|
||||
out_size = ((((out_size << 1) - (out_size >> 1)) + 7) & ~7);
|
||||
|
||||
if (out_size > NTLM_UNICODE_MAX_LEN) {
|
||||
ntlm_client_set_errmsg(ctx->ntlm,
|
||||
"unicode conversion too large");
|
||||
ntlm_client_set_errmsg(ntlm, "unicode conversion too large");
|
||||
goto on_error;
|
||||
}
|
||||
|
||||
if ((new_out = realloc(out, out_size)) == NULL) {
|
||||
ntlm_client_set_errmsg(ctx->ntlm, "out of memory");
|
||||
ntlm_client_set_errmsg(ntlm, "out of memory");
|
||||
goto on_error;
|
||||
}
|
||||
|
||||
@@ -139,7 +115,7 @@ static inline bool unicode_iconv_encoding_convert(
|
||||
}
|
||||
|
||||
if (in_start_len != 0) {
|
||||
ntlm_client_set_errmsg(ctx->ntlm,
|
||||
ntlm_client_set_errmsg(ntlm,
|
||||
"invalid unicode string; trailing data remains");
|
||||
goto on_error;
|
||||
}
|
||||
@@ -165,37 +141,37 @@ on_error:
|
||||
bool ntlm_unicode_utf8_to_16(
|
||||
char **converted,
|
||||
size_t *converted_len,
|
||||
ntlm_unicode_ctx *ctx,
|
||||
ntlm_client *ntlm,
|
||||
const char *string,
|
||||
size_t string_len)
|
||||
{
|
||||
return unicode_iconv_encoding_convert(
|
||||
converted, converted_len, ctx, string, string_len,
|
||||
converted, converted_len, ntlm, string, string_len,
|
||||
unicode_iconv_utf8_to_16);
|
||||
}
|
||||
|
||||
bool ntlm_unicode_utf16_to_8(
|
||||
char **converted,
|
||||
size_t *converted_len,
|
||||
ntlm_unicode_ctx *ctx,
|
||||
ntlm_client *ntlm,
|
||||
const char *string,
|
||||
size_t string_len)
|
||||
{
|
||||
return unicode_iconv_encoding_convert(
|
||||
converted, converted_len, ctx, string, string_len,
|
||||
converted, converted_len, ntlm, string, string_len,
|
||||
unicode_iconv_utf16_to_8);
|
||||
}
|
||||
|
||||
void ntlm_unicode_ctx_free(ntlm_unicode_ctx *ctx)
|
||||
void ntlm_unicode_shutdown(ntlm_client *ntlm)
|
||||
{
|
||||
if (!ctx)
|
||||
return;
|
||||
if (ntlm->unicode_ctx.utf16_to_8 != (iconv_t)0 &&
|
||||
ntlm->unicode_ctx.utf16_to_8 != (iconv_t)-1)
|
||||
iconv_close(ntlm->unicode_ctx.utf16_to_8);
|
||||
|
||||
if (ctx->utf16_to_8 != (iconv_t)-1)
|
||||
iconv_close(ctx->utf16_to_8);
|
||||
if (ntlm->unicode_ctx.utf8_to_16 != (iconv_t)0 &&
|
||||
ntlm->unicode_ctx.utf8_to_16 != (iconv_t)-1)
|
||||
iconv_close(ntlm->unicode_ctx.utf8_to_16);
|
||||
|
||||
if (ctx->utf8_to_16 != (iconv_t)-1)
|
||||
iconv_close(ctx->utf8_to_16);
|
||||
|
||||
free(ctx);
|
||||
ntlm->unicode_ctx.utf8_to_16 = (iconv_t)-1;
|
||||
ntlm->unicode_ctx.utf16_to_8 = (iconv_t)-1;
|
||||
}
|
||||
|
||||
22
deps/ntlmclient/unicode_iconv.h
vendored
Normal file
22
deps/ntlmclient/unicode_iconv.h
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
* Copyright (c) Edward Thomson. All rights reserved.
|
||||
*
|
||||
* This file is part of ntlmclient, distributed under the MIT license.
|
||||
* For full terms and copyright information, and for third-party
|
||||
* copyright information, see the included LICENSE.txt file.
|
||||
*/
|
||||
|
||||
#ifndef PRIVATE_UNICODE_ICONV_H__
|
||||
#define PRIVATE_UNICODE_ICONV_H__
|
||||
|
||||
#include <locale.h>
|
||||
#include <iconv.h>
|
||||
|
||||
#include "ntlmclient.h"
|
||||
|
||||
struct ntlm_unicode_ctx {
|
||||
iconv_t utf8_to_16;
|
||||
iconv_t utf16_to_8;
|
||||
};
|
||||
|
||||
#endif /* PRIVATE_UNICODE_ICONV_H__ */
|
||||
@@ -41,6 +41,38 @@
|
||||
...
|
||||
}
|
||||
|
||||
{
|
||||
ignore-openssl-init-leak
|
||||
Memcheck:Leak
|
||||
...
|
||||
fun:git_openssl_stream_global_init
|
||||
...
|
||||
}
|
||||
|
||||
{
|
||||
ignore-openssl-legacy-init-leak
|
||||
Memcheck:Leak
|
||||
...
|
||||
fun:OPENSSL_init_ssl__legacy
|
||||
...
|
||||
}
|
||||
|
||||
{
|
||||
ignore-openssl-malloc-leak
|
||||
Memcheck:Leak
|
||||
...
|
||||
fun:git_openssl_malloc
|
||||
...
|
||||
}
|
||||
|
||||
{
|
||||
ignore-openssl-realloc-leak
|
||||
Memcheck:Leak
|
||||
...
|
||||
fun:git_openssl_realloc
|
||||
...
|
||||
}
|
||||
|
||||
{
|
||||
ignore-glibc-getaddrinfo-cache
|
||||
Memcheck:Leak
|
||||
@@ -64,6 +96,22 @@
|
||||
...
|
||||
}
|
||||
|
||||
{
|
||||
ignore-libssh2-session-create
|
||||
Memcheck:Leak
|
||||
...
|
||||
fun:_git_ssh_session_create
|
||||
...
|
||||
}
|
||||
|
||||
{
|
||||
ignore-libssh2-setup-conn
|
||||
Memcheck:Leak
|
||||
...
|
||||
fun:_git_ssh_setup_conn
|
||||
...
|
||||
}
|
||||
|
||||
{
|
||||
ignore-libssh2-gcrypt-control-leak
|
||||
Memcheck:Leak
|
||||
@@ -178,3 +226,19 @@
|
||||
obj:*libcrypto.so*
|
||||
...
|
||||
}
|
||||
|
||||
{
|
||||
ignore-dlopen-leak
|
||||
Memcheck:Leak
|
||||
...
|
||||
fun:dlopen
|
||||
...
|
||||
}
|
||||
|
||||
{
|
||||
ignore-dlopen-leak
|
||||
Memcheck:Leak
|
||||
...
|
||||
fun:_dlerror_run
|
||||
...
|
||||
}
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
#cmakedefine GIT_WINHTTP 1
|
||||
#cmakedefine GIT_HTTPS 1
|
||||
#cmakedefine GIT_OPENSSL 1
|
||||
#cmakedefine GIT_OPENSSL_DYNAMIC 1
|
||||
#cmakedefine GIT_SECURE_TRANSPORT 1
|
||||
#cmakedefine GIT_MBEDTLS 1
|
||||
|
||||
|
||||
@@ -36,14 +36,6 @@
|
||||
# include "win32/w32_leakcheck.h"
|
||||
#endif
|
||||
|
||||
#ifdef GIT_OPENSSL
|
||||
# include <openssl/err.h>
|
||||
#endif
|
||||
|
||||
#ifdef GIT_MBEDTLS
|
||||
# include <mbedtls/error.h>
|
||||
#endif
|
||||
|
||||
/* Declarations for tuneable settings */
|
||||
extern size_t git_mwindow__window_size;
|
||||
extern size_t git_mwindow__mapped_limit;
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
#include "net.h"
|
||||
|
||||
#ifdef GIT_OPENSSL
|
||||
# include <openssl/ssl.h>
|
||||
# include "streams/openssl.h"
|
||||
#endif
|
||||
|
||||
typedef struct gitno_ssl {
|
||||
|
||||
@@ -6,11 +6,14 @@
|
||||
*/
|
||||
|
||||
#include "streams/openssl.h"
|
||||
#include "streams/openssl_legacy.h"
|
||||
#include "streams/openssl_dynamic.h"
|
||||
|
||||
#ifdef GIT_OPENSSL
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
#include "common.h"
|
||||
#include "runtime.h"
|
||||
#include "settings.h"
|
||||
#include "posix.h"
|
||||
@@ -26,156 +29,17 @@
|
||||
# include <netinet/in.h>
|
||||
#endif
|
||||
|
||||
#include <openssl/ssl.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/x509v3.h>
|
||||
#include <openssl/bio.h>
|
||||
#ifndef GIT_OPENSSL_DYNAMIC
|
||||
# include <openssl/ssl.h>
|
||||
# include <openssl/err.h>
|
||||
# include <openssl/x509v3.h>
|
||||
# include <openssl/bio.h>
|
||||
#endif
|
||||
|
||||
SSL_CTX *git__ssl_ctx;
|
||||
|
||||
#define GIT_SSL_DEFAULT_CIPHERS "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-DSS-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA:DHE-DSS-AES128-SHA256:DHE-DSS-AES256-SHA256:DHE-DSS-AES128-SHA:DHE-DSS-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA"
|
||||
|
||||
#if (defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER < 0x10100000L) || \
|
||||
(defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x20700000L)
|
||||
# define OPENSSL_LEGACY_API
|
||||
#endif
|
||||
|
||||
/*
|
||||
* OpenSSL 1.1 made BIO opaque so we have to use functions to interact with it
|
||||
* which do not exist in previous versions. We define these inline functions so
|
||||
* we can program against the interface instead of littering the implementation
|
||||
* with ifdefs. We do the same for OPENSSL_init_ssl.
|
||||
*/
|
||||
#if defined(OPENSSL_LEGACY_API)
|
||||
static int OPENSSL_init_ssl(int opts, void *settings)
|
||||
{
|
||||
GIT_UNUSED(opts);
|
||||
GIT_UNUSED(settings);
|
||||
SSL_load_error_strings();
|
||||
OpenSSL_add_ssl_algorithms();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static BIO_METHOD* BIO_meth_new(int type, const char *name)
|
||||
{
|
||||
BIO_METHOD *meth = git__calloc(1, sizeof(BIO_METHOD));
|
||||
if (!meth) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
meth->type = type;
|
||||
meth->name = name;
|
||||
|
||||
return meth;
|
||||
}
|
||||
|
||||
static void BIO_meth_free(BIO_METHOD *biom)
|
||||
{
|
||||
git__free(biom);
|
||||
}
|
||||
|
||||
static int BIO_meth_set_write(BIO_METHOD *biom, int (*write) (BIO *, const char *, int))
|
||||
{
|
||||
biom->bwrite = write;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int BIO_meth_set_read(BIO_METHOD *biom, int (*read) (BIO *, char *, int))
|
||||
{
|
||||
biom->bread = read;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int BIO_meth_set_puts(BIO_METHOD *biom, int (*puts) (BIO *, const char *))
|
||||
{
|
||||
biom->bputs = puts;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int BIO_meth_set_gets(BIO_METHOD *biom, int (*gets) (BIO *, char *, int))
|
||||
|
||||
{
|
||||
biom->bgets = gets;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int BIO_meth_set_ctrl(BIO_METHOD *biom, long (*ctrl) (BIO *, int, long, void *))
|
||||
{
|
||||
biom->ctrl = ctrl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int BIO_meth_set_create(BIO_METHOD *biom, int (*create) (BIO *))
|
||||
{
|
||||
biom->create = create;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int BIO_meth_set_destroy(BIO_METHOD *biom, int (*destroy) (BIO *))
|
||||
{
|
||||
biom->destroy = destroy;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int BIO_get_new_index(void)
|
||||
{
|
||||
/* This exists as of 1.1 so before we'd just have 0 */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void BIO_set_init(BIO *b, int init)
|
||||
{
|
||||
b->init = init;
|
||||
}
|
||||
|
||||
static void BIO_set_data(BIO *a, void *ptr)
|
||||
{
|
||||
a->ptr = ptr;
|
||||
}
|
||||
|
||||
static void *BIO_get_data(BIO *a)
|
||||
{
|
||||
return a->ptr;
|
||||
}
|
||||
|
||||
static const unsigned char *ASN1_STRING_get0_data(const ASN1_STRING *x)
|
||||
{
|
||||
return ASN1_STRING_data((ASN1_STRING *)x);
|
||||
}
|
||||
|
||||
# if defined(GIT_THREADS)
|
||||
static git_mutex *openssl_locks;
|
||||
|
||||
static void openssl_locking_function(
|
||||
int mode, int n, const char *file, int line)
|
||||
{
|
||||
int lock;
|
||||
|
||||
GIT_UNUSED(file);
|
||||
GIT_UNUSED(line);
|
||||
|
||||
lock = mode & CRYPTO_LOCK;
|
||||
|
||||
if (lock) {
|
||||
(void)git_mutex_lock(&openssl_locks[n]);
|
||||
} else {
|
||||
git_mutex_unlock(&openssl_locks[n]);
|
||||
}
|
||||
}
|
||||
|
||||
static void shutdown_ssl_locking(void)
|
||||
{
|
||||
int num_locks, i;
|
||||
|
||||
num_locks = CRYPTO_num_locks();
|
||||
CRYPTO_set_locking_callback(NULL);
|
||||
|
||||
for (i = 0; i < num_locks; ++i)
|
||||
git_mutex_free(&openssl_locks[i]);
|
||||
git__free(openssl_locks);
|
||||
}
|
||||
# endif /* GIT_THREADS */
|
||||
#endif /* OPENSSL_LEGACY_API */
|
||||
|
||||
static BIO_METHOD *git_stream_bio_method;
|
||||
static int init_bio_method(void);
|
||||
@@ -198,7 +62,29 @@ static void shutdown_ssl(void)
|
||||
}
|
||||
|
||||
#ifdef VALGRIND
|
||||
#ifdef OPENSSL_LEGACY_API
|
||||
# if !defined(GIT_OPENSSL_LEGACY) && !defined(GIT_OPENSSL_DYNAMIC)
|
||||
|
||||
static void *git_openssl_malloc(size_t bytes, const char *file, int line)
|
||||
{
|
||||
GIT_UNUSED(file);
|
||||
GIT_UNUSED(line);
|
||||
return git__calloc(1, bytes);
|
||||
}
|
||||
|
||||
static void *git_openssl_realloc(void *mem, size_t size, const char *file, int line)
|
||||
{
|
||||
GIT_UNUSED(file);
|
||||
GIT_UNUSED(line);
|
||||
return git__realloc(mem, size);
|
||||
}
|
||||
|
||||
static void git_openssl_free(void *mem, const char *file, int line)
|
||||
{
|
||||
GIT_UNUSED(file);
|
||||
GIT_UNUSED(line);
|
||||
git__free(mem);
|
||||
}
|
||||
# else /* !GIT_OPENSSL_LEGACY && !GIT_OPENSSL_DYNAMIC */
|
||||
static void *git_openssl_malloc(size_t bytes)
|
||||
{
|
||||
return git__calloc(1, bytes);
|
||||
@@ -211,33 +97,12 @@ static void *git_openssl_realloc(void *mem, size_t size)
|
||||
|
||||
static void git_openssl_free(void *mem)
|
||||
{
|
||||
return git__free(mem);
|
||||
}
|
||||
#else
|
||||
static void *git_openssl_malloc(size_t bytes, const char *file, int line)
|
||||
{
|
||||
GIT_UNUSED(file);
|
||||
GIT_UNUSED(line);
|
||||
return git__calloc(1, bytes);
|
||||
git__free(mem);
|
||||
}
|
||||
# endif /* !GIT_OPENSSL_LEGACY && !GIT_OPENSSL_DYNAMIC */
|
||||
#endif /* VALGRIND */
|
||||
|
||||
static void *git_openssl_realloc(void *mem, size_t size, const char *file, int line)
|
||||
{
|
||||
GIT_UNUSED(file);
|
||||
GIT_UNUSED(line);
|
||||
return git__realloc(mem, size);
|
||||
}
|
||||
|
||||
static void git_openssl_free(void *mem, const char *file, int line)
|
||||
{
|
||||
GIT_UNUSED(file);
|
||||
GIT_UNUSED(line);
|
||||
return git__free(mem);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
int git_openssl_stream_global_init(void)
|
||||
static int openssl_init(void)
|
||||
{
|
||||
long ssl_opts = SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3;
|
||||
const char *ciphers = git_libgit2__ssl_ciphers();
|
||||
@@ -301,43 +166,61 @@ error:
|
||||
return -1;
|
||||
}
|
||||
|
||||
#if defined(GIT_THREADS) && defined(OPENSSL_LEGACY_API)
|
||||
static void threadid_cb(CRYPTO_THREADID *threadid)
|
||||
/*
|
||||
* When we use dynamic loading, we defer OpenSSL initialization until
|
||||
* it's first used. `openssl_ensure_initialized` will do the work
|
||||
* under a mutex.
|
||||
*/
|
||||
git_mutex openssl_mutex;
|
||||
bool openssl_initialized;
|
||||
|
||||
int git_openssl_stream_global_init(void)
|
||||
{
|
||||
GIT_UNUSED(threadid);
|
||||
CRYPTO_THREADID_set_numeric(threadid, git_thread_currentid());
|
||||
}
|
||||
#ifndef GIT_OPENSSL_DYNAMIC
|
||||
return openssl_init();
|
||||
#else
|
||||
if (git_mutex_init(&openssl_mutex) != 0)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
int git_openssl_set_locking(void)
|
||||
static int openssl_ensure_initialized(void)
|
||||
{
|
||||
#if defined(GIT_THREADS) && defined(OPENSSL_LEGACY_API)
|
||||
int num_locks, i;
|
||||
#ifdef GIT_OPENSSL_DYNAMIC
|
||||
int error = 0;
|
||||
|
||||
CRYPTO_THREADID_set_callback(threadid_cb);
|
||||
if (git_mutex_lock(&openssl_mutex) != 0)
|
||||
return -1;
|
||||
|
||||
num_locks = CRYPTO_num_locks();
|
||||
openssl_locks = git__calloc(num_locks, sizeof(git_mutex));
|
||||
GIT_ERROR_CHECK_ALLOC(openssl_locks);
|
||||
if (!openssl_initialized) {
|
||||
if ((error = git_openssl_stream_dynamic_init()) == 0)
|
||||
error = openssl_init();
|
||||
|
||||
for (i = 0; i < num_locks; i++) {
|
||||
if (git_mutex_init(&openssl_locks[i]) != 0) {
|
||||
git_error_set(GIT_ERROR_SSL, "failed to initialize openssl locks");
|
||||
return -1;
|
||||
}
|
||||
openssl_initialized = true;
|
||||
}
|
||||
|
||||
CRYPTO_set_locking_callback(openssl_locking_function);
|
||||
return git_runtime_shutdown_register(shutdown_ssl_locking);
|
||||
error |= git_mutex_unlock(&openssl_mutex);
|
||||
return error;
|
||||
|
||||
#elif !defined(OPENSSL_LEGACY_API)
|
||||
return 0;
|
||||
#else
|
||||
git_error_set(GIT_ERROR_THREAD, "libgit2 was not built with threads");
|
||||
return -1;
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if !defined(GIT_OPENSSL_LEGACY) && !defined(GIT_OPENSSL_DYNAMIC)
|
||||
int git_openssl_set_locking(void)
|
||||
{
|
||||
# ifdef GIT_THREADS
|
||||
return 0;
|
||||
# else
|
||||
git_error_set(GIT_ERROR_THREAD, "libgit2 was not built with threads");
|
||||
return -1;
|
||||
# endif
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static int bio_create(BIO *b)
|
||||
{
|
||||
@@ -799,6 +682,9 @@ static int openssl_stream_wrap(
|
||||
|
||||
int git_openssl_stream_wrap(git_stream **out, git_stream *in, const char *host)
|
||||
{
|
||||
if (openssl_ensure_initialized() < 0)
|
||||
return -1;
|
||||
|
||||
return openssl_stream_wrap(out, in, host, 0);
|
||||
}
|
||||
|
||||
@@ -811,6 +697,9 @@ int git_openssl_stream_new(git_stream **out, const char *host, const char *port)
|
||||
GIT_ASSERT_ARG(host);
|
||||
GIT_ASSERT_ARG(port);
|
||||
|
||||
if (openssl_ensure_initialized() < 0)
|
||||
return -1;
|
||||
|
||||
if ((error = git_socket_stream_new(&stream, host, port)) < 0)
|
||||
return error;
|
||||
|
||||
@@ -824,6 +713,9 @@ int git_openssl_stream_new(git_stream **out, const char *host, const char *port)
|
||||
|
||||
int git_openssl__set_cert_location(const char *file, const char *path)
|
||||
{
|
||||
if (openssl_ensure_initialized() < 0)
|
||||
return -1;
|
||||
|
||||
if (SSL_CTX_load_verify_locations(git__ssl_ctx, file, path) == 0) {
|
||||
char errmsg[256];
|
||||
|
||||
|
||||
@@ -8,14 +8,22 @@
|
||||
#define INCLUDE_streams_openssl_h__
|
||||
|
||||
#include "common.h"
|
||||
#include "streams/openssl_legacy.h"
|
||||
#include "streams/openssl_dynamic.h"
|
||||
|
||||
#include "git2/sys/stream.h"
|
||||
|
||||
extern int git_openssl_stream_global_init(void);
|
||||
|
||||
#if defined(GIT_OPENSSL) && !defined(GIT_OPENSSL_DYNAMIC)
|
||||
# include <openssl/ssl.h>
|
||||
# include <openssl/err.h>
|
||||
# include <openssl/x509v3.h>
|
||||
# include <openssl/bio.h>
|
||||
# endif
|
||||
|
||||
#ifdef GIT_OPENSSL
|
||||
extern int git_openssl__set_cert_location(const char *file, const char *path);
|
||||
|
||||
extern int git_openssl_stream_new(git_stream **out, const char *host, const char *port);
|
||||
extern int git_openssl_stream_wrap(git_stream **out, git_stream *in, const char *host);
|
||||
#endif
|
||||
|
||||
309
src/streams/openssl_dynamic.c
Normal file
309
src/streams/openssl_dynamic.c
Normal file
@@ -0,0 +1,309 @@
|
||||
/*
|
||||
* Copyright (C) the libgit2 contributors. All rights reserved.
|
||||
*
|
||||
* This file is part of libgit2, distributed under the GNU GPL v2 with
|
||||
* a Linking Exception. For full terms see the included COPYING file.
|
||||
*/
|
||||
|
||||
#include "streams/openssl.h"
|
||||
#include "streams/openssl_dynamic.h"
|
||||
|
||||
#if defined(GIT_OPENSSL) && defined(GIT_OPENSSL_DYNAMIC)
|
||||
|
||||
#include "runtime.h"
|
||||
|
||||
#include <dlfcn.h>
|
||||
|
||||
unsigned char *(*ASN1_STRING_data)(ASN1_STRING *x);
|
||||
const unsigned char *(*ASN1_STRING_get0_data)(const ASN1_STRING *x);
|
||||
int (*ASN1_STRING_length)(const ASN1_STRING *x);
|
||||
int (*ASN1_STRING_to_UTF8)(unsigned char **out, const ASN1_STRING *in);
|
||||
int (*ASN1_STRING_type)(const ASN1_STRING *x);
|
||||
|
||||
void *(*BIO_get_data)(BIO *a);
|
||||
int (*BIO_get_new_index)(void);
|
||||
int (*OPENSSL_init_ssl)(uint64_t opts, const void *settings);
|
||||
void (*BIO_meth_free)(BIO_METHOD *biom);
|
||||
int (*BIO_meth_set_create)(BIO_METHOD *biom, int (*create) (BIO *));
|
||||
int (*BIO_meth_set_ctrl)(BIO_METHOD *biom, long (*ctrl) (BIO *, int, long, void *));
|
||||
int (*BIO_meth_set_destroy)(BIO_METHOD *biom, int (*destroy) (BIO *));
|
||||
int (*BIO_meth_set_gets)(BIO_METHOD *biom, int (*gets) (BIO *, char *, int));
|
||||
int (*BIO_meth_set_puts)(BIO_METHOD *biom, int (*puts) (BIO *, const char *));
|
||||
int (*BIO_meth_set_read)(BIO_METHOD *biom, int (*read) (BIO *, char *, int));
|
||||
int (*BIO_meth_set_write)(BIO_METHOD *biom, int (*write) (BIO *, const char *, int));
|
||||
BIO_METHOD *(*BIO_meth_new)(int type, const char *name);
|
||||
BIO *(*BIO_new)(const BIO_METHOD *type);
|
||||
void (*BIO_set_data)(BIO *a, void *ptr);
|
||||
void (*BIO_set_init)(BIO *a, int init);
|
||||
|
||||
void (*CRYPTO_free)(void *ptr, const char *file, int line);
|
||||
void *(*CRYPTO_malloc)(size_t num, const char *file, int line);
|
||||
int (*CRYPTO_num_locks)(void);
|
||||
void (*CRYPTO_set_locking_callback)(void (*func)(int mode, int type, const char *file, int line));
|
||||
int (*CRYPTO_set_mem_functions)(void *(*m)(size_t bytes), void *(*r)(void *mem, size_t size), void (*f)(void *mem));
|
||||
int (*CRYPTO_THREADID_set_callback)(void (*func)(CRYPTO_THREADID *id));
|
||||
void (*CRYPTO_THREADID_set_numeric)(CRYPTO_THREADID *id, unsigned long val);
|
||||
|
||||
char *(*ERR_error_string)(unsigned long e, char *buf);
|
||||
void (*ERR_error_string_n)(unsigned long e, char *buf, size_t len);
|
||||
unsigned long (*ERR_get_error)(void);
|
||||
|
||||
int (*SSL_connect)(SSL *ssl);
|
||||
long (*SSL_ctrl)(SSL *ssl, int cmd, long arg, void *parg);
|
||||
void (*SSL_free)(SSL *ssl);
|
||||
int (*SSL_get_error)(SSL *ssl, int ret);
|
||||
X509 *(*SSL_get_peer_certificate)(const SSL *ssl);
|
||||
long (*SSL_get_verify_result)(const SSL *ssl);
|
||||
int (*SSL_library_init)(void);
|
||||
void (*SSL_load_error_strings)(void);
|
||||
SSL *(*SSL_new)(SSL_CTX *ctx);
|
||||
int (*SSL_read)(SSL *ssl, const void *buf, int num);
|
||||
void (*SSL_set_bio)(SSL *ssl, BIO *rbio, BIO *wbio);
|
||||
int (*SSL_shutdown)(SSL *ssl);
|
||||
int (*SSL_write)(SSL *ssl, const void *buf, int num);
|
||||
|
||||
long (*SSL_CTX_ctrl)(SSL_CTX *ctx, int cmd, long larg, void *parg);
|
||||
void (*SSL_CTX_free)(SSL_CTX *ctx);
|
||||
SSL_CTX *(*SSL_CTX_new)(const SSL_METHOD *method);
|
||||
int (*SSL_CTX_set_cipher_list)(SSL_CTX *ctx, const char *str);
|
||||
int (*SSL_CTX_set_default_verify_paths)(SSL_CTX *ctx);
|
||||
long (*SSL_CTX_set_options)(SSL_CTX *ctx, long options);
|
||||
void (*SSL_CTX_set_verify)(SSL_CTX *ctx, int mode, int (*verify_callback)(int, X509_STORE_CTX *));
|
||||
int (*SSL_CTX_load_verify_locations)(SSL_CTX *ctx, const char *CAfile, const char *CApath);
|
||||
|
||||
const SSL_METHOD *(*SSLv23_method)(void);
|
||||
const SSL_METHOD *(*TLS_method)(void);
|
||||
|
||||
ASN1_STRING *(*X509_NAME_ENTRY_get_data)(const X509_NAME_ENTRY *ne);
|
||||
X509_NAME_ENTRY *(*X509_NAME_get_entry)(X509_NAME *name, int loc);
|
||||
int (*X509_NAME_get_index_by_NID)(X509_NAME *name, int nid, int lastpos);
|
||||
void (*X509_free)(X509 *a);
|
||||
void *(*X509_get_ext_d2i)(const X509 *x, int nid, int *crit, int *idx);
|
||||
X509_NAME *(*X509_get_subject_name)(const X509 *x);
|
||||
|
||||
int (*i2d_X509)(X509 *a, unsigned char **ppout);
|
||||
|
||||
int (*OPENSSL_sk_num)(const void *sk);
|
||||
void *(*OPENSSL_sk_value)(const void *sk, int i);
|
||||
void (*OPENSSL_sk_free)(void *sk);
|
||||
|
||||
int (*sk_num)(const void *sk);
|
||||
void *(*sk_value)(const void *sk, int i);
|
||||
void (*sk_free)(void *sk);
|
||||
|
||||
void *openssl_handle;
|
||||
|
||||
GIT_INLINE(void *) openssl_sym(int *err, const char *name, bool required)
|
||||
{
|
||||
void *symbol;
|
||||
|
||||
/* if we've seen an err, noop to retain it */
|
||||
if (*err)
|
||||
return NULL;
|
||||
|
||||
|
||||
if ((symbol = dlsym(openssl_handle, name)) == NULL && required) {
|
||||
const char *msg = dlerror();
|
||||
git_error_set(GIT_ERROR_SSL, "could not load ssl function '%s': %s", name, msg ? msg : "unknown error");
|
||||
*err = -1;
|
||||
}
|
||||
|
||||
return symbol;
|
||||
}
|
||||
|
||||
static void dynamic_shutdown(void)
|
||||
{
|
||||
dlclose(openssl_handle);
|
||||
openssl_handle = NULL;
|
||||
}
|
||||
|
||||
int git_openssl_stream_dynamic_init(void)
|
||||
{
|
||||
int err = 0;
|
||||
|
||||
if ((openssl_handle = dlopen("libssl.so.1.1", RTLD_NOW)) == NULL &&
|
||||
(openssl_handle = dlopen("libssl.1.1.dylib", RTLD_NOW)) == NULL &&
|
||||
(openssl_handle = dlopen("libssl.so.1.0.0", RTLD_NOW)) == NULL &&
|
||||
(openssl_handle = dlopen("libssl.1.0.0.dylib", RTLD_NOW)) == NULL &&
|
||||
(openssl_handle = dlopen("libssl.so.10", RTLD_NOW)) == NULL) {
|
||||
git_error_set(GIT_ERROR_SSL, "could not load ssl libraries");
|
||||
return -1;
|
||||
}
|
||||
|
||||
ASN1_STRING_data = (unsigned char *(*)(ASN1_STRING *x))openssl_sym(&err, "ASN1_STRING_data", false);
|
||||
ASN1_STRING_get0_data = (const unsigned char *(*)(const ASN1_STRING *x))openssl_sym(&err, "ASN1_STRING_get0_data", false);
|
||||
ASN1_STRING_length = (int (*)(const ASN1_STRING *))openssl_sym(&err, "ASN1_STRING_length", true);
|
||||
ASN1_STRING_to_UTF8 = (int (*)(unsigned char **, const ASN1_STRING *))openssl_sym(&err, "ASN1_STRING_to_UTF8", true);
|
||||
ASN1_STRING_type = (int (*)(const ASN1_STRING *))openssl_sym(&err, "ASN1_STRING_type", true);
|
||||
|
||||
BIO_get_data = (void *(*)(BIO *))openssl_sym(&err, "BIO_get_data", false);
|
||||
BIO_get_new_index = (int (*)(void))openssl_sym(&err, "BIO_get_new_index", false);
|
||||
BIO_meth_free = (void (*)(BIO_METHOD *))openssl_sym(&err, "BIO_meth_free", false);
|
||||
BIO_meth_new = (BIO_METHOD *(*)(int, const char *))openssl_sym(&err, "BIO_meth_new", false);
|
||||
BIO_meth_set_create = (int (*)(BIO_METHOD *, int (*)(BIO *)))openssl_sym(&err, "BIO_meth_set_create", false);
|
||||
BIO_meth_set_ctrl = (int (*)(BIO_METHOD *, long (*)(BIO *, int, long, void *)))openssl_sym(&err, "BIO_meth_set_ctrl", false);
|
||||
BIO_meth_set_destroy = (int (*)(BIO_METHOD *, int (*)(BIO *)))openssl_sym(&err, "BIO_meth_set_destroy", false);
|
||||
BIO_meth_set_gets = (int (*)(BIO_METHOD *, int (*)(BIO *, char *, int)))openssl_sym(&err, "BIO_meth_set_gets", false);
|
||||
BIO_meth_set_puts = (int (*)(BIO_METHOD *, int (*)(BIO *, const char *)))openssl_sym(&err, "BIO_meth_set_puts", false);
|
||||
BIO_meth_set_read = (int (*)(BIO_METHOD *, int (*)(BIO *, char *, int)))openssl_sym(&err, "BIO_meth_set_read", false);
|
||||
BIO_meth_set_write = (int (*)(BIO_METHOD *, int (*)(BIO *, const char *, int)))openssl_sym(&err, "BIO_meth_set_write", false);
|
||||
BIO_new = (BIO *(*)(const BIO_METHOD *))openssl_sym(&err, "BIO_new", true);
|
||||
BIO_set_data = (void (*)(BIO *a, void *))openssl_sym(&err, "BIO_set_data", false);
|
||||
BIO_set_init = (void (*)(BIO *a, int))openssl_sym(&err, "BIO_set_init", false);
|
||||
|
||||
CRYPTO_free = (void (*)(void *, const char *, int))openssl_sym(&err, "CRYPTO_free", true);
|
||||
CRYPTO_malloc = (void *(*)(size_t, const char *, int))openssl_sym(&err, "CRYPTO_malloc", true);
|
||||
CRYPTO_num_locks = (int (*)(void))openssl_sym(&err, "CRYPTO_num_locks", false);
|
||||
CRYPTO_set_locking_callback = (void (*)(void (*)(int, int, const char *, int)))openssl_sym(&err, "CRYPTO_set_locking_callback", false);
|
||||
CRYPTO_set_mem_functions = (int (*)(void *(*)(size_t), void *(*)(void *, size_t), void (*f)(void *)))openssl_sym(&err, "CRYPTO_set_mem_functions", true);
|
||||
|
||||
CRYPTO_THREADID_set_callback = (int (*)(void (*)(CRYPTO_THREADID *)))openssl_sym(&err, "CRYPTO_THREADID_set_callback", false);
|
||||
CRYPTO_THREADID_set_numeric = (void (*)(CRYPTO_THREADID *, unsigned long))openssl_sym(&err, "CRYPTO_THREADID_set_numeric", false);
|
||||
|
||||
ERR_error_string = (char *(*)(unsigned long, char *))openssl_sym(&err, "ERR_error_string", true);
|
||||
ERR_error_string_n = (void (*)(unsigned long, char *, size_t))openssl_sym(&err, "ERR_error_string_n", true);
|
||||
ERR_get_error = (unsigned long (*)(void))openssl_sym(&err, "ERR_get_error", true);
|
||||
|
||||
OPENSSL_init_ssl = (int (*)(uint64_t opts, const void *settings))openssl_sym(&err, "OPENSSL_init_ssl", false);
|
||||
OPENSSL_sk_num = (int (*)(const void *))openssl_sym(&err, "OPENSSL_sk_num", false);
|
||||
OPENSSL_sk_value = (void *(*)(const void *sk, int i))openssl_sym(&err, "OPENSSL_sk_value", false);
|
||||
OPENSSL_sk_free = (void (*)(void *))openssl_sym(&err, "OPENSSL_sk_free", false);
|
||||
|
||||
sk_num = (int (*)(const void *))openssl_sym(&err, "sk_num", false);
|
||||
sk_value = (void *(*)(const void *sk, int i))openssl_sym(&err, "sk_value", false);
|
||||
sk_free = (void (*)(void *))openssl_sym(&err, "sk_free", false);
|
||||
|
||||
SSL_connect = (int (*)(SSL *))openssl_sym(&err, "SSL_connect", true);
|
||||
SSL_ctrl = (long (*)(SSL *, int, long, void *))openssl_sym(&err, "SSL_ctrl", true);
|
||||
SSL_get_peer_certificate = (X509 *(*)(const SSL *))openssl_sym(&err, "SSL_get_peer_certificate", true);
|
||||
SSL_library_init = (int (*)(void))openssl_sym(&err, "SSL_library_init", false);
|
||||
SSL_free = (void (*)(SSL *))openssl_sym(&err, "SSL_free", true);
|
||||
SSL_get_error = (int (*)(SSL *, int))openssl_sym(&err, "SSL_get_error", true);
|
||||
SSL_get_verify_result = (long (*)(const SSL *ssl))openssl_sym(&err, "SSL_get_verify_result", true);
|
||||
SSL_load_error_strings = (void (*)(void))openssl_sym(&err, "SSL_load_error_strings", false);
|
||||
SSL_new = (SSL *(*)(SSL_CTX *))openssl_sym(&err, "SSL_new", true);
|
||||
SSL_read = (int (*)(SSL *, const void *, int))openssl_sym(&err, "SSL_read", true);
|
||||
SSL_set_bio = (void (*)(SSL *, BIO *, BIO *))openssl_sym(&err, "SSL_set_bio", true);
|
||||
SSL_shutdown = (int (*)(SSL *ssl))openssl_sym(&err, "SSL_shutdown", true);
|
||||
SSL_write = (int (*)(SSL *, const void *, int))openssl_sym(&err, "SSL_write", true);
|
||||
|
||||
SSL_CTX_ctrl = (long (*)(SSL_CTX *, int, long, void *))openssl_sym(&err, "SSL_CTX_ctrl", true);
|
||||
SSL_CTX_free = (void (*)(SSL_CTX *))openssl_sym(&err, "SSL_CTX_free", true);
|
||||
SSL_CTX_new = (SSL_CTX *(*)(const SSL_METHOD *))openssl_sym(&err, "SSL_CTX_new", true);
|
||||
SSL_CTX_set_cipher_list = (int (*)(SSL_CTX *, const char *))openssl_sym(&err, "SSL_CTX_set_cipher_list", true);
|
||||
SSL_CTX_set_default_verify_paths = (int (*)(SSL_CTX *ctx))openssl_sym(&err, "SSL_CTX_set_default_verify_paths", true);
|
||||
SSL_CTX_set_options = (long (*)(SSL_CTX *, long))openssl_sym(&err, "SSL_CTX_set_options", false);
|
||||
SSL_CTX_set_verify = (void (*)(SSL_CTX *, int, int (*)(int, X509_STORE_CTX *)))openssl_sym(&err, "SSL_CTX_set_verify", true);
|
||||
SSL_CTX_load_verify_locations = (int (*)(SSL_CTX *, const char *, const char *))openssl_sym(&err, "SSL_CTX_load_verify_locations", true);
|
||||
|
||||
SSLv23_method = (const SSL_METHOD *(*)(void))openssl_sym(&err, "SSLv23_method", false);
|
||||
TLS_method = (const SSL_METHOD *(*)(void))openssl_sym(&err, "TLS_method", false);
|
||||
|
||||
X509_NAME_ENTRY_get_data = (ASN1_STRING *(*)(const X509_NAME_ENTRY *))openssl_sym(&err, "X509_NAME_ENTRY_get_data", true);
|
||||
X509_NAME_get_entry = (X509_NAME_ENTRY *(*)(X509_NAME *, int))openssl_sym(&err, "X509_NAME_get_entry", true);
|
||||
X509_NAME_get_index_by_NID = (int (*)(X509_NAME *, int, int))openssl_sym(&err, "X509_NAME_get_index_by_NID", true);
|
||||
X509_free = (void (*)(X509 *))openssl_sym(&err, "X509_free", true);
|
||||
X509_get_ext_d2i = (void *(*)(const X509 *x, int nid, int *crit, int *idx))openssl_sym(&err, "X509_get_ext_d2i", true);
|
||||
X509_get_subject_name = (X509_NAME *(*)(const X509 *))openssl_sym(&err, "X509_get_subject_name", true);
|
||||
|
||||
i2d_X509 = (int (*)(X509 *a, unsigned char **ppout))openssl_sym(&err, "i2d_X509", true);
|
||||
|
||||
if (err)
|
||||
goto on_error;
|
||||
|
||||
/* Add legacy functionality */
|
||||
if (!OPENSSL_init_ssl) {
|
||||
OPENSSL_init_ssl = OPENSSL_init_ssl__legacy;
|
||||
|
||||
if (!SSL_library_init ||
|
||||
!SSL_load_error_strings ||
|
||||
!CRYPTO_num_locks ||
|
||||
!CRYPTO_set_locking_callback ||
|
||||
!CRYPTO_THREADID_set_callback ||
|
||||
!CRYPTO_THREADID_set_numeric) {
|
||||
git_error_set(GIT_ERROR_SSL, "could not load legacy openssl initialization functions");
|
||||
goto on_error;
|
||||
}
|
||||
}
|
||||
|
||||
if (!SSL_CTX_set_options)
|
||||
SSL_CTX_set_options = SSL_CTX_set_options__legacy;
|
||||
|
||||
if (TLS_method)
|
||||
SSLv23_method = TLS_method;
|
||||
|
||||
if (!BIO_meth_new) {
|
||||
BIO_meth_new = BIO_meth_new__legacy;
|
||||
BIO_meth_new = BIO_meth_new__legacy;
|
||||
BIO_meth_free = BIO_meth_free__legacy;
|
||||
BIO_meth_set_write = BIO_meth_set_write__legacy;
|
||||
BIO_meth_set_read = BIO_meth_set_read__legacy;
|
||||
BIO_meth_set_puts = BIO_meth_set_puts__legacy;
|
||||
BIO_meth_set_gets = BIO_meth_set_gets__legacy;
|
||||
BIO_meth_set_ctrl = BIO_meth_set_ctrl__legacy;
|
||||
BIO_meth_set_create = BIO_meth_set_create__legacy;
|
||||
BIO_meth_set_destroy = BIO_meth_set_destroy__legacy;
|
||||
BIO_get_new_index = BIO_get_new_index__legacy;
|
||||
BIO_set_data = BIO_set_data__legacy;
|
||||
BIO_set_init = BIO_set_init__legacy;
|
||||
BIO_get_data = BIO_get_data__legacy;
|
||||
}
|
||||
|
||||
if (!ASN1_STRING_get0_data) {
|
||||
if (!ASN1_STRING_data) {
|
||||
git_error_set(GIT_ERROR_SSL, "could not load legacy openssl string function");
|
||||
goto on_error;
|
||||
}
|
||||
|
||||
ASN1_STRING_get0_data = ASN1_STRING_get0_data__legacy;
|
||||
}
|
||||
|
||||
if ((!OPENSSL_sk_num && !sk_num) ||
|
||||
(!OPENSSL_sk_value && !sk_value) ||
|
||||
(!OPENSSL_sk_free && !sk_free)) {
|
||||
git_error_set(GIT_ERROR_SSL, "could not load legacy openssl stack functions");
|
||||
goto on_error;
|
||||
}
|
||||
|
||||
if (git_runtime_shutdown_register(dynamic_shutdown) != 0)
|
||||
goto on_error;
|
||||
|
||||
return 0;
|
||||
|
||||
on_error:
|
||||
dlclose(openssl_handle);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int sk_GENERAL_NAME_num(const GENERAL_NAME *sk)
|
||||
{
|
||||
if (OPENSSL_sk_num)
|
||||
return OPENSSL_sk_num(sk);
|
||||
else if (sk_num)
|
||||
return sk_num(sk);
|
||||
|
||||
GIT_ASSERT_WITH_RETVAL(false, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
GENERAL_NAME *sk_GENERAL_NAME_value(const GENERAL_NAME *sk, int i)
|
||||
{
|
||||
if (OPENSSL_sk_value)
|
||||
return OPENSSL_sk_value(sk, i);
|
||||
else if (sk_value)
|
||||
return sk_value(sk, i);
|
||||
|
||||
GIT_ASSERT_WITH_RETVAL(false, NULL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void GENERAL_NAMES_free(GENERAL_NAME *sk)
|
||||
{
|
||||
if (OPENSSL_sk_free)
|
||||
OPENSSL_sk_free(sk);
|
||||
else if (sk_free)
|
||||
sk_free(sk);
|
||||
}
|
||||
|
||||
#endif /* GIT_OPENSSL && GIT_OPENSSL_DYNAMIC */
|
||||
348
src/streams/openssl_dynamic.h
Normal file
348
src/streams/openssl_dynamic.h
Normal file
@@ -0,0 +1,348 @@
|
||||
/*
|
||||
* Copyright (C) the libgit2 contributors. All rights reserved.
|
||||
*
|
||||
* This file is part of libgit2, distributed under the GNU GPL v2 with
|
||||
* a Linking Exception. For full terms see the included COPYING file.
|
||||
*/
|
||||
|
||||
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* "This product includes cryptographic software written by
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
* [including the GNU Public Licence.]
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1998-2007 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* openssl-core@openssl.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This product includes cryptographic software written by Eric Young
|
||||
* (eay@cryptsoft.com). This product includes software written by Tim
|
||||
* Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
|
||||
* ECC cipher suite support in OpenSSL originally developed by
|
||||
* SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright 2005 Nokia. All rights reserved.
|
||||
*
|
||||
* The portions of the attached software ("Contribution") is developed by
|
||||
* Nokia Corporation and is licensed pursuant to the OpenSSL open source
|
||||
* license.
|
||||
*
|
||||
* The Contribution, originally written by Mika Kousa and Pasi Eronen of
|
||||
* Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
|
||||
* support (see RFC 4279) to OpenSSL.
|
||||
*
|
||||
* No patent licenses or other rights except those expressly stated in
|
||||
* the OpenSSL open source license shall be deemed granted or received
|
||||
* expressly, by implication, estoppel, or otherwise.
|
||||
*
|
||||
* No assurances are provided by Nokia that the Contribution does not
|
||||
* infringe the patent or other intellectual property rights of any third
|
||||
* party or that the license provides you with all the necessary rights
|
||||
* to make use of the Contribution.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
|
||||
* ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
|
||||
* SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
|
||||
* OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
|
||||
* OTHERWISE.
|
||||
*/
|
||||
|
||||
#ifndef INCLUDE_streams_openssl_dynamic_h__
|
||||
#define INCLUDE_streams_openssl_dynamic_h__
|
||||
|
||||
#ifdef GIT_OPENSSL_DYNAMIC
|
||||
|
||||
# define BIO_CTRL_FLUSH 11
|
||||
|
||||
# define BIO_TYPE_SOURCE_SINK 0x0400
|
||||
|
||||
# define CRYPTO_LOCK 1
|
||||
|
||||
# define GEN_DNS 2
|
||||
# define GEN_IPADD 7
|
||||
|
||||
# define NID_commonName 13
|
||||
# define NID_subject_alt_name 85
|
||||
|
||||
# define SSL_VERIFY_NONE 0x00
|
||||
|
||||
# define SSL_CTRL_OPTIONS 32
|
||||
# define SSL_CTRL_MODE 33
|
||||
# define SSL_CTRL_SET_TLSEXT_HOSTNAME 55
|
||||
|
||||
# define SSL_ERROR_NONE 0
|
||||
# define SSL_ERROR_SSL 1
|
||||
# define SSL_ERROR_WANT_READ 2
|
||||
# define SSL_ERROR_WANT_WRITE 3
|
||||
# define SSL_ERROR_WANT_X509_LOOKUP 4
|
||||
# define SSL_ERROR_SYSCALL 5
|
||||
# define SSL_ERROR_ZERO_RETURN 6
|
||||
# define SSL_ERROR_WANT_CONNECT 7
|
||||
# define SSL_ERROR_WANT_ACCEPT 8
|
||||
|
||||
# define SSL_OP_NO_COMPRESSION 0x00020000L
|
||||
# define SSL_OP_NO_SSLv2 0x01000000L
|
||||
# define SSL_OP_NO_SSLv3 0x02000000L
|
||||
|
||||
# define SSL_MODE_AUTO_RETRY 0x00000004L
|
||||
|
||||
# define TLSEXT_NAMETYPE_host_name 0
|
||||
|
||||
# define V_ASN1_UTF8STRING 12
|
||||
|
||||
# define X509_V_OK 0
|
||||
|
||||
/* Most of the OpenSSL types are mercifully opaque, so we can treat them like `void *` */
|
||||
typedef struct bio_st BIO;
|
||||
typedef struct bio_method_st BIO_METHOD;
|
||||
typedef void bio_info_cb;
|
||||
typedef void * CRYPTO_EX_DATA;
|
||||
typedef void CRYPTO_THREADID;
|
||||
typedef void GENERAL_NAMES;
|
||||
typedef void SSL;
|
||||
typedef void SSL_CTX;
|
||||
typedef void SSL_METHOD;
|
||||
typedef void X509;
|
||||
typedef void X509_NAME;
|
||||
typedef void X509_NAME_ENTRY;
|
||||
typedef void X509_STORE_CTX;
|
||||
|
||||
typedef struct {
|
||||
int length;
|
||||
int type;
|
||||
unsigned char *data;
|
||||
long flags;
|
||||
} ASN1_STRING;
|
||||
|
||||
typedef struct {
|
||||
int type;
|
||||
union {
|
||||
char *ptr;
|
||||
ASN1_STRING *ia5;
|
||||
} d;
|
||||
} GENERAL_NAME;
|
||||
|
||||
struct bio_st {
|
||||
BIO_METHOD *method;
|
||||
/* bio, mode, argp, argi, argl, ret */
|
||||
long (*callback) (struct bio_st *, int, const char *, int, long, long);
|
||||
char *cb_arg; /* first argument for the callback */
|
||||
int init;
|
||||
int shutdown;
|
||||
int flags; /* extra storage */
|
||||
int retry_reason;
|
||||
int num;
|
||||
void *ptr;
|
||||
struct bio_st *next_bio; /* used by filter BIOs */
|
||||
struct bio_st *prev_bio; /* used by filter BIOs */
|
||||
int references;
|
||||
unsigned long num_read;
|
||||
unsigned long num_write;
|
||||
CRYPTO_EX_DATA ex_data;
|
||||
};
|
||||
|
||||
struct bio_method_st {
|
||||
int type;
|
||||
const char *name;
|
||||
int (*bwrite) (BIO *, const char *, int);
|
||||
int (*bread) (BIO *, char *, int);
|
||||
int (*bputs) (BIO *, const char *);
|
||||
int (*bgets) (BIO *, char *, int);
|
||||
long (*ctrl) (BIO *, int, long, void *);
|
||||
int (*create) (BIO *);
|
||||
int (*destroy) (BIO *);
|
||||
long (*callback_ctrl) (BIO *, int, bio_info_cb *);
|
||||
};
|
||||
|
||||
extern unsigned char *(*ASN1_STRING_data)(ASN1_STRING *x);
|
||||
extern const unsigned char *(*ASN1_STRING_get0_data)(const ASN1_STRING *x);
|
||||
extern int (*ASN1_STRING_length)(const ASN1_STRING *x);
|
||||
extern int (*ASN1_STRING_to_UTF8)(unsigned char **out, const ASN1_STRING *in);
|
||||
extern int (*ASN1_STRING_type)(const ASN1_STRING *x);
|
||||
|
||||
extern void *(*BIO_get_data)(BIO *a);
|
||||
extern int (*BIO_get_new_index)(void);
|
||||
extern int (*OPENSSL_init_ssl)(uint64_t opts, const void *settings);
|
||||
extern void (*BIO_meth_free)(BIO_METHOD *biom);
|
||||
extern int (*BIO_meth_set_create)(BIO_METHOD *biom, int (*create) (BIO *));
|
||||
extern int (*BIO_meth_set_ctrl)(BIO_METHOD *biom, long (*ctrl) (BIO *, int, long, void *));
|
||||
extern int (*BIO_meth_set_destroy)(BIO_METHOD *biom, int (*destroy) (BIO *));
|
||||
extern int (*BIO_meth_set_gets)(BIO_METHOD *biom, int (*gets) (BIO *, char *, int));
|
||||
extern int (*BIO_meth_set_puts)(BIO_METHOD *biom, int (*puts) (BIO *, const char *));
|
||||
extern int (*BIO_meth_set_read)(BIO_METHOD *biom, int (*read) (BIO *, char *, int));
|
||||
extern int (*BIO_meth_set_write)(BIO_METHOD *biom, int (*write) (BIO *, const char *, int));
|
||||
extern BIO_METHOD *(*BIO_meth_new)(int type, const char *name);
|
||||
extern BIO *(*BIO_new)(const BIO_METHOD *type);
|
||||
extern void (*BIO_set_data)(BIO *a, void *ptr);
|
||||
extern void (*BIO_set_init)(BIO *a, int init);
|
||||
|
||||
extern void (*CRYPTO_free)(void *ptr, const char *file, int line);
|
||||
extern void *(*CRYPTO_malloc)(size_t num, const char *file, int line);
|
||||
extern int (*CRYPTO_num_locks)(void);
|
||||
extern void (*CRYPTO_set_locking_callback)(void (*func)(int mode, int type, const char *file, int line));
|
||||
extern int (*CRYPTO_set_mem_functions)(void *(*m)(size_t bytes), void *(*r)(void *mem, size_t size), void (*f)(void *mem));
|
||||
extern int (*CRYPTO_THREADID_set_callback)(void (*func)(CRYPTO_THREADID *id));
|
||||
extern void (*CRYPTO_THREADID_set_numeric)(CRYPTO_THREADID *id, unsigned long val);
|
||||
|
||||
extern char *(*ERR_error_string)(unsigned long e, char *buf);
|
||||
extern void (*ERR_error_string_n)(unsigned long e, char *buf, size_t len);
|
||||
extern unsigned long (*ERR_get_error)(void);
|
||||
|
||||
# define OPENSSL_malloc(num) CRYPTO_malloc(num, __FILE__, __LINE__)
|
||||
# define OPENSSL_free(addr) CRYPTO_free(addr, __FILE__, __LINE__)
|
||||
|
||||
extern int (*SSL_connect)(SSL *ssl);
|
||||
extern long (*SSL_ctrl)(SSL *ssl, int cmd, long arg, void *parg);
|
||||
extern void (*SSL_free)(SSL *ssl);
|
||||
extern int (*SSL_get_error)(SSL *ssl, int ret);
|
||||
extern X509 *(*SSL_get_peer_certificate)(const SSL *ssl);
|
||||
extern long (*SSL_get_verify_result)(const SSL *ssl);
|
||||
extern int (*SSL_library_init)(void);
|
||||
extern void (*SSL_load_error_strings)(void);
|
||||
extern SSL *(*SSL_new)(SSL_CTX *ctx);
|
||||
extern int (*SSL_read)(SSL *ssl, const void *buf, int num);
|
||||
extern void (*SSL_set_bio)(SSL *ssl, BIO *rbio, BIO *wbio);
|
||||
extern int (*SSL_shutdown)(SSL *ssl);
|
||||
extern int (*SSL_write)(SSL *ssl, const void *buf, int num);
|
||||
|
||||
# define SSL_set_tlsext_host_name(s, name) SSL_ctrl((s), SSL_CTRL_SET_TLSEXT_HOSTNAME, TLSEXT_NAMETYPE_host_name, (char *)(name));
|
||||
|
||||
extern long (*SSL_CTX_ctrl)(SSL_CTX *ctx, int cmd, long larg, void *parg);
|
||||
extern void (*SSL_CTX_free)(SSL_CTX *ctx);
|
||||
extern SSL_CTX *(*SSL_CTX_new)(const SSL_METHOD *method);
|
||||
extern int (*SSL_CTX_set_cipher_list)(SSL_CTX *ctx, const char *str);
|
||||
extern int (*SSL_CTX_set_default_verify_paths)(SSL_CTX *ctx);
|
||||
extern long (*SSL_CTX_set_options)(SSL_CTX *ctx, long options);
|
||||
extern void (*SSL_CTX_set_verify)(SSL_CTX *ctx, int mode, int (*verify_callback)(int, X509_STORE_CTX *));
|
||||
extern int (*SSL_CTX_load_verify_locations)(SSL_CTX *ctx, const char *CAfile, const char *CApath);
|
||||
|
||||
# define SSL_CTX_set_mode(ctx, mode) SSL_CTX_ctrl((ctx), SSL_CTRL_MODE, (mode), NULL);
|
||||
|
||||
extern const SSL_METHOD *(*SSLv23_method)(void);
|
||||
extern const SSL_METHOD *(*TLS_method)(void);
|
||||
|
||||
extern ASN1_STRING *(*X509_NAME_ENTRY_get_data)(const X509_NAME_ENTRY *ne);
|
||||
extern X509_NAME_ENTRY *(*X509_NAME_get_entry)(X509_NAME *name, int loc);
|
||||
extern int (*X509_NAME_get_index_by_NID)(X509_NAME *name, int nid, int lastpos);
|
||||
extern void (*X509_free)(X509 *a);
|
||||
extern void *(*X509_get_ext_d2i)(const X509 *x, int nid, int *crit, int *idx);
|
||||
extern X509_NAME *(*X509_get_subject_name)(const X509 *x);
|
||||
|
||||
extern int (*i2d_X509)(X509 *a, unsigned char **ppout);
|
||||
|
||||
extern int (*OPENSSL_sk_num)(const void *sk);
|
||||
extern void *(*OPENSSL_sk_value)(const void *sk, int i);
|
||||
extern void (*OPENSSL_sk_free)(void *sk);
|
||||
|
||||
extern int (*sk_num)(const void *sk);
|
||||
extern void *(*sk_value)(const void *sk, int i);
|
||||
extern void (*sk_free)(void *sk);
|
||||
|
||||
extern int sk_GENERAL_NAME_num(const GENERAL_NAME *sk);
|
||||
extern GENERAL_NAME *sk_GENERAL_NAME_value(const GENERAL_NAME *sk, int i);
|
||||
extern void GENERAL_NAMES_free(GENERAL_NAME *sk);
|
||||
|
||||
extern int git_openssl_stream_dynamic_init(void);
|
||||
|
||||
#endif /* GIT_OPENSSL_DYNAMIC */
|
||||
|
||||
#endif
|
||||
203
src/streams/openssl_legacy.c
Normal file
203
src/streams/openssl_legacy.c
Normal file
@@ -0,0 +1,203 @@
|
||||
/*
|
||||
* Copyright (C) the libgit2 contributors. All rights reserved.
|
||||
*
|
||||
* This file is part of libgit2, distributed under the GNU GPL v2 with
|
||||
* a Linking Exception. For full terms see the included COPYING file.
|
||||
*/
|
||||
|
||||
#include "streams/openssl.h"
|
||||
#include "streams/openssl_legacy.h"
|
||||
|
||||
#include "runtime.h"
|
||||
#include "git2/sys/openssl.h"
|
||||
|
||||
#if defined(GIT_OPENSSL) && !defined(GIT_OPENSSL_DYNAMIC)
|
||||
# include <openssl/ssl.h>
|
||||
# include <openssl/err.h>
|
||||
# include <openssl/x509v3.h>
|
||||
# include <openssl/bio.h>
|
||||
#endif
|
||||
|
||||
#if defined(GIT_OPENSSL_LEGACY) || defined(GIT_OPENSSL_DYNAMIC)
|
||||
|
||||
/*
|
||||
* OpenSSL 1.1 made BIO opaque so we have to use functions to interact with it
|
||||
* which do not exist in previous versions. We define these inline functions so
|
||||
* we can program against the interface instead of littering the implementation
|
||||
* with ifdefs. We do the same for OPENSSL_init_ssl.
|
||||
*/
|
||||
|
||||
int OPENSSL_init_ssl__legacy(uint64_t opts, const void *settings)
|
||||
{
|
||||
GIT_UNUSED(opts);
|
||||
GIT_UNUSED(settings);
|
||||
SSL_load_error_strings();
|
||||
SSL_library_init();
|
||||
return 0;
|
||||
}
|
||||
|
||||
BIO_METHOD* BIO_meth_new__legacy(int type, const char *name)
|
||||
{
|
||||
BIO_METHOD *meth = git__calloc(1, sizeof(BIO_METHOD));
|
||||
if (!meth) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
meth->type = type;
|
||||
meth->name = name;
|
||||
|
||||
return meth;
|
||||
}
|
||||
|
||||
void BIO_meth_free__legacy(BIO_METHOD *biom)
|
||||
{
|
||||
git__free(biom);
|
||||
}
|
||||
|
||||
int BIO_meth_set_write__legacy(BIO_METHOD *biom, int (*write) (BIO *, const char *, int))
|
||||
{
|
||||
biom->bwrite = write;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int BIO_meth_set_read__legacy(BIO_METHOD *biom, int (*read) (BIO *, char *, int))
|
||||
{
|
||||
biom->bread = read;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int BIO_meth_set_puts__legacy(BIO_METHOD *biom, int (*puts) (BIO *, const char *))
|
||||
{
|
||||
biom->bputs = puts;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int BIO_meth_set_gets__legacy(BIO_METHOD *biom, int (*gets) (BIO *, char *, int))
|
||||
|
||||
{
|
||||
biom->bgets = gets;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int BIO_meth_set_ctrl__legacy(BIO_METHOD *biom, long (*ctrl) (BIO *, int, long, void *))
|
||||
{
|
||||
biom->ctrl = ctrl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int BIO_meth_set_create__legacy(BIO_METHOD *biom, int (*create) (BIO *))
|
||||
{
|
||||
biom->create = create;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int BIO_meth_set_destroy__legacy(BIO_METHOD *biom, int (*destroy) (BIO *))
|
||||
{
|
||||
biom->destroy = destroy;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int BIO_get_new_index__legacy(void)
|
||||
{
|
||||
/* This exists as of 1.1 so before we'd just have 0 */
|
||||
return 0;
|
||||
}
|
||||
|
||||
void BIO_set_init__legacy(BIO *b, int init)
|
||||
{
|
||||
b->init = init;
|
||||
}
|
||||
|
||||
void BIO_set_data__legacy(BIO *a, void *ptr)
|
||||
{
|
||||
a->ptr = ptr;
|
||||
}
|
||||
|
||||
void *BIO_get_data__legacy(BIO *a)
|
||||
{
|
||||
return a->ptr;
|
||||
}
|
||||
|
||||
const unsigned char *ASN1_STRING_get0_data__legacy(const ASN1_STRING *x)
|
||||
{
|
||||
return ASN1_STRING_data((ASN1_STRING *)x);
|
||||
}
|
||||
|
||||
long SSL_CTX_set_options__legacy(SSL_CTX *ctx, long op)
|
||||
{
|
||||
return SSL_CTX_ctrl(ctx, SSL_CTRL_OPTIONS, op, NULL);
|
||||
}
|
||||
|
||||
# if defined(GIT_THREADS)
|
||||
static git_mutex *openssl_locks;
|
||||
|
||||
static void openssl_locking_function(int mode, int n, const char *file, int line)
|
||||
{
|
||||
int lock;
|
||||
|
||||
GIT_UNUSED(file);
|
||||
GIT_UNUSED(line);
|
||||
|
||||
lock = mode & CRYPTO_LOCK;
|
||||
|
||||
if (lock)
|
||||
(void)git_mutex_lock(&openssl_locks[n]);
|
||||
else
|
||||
git_mutex_unlock(&openssl_locks[n]);
|
||||
}
|
||||
|
||||
static void shutdown_ssl_locking(void)
|
||||
{
|
||||
int num_locks, i;
|
||||
|
||||
num_locks = CRYPTO_num_locks();
|
||||
CRYPTO_set_locking_callback(NULL);
|
||||
|
||||
for (i = 0; i < num_locks; ++i)
|
||||
git_mutex_free(&openssl_locks[i]);
|
||||
git__free(openssl_locks);
|
||||
}
|
||||
|
||||
static void threadid_cb(CRYPTO_THREADID *threadid)
|
||||
{
|
||||
GIT_UNUSED(threadid);
|
||||
CRYPTO_THREADID_set_numeric(threadid, git_thread_currentid());
|
||||
}
|
||||
|
||||
int git_openssl_set_locking(void)
|
||||
{
|
||||
int num_locks, i;
|
||||
|
||||
#ifndef GIT_THREADS
|
||||
git_error_set(GIT_ERROR_THREAD, "libgit2 was not built with threads");
|
||||
return -1;
|
||||
#endif
|
||||
|
||||
#ifdef GIT_OPENSSL_DYNAMIC
|
||||
/*
|
||||
* This function is required on legacy versions of OpenSSL; when building
|
||||
* with dynamically-loaded OpenSSL, we detect whether we loaded it or not.
|
||||
*/
|
||||
if (!CRYPTO_set_locking_callback)
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
CRYPTO_THREADID_set_callback(threadid_cb);
|
||||
|
||||
num_locks = CRYPTO_num_locks();
|
||||
openssl_locks = git__calloc(num_locks, sizeof(git_mutex));
|
||||
GIT_ERROR_CHECK_ALLOC(openssl_locks);
|
||||
|
||||
for (i = 0; i < num_locks; i++) {
|
||||
if (git_mutex_init(&openssl_locks[i]) != 0) {
|
||||
git_error_set(GIT_ERROR_SSL, "failed to initialize openssl locks");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
CRYPTO_set_locking_callback(openssl_locking_function);
|
||||
return git_runtime_shutdown_register(shutdown_ssl_locking);
|
||||
}
|
||||
#endif /* GIT_THREADS */
|
||||
|
||||
#endif /* GIT_OPENSSL_LEGACY || GIT_OPENSSL_DYNAMIC */
|
||||
63
src/streams/openssl_legacy.h
Normal file
63
src/streams/openssl_legacy.h
Normal file
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright (C) the libgit2 contributors. All rights reserved.
|
||||
*
|
||||
* This file is part of libgit2, distributed under the GNU GPL v2 with
|
||||
* a Linking Exception. For full terms see the included COPYING file.
|
||||
*/
|
||||
#ifndef INCLUDE_streams_openssl_legacy_h__
|
||||
#define INCLUDE_streams_openssl_legacy_h__
|
||||
|
||||
#include "streams/openssl_dynamic.h"
|
||||
|
||||
#if defined(GIT_OPENSSL) && !defined(GIT_OPENSSL_DYNAMIC)
|
||||
# include <openssl/ssl.h>
|
||||
# include <openssl/err.h>
|
||||
# include <openssl/x509v3.h>
|
||||
# include <openssl/bio.h>
|
||||
|
||||
# if (defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER < 0x10100000L) || \
|
||||
(defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x20700000L)
|
||||
# define GIT_OPENSSL_LEGACY
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(GIT_OPENSSL_LEGACY) && !defined(GIT_OPENSSL_DYNAMIC)
|
||||
# define OPENSSL_init_ssl OPENSSL_init_ssl__legacy
|
||||
# define BIO_meth_new BIO_meth_new__legacy
|
||||
# define BIO_meth_free BIO_meth_free__legacy
|
||||
# define BIO_meth_set_write BIO_meth_set_write__legacy
|
||||
# define BIO_meth_set_read BIO_meth_set_read__legacy
|
||||
# define BIO_meth_set_puts BIO_meth_set_puts__legacy
|
||||
# define BIO_meth_set_gets BIO_meth_set_gets__legacy
|
||||
# define BIO_meth_set_ctrl BIO_meth_set_ctrl__legacy
|
||||
# define BIO_meth_set_create BIO_meth_set_create__legacy
|
||||
# define BIO_meth_set_destroy BIO_meth_set_destroy__legacy
|
||||
# define BIO_get_new_index BIO_get_new_index__legacy
|
||||
# define BIO_set_data BIO_set_data__legacy
|
||||
# define BIO_set_init BIO_set_init__legacy
|
||||
# define BIO_get_data BIO_get_data__legacy
|
||||
# define ASN1_STRING_get0_data ASN1_STRING_get0_data__legacy
|
||||
#endif
|
||||
|
||||
#if defined(GIT_OPENSSL_LEGACY) || defined(GIT_OPENSSL_DYNAMIC)
|
||||
|
||||
extern int OPENSSL_init_ssl__legacy(uint64_t opts, const void *settings);
|
||||
extern BIO_METHOD* BIO_meth_new__legacy(int type, const char *name);
|
||||
extern void BIO_meth_free__legacy(BIO_METHOD *biom);
|
||||
extern int BIO_meth_set_write__legacy(BIO_METHOD *biom, int (*write) (BIO *, const char *, int));
|
||||
extern int BIO_meth_set_read__legacy(BIO_METHOD *biom, int (*read) (BIO *, char *, int));
|
||||
extern int BIO_meth_set_puts__legacy(BIO_METHOD *biom, int (*puts) (BIO *, const char *));
|
||||
extern int BIO_meth_set_gets__legacy(BIO_METHOD *biom, int (*gets) (BIO *, char *, int));
|
||||
extern int BIO_meth_set_ctrl__legacy(BIO_METHOD *biom, long (*ctrl) (BIO *, int, long, void *));
|
||||
extern int BIO_meth_set_create__legacy(BIO_METHOD *biom, int (*create) (BIO *));
|
||||
extern int BIO_meth_set_destroy__legacy(BIO_METHOD *biom, int (*destroy) (BIO *));
|
||||
extern int BIO_get_new_index__legacy(void);
|
||||
extern void BIO_set_data__legacy(BIO *a, void *ptr);
|
||||
extern void BIO_set_init__legacy(BIO *b, int init);
|
||||
extern void *BIO_get_data__legacy(BIO *a);
|
||||
extern const unsigned char *ASN1_STRING_get0_data__legacy(const ASN1_STRING *x);
|
||||
extern long SSL_CTX_set_options__legacy(SSL_CTX *ctx, long op);
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -14,7 +14,7 @@
|
||||
|
||||
#ifdef GIT_NTLM
|
||||
|
||||
#include "ntlm.h"
|
||||
#include "ntlmclient.h"
|
||||
|
||||
typedef struct {
|
||||
git_http_auth_context parent;
|
||||
|
||||
@@ -18,7 +18,9 @@ int main(int argc, char *argv[])
|
||||
|
||||
res = git_libgit2_init();
|
||||
if (res < 0) {
|
||||
fprintf(stderr, "failed to init libgit2");
|
||||
const git_error *err = git_error_last();
|
||||
const char *msg = err ? err->message : "unknown failure";
|
||||
fprintf(stderr, "failed to init libgit2: %s\n", msg);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user