d8b67b9d0f
PR #3399 converted shlibloadtest to the new test framework. It also seemed to add some `OPENSSL_USE_NODELETE` guards to the library unloading part of the test. This part was added in a commit with this description: Review feedback; use single main, #ifdef ADD_TEST Suppose OPENSSL_USE_NODELETE (via Nick Reilly) Strangely though there doesn't seem to be any relevant review feedback in that PR that could justify the addition of those guards. The guards do not appear in 1.1.0. Having the guards changes the nature of the test, so that we only test library unloading on platforms where OPENSSL_USE_NODELETE is set (Linux and Windows). I can't think of any good reason for this and as it doesn't seem to be necessary in 1.1.0 so I think we should remove them. Reviewed-by: Richard Levitte <levitte@openssl.org> (Merged from https://github.com/openssl/openssl/pull/5530)
194 lines
4.9 KiB
C
194 lines
4.9 KiB
C
/*
|
|
* Copyright 2016-2017 The OpenSSL Project Authors. All Rights Reserved.
|
|
*
|
|
* Licensed under the OpenSSL license (the "License"). You may not use
|
|
* this file except in compliance with the License. You can obtain a copy
|
|
* in the file LICENSE in the source distribution or at
|
|
* https://www.openssl.org/source/license.html
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
#include <openssl/opensslv.h>
|
|
#include <openssl/ssl.h>
|
|
#include <openssl/ossl_typ.h>
|
|
#include "testutil.h"
|
|
|
|
typedef const SSL_METHOD * (*TLS_method_t)(void);
|
|
typedef SSL_CTX * (*SSL_CTX_new_t)(const SSL_METHOD *meth);
|
|
typedef void (*SSL_CTX_free_t)(SSL_CTX *);
|
|
typedef unsigned long (*ERR_get_error_t)(void);
|
|
typedef unsigned long (*OpenSSL_version_num_t)(void);
|
|
|
|
typedef enum test_types_en {
|
|
CRYPTO_FIRST,
|
|
SSL_FIRST,
|
|
JUST_CRYPTO
|
|
} TEST_TYPE;
|
|
|
|
static TEST_TYPE test_type;
|
|
static const char *path_crypto;
|
|
static const char *path_ssl;
|
|
|
|
#ifdef DSO_DLFCN
|
|
|
|
# include <dlfcn.h>
|
|
|
|
# define SHLIB_INIT NULL
|
|
|
|
typedef void *SHLIB;
|
|
typedef void *SHLIB_SYM;
|
|
|
|
static int shlib_load(const char *filename, SHLIB *lib)
|
|
{
|
|
*lib = dlopen(filename, RTLD_GLOBAL | RTLD_LAZY);
|
|
return *lib == NULL ? 0 : 1;
|
|
}
|
|
|
|
static int shlib_sym(SHLIB lib, const char *symname, SHLIB_SYM *sym)
|
|
{
|
|
*sym = dlsym(lib, symname);
|
|
return *sym != NULL;
|
|
}
|
|
|
|
static int shlib_close(SHLIB lib)
|
|
{
|
|
return dlclose(lib) != 0 ? 0 : 1;
|
|
}
|
|
#endif
|
|
|
|
#ifdef DSO_WIN32
|
|
|
|
# include <windows.h>
|
|
|
|
# define SHLIB_INIT 0
|
|
|
|
typedef HINSTANCE SHLIB;
|
|
typedef void *SHLIB_SYM;
|
|
|
|
static int shlib_load(const char *filename, SHLIB *lib)
|
|
{
|
|
*lib = LoadLibraryA(filename);
|
|
return *lib == NULL ? 0 : 1;
|
|
}
|
|
|
|
static int shlib_sym(SHLIB lib, const char *symname, SHLIB_SYM *sym)
|
|
{
|
|
*sym = (SHLIB_SYM)GetProcAddress(lib, symname);
|
|
return *sym != NULL;
|
|
}
|
|
|
|
static int shlib_close(SHLIB lib)
|
|
{
|
|
return FreeLibrary(lib) == 0 ? 0 : 1;
|
|
}
|
|
#endif
|
|
|
|
|
|
#if defined(DSO_DLFCN) || defined(DSO_WIN32)
|
|
|
|
static int test_lib(void)
|
|
{
|
|
SHLIB ssllib = SHLIB_INIT;
|
|
SHLIB cryptolib = SHLIB_INIT;
|
|
SSL_CTX *ctx;
|
|
union {
|
|
void (*func)(void);
|
|
SHLIB_SYM sym;
|
|
} symbols[3];
|
|
TLS_method_t myTLS_method;
|
|
SSL_CTX_new_t mySSL_CTX_new;
|
|
SSL_CTX_free_t mySSL_CTX_free;
|
|
ERR_get_error_t myERR_get_error;
|
|
OpenSSL_version_num_t myOpenSSL_version_num;
|
|
int result = 0;
|
|
|
|
switch (test_type) {
|
|
case JUST_CRYPTO:
|
|
if (!TEST_true(shlib_load(path_crypto, &cryptolib)))
|
|
goto end;
|
|
break;
|
|
case CRYPTO_FIRST:
|
|
if (!TEST_true(shlib_load(path_crypto, &cryptolib))
|
|
|| !TEST_true(shlib_load(path_ssl, &ssllib)))
|
|
goto end;
|
|
break;
|
|
case SSL_FIRST:
|
|
if (!TEST_true(shlib_load(path_ssl, &ssllib))
|
|
|| !TEST_true(shlib_load(path_crypto, &cryptolib)))
|
|
goto end;
|
|
break;
|
|
}
|
|
|
|
if (test_type != JUST_CRYPTO) {
|
|
if (!TEST_true(shlib_sym(ssllib, "TLS_method", &symbols[0].sym))
|
|
|| !TEST_true(shlib_sym(ssllib, "SSL_CTX_new", &symbols[1].sym))
|
|
|| !TEST_true(shlib_sym(ssllib, "SSL_CTX_free", &symbols[2].sym)))
|
|
goto end;
|
|
myTLS_method = (TLS_method_t)symbols[0].func;
|
|
mySSL_CTX_new = (SSL_CTX_new_t)symbols[1].func;
|
|
mySSL_CTX_free = (SSL_CTX_free_t)symbols[2].func;
|
|
if (!TEST_ptr(ctx = mySSL_CTX_new(myTLS_method())))
|
|
goto end;
|
|
mySSL_CTX_free(ctx);
|
|
}
|
|
|
|
if (!TEST_true(shlib_sym(cryptolib, "ERR_get_error", &symbols[0].sym))
|
|
|| !TEST_true(shlib_sym(cryptolib, "OpenSSL_version_num",
|
|
&symbols[1].sym)))
|
|
goto end;
|
|
myERR_get_error = (ERR_get_error_t)symbols[0].func;
|
|
if (!TEST_int_eq(myERR_get_error(), 0))
|
|
goto end;
|
|
myOpenSSL_version_num = (OpenSSL_version_num_t)symbols[1].func;
|
|
if (!TEST_int_eq(myOpenSSL_version_num(), OPENSSL_VERSION_NUMBER))
|
|
goto end;
|
|
|
|
switch (test_type) {
|
|
case JUST_CRYPTO:
|
|
if (!TEST_true(shlib_close(cryptolib)))
|
|
goto end;
|
|
break;
|
|
case CRYPTO_FIRST:
|
|
if (!TEST_true(shlib_close(cryptolib))
|
|
|| !TEST_true(shlib_close(ssllib)))
|
|
goto end;
|
|
break;
|
|
case SSL_FIRST:
|
|
if (!TEST_true(shlib_close(ssllib))
|
|
|| !TEST_true(shlib_close(cryptolib)))
|
|
goto end;
|
|
break;
|
|
}
|
|
|
|
result = 1;
|
|
end:
|
|
return result;
|
|
}
|
|
#endif
|
|
|
|
|
|
int setup_tests(void)
|
|
{
|
|
const char *p = test_get_argument(0);
|
|
|
|
if (strcmp(p, "-crypto_first") == 0) {
|
|
test_type = CRYPTO_FIRST;
|
|
} else if (strcmp(p, "-ssl_first") == 0) {
|
|
test_type = SSL_FIRST;
|
|
} else if (strcmp(p, "-just_crypto") == 0) {
|
|
test_type = JUST_CRYPTO;
|
|
} else {
|
|
TEST_error("Unrecognised argument");
|
|
return 0;
|
|
}
|
|
if (!TEST_ptr(path_crypto = test_get_argument(1))
|
|
|| !TEST_ptr(path_ssl = test_get_argument(2)))
|
|
return 0;
|
|
|
|
#if defined(DSO_DLFCN) || defined(DSO_WIN32)
|
|
ADD_TEST(test_lib);
|
|
#endif
|
|
return 1;
|
|
}
|