Set up the openssl(3) plugin to statically link for windows, so people can actually host properly with dtls on windows.

git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@6163 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2022-01-16 18:41:53 +00:00
parent 6c112c3368
commit b21a648a4b
4 changed files with 73 additions and 24 deletions

View file

@ -154,6 +154,7 @@ extern cvar_t net_ice_exchangeprivateips;
#if defined(HAVE_DTLS) && defined(HAVE_SERVER) #if defined(HAVE_DTLS) && defined(HAVE_SERVER)
static void QDECL NET_Enable_DTLS_Changed(struct cvar_s *var, char *oldvalue) static void QDECL NET_Enable_DTLS_Changed(struct cvar_s *var, char *oldvalue)
{ {
var->ival = var->value;
//set up the default value //set up the default value
if (!*var->string) if (!*var->string)
var->ival = 0; //FIXME: change to 1 then 2 when better tested. var->ival = 0; //FIXME: change to 1 then 2 when better tested.
@ -250,6 +251,10 @@ static void NET_TLS_Provider_Changed(struct cvar_s *var, char *oldvalue)
Con_Printf(" %s", cryptolib[i]->drivername); Con_Printf(" %s", cryptolib[i]->drivername);
Con_Printf("\n"); Con_Printf("\n");
} }
#if defined(HAVE_DTLS) && defined(HAVE_SERVER)
Cvar_ForceCallback(&net_enable_dtls);
#endif
} }
#endif #endif
qboolean NET_RegisterCrypto(void *module, ftecrypto_t *driver) qboolean NET_RegisterCrypto(void *module, ftecrypto_t *driver)
@ -2973,13 +2978,24 @@ const dtlsfuncs_t *DTLS_InitServer(void)
{ {
const dtlsfuncs_t *f = NULL; const dtlsfuncs_t *f = NULL;
int i; int i;
const char *provname;
if (tls_provider.ival>0 && tls_provider.ival <= cryptolib_count && cryptolib[tls_provider.ival-1]) if (tls_provider.ival>0 && tls_provider.ival <= cryptolib_count && cryptolib[tls_provider.ival-1])
{
f = !cryptolib[tls_provider.ival-1]->DTLS_InitServer?NULL:cryptolib[tls_provider.ival-1]->DTLS_InitServer(); f = !cryptolib[tls_provider.ival-1]->DTLS_InitServer?NULL:cryptolib[tls_provider.ival-1]->DTLS_InitServer();
provname = cryptolib[tls_provider.ival-1]->drivername;
}
else for (i = 0; !f && i < cryptolib_count; i++) else for (i = 0; !f && i < cryptolib_count; i++)
{ {
if (cryptolib[i] && cryptolib[i]->DTLS_InitServer) if (cryptolib[i] && cryptolib[i]->DTLS_InitServer)
{
f = cryptolib[i]->DTLS_InitServer(); f = cryptolib[i]->DTLS_InitServer();
provname = cryptolib[i]->drivername;
if (!f)
Con_Printf("DTLS provider %s failed\n", cryptolib[i]->drivername);
}
} }
if (f)
Con_DPrintf("Using DTLS provider %s\n", provname);
return f; return f;
} }
const dtlsfuncs_t *DTLS_InitClient(void) const dtlsfuncs_t *DTLS_InitClient(void)

View file

@ -1789,23 +1789,27 @@ svextqcfields
} }
static qintptr_t QVM_SetExtField (void *offset, quintptr_t mask, const qintptr_t *arg) static qintptr_t QVM_SetExtField (void *offset, quintptr_t mask, const qintptr_t *arg)
{ {
edict_t *e = VM_POINTER(arg[0]); unsigned int entnum = ((char*)VM_POINTER(arg[0]) - (char*)evars)/sv.world.edict_size;
int i = QVM_FindExtField(VM_POINTER(arg[1])); int i = QVM_FindExtField(VM_POINTER(arg[1]));
int value = VM_LONG(arg[2]); int value = VM_LONG(arg[2]);
if (i < 0) if (i >= 0 && entnum < q1qvmprogfuncs.edicttable_length && q1qvmprogfuncs.edicttable[entnum])
return 0; {
((int*)e->xv)[i] = value; ((int*)q1qvmprogfuncs.edicttable[entnum]->xv)[i] = value;
return value; return value;
}
return 0;
} }
static qintptr_t QVM_GetExtField (void *offset, quintptr_t mask, const qintptr_t *arg) static qintptr_t QVM_GetExtField (void *offset, quintptr_t mask, const qintptr_t *arg)
{ {
edict_t *e = VM_POINTER(arg[0]); unsigned int entnum = ((char*)VM_POINTER(arg[0]) - (char*)evars)/sv.world.edict_size;
int i = QVM_FindExtField(VM_POINTER(arg[1])); int i = QVM_FindExtField(VM_POINTER(arg[1]));
if (i < 0) if (i >= 0 && entnum < q1qvmprogfuncs.edicttable_length && q1qvmprogfuncs.edicttable[entnum])
return 0; {
return ((int*)e->xv)[i]; return ((int*)q1qvmprogfuncs.edicttable[entnum]->xv)[i];
}
return 0;
} }
#ifdef WEBCLIENT #ifdef WEBCLIENT

View file

@ -405,13 +405,42 @@ $(PLUG_PREFIX)models$(PLUG_NATIVE_EXT): models/gltf.c models/exportiqm.c models/
$(call EMBEDMETA,models,$@,Models Plugin,Kinda redundant now that the engine has gltf2 loading) $(call EMBEDMETA,models,$@,Models Plugin,Kinda redundant now that the engine has gltf2 loading)
#NATIVE_PLUGINS+=models #NATIVE_PLUGINS+=models
#####################
#Openssl crypto plugin, to replace microsoft's shoddy dtls implementation. could also be useful on the BSDs, yay system components? #Openssl crypto plugin, to replace microsoft's shoddy dtls implementation. could also be useful on the BSDs, yay system components?
ifeq ($(FTE_TARGET),win32)
OSSL_ARCH=mingw32
endif
ifeq ($(FTE_TARGET),win64)
OSSL_ARCH=mingw64
endif
#statically link openssl on the above systems (instead of depending on system libs)
ifneq ($(OSSL_ARCH),)
OSSL_VERSION=3.0.1
ARCHLIBS=../engine/libs-$(ARCH)
#../engine/libs-$(ARCH)/openssl-$(OSSL_VERSION).tar.gz:
../engine/openssl-$(OSSL_VERSION).tar.gz:
wget -O $@ -N https://github.com/openssl/openssl/archive/refs/tags/openssl-$(OSSL_VERSION).tar.gz
$(ARCHLIBS)/openssl-openssl-$(OSSL_VERSION)/libssl.a: ../engine/openssl-$(OSSL_VERSION).tar.gz
(cd $(ARCHLIBS) && tar xvfz ../openssl-$(OSSL_VERSION).tar.gz)
(cd $(ARCHLIBS)/openssl-openssl-$(OSSL_VERSION) && CFLAGS=-Os ./Configure --release no-filenames no-legacy no-shared no-stdio no-asm $(OSSL_ARCH) --cross-compile-prefix=$(ARCH)- && $(MAKE))
net_ssl_openssl.c: $(ARCHLIBS)/openssl-openssl-$(OSSL_VERSION)/libssl.a $(ARCHLIBS)/openssl-openssl-$(OSSL_VERSION)/libcrypt.a
#we should be using openssl's no-sock option, but that also disables core dtls functionality (despite us using our own BIOs).
OPENSSL_LDCFLAGS=-I$(ARCHLIBS)/openssl-openssl-$(OSSL_VERSION)/include -L$(ARCHLIBS)/openssl-openssl-$(OSSL_VERSION) -lssl -lcrypto -lws2_32
OPENSSL_AVAILABLE=1
endif
OPENSSL_LDCFLAGS?=`$(PKGCONFIG) --libs --cflags openssl`
OPENSSL_AVAILABLE?=$(shell $(OPENSSLPKGPATH) $(PKGCONFIG) --atleast-version=3.0.0 openssl && echo 1)
$(PLUG_PREFIX)openssl$(PLUG_NATIVE_EXT): net_ssl_openssl.c plugin.c $(PLUG_PREFIX)openssl$(PLUG_NATIVE_EXT): net_ssl_openssl.c plugin.c
$(CC) $(BASE_CFLAGS) $(CFLAGS) -DFTEPLUGIN -o $@ -shared $(PLUG_CFLAGS) $^ $(PLUG_DEFFILE) $(PLUG_LDFLAGS) `$(PKGCONFIG) --libs --cflags openssl` $(CC) -s $(BASE_CFLAGS) $(CFLAGS) -DFTEPLUGIN -o $@ -shared $(PLUG_CFLAGS) $^ $(PLUG_DEFFILE) $(PLUG_LDFLAGS) $(OPENSSL_LDCFLAGS)
$(call EMBEDMETA,openssl,$@,OpenSSL,Provides OpenSSL support for dtls/tls/https support. The crypto library that is actually used is controlled via the tls_provider cvar.) $(call EMBEDMETA,openssl,$@,OpenSSL,Provides OpenSSL support for dtls/tls/https support. The crypto library that is actually used is controlled via the tls_provider cvar.)
#ifeq ($(shell $(PKGCONFIG) --exists openssl && echo 1),1) #OpenSSL 3.0.0 is apache2 and thus GPL3-compatible, earlier versions are NOT GPL-compatible at all, so only enable it if its okay.
#Disabled due to licensing issues #NATIVE_PLUGINS+=openssl #(you can still force it, but don't distribute)
#endif ifeq ($(OPENSSL_AVAILABLE),1)
NATIVE_PLUGINS+=openssl
endif
##################### #####################
#for compat with half-life 2's file formats #for compat with half-life 2's file formats

View file

@ -770,18 +770,16 @@ static void *OSSL_CreateContext(const char *remotehost, void *cbctx, neterr_t(*p
return NULL; return NULL;
} }
static char dtlscookiekey[16]; static qbyte dtlscookiekey[16];
static int OSSL_GenCookie(SSL *ssl, unsigned char *cookie, unsigned int *cookie_len) static int OSSL_GenCookie(SSL *ssl, unsigned char *cookie, unsigned int *cookie_len)
{ {
ossldtls_t *f = SSL_get_app_data(ssl); ossldtls_t *f = SSL_get_app_data(ssl);
qbyte *blurgh = alloca(sizeof(dtlscookiekey) + f->peeraddrsize);
SHA_CTX ctx; memcpy(blurgh, dtlscookiekey, sizeof(dtlscookiekey));
memcpy(blurgh+sizeof(dtlscookiekey), f->peeraddr, f->peeraddrsize);
SHA1_Init(&ctx); SHA1(blurgh, sizeof(dtlscookiekey) + f->peeraddrsize, cookie);
SHA1_Update(&ctx, dtlscookiekey, sizeof(dtlscookiekey));
SHA1_Update(&ctx, "somethinghashy", 15);
SHA1_Update(&ctx, f->peeraddr, f->peeraddrsize);
SHA1_Final(cookie, &ctx);
*cookie_len = SHA_DIGEST_LENGTH; *cookie_len = SHA_DIGEST_LENGTH;
return 1; return 1;
@ -949,7 +947,8 @@ static qboolean OSSL_Init(void)
static qboolean init_success; static qboolean init_success;
if (inited) if (inited)
return init_success; return init_success;
#ifdef LOADERTHREAD inited = true;
#if 0//def LOADERTHREAD
Sys_LockMutex(com_resourcemutex); Sys_LockMutex(com_resourcemutex);
if (inited) //now check again, just in case if (inited) //now check again, just in case
{ {
@ -960,7 +959,6 @@ static qboolean OSSL_Init(void)
SSL_library_init(); SSL_library_init();
SSL_load_error_strings(); SSL_load_error_strings();
ERR_load_BIO_strings();
// OPENSSL_config(NULL); // OPENSSL_config(NULL);
ERR_print_errors_cb(OSSL_PrintError_CB, NULL); ERR_print_errors_cb(OSSL_PrintError_CB, NULL);
@ -997,8 +995,7 @@ static qboolean OSSL_Init(void)
ossl_fte_certctx = SSL_get_ex_new_index(0, "ossl_fte_certctx", NULL, NULL, NULL); ossl_fte_certctx = SSL_get_ex_new_index(0, "ossl_fte_certctx", NULL, NULL, NULL);
inited = true; #if 0//def LOADERTHREAD
#ifdef LOADERTHREAD
Sys_UnlockMutex(com_resourcemutex); Sys_UnlockMutex(com_resourcemutex);
#endif #endif
return init_success; return init_success;
@ -1056,5 +1053,8 @@ qboolean Plug_Init(void)
pdtls_psk_user = cvarfuncs->GetNVFDG("dtls_psk_user", "", 0, NULL, "DTLS stuff"); pdtls_psk_user = cvarfuncs->GetNVFDG("dtls_psk_user", "", 0, NULL, "DTLS stuff");
pdtls_psk_key = cvarfuncs->GetNVFDG("dtls_psk_key", "", 0, NULL, "DTLS stuff"); pdtls_psk_key = cvarfuncs->GetNVFDG("dtls_psk_key", "", 0, NULL, "DTLS stuff");
netfuncs->RandomBytes(dtlscookiekey, sizeof(dtlscookiekey)); //something random so people can't guess cookies for arbitrary victim IPs. netfuncs->RandomBytes(dtlscookiekey, sizeof(dtlscookiekey)); //something random so people can't guess cookies for arbitrary victim IPs.
OSSL_Init(); //shoving this here solves threading issues (eg two loader threads racing to open an https image url)
return plugfuncs->ExportInterface("Crypto", &crypto_openssl, sizeof(crypto_openssl)); //export a named interface struct to the engine return plugfuncs->ExportInterface("Crypto", &crypto_openssl, sizeof(crypto_openssl)); //export a named interface struct to the engine
} }