Compare commits

...

2 Commits

Author SHA1 Message Date
Vladimir Dubrovin
f8c22d5f91 Fix: symbols collision with openssl, could lead to crash
Some checks are pending
C/C++ CI Linux / ${{ matrix.target }} (ubuntu-24.04-arm) (push) Waiting to run
C/C++ CI Linux / ${{ matrix.target }} (ubuntu-latest) (push) Waiting to run
C/C++ CI MacOS / ${{ matrix.target }} (macos-15) (push) Waiting to run
C/C++ CI Windows / ${{ matrix.target }} (windows-2022) (push) Waiting to run
C/C++ CI cmake / ${{ matrix.target }} (macos-15) (push) Waiting to run
C/C++ CI cmake / ${{ matrix.target }} (ubuntu-24.04-arm) (push) Waiting to run
C/C++ CI cmake / ${{ matrix.target }} (ubuntu-latest) (push) Waiting to run
C/C++ CI cmake / ${{ matrix.target }} (windows-2022) (push) Waiting to run
2026-05-08 14:03:47 +03:00
Vladimir Dubrovin
c104203765 Fix memory leak in hash functions 2026-05-08 12:10:08 +03:00
8 changed files with 117 additions and 116 deletions

View File

@ -405,7 +405,6 @@ endif()
add_executable(3proxy
${3PROXY_CORE_SOURCES}
${MD_SOURCES}
$<TARGET_OBJECTS:srv_modules>
$<TARGET_OBJECTS:srvudppm_obj>
$<TARGET_OBJECTS:mainfunc>
@ -415,6 +414,9 @@ add_executable(3proxy
$<TARGET_OBJECTS:ftp_obj>
$<TARGET_OBJECTS:3proxy_crypt_obj>
)
if(NOT OpenSSL_FOUND)
target_sources(3proxy PRIVATE ${MD_SOURCES})
endif()
if(OpenSSL_FOUND)
target_sources(3proxy PRIVATE src/ssllib.c src/ssl.c)
@ -519,9 +521,11 @@ endif()
# Build 3proxy_crypt utility
add_executable(3proxy_crypt
src/3proxy_crypt.c
${MD_SOURCES}
$<TARGET_OBJECTS:base64_obj>
)
if(NOT OpenSSL_FOUND)
target_sources(3proxy_crypt PRIVATE ${MD_SOURCES})
endif()
target_compile_definitions(3proxy_crypt PRIVATE WITHMAIN)
target_include_directories(3proxy_crypt PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/src

View File

@ -8,8 +8,9 @@
#include "blake2_compat.h"
#ifdef WITH_SSL
#include <openssl/evp.h>
#ifndef WITHMAIN
/* MD5 needed for $1$ crypt */
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
#include <openssl/params.h>
#include <openssl/core_names.h>
#endif
#endif
#include <string.h>
@ -28,10 +29,52 @@ static unsigned char itoa64[] =
#if defined(WITH_SSL)
EVP_MD *md4 = NULL;
EVP_MD *md5 = NULL;
EVP_MD *md4_hash = NULL;
EVP_MD *md5_hash = NULL;
#endif
#if defined(WITH_SSL) && OPENSSL_VERSION_NUMBER >= 0x10100000L
int blake2b_init_3p(blake2b_state *S, size_t outlen) {
*S = EVP_MD_CTX_new();
if (!*S) return -1;
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
size_t sz = outlen;
OSSL_PARAM params[2];
params[0] = OSSL_PARAM_construct_size_t(OSSL_DIGEST_PARAM_SIZE, &sz);
params[1] = OSSL_PARAM_construct_end();
if (!EVP_DigestInit_ex2(*S, EVP_blake2b512(), params)) {
#else
(void)outlen;
if (!EVP_DigestInit_ex(*S, EVP_blake2b512(), NULL)) {
#endif
EVP_MD_CTX_free(*S);
*S = NULL;
return -1;
}
return 0;
}
int blake2b_update_3p(blake2b_state *S, const void *in, size_t inlen) {
if (inlen == 0) return 0;
return EVP_DigestUpdate(*S, in, inlen) ? 0 : -1;
}
int blake2b_final_3p(blake2b_state *S, void *out, size_t outlen) {
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
unsigned int len = 0;
int ret = EVP_DigestFinal_ex(*S, out, &len) ? 0 : -1;
#else
unsigned char tmp[64];
unsigned int len = 0;
int ret = EVP_DigestFinal_ex(*S, tmp, &len) ? 0 : -1;
if (ret == 0) memcpy(out, tmp, outlen);
#endif
EVP_MD_CTX_free(*S);
*S = NULL;
return ret;
}
#endif /* WITH_SSL && OPENSSL >= 1.1 */
void
_crypt_to64(unsigned char *s, unsigned long v, int n)
{
@ -51,7 +94,7 @@ unsigned char * ntpwdhash (unsigned char *szHash, const unsigned char *szPasswor
unsigned int len=sizeof(szUnicodePass);
unsigned int i;
if(md4 == NULL) return NULL;
if(md4_hash == NULL) return NULL;
/*
* NT passwords are unicode. Convert plain text password
@ -67,7 +110,7 @@ unsigned char * ntpwdhash (unsigned char *szHash, const unsigned char *szPasswor
/* Encrypt Unicode password to a 16-byte MD4 hash */
ctx = EVP_MD_CTX_new();
if(!ctx) return NULL;
if(!EVP_DigestInit_ex(ctx, md4, NULL)){
if(!EVP_DigestInit_ex(ctx, md4_hash, NULL)){
EVP_MD_CTX_free(ctx);
return NULL;
}
@ -100,7 +143,7 @@ unsigned char * mycrypt(const unsigned char *pw, const unsigned char *salt, unsi
unsigned int len;
int pl, i;
if(md5 == NULL) {
if(md5_hash == NULL) {
*passwd = 0;
return NULL;
}
@ -114,7 +157,7 @@ unsigned char * mycrypt(const unsigned char *pw, const unsigned char *salt, unsi
*passwd = 0;
return NULL;
}
EVP_DigestInit_ex(ctx, md5, NULL);
EVP_DigestInit_ex(ctx, md5_hash, NULL);
/* The password first, since that is what is most unknown */
EVP_DigestUpdate(ctx,pw,strlen((char *)pw));
@ -161,7 +204,7 @@ unsigned char * mycrypt(const unsigned char *pw, const unsigned char *salt, unsi
*/
for(i=0;i<1000;i++) {
EVP_MD_CTX_reset(ctx1);
EVP_DigestInit_ex(ctx1, md5, NULL);
EVP_DigestInit_ex(ctx1, md5_hash, NULL);
if(i & 1)
EVP_DigestUpdate(ctx1,pw,strlen((char *)pw));
else
@ -189,10 +232,10 @@ unsigned char * mycrypt(const unsigned char *pw, const unsigned char *salt, unsi
magic = (unsigned char *)"$3$";
{
blake2b_state S;
if(blake2b_init(&S, MD5_SIZE) != 0 ||
blake2b_update(&S, pw, strlen((char *)pw) + 1) != 0 ||
blake2b_update(&S, sp, sl) != 0 ||
blake2b_final(&S, final, MD5_SIZE) != 0) {
if(blake2b_init_3p(&S, MD5_SIZE) != 0 ||
blake2b_update_3p(&S, pw, strlen((char *)pw) + 1) != 0 ||
blake2b_update_3p(&S, sp, sl) != 0 ||
blake2b_final_3p(&S, final, MD5_SIZE) != 0) {
*passwd = 0;
return NULL;
}
@ -231,7 +274,8 @@ OSSL_LIB_CTX *library_ctx = NULL;
#endif
#include <stdio.h>
int main(int argc, char* argv[]){
unsigned char buf[1024];
unsigned char buf1[128];
unsigned char buf2[128];
unsigned i;
if(argc < 2 || argc > 3) {
fprintf(stderr, "usage: \n"
@ -259,18 +303,18 @@ int main(int argc, char* argv[]){
library_ctx = OSSL_LIB_CTX_new();
OSSL_PROVIDER_load(library_ctx, "legacy");
OSSL_PROVIDER_load(library_ctx, "default");
md4 = EVP_MD_fetch(library_ctx, "MD4", NULL);
if (md4 == NULL) {
md4_hash = EVP_MD_fetch(library_ctx, "MD4", NULL);
if (md4_hash == NULL) {
fprintf(stderr, "Error fetching MD4\n");
}
md5 = EVP_MD_fetch(library_ctx, "MD5", NULL);
if (md5 == NULL) {
md5_hash = EVP_MD_fetch(library_ctx, "MD5", NULL);
if (md5_hash == NULL) {
fprintf(stderr, "Error fetching MD5\n");
}
#endif
if(argc == 2) {
#ifdef WITH_SSL
{ unsigned char *nt = ntpwdhash(buf, (unsigned char *)argv[1], 1);
{ unsigned char *nt = ntpwdhash(buf1, (unsigned char *)argv[1], 1);
if(nt) printf("NT:%s\n", nt); }
#else
fprintf(stderr, "NT crypt not available (compiled without OpenSSL)\n");
@ -280,8 +324,8 @@ int main(int argc, char* argv[]){
unsigned char *cr;
i = (int)strlen((char *)argv[1]);
if (i > 64) argv[1][64] = 0;
sprintf((char *)buf, "$3$%s$", argv[1]);
cr = mycrypt((unsigned char *)argv[2], buf, buf+256);
sprintf((char *)buf1, "$3$%.64s$", argv[1]);
cr = mycrypt((unsigned char *)argv[2], buf1, buf2);
if(cr) printf("CR:%s\n", cr);
}
return 0;

View File

@ -234,9 +234,9 @@ int strongauth(struct clientparam * param){
unsigned hashsz;
hashsz = pwl_table.recsize - 1 < 64 ? pwl_table.recsize - 1 : 64;
memset(buf, 0, pwl_table.recsize - 1);
blake2b_init(&S, hashsz);
blake2b_update(&S, param->password, pwlen + 1);
blake2b_final(&S, buf, hashsz);
blake2b_init_3p(&S, hashsz);
blake2b_update_3p(&S, param->password, pwlen + 1);
blake2b_final_3p(&S, buf, hashsz);
if(!memcmp(pass + 1, buf, pwl_table.recsize - 1)) return 0;
}
return 6;

View File

@ -183,8 +183,8 @@ char *strNcpy(char *dest, const char *src, int n)
return dest;
}
extern EVP_MD *md4;
extern EVP_MD *md5;
extern EVP_MD *md4_hash;
extern EVP_MD *md5_hash;
void md5_calc(unsigned char *output, unsigned char *input,
@ -192,7 +192,7 @@ void md5_calc(unsigned char *output, unsigned char *input,
{
EVP_MD_CTX *ctx = EVP_MD_CTX_new();
unsigned int len = 0;
EVP_DigestInit_ex(ctx, md5, NULL);
EVP_DigestInit_ex(ctx, md5_hash, NULL);
EVP_DigestUpdate(ctx, input, inlen);
EVP_DigestFinal_ex(ctx, output, &len);
EVP_MD_CTX_free(ctx);

View File

@ -8,69 +8,21 @@
#if defined(WITH_SSL) && OPENSSL_VERSION_NUMBER >= 0x10100000L
#include <openssl/evp.h>
#include <string.h>
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
#include <openssl/params.h>
#include <openssl/core_names.h>
#endif
/*
* OpenSSL 1.1.0+ BLAKE2b implementation.
* Provides the same streaming API as libs/blake2.h but uses EVP internally.
*
* OpenSSL 3.0+: uses OSSL_DIGEST_PARAM_SIZE for proper custom output sizes.
* OpenSSL 1.1.x: computes full 64-byte output and truncates in blake2b_final.
*/
typedef EVP_MD_CTX *blake2b_state;
static int blake2b_init(blake2b_state *S, size_t outlen) {
*S = EVP_MD_CTX_new();
if (!*S) return -1;
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
size_t sz = outlen;
OSSL_PARAM params[2];
params[0] = OSSL_PARAM_construct_size_t(OSSL_DIGEST_PARAM_SIZE, &sz);
params[1] = OSSL_PARAM_construct_end();
if (!EVP_DigestInit_ex2(*S, EVP_blake2b512(), params)) {
#else
(void)outlen;
if (!EVP_DigestInit_ex(*S, EVP_blake2b512(), NULL)) {
#endif
EVP_MD_CTX_free(*S);
*S = NULL;
return -1;
}
return 0;
}
static int blake2b_update(blake2b_state *S, const void *in, size_t inlen) {
if (inlen == 0) return 0;
return EVP_DigestUpdate(*S, in, inlen) ? 0 : -1;
}
static int blake2b_final(blake2b_state *S, void *out, size_t outlen) {
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
unsigned int len = 0;
int ret = EVP_DigestFinal_ex(*S, out, &len) ? 0 : -1;
#else
unsigned char tmp[64];
unsigned int len = 0;
int ret = EVP_DigestFinal_ex(*S, tmp, &len) ? 0 : -1;
if (ret == 0) memcpy(out, tmp, outlen);
#endif
EVP_MD_CTX_free(*S);
*S = NULL;
return ret;
}
int blake2b_init_3p(blake2b_state *S, size_t outlen);
int blake2b_update_3p(blake2b_state *S, const void *in, size_t inlen);
int blake2b_final_3p(blake2b_state *S, void *out, size_t outlen);
#else
#include "libs/blake2.h"
#define blake2b_init_3p blake2b_init
#define blake2b_update_3p blake2b_update
#define blake2b_final_3p blake2b_final
#endif
#endif /* BLAKE2_COMPAT_H */

View File

@ -561,9 +561,9 @@ static int h_users(int argc, unsigned char **argv){
blake2b_state S;
unsigned hashsz;
hashsz = pwl_table.recsize - 1 < 64 ? pwl_table.recsize - 1 : 64;
blake2b_init(&S, hashsz);
blake2b_update(&S, pw[1], l + 1);
blake2b_final(&S, (uint8_t *)(pass + 1), hashsz);
blake2b_init_3p(&S, hashsz);
blake2b_update_3p(&S, pw[1], l + 1);
blake2b_final_3p(&S, (uint8_t *)(pass + 1), hashsz);
} else {
memcpy(pass + 1, pw[1], l);
}

View File

@ -10,9 +10,9 @@ static void char_index2hash(const struct hashtable *ht, void *index, uint8_t *ha
memset(hash, 0, ht->hash_size);
if(len <= ht->hash_size) memcpy(hash, index, len);
else {
blake2b_init(&S, ht->hash_size);
blake2b_update(&S, index, strlen((const char*)index) + 1);
blake2b_final(&S, hash, ht->hash_size);
blake2b_init_3p(&S, ht->hash_size);
blake2b_update_3p(&S, index, strlen((const char*)index) + 1);
blake2b_final_3p(&S, hash, ht->hash_size);
}
}
@ -49,18 +49,18 @@ static void param2hash_add(const struct hashtable *ht, void *index, uint8_t *has
if((type & 2048)){ memcpy(hash + offset, SAPORT(&param->srv->intsa), p2len); offset += 2; }
}
else {
blake2b_init(&S, ht->hash_size);
if((type & 2) && param->username)blake2b_update(&S, param->username, ulen);
if((type & 4) && param->password)blake2b_update(&S, param->password, plen);
if((type & 1) && !(type & 8))blake2b_update(&S, SAADDR(&param->sincr), a1len);
if((type & 16))blake2b_update(&S, &param->srv->acl, acllen);
if((type & 64))blake2b_update(&S, SAADDR(&param->req), a2len);
if((type & 128))blake2b_update(&S, SAPORT(&param->req), 2);
if((type & 256) && param->hostname)blake2b_update(&S, param->hostname, hlen);
if((type & 512))blake2b_update(&S, &param->operation, sizeof(param->operation));
if((type & 1024))blake2b_update(&S, SAADDR(&param->srv->intsa), a3len);
if((type & 2048))blake2b_update(&S, SAPORT(&param->srv->intsa), 2);
blake2b_final(&S, hash, ht->hash_size);
blake2b_init_3p(&S, ht->hash_size);
if((type & 2) && param->username)blake2b_update_3p(&S, param->username, ulen);
if((type & 4) && param->password)blake2b_update_3p(&S, param->password, plen);
if((type & 1) && !(type & 8))blake2b_update_3p(&S, SAADDR(&param->sincr), a1len);
if((type & 16))blake2b_update_3p(&S, &param->srv->acl, acllen);
if((type & 64))blake2b_update_3p(&S, SAADDR(&param->req), a2len);
if((type & 128))blake2b_update_3p(&S, SAPORT(&param->req), 2);
if((type & 256) && param->hostname)blake2b_update_3p(&S, param->hostname, hlen);
if((type & 512))blake2b_update_3p(&S, &param->operation, sizeof(param->operation));
if((type & 1024))blake2b_update_3p(&S, SAADDR(&param->srv->intsa), a3len);
if((type & 2048))blake2b_update_3p(&S, SAPORT(&param->srv->intsa), 2);
blake2b_final_3p(&S, hash, ht->hash_size);
}
memcpy(param->hash, hash, ht->hash_size);
}
@ -74,12 +74,12 @@ void param2hash_search(const struct hashtable *ht, void *index, uint8_t *hash){
static void udpparam2hash(const struct hashtable *ht, void *index, uint8_t *hash){
struct clientparam *param = (struct clientparam *)index;
blake2b_state S;
blake2b_init(&S, ht->hash_size);
blake2b_update(&S, SAADDR(&param->srv->intsa), SAADDRLEN(&param->srv->intsa));
blake2b_update(&S, SAPORT(&param->srv->intsa), 2);
blake2b_update(&S, SAADDR(&param->sincr), SAADDRLEN(&param->sincr));
blake2b_update(&S, SAPORT(&param->sincr), 2);
blake2b_final(&S, hash, ht->hash_size);
blake2b_init_3p(&S, ht->hash_size);
blake2b_update_3p(&S, SAADDR(&param->srv->intsa), SAADDRLEN(&param->srv->intsa));
blake2b_update_3p(&S, SAPORT(&param->srv->intsa), 2);
blake2b_update_3p(&S, SAADDR(&param->sincr), SAADDRLEN(&param->sincr));
blake2b_update_3p(&S, SAPORT(&param->sincr), 2);
blake2b_final_3p(&S, hash, ht->hash_size);
}
struct hashtable dns_table = {char_index2hash, char_index2hash, 4, 32};

View File

@ -279,8 +279,8 @@ int ssl_file_init = 0;
int ssl_init_done = 0;
OSSL_LIB_CTX *library_ctx = NULL;
extern EVP_MD *md4;
extern EVP_MD *md5;
extern EVP_MD *md4_hash;
extern EVP_MD *md5_hash;
void ssl_init()
@ -296,13 +296,14 @@ void ssl_init()
library_ctx = OSSL_LIB_CTX_new();
OSSL_PROVIDER_load(library_ctx, "legacy");
OSSL_PROVIDER_load(library_ctx, "default");
md4 = EVP_MD_fetch(library_ctx, "MD4", NULL);
if (md4 == NULL) {
printf("Error fetching MD4\n");
}
md5 = EVP_MD_fetch(library_ctx, "MD5", NULL);
if (md5 == NULL) {
printf("Error fetching MD5\n");
md4_hash = EVP_MD_fetch(library_ctx, "MD4", NULL);
if (md4_hash == NULL) {
fprintf(stderr, "Error fetching MD4\n");
}
md5_hash = EVP_MD_fetch(library_ctx, "MD5", NULL);
if (md5_hash == NULL) {
fprintf(stderr, "Error fetching MD5\n");
}
}
}