Fix some misc memory leaks and a few other minor issues.

git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@6176 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2022-01-30 05:55:01 +00:00
parent a61976a3e6
commit 42430d4712
18 changed files with 341 additions and 319 deletions

View file

@ -1091,15 +1091,20 @@ IF(FTE_PLUG_QI)
EMBED_PLUGIN_META(qi "Quaddicted Map Database" "Provides easy access to the quaddicted map database. Once installed you can use eg 'map qi_dopa:start' to begin playing dopa, or load it via the menus.")
ENDIF()
SET(FTE_PLUG_OPENSSL false CACHE BOOL "Compile OpenSSL (beware license).")
SET(FTE_PLUG_OPENSSL false CACHE BOOL "Compile OpenSSL.")
IF(FTE_PLUG_OPENSSL)
#the openssl license is incompatible with the GPL, so while we have code to use it distributing the binaries built with it is not a (legal) option.
#note that openssl 3.0.0 upwards are apache-2 licensed, which IS gpl-3 compatible (though not gpl-2). debian has not caught up with that yet, however.
FIND_PACKAGE(OpenSSL)
IF(OPENSSL_VERSION_MAJOR LESS 3)
SET(FTE_PRIVATE_USE_ONLY false CACHE BOOL "Ignore license violations.")
ENDIF()
IF(NOT OPENSSL_FOUND)
MESSAGE(WARNING "openssl library NOT available. you'll have to use some other library.")
ELSEIF(OPENSSL_VERSION_MAJOR LESS 3 AND NOT FTE_PRIVATE_USE_ONLY)
MESSAGE(WARNING "openssl v3 required for GPL compliance. Enable FTE_PRIVATE_USE_ONLY to compile openssl plugin.")
ELSE()
IF(OPENSSL_VERSION_MAJOR LESS 3 AND NOT FTE_PRIVATE_USE_ONLY)
IF(OPENSSL_VERSION_MAJOR LESS 3)
MESSAGE(WARNING "openssl library version is not 3 or above. You may not distribute plugin binaries due to license conflict.")
ELSE()
MESSAGE(WARNING "Using openssl. Resulting plugin must be licensed as GPLv3.")
@ -1117,6 +1122,25 @@ IF(FTE_PLUG_OPENSSL)
ENDIF()
ENDIF()
#SET(FTE_PLUG_GNUTLS true CACHE BOOL "Compile GnuTLS Library.")
#IF(FTE_PLUG_GNUTLS)
# FIND_PACKAGE(GnuTLS)
# IF(NOT GNUTLS_FOUND)
# MESSAGE(WARNING "openssl library NOT available. you'll have to use some other library.")
# ELSE()
# SET(FTE_LIB_DEFINES ${FTE_LIB_DEFINES})
#
# ADD_LIBRARY(plug_gnutls MODULE
# plugins/plugin.c
# engine/common/net_ssl_gnutls.c
# )
# SET_TARGET_PROPERTIES(plug_gnutls PROPERTIES COMPILE_DEFINITIONS "FTEPLUGIN;${FTE_LIB_DEFINES}")
# TARGET_LINK_LIBRARIES(plug_gnutls ${SYS_LIBS} ${GNUTLS_LIBRARIES})
#
# EMBED_PLUGIN_META(gnutls "GnuTLS" "Provides GnuTLS support for dtls/tls/https support. The crypto library that is actually used is controlled via the tls_provider cvar.")
# ENDIF()
#ENDIF()
#ODE Physics library plugin
SET(FTE_PLUG_ODE true CACHE BOOL "Compile ODE rigid body physics plugin.")
IF(FTE_PLUG_ODE)

View file

@ -35,6 +35,7 @@ void QDECL Name_Callback(struct cvar_s *var, char *oldvalue);
#else
#define Name_Callback NULL
#endif
void GnuTLS_Shutdown(void);
static void CL_ForceStopDownload (qboolean finish);
@ -7223,6 +7224,10 @@ void Host_Shutdown(void)
Cvar_Shutdown();
Validation_FlushFileList();
#ifdef HAVE_GNUTLS
GnuTLS_Shutdown();
#endif
Cmd_Shutdown();
#ifdef PACKAGEMANAGER
PM_Shutdown(false);

View file

@ -311,6 +311,10 @@ static void PM_FreePackage(package_t *p)
Z_Free(p->previewimage);
Z_Free(p->qhash);
Z_Free(p->arch);
Z_Free(p->packprefix);
Z_Free(p->filesha1);
Z_Free(p->filesha512);
Z_Free(p->signature);
Z_Free(p);
}

View file

@ -913,9 +913,18 @@ void Ruleset_Shutdown(void)
rs->rules--;
Z_Free(rs->rule[rs->rules].rulename);
Z_Free(rs->rule[rs->rules].rulevalue);
Z_Free(rs->rule[rs->rules].rulecond);
}
Z_Free(rs->rule);
while (rs->filehashes)
{
rs->filehashes--;
Z_Free(rs->filehash[rs->filehashes].filename);
Z_Free(rs->filehash[rs->filehashes].hash);
}
Z_Free(rs->filehash);
Z_Free(rs);
}
}

View file

@ -6172,7 +6172,10 @@ static galiasinfo_t *Mod_LoadQ3ModelLod(model_t *mod, int *surfcount, void *buff
if (i >= LittleLong(surf->numShaders))
Q_strncpyz(frames->shadername, "", sizeof(frames->shadername)); //this shouldn't be possible
else
{
Q_strncpyz(frames->shadername, inshader->name, sizeof(frames->shadername));
Q_strncpyz(skin->name, inshader->name, sizeof(frames->shadername));
}
inshader++;
skin++;

View file

@ -1714,6 +1714,11 @@ void Cvar_Shutdown(void)
}
Z_Free(var->latched_string);
Z_Free(var->string);
AHash_RemoveDataInsensitive(&cvar_hash, var->name, var);
if (var->name2)
AHash_RemoveDataInsensitive(&cvar_hash, var->name2, var);
if (var->flags & CVAR_POINTER)
Z_Free(var);
else

View file

@ -223,6 +223,7 @@ void FS_Manifest_Free(ftemanifest_t *man)
Z_Free(man->downloadsurl);
Z_Free(man->installupd);
#endif
Z_Free(man->mainconfig);
Z_Free(man->schemes);
Z_Free(man->protocolname);
Z_Free(man->eula);

View file

@ -407,7 +407,11 @@ static struct icestate_s *QDECL ICE_Create(void *module, const char *conname, co
con->dtlsfuncs = DTLS_InitClient(); //credentials are a bit different, though fingerprints make it somewhat irrelevant.
}
if (con->dtlsfuncs && con->dtlsfuncs->GenTempCertificate && !con->cred.local.certsize)
{
Con_DPrintf("Generating dtls certificate...\n");
con->dtlsfuncs->GenTempCertificate(NULL, &con->cred.local);
Con_DPrintf("Done\n");
}
con->mysctpport = 27500;
}
@ -931,9 +935,9 @@ static qboolean QDECL ICE_Set(struct icestate_s *con, const char *prop, const ch
CL_Transfer(&con->qadr); //okay, the client should be using this ice connection now.
#endif
#ifndef CLIENTONLY
else if (con->proto == ICEP_QWSERVER)
else if (con->proto == ICEP_QWSERVER && con->mode != ICEM_WEBRTC)
{
net_from = con->chosenpeer;
net_from = con->qadr;
SVC_GetChallenge(false);
}
#endif
@ -1329,12 +1333,40 @@ void QDECL ICE_AddLCandidateConn(ftenet_connections_t *col, netadr_t *addr, int
static void ICE_Destroy(struct icestate_s *con)
{
struct icecandidate_s *c;
if (con->sctp)
{
Z_Free(con->sctp->cookie);
Z_Free(con->sctp);
}
if (con->dtlsstate)
con->dtlsfuncs->DestroyContext(con->dtlsstate);
if (con->connections)
FTENET_CloseCollection(con->connections);
if (con->cred.local.cert)
Z_Free(con->cred.local.cert);
if (con->cred.local.key)
Z_Free(con->cred.local.key);
Z_Free(con->cred.local.key);
while(con->rc)
{
c = con->rc;
con->rc = c->next;
Z_Free(c);
}
while(con->lc)
{
c = con->lc;
con->lc = c->next;
Z_Free(c);
}
Z_Free(con->stunserver);
Z_Free(con->lufrag);
Z_Free(con->lpwd);
Z_Free(con->rufrag);
Z_Free(con->rpwd);
Z_Free(con->friendlyname);
Z_Free(con->conname);
//has already been unlinked
Z_Free(con);
}
@ -1406,7 +1438,7 @@ void ICE_Tick(void)
{
if (con->sctp)
SCTP_Transmit(con->sctp, con, NULL,0); //try to keep it ticking...
if (con->dtlsfuncs)
if (con->dtlsstate)
con->dtlsfuncs->Timeouts(con->dtlsstate);
//FIXME: We should be sending a stun binding indication every 15 secs with a fingerprint attribute
@ -2154,6 +2186,8 @@ qboolean ICE_WasStun(ftenet_connections_t *col)
if (net_from.type == NA_ICE)
return false; //this stuff over an ICE connection doesn't make sense.
#endif
if (net_from.prot != NP_DGRAM)
return false;
#if defined(HAVE_CLIENT) && defined(VOICECHAT)
if (col == cls.sockets)
@ -3110,7 +3144,6 @@ handleerror:
}
if (b->generic.islisten)
{
Con_Printf("Client offered: %s\n", data);
if (cl >= 0 && cl < b->numclients && b->clients[cl].ice)
{
iceapi.ICE_Set(b->clients[cl].ice, "sdpoffer", data);

View file

@ -139,100 +139,125 @@ typedef int (VARGS gnutls_certificate_verify_function)(gnutls_session_t session)
#endif
static int (VARGS *qgnutls_bye)(gnutls_session_t session, gnutls_close_request_t how);
static void (VARGS *qgnutls_perror)(int error);
static gnutls_alert_description_t (VARGS *qgnutls_alert_get)(gnutls_session_t session);
static const char *(VARGS *qgnutls_alert_get_name)(gnutls_alert_description_t alert);
static int (VARGS *qgnutls_handshake)(gnutls_session_t session);
static void (VARGS *qgnutls_transport_set_ptr)(gnutls_session_t session, gnutls_transport_ptr_t ptr);
static void (VARGS *qgnutls_transport_set_push_function)(gnutls_session_t session, gnutls_push_func push_func);
static void (VARGS *qgnutls_transport_set_pull_function)(gnutls_session_t session, gnutls_pull_func pull_func);
static void (VARGS *qgnutls_transport_set_errno)(gnutls_session_t session, int err);
static int (VARGS *qgnutls_error_is_fatal)(int error);
static int (VARGS *qgnutls_credentials_set)(gnutls_session_t, gnutls_credentials_type_t type, void* cred);
//static int (VARGS *qgnutls_kx_set_priority)(gnutls_session_t session, const int*);
static int (VARGS *qgnutls_init)(gnutls_session_t * session, gnutls_connection_end_t con_end);
static void (VARGS *qgnutls_deinit)(gnutls_session_t session);
static int (VARGS *qgnutls_set_default_priority)(gnutls_session_t session);
#ifdef HAVE_DTLS
static int (VARGS *qgnutls_set_default_priority_append)(gnutls_session_t session, const char *add_prio, const char **err_pos, unsigned flags);
#endif
static int (VARGS *qgnutls_certificate_allocate_credentials)(gnutls_certificate_credentials_t *sc);
static int (VARGS *qgnutls_anon_allocate_client_credentials)(gnutls_anon_client_credentials_t *sc);
static int (VARGS *qgnutls_global_init)(void);
static ssize_t (VARGS *qgnutls_record_send)(gnutls_session_t session, const void *data, size_t sizeofdata);
static ssize_t (VARGS *qgnutls_record_recv)(gnutls_session_t session, void *data, size_t sizeofdata);
static void (VARGS *qgnutls_certificate_set_verify_function)(gnutls_certificate_credentials_t cred, gnutls_certificate_verify_function *func);
static void *(VARGS *qgnutls_session_get_ptr)(gnutls_session_t session);
static void (VARGS *qgnutls_session_set_ptr)(gnutls_session_t session, void *ptr);
static int (VARGS *qgnutls_session_channel_binding)(gnutls_session_t session, gnutls_channel_binding_t cbtype, gnutls_datum_t * cb);
#ifdef GNUTLS_HAVE_SYSTEMTRUST
static int (VARGS *qgnutls_certificate_set_x509_system_trust)(gnutls_certificate_credentials_t cred);
#define GNUTLS_TRUSTFUNCS GNUTLS_FUNC(gnutls_certificate_set_x509_system_trust,int,(gnutls_certificate_credentials_t cred))
#else
static int (VARGS *qgnutls_certificate_set_x509_trust_file)(gnutls_certificate_credentials_t cred, const char * cafile, gnutls_x509_crt_fmt_t type);
#define GNUTLS_TRUSTFUNCS GNUTLS_FUNC(gnutls_certificate_set_x509_trust_file,void,(void))
#endif
static int (VARGS *qgnutls_certificate_set_x509_key_file)(gnutls_certificate_credentials_t res, const char * certfile, const char * keyfile, gnutls_x509_crt_fmt_t type);
#ifdef GNUTLS_HAVE_VERIFY3
static int (VARGS *qgnutls_certificate_verify_peers3)(gnutls_session_t session, const char* hostname, unsigned int * status);
static int (VARGS *qgnutls_certificate_verification_status_print)(unsigned int status, gnutls_certificate_type_t type, gnutls_datum_t * out, unsigned int flags);
#define GNUTLS_VERIFYFUNCS \
GNUTLS_FUNC(gnutls_certificate_verify_peers3,int,(gnutls_session_t session,const char *hostname,unsigned int *status)) \
GNUTLS_FUNC(gnutls_certificate_verification_status_print,int,(unsigned int status, gnutls_certificate_type_t type, gnutls_datum_t * out, unsigned int flags)) \
GNUTLS_FUNC(gnutls_certificate_type_get,gnutls_certificate_type_t,(gnutls_session_t session)) \
GNUTLS_FUNC(gnutls_certificate_get_peers,const gnutls_datum_t *,(gnutls_session_t session, unsigned int *list_size))
#else
static int (VARGS *qgnutls_certificate_verify_peers2)(gnutls_session_t session, unsigned int * status);
static int (VARGS *qgnutls_x509_crt_check_hostname)(gnutls_x509_crt_t cert, const char * hostname);
static int (VARGS *qgnutls_x509_crt_init)(gnutls_x509_crt_t * cert);
static int (VARGS *qgnutls_x509_crt_import)(gnutls_x509_crt_t cert, const gnutls_datum_t *data, gnutls_x509_crt_fmt_t format);
#define GNUTLS_VERIFYFUNCS \
GNUTLS_FUNC(gnutls_certificate_verify_peers2,int,(gnutls_session_t session, unsigned int *status)) \
GNUTLS_FUNC(gnutls_x509_crt_check_hostname,unsigned,(gnutls_x509_crt_t cert, const char *hostname)) \
GNUTLS_FUNC(gnutls_x509_crt_import,int,(gnutls_x509_crt_t cert, const gnutls_datum_t * data, gnutls_x509_crt_fmt_t format)) \
GNUTLS_FUNC(gnutls_certificate_get_peers,const gnutls_datum_t *,(gnutls_session_t session, unsigned int *list_size))
#endif
static const gnutls_datum_t *(VARGS *qgnutls_certificate_get_peers)(gnutls_session_t session, unsigned int * list_size);
static gnutls_certificate_type_t (VARGS *qgnutls_certificate_type_get)(gnutls_session_t session);
static void *(VARGS **qgnutls_malloc)(size_t);
static void (VARGS **qgnutls_free)(void * ptr);
static int (VARGS *qgnutls_server_name_set)(gnutls_session_t session, gnutls_server_name_type_t type, const void * name, size_t name_length);
#ifdef HAVE_DTLS
static int (VARGS *qgnutls_key_generate)(gnutls_datum_t * key, unsigned int key_size);
static void (VARGS *qgnutls_transport_set_pull_timeout_function)(gnutls_session_t session, gnutls_pull_timeout_func func);
static int (VARGS *qgnutls_dtls_cookie_verify)(gnutls_datum_t * key, void *client_data, size_t client_data_size, void *_msg, size_t msg_size, gnutls_dtls_prestate_st * prestate);
static int (VARGS *qgnutls_dtls_cookie_send)(gnutls_datum_t * key, void *client_data, size_t client_data_size, gnutls_dtls_prestate_st * prestate, gnutls_transport_ptr_t ptr, gnutls_push_func push_func);
static void (VARGS *qgnutls_dtls_prestate_set)(gnutls_session_t session, gnutls_dtls_prestate_st * prestate);
static void (VARGS *qgnutls_dtls_set_mtu)(gnutls_session_t session, unsigned int mtu);
static int (VARGS *qgnutls_psk_allocate_server_credentials)(gnutls_psk_server_credentials_t *sc);
static void (VARGS *qgnutls_psk_set_server_credentials_function)(gnutls_psk_server_credentials_t cred, gnutls_psk_server_credentials_function *func);
static int (VARGS *qgnutls_psk_set_server_credentials_hint)(gnutls_psk_server_credentials_t res, const char *hint);
static const char *(VARGS *qgnutls_psk_client_get_hint)(gnutls_session_t session);
static int (VARGS *qgnutls_psk_allocate_client_credentials)(gnutls_psk_client_credentials_t *sc);
static void (VARGS *qgnutls_psk_set_client_credentials_function)(gnutls_psk_client_credentials_t cred, gnutls_psk_client_credentials_function *func);
#define GNUTLS_DTLS_STUFF \
GNUTLS_FUNC(gnutls_key_generate,int,(gnutls_datum_t *key, unsigned int key_size)) \
GNUTLS_FUNC(gnutls_privkey_sign_hash,int,(gnutls_privkey_t signer, gnutls_digest_algorithm_t hash_algo, unsigned int flags, const gnutls_datum_t * hash_data, gnutls_datum_t * signature)) \
GNUTLS_FUNC(gnutls_certificate_get_x509_key,int,(gnutls_certificate_credentials_t res, unsigned index, gnutls_x509_privkey_t *key)) \
GNUTLS_FUNC(gnutls_transport_set_pull_timeout_function,void,(gnutls_session_t session, gnutls_pull_timeout_func func)) \
GNUTLS_FUNC(gnutls_dtls_cookie_verify,int,(gnutls_datum_t *key, void *client_data, size_t client_data_size, void *_msg, size_t msg_size, gnutls_dtls_prestate_st *prestate)) \
GNUTLS_FUNC(gnutls_dtls_cookie_send,int,(gnutls_datum_t *key, void *client_data, size_t client_data_size, gnutls_dtls_prestate_st *prestate, gnutls_transport_ptr_t ptr, gnutls_push_func push_func)) \
GNUTLS_FUNC(gnutls_dtls_prestate_set,void,(gnutls_session_t session, gnutls_dtls_prestate_st *prestate)) \
GNUTLS_FUNC(gnutls_dtls_set_mtu,void,(gnutls_session_t session, unsigned int mtu)) \
GNUTLS_FUNC(gnutls_psk_allocate_server_credentials,int,(gnutls_psk_server_credentials_t *sc)) \
GNUTLS_FUNC(gnutls_psk_set_server_credentials_function,void,(gnutls_psk_server_credentials_t cred, gnutls_psk_server_credentials_function *func)) \
GNUTLS_FUNC(gnutls_psk_set_server_credentials_hint,int,(gnutls_psk_server_credentials_t res, const char *hint)) \
GNUTLS_FUNC(gnutls_psk_allocate_client_credentials,int,(gnutls_psk_client_credentials_t *sc)) \
GNUTLS_FUNC(gnutls_psk_set_client_credentials_function,void,(gnutls_psk_client_credentials_t cred, gnutls_psk_client_credentials_function *func)) \
GNUTLS_FUNC(gnutls_psk_client_get_hint,const char *,(gnutls_session_t session))
#else
#define GNUTLS_DTLS_STUFF
#endif
static unsigned int (VARGS *qgnutls_sec_param_to_pk_bits)(gnutls_pk_algorithm_t algo, gnutls_sec_param_t param);
static int (VARGS *qgnutls_x509_crt_init)(gnutls_x509_crt_t * cert);
static void (VARGS *qgnutls_x509_crt_deinit)(gnutls_x509_crt_t cert);
static int (VARGS *qgnutls_x509_crt_set_version)(gnutls_x509_crt_t crt, unsigned int version);
static int (VARGS *qgnutls_x509_crt_set_activation_time)(gnutls_x509_crt_t cert, time_t act_time);
static int (VARGS *qgnutls_x509_crt_set_expiration_time)(gnutls_x509_crt_t cert, time_t exp_time);
static int (VARGS *qgnutls_x509_crt_set_serial)(gnutls_x509_crt_t cert, const void *serial, size_t serial_size);
static int (VARGS *qgnutls_x509_crt_set_dn)(gnutls_x509_crt_t crt, const char *dn, const char **err);
static int (VARGS *qgnutls_x509_crt_set_issuer_dn)(gnutls_x509_crt_t crt, const char *dn, const char **err);
static int (VARGS *qgnutls_x509_crt_set_key)(gnutls_x509_crt_t crt, gnutls_x509_privkey_t key);
static int (VARGS *qgnutls_x509_crt_export2)(gnutls_x509_crt_t cert, gnutls_x509_crt_fmt_t format, gnutls_datum_t * out);
static int (VARGS *qgnutls_x509_crt_import)(gnutls_x509_crt_t cert, const gnutls_datum_t *data, gnutls_x509_crt_fmt_t format);
static int (VARGS *qgnutls_x509_privkey_init)(gnutls_x509_privkey_t * key);
static void (VARGS *qgnutls_x509_privkey_deinit)(gnutls_x509_privkey_t key);
static int (VARGS *qgnutls_x509_privkey_generate)(gnutls_x509_privkey_t key, gnutls_pk_algorithm_t algo, unsigned int bits, unsigned int flags);
static int (VARGS *qgnutls_x509_privkey_export2)(gnutls_x509_privkey_t key, gnutls_x509_crt_fmt_t format, gnutls_datum_t * out);
static int (VARGS *qgnutls_x509_crt_privkey_sign)(gnutls_x509_crt_t crt, gnutls_x509_crt_t issuer, gnutls_privkey_t issuer_key, gnutls_digest_algorithm_t dig, unsigned int flags);
static int (VARGS *qgnutls_privkey_init)(gnutls_privkey_t * key);
static void (VARGS *qgnutls_privkey_deinit)(gnutls_privkey_t key);
static int (VARGS *qgnutls_privkey_import_x509)(gnutls_privkey_t pkey, gnutls_x509_privkey_t key, unsigned int flags);
//static int (VARGS *qgnutls_privkey_sign_hash2)(gnutls_privkey_t signer, gnutls_sign_algorithm_t algo, unsigned int flags, const gnutls_datum_t * hash_data, gnutls_datum_t * signature);
static int (VARGS *qgnutls_privkey_sign_hash)(gnutls_privkey_t signer, gnutls_digest_algorithm_t hash_algo, unsigned int flags, const gnutls_datum_t * hash_data, gnutls_datum_t * signature);
static int (VARGS *qgnutls_pubkey_init)(gnutls_pubkey_t * key);
static int (VARGS *qgnutls_pubkey_import_x509)(gnutls_pubkey_t key, gnutls_x509_crt_t crt, unsigned int flags);
static int (VARGS *qgnutls_pubkey_verify_hash2)(gnutls_pubkey_t key, gnutls_sign_algorithm_t algo, unsigned int flags, const gnutls_datum_t * hash, const gnutls_datum_t * signature);
static int (VARGS *qgnutls_certificate_set_x509_key_mem)(gnutls_certificate_credentials_t res, const gnutls_datum_t * cert, const gnutls_datum_t * key, gnutls_x509_crt_fmt_t type);
static int (VARGS *qgnutls_certificate_get_x509_key)(gnutls_certificate_credentials_t res, unsigned index, gnutls_x509_privkey_t *key);
static void (VARGS *qgnutls_certificate_free_credentials)(gnutls_certificate_credentials_t sc);
#define GNUTLS_X509_STUFF \
GNUTLS_FUNC(gnutls_sec_param_to_pk_bits,unsigned int,(gnutls_pk_algorithm_t algo, gnutls_sec_param_t param)) \
GNUTLS_FUNC(gnutls_x509_crt_init,int,(gnutls_x509_crt_t * cert)) \
GNUTLS_FUNC(gnutls_x509_crt_deinit,void,(gnutls_x509_crt_t cert)) \
GNUTLS_FUNC(gnutls_x509_crt_import,int,(gnutls_x509_crt_t cert, const gnutls_datum_t * data, gnutls_x509_crt_fmt_t format)) \
GNUTLS_FUNC(gnutls_x509_crt_set_version,int,(gnutls_x509_crt_t crt, unsigned int version)) \
GNUTLS_FUNC(gnutls_x509_crt_set_activation_time,int,(gnutls_x509_crt_t cert, time_t act_time)) \
GNUTLS_FUNC(gnutls_x509_crt_set_expiration_time,int,(gnutls_x509_crt_t cert, time_t exp_time)) \
GNUTLS_FUNC(gnutls_x509_crt_set_serial,int,(gnutls_x509_crt_t cert, const void *serial, size_t serial_size)) \
GNUTLS_FUNC(gnutls_x509_crt_set_dn,int,(gnutls_x509_crt_t crt, const char *dn, const char **err)) \
GNUTLS_FUNC(gnutls_x509_crt_set_issuer_dn,int,(gnutls_x509_crt_t crt,const char *dn, const char **err)) \
GNUTLS_FUNC(gnutls_x509_crt_set_key,int,(gnutls_x509_crt_t crt, gnutls_x509_privkey_t key)) \
GNUTLS_FUNC(gnutls_x509_crt_export2,int,(gnutls_x509_crt_t cert, gnutls_x509_crt_fmt_t format, gnutls_datum_t * out)) \
GNUTLS_FUNC(gnutls_x509_privkey_init,int,(gnutls_x509_privkey_t * key)) \
GNUTLS_FUNC(gnutls_x509_privkey_deinit,void,(gnutls_x509_privkey_t key)) \
GNUTLS_FUNC(gnutls_x509_privkey_generate,int,(gnutls_x509_privkey_t key, gnutls_pk_algorithm_t algo, unsigned int bits, unsigned int flags)) \
GNUTLS_FUNC(gnutls_x509_privkey_export2,int,(gnutls_x509_privkey_t key, gnutls_x509_crt_fmt_t format, gnutls_datum_t * out)) \
GNUTLS_FUNC(gnutls_x509_crt_privkey_sign,int,(gnutls_x509_crt_t crt, gnutls_x509_crt_t issuer, gnutls_privkey_t issuer_key, gnutls_digest_algorithm_t dig, unsigned int flags)) \
GNUTLS_FUNC(gnutls_privkey_init,int,(gnutls_privkey_t * key)) \
GNUTLS_FUNC(gnutls_privkey_deinit,void,(gnutls_privkey_t key)) \
GNUTLS_FUNC(gnutls_privkey_import_x509,int,(gnutls_privkey_t pkey, gnutls_x509_privkey_t key, unsigned int flags)) \
GNUTLS_FUNC(gnutls_certificate_set_x509_key_mem,int,(gnutls_certificate_credentials_t res, const gnutls_datum_t * cert, const gnutls_datum_t * key, gnutls_x509_crt_fmt_t type)) \
GNUTLS_FUNC(gnutls_pubkey_init,int,(gnutls_pubkey_t * key)) \
GNUTLS_FUNC(gnutls_pubkey_deinit,void,(gnutls_pubkey_t key)) \
GNUTLS_FUNC(gnutls_pubkey_import_x509,int,(gnutls_pubkey_t key, gnutls_x509_crt_t crt, unsigned int flags)) \
GNUTLS_FUNC(gnutls_pubkey_verify_hash2,int,(gnutls_pubkey_t key, gnutls_sign_algorithm_t algo, unsigned int flags, const gnutls_datum_t * hash, const gnutls_datum_t * signature))
#define GNUTLS_FUNCS \
GNUTLS_FUNC(gnutls_bye,int,(gnutls_session_t session, gnutls_close_request_t how)) \
GNUTLS_FUNC(gnutls_alert_get,gnutls_alert_description_t,(gnutls_session_t session)) \
GNUTLS_FUNC(gnutls_alert_get_name,const char *,(gnutls_alert_description_t alert)) \
GNUTLS_FUNC(gnutls_perror,void,(int error)) \
GNUTLS_FUNC(gnutls_handshake,int,(gnutls_session_t session)) \
GNUTLS_FUNC(gnutls_transport_set_ptr,void,(gnutls_session_t session, gnutls_transport_ptr_t ptr)) \
GNUTLS_FUNC(gnutls_transport_set_push_function,void,(gnutls_session_t session, gnutls_push_func push_func)) \
GNUTLS_FUNC(gnutls_transport_set_pull_function,void,(gnutls_session_t session, gnutls_pull_func pull_func)) \
GNUTLS_FUNC(gnutls_transport_set_errno,void,(gnutls_session_t session, int err)) \
GNUTLS_FUNC(gnutls_error_is_fatal,int,(int error)) \
GNUTLS_FUNC(gnutls_credentials_set,int,(gnutls_session_t, gnutls_credentials_type_t type, void* cred)) \
GNUTLS_FUNC(gnutls_init,int,(gnutls_session_t * session, gnutls_connection_end_t con_end)) \
GNUTLS_FUNC(gnutls_deinit,void,(gnutls_session_t session)) \
GNUTLS_FUNC(gnutls_set_default_priority,int,(gnutls_session_t session)) \
GNUTLS_FUNC(gnutls_certificate_allocate_credentials,int,(gnutls_certificate_credentials_t *sc)) \
GNUTLS_FUNC(gnutls_certificate_free_credentials,void,(gnutls_certificate_credentials_t sc)) \
GNUTLS_FUNC(gnutls_session_channel_binding,int,(gnutls_session_t session, gnutls_channel_binding_t cbtype, gnutls_datum_t * cb)) \
GNUTLS_FUNC(gnutls_global_init,int,(void)) \
GNUTLS_FUNC(gnutls_global_deinit,void,(void)) \
GNUTLS_FUNC(gnutls_record_send,ssize_t,(gnutls_session_t session, const void *data, size_t sizeofdata)) \
GNUTLS_FUNC(gnutls_record_recv,ssize_t,(gnutls_session_t session, void *data, size_t sizeofdata)) \
GNUTLS_FUNC(gnutls_certificate_set_verify_function,void,(gnutls_certificate_credentials_t cred, gnutls_certificate_verify_function *func)) \
GNUTLS_FUNC(gnutls_session_get_ptr,void*,(gnutls_session_t session)) \
GNUTLS_FUNC(gnutls_session_set_ptr,void,(gnutls_session_t session, void *ptr)) \
GNUTLS_FUNCPTR(gnutls_malloc,void*,(size_t)) \
GNUTLS_FUNCPTR(gnutls_free,void,(void * ptr)) \
GNUTLS_FUNC(gnutls_server_name_set,int,(gnutls_session_t session, gnutls_server_name_type_t type, const void * name, size_t name_length)) \
GNUTLS_TRUSTFUNCS \
GNUTLS_VERIFYFUNCS \
GNUTLS_DTLS_STUFF \
GNUTLS_X509_STUFF
#ifdef GNUTLS_DYNAMIC
#define GNUTLS_FUNC(n,ret,args) static ret (VARGS *q##n)args;
#define GNUTLS_FUNCPTR(n,ret,args) static ret (VARGS **q##n)args;
#else
#define GNUTLS_FUNC(n,ret,args) static ret (VARGS *q##n)args = n;
#define GNUTLS_FUNCPTR(n,ret,args) static ret (VARGS **q##n)args = &n;
#endif
#ifdef HAVE_DTLS
GNUTLS_FUNC(gnutls_set_default_priority_append,int,(gnutls_session_t session, const char *add_prio, const char **err_pos, unsigned flags))
#endif
GNUTLS_FUNCS
#undef GNUTLS_FUNC
#undef GNUTLS_FUNCPTR
#if defined(GNUTLS_DYNAMIC) && defined(HAVE_DTLS)
static int VARGS fallback_gnutls_set_default_priority_append(gnutls_session_t session, const char *add_prio, const char **err_pos, unsigned flags)
@ -241,226 +266,45 @@ static int VARGS fallback_gnutls_set_default_priority_append(gnutls_session_t se
}
#endif
static qboolean Init_GNUTLS(void)
static struct
{
#ifdef GNUTLS_HAVE_SYSTEMTRUST
#define GNUTLS_TRUSTFUNCS GNUTLS_FUNC(gnutls_certificate_set_x509_system_trust)
#else
#define GNUTLS_TRUSTFUNCS GNUTLS_FUNC(gnutls_certificate_set_x509_trust_file)
#endif
#ifdef GNUTLS_HAVE_VERIFY3
#define GNUTLS_VERIFYFUNCS \
GNUTLS_FUNC(gnutls_certificate_verify_peers3) \
GNUTLS_FUNC(gnutls_certificate_verification_status_print) \
GNUTLS_FUNC(gnutls_certificate_get_peers)
#else
#define GNUTLS_VERIFYFUNCS \
GNUTLS_FUNC(gnutls_certificate_verify_peers2) \
GNUTLS_FUNC(gnutls_x509_crt_check_hostname) \
GNUTLS_FUNC(gnutls_x509_crt_init) \
GNUTLS_FUNC(gnutls_x509_crt_import) \
GNUTLS_FUNC(gnutls_certificate_get_peers)
#endif
#ifdef HAVE_DTLS
#define GNUTLS_DTLS_STUFF \
GNUTLS_FUNC(gnutls_key_generate) \
GNUTLS_FUNC(gnutls_transport_set_pull_timeout_function) \
GNUTLS_FUNC(gnutls_dtls_cookie_verify) \
GNUTLS_FUNC(gnutls_dtls_cookie_send) \
GNUTLS_FUNC(gnutls_dtls_prestate_set) \
GNUTLS_FUNC(gnutls_dtls_set_mtu) \
GNUTLS_FUNC(gnutls_psk_allocate_server_credentials) \
GNUTLS_FUNC(gnutls_psk_set_server_credentials_function) \
GNUTLS_FUNC(gnutls_psk_set_server_credentials_hint) \
GNUTLS_FUNC(gnutls_psk_allocate_client_credentials) \
GNUTLS_FUNC(gnutls_psk_set_client_credentials_function)
#else
#define GNUTLS_DTLS_STUFF
#endif
#define GNUTLS_X509_STUFF \
GNUTLS_FUNC(gnutls_sec_param_to_pk_bits) \
GNUTLS_FUNC(gnutls_x509_crt_init) \
GNUTLS_FUNC(gnutls_x509_crt_deinit) \
GNUTLS_FUNC(gnutls_x509_crt_set_version) \
GNUTLS_FUNC(gnutls_x509_crt_set_activation_time) \
GNUTLS_FUNC(gnutls_x509_crt_set_expiration_time) \
GNUTLS_FUNC(gnutls_x509_crt_set_serial) \
GNUTLS_FUNC(gnutls_x509_crt_set_dn) \
GNUTLS_FUNC(gnutls_x509_crt_set_issuer_dn) \
GNUTLS_FUNC(gnutls_x509_crt_set_key) \
GNUTLS_FUNC(gnutls_x509_crt_export2) \
GNUTLS_FUNC(gnutls_x509_privkey_init) \
GNUTLS_FUNC(gnutls_x509_privkey_deinit) \
GNUTLS_FUNC(gnutls_x509_privkey_generate) \
GNUTLS_FUNC(gnutls_x509_privkey_export2) \
GNUTLS_FUNC(gnutls_x509_crt_privkey_sign) \
GNUTLS_FUNC(gnutls_privkey_init) \
GNUTLS_FUNC(gnutls_privkey_deinit) \
GNUTLS_FUNC(gnutls_privkey_import_x509) \
GNUTLS_FUNC(gnutls_certificate_set_x509_key_mem)
#define GNUTLS_FUNCS \
GNUTLS_FUNC(gnutls_bye) \
GNUTLS_FUNC(gnutls_alert_get) \
GNUTLS_FUNC(gnutls_alert_get_name) \
GNUTLS_FUNC(gnutls_perror) \
GNUTLS_FUNC(gnutls_handshake) \
GNUTLS_FUNC(gnutls_transport_set_ptr) \
GNUTLS_FUNC(gnutls_transport_set_push_function) \
GNUTLS_FUNC(gnutls_transport_set_pull_function) \
GNUTLS_FUNC(gnutls_transport_set_errno) \
GNUTLS_FUNC(gnutls_error_is_fatal) \
GNUTLS_FUNC(gnutls_credentials_set) \
GNUTLS_FUNC(gnutls_init) \
GNUTLS_FUNC(gnutls_deinit) \
GNUTLS_FUNC(gnutls_set_default_priority) \
GNUTLS_FUNC(gnutls_certificate_allocate_credentials) \
GNUTLS_FUNC(gnutls_anon_allocate_client_credentials) \
GNUTLS_FUNC(gnutls_global_init) \
GNUTLS_FUNC(gnutls_record_send) \
GNUTLS_FUNC(gnutls_record_recv) \
GNUTLS_FUNC(gnutls_certificate_set_verify_function) \
GNUTLS_FUNC(gnutls_session_get_ptr) \
GNUTLS_FUNC(gnutls_session_set_ptr) \
GNUTLS_TRUSTFUNCS \
GNUTLS_FUNC(gnutls_certificate_set_x509_key_file) \
GNUTLS_VERIFYFUNCS \
GNUTLS_FUNC(gnutls_certificate_type_get) \
GNUTLS_FUNCPTR(gnutls_malloc) \
GNUTLS_FUNCPTR(gnutls_free) \
GNUTLS_FUNC(gnutls_server_name_set) \
GNUTLS_DTLS_STUFF \
GNUTLS_X509_STUFF
#ifdef GNUTLS_DYNAMIC
dllhandle_t *hmod;
#endif
int initstatus[2];
} gnutls;
static qboolean Init_GNUTLS(void)
{
#ifdef GNUTLS_DYNAMIC
dllfunction_t functable[] =
{
//#define GNUTLS_FUNC(nam) {(void**)&q##nam, #nam},
// GNUTLS_FUNCS
//#undef GNUTLS_FUNC
{(void**)&qgnutls_bye, "gnutls_bye"},
{(void**)&qgnutls_perror, "gnutls_perror"},
{(void**)&qgnutls_alert_get, "gnutls_alert_get"},
{(void**)&qgnutls_alert_get_name, "gnutls_alert_get_name"},
{(void**)&qgnutls_handshake, "gnutls_handshake"},
{(void**)&qgnutls_transport_set_ptr, "gnutls_transport_set_ptr"},
{(void**)&qgnutls_transport_set_push_function, "gnutls_transport_set_push_function"},
{(void**)&qgnutls_transport_set_pull_function, "gnutls_transport_set_pull_function"},
{(void**)&qgnutls_transport_set_errno, "gnutls_transport_set_errno"},
{(void**)&qgnutls_error_is_fatal, "gnutls_error_is_fatal"},
{(void**)&qgnutls_credentials_set, "gnutls_credentials_set"},
// {(void**)&qgnutls_kx_set_priority, "gnutls_kx_set_priority"},
{(void**)&qgnutls_init, "gnutls_init"},
{(void**)&qgnutls_deinit, "gnutls_deinit"},
{(void**)&qgnutls_set_default_priority, "gnutls_set_default_priority"},
{(void**)&qgnutls_certificate_allocate_credentials, "gnutls_certificate_allocate_credentials"},
{(void**)&qgnutls_anon_allocate_client_credentials, "gnutls_anon_allocate_client_credentials"},
{(void**)&qgnutls_global_init, "gnutls_global_init"},
{(void**)&qgnutls_record_send, "gnutls_record_send"},
{(void**)&qgnutls_record_recv, "gnutls_record_recv"},
{(void**)&qgnutls_certificate_set_verify_function, "gnutls_certificate_set_verify_function"},
{(void**)&qgnutls_session_get_ptr, "gnutls_session_get_ptr"},
{(void**)&qgnutls_session_set_ptr, "gnutls_session_set_ptr"},
{(void**)&qgnutls_session_channel_binding, "gnutls_session_channel_binding"},
#ifdef GNUTLS_HAVE_SYSTEMTRUST
{(void**)&qgnutls_certificate_set_x509_system_trust, "gnutls_certificate_set_x509_system_trust"},
#else
{(void**)&qgnutls_certificate_set_x509_trust_file, "gnutls_certificate_set_x509_trust_file"},
#endif
{(void**)&qgnutls_certificate_set_x509_key_file, "gnutls_certificate_set_x509_key_file"},
#ifdef GNUTLS_HAVE_VERIFY3
{(void**)&qgnutls_certificate_verify_peers3, "gnutls_certificate_verify_peers3"},
{(void**)&qgnutls_certificate_verification_status_print, "gnutls_certificate_verification_status_print"},
#else
{(void**)&qgnutls_certificate_verify_peers2, "gnutls_certificate_verify_peers2"},
{(void**)&qgnutls_x509_crt_init, "gnutls_x509_crt_init"},
{(void**)&qgnutls_x509_crt_import, "gnutls_x509_crt_import"},
{(void**)&qgnutls_x509_crt_check_hostname, "gnutls_x509_crt_check_hostname"},
#endif
{(void**)&qgnutls_certificate_get_peers, "gnutls_certificate_get_peers"},
{(void**)&qgnutls_certificate_type_get, "gnutls_certificate_type_get"},
{(void**)&qgnutls_malloc, "gnutls_malloc"},
{(void**)&qgnutls_free, "gnutls_free"},
{(void**)&qgnutls_server_name_set, "gnutls_server_name_set"},
#ifdef HAVE_DTLS
{(void**)&qgnutls_key_generate, "gnutls_key_generate"},
{(void**)&qgnutls_transport_set_pull_timeout_function, "gnutls_transport_set_pull_timeout_function"},
{(void**)&qgnutls_dtls_cookie_verify, "gnutls_dtls_cookie_verify"},
{(void**)&qgnutls_dtls_cookie_send, "gnutls_dtls_cookie_send"},
{(void**)&qgnutls_dtls_prestate_set, "gnutls_dtls_prestate_set"},
{(void**)&qgnutls_dtls_set_mtu, "gnutls_dtls_set_mtu"},
{(void**)&qgnutls_psk_allocate_server_credentials, "gnutls_psk_allocate_server_credentials"},
{(void**)&qgnutls_psk_set_server_credentials_function, "gnutls_psk_set_server_credentials_function"},
{(void**)&qgnutls_psk_set_server_credentials_hint, "gnutls_psk_set_server_credentials_hint"},
{(void**)&qgnutls_psk_client_get_hint, "gnutls_psk_client_get_hint"},
{(void**)&qgnutls_psk_allocate_client_credentials, "gnutls_psk_allocate_client_credentials"},
{(void**)&qgnutls_psk_set_client_credentials_function, "gnutls_psk_set_client_credentials_function"},
#endif
{(void**)&qgnutls_sec_param_to_pk_bits, "gnutls_sec_param_to_pk_bits"},
{(void**)&qgnutls_x509_crt_init, "gnutls_x509_crt_init"},
{(void**)&qgnutls_x509_crt_deinit, "gnutls_x509_crt_deinit"},
{(void**)&qgnutls_x509_crt_set_version, "gnutls_x509_crt_set_version"},
{(void**)&qgnutls_x509_crt_set_activation_time, "gnutls_x509_crt_set_activation_time"},
{(void**)&qgnutls_x509_crt_set_expiration_time, "gnutls_x509_crt_set_expiration_time"},
{(void**)&qgnutls_x509_crt_set_serial, "gnutls_x509_crt_set_serial"},
{(void**)&qgnutls_x509_crt_set_dn, "gnutls_x509_crt_set_dn"},
{(void**)&qgnutls_x509_crt_set_issuer_dn, "gnutls_x509_crt_set_issuer_dn"},
{(void**)&qgnutls_x509_crt_set_key, "gnutls_x509_crt_set_key"},
{(void**)&qgnutls_x509_crt_export2, "gnutls_x509_crt_export2"},
{(void**)&qgnutls_x509_privkey_init, "gnutls_x509_privkey_init"},
{(void**)&qgnutls_x509_privkey_deinit, "gnutls_x509_privkey_deinit"},
{(void**)&qgnutls_x509_privkey_generate, "gnutls_x509_privkey_generate"},
{(void**)&qgnutls_x509_privkey_export2, "gnutls_x509_privkey_export2"},
{(void**)&qgnutls_x509_crt_privkey_sign, "gnutls_x509_crt_privkey_sign"},
{(void**)&qgnutls_privkey_init, "gnutls_privkey_init"},
{(void**)&qgnutls_privkey_deinit, "gnutls_privkey_deinit"},
{(void**)&qgnutls_privkey_import_x509, "gnutls_privkey_import_x509"},
{(void**)&qgnutls_certificate_set_x509_key_mem, "gnutls_certificate_set_x509_key_mem"},
{(void**)&qgnutls_certificate_get_x509_key, "gnutls_certificate_get_x509_key"},
{(void**)&qgnutls_certificate_free_credentials, "gnutls_certificate_free_credentials"},
{(void**)&qgnutls_pubkey_init, "gnutls_pubkey_init"},
{(void**)&qgnutls_pubkey_import_x509, "gnutls_pubkey_import_x509"},
{(void**)&qgnutls_privkey_sign_hash, "gnutls_privkey_sign_hash"},
{(void**)&qgnutls_pubkey_verify_hash2, "gnutls_pubkey_verify_hash2"},
{(void**)&qgnutls_x509_crt_import, "gnutls_x509_crt_import"},
#define GNUTLS_FUNC(nam,ret,args) {(void**)&q##nam, #nam},
#define GNUTLS_FUNCPTR(nam,ret,args) {(void**)&q##nam, #nam},
GNUTLS_FUNCS
#undef GNUTLS_FUNC
#undef GNUTLS_FUNCPTR
{NULL, NULL}
};
#ifdef GNUTLS_SONUM
#ifdef __CYGWIN__
hmod = Sys_LoadLibrary("cyggnutls"GNUTLS_SOPREFIX"-"STRINGIFY(GNUTLS_SONUM)".dll", functable);
gnutls.hmod = Sys_LoadLibrary("cyggnutls"GNUTLS_SOPREFIX"-"STRINGIFY(GNUTLS_SONUM)".dll", functable);
#else
hmod = Sys_LoadLibrary("libgnutls"GNUTLS_SOPREFIX".so."STRINGIFY(GNUTLS_SONUM), functable);
gnutls.hmod = Sys_LoadLibrary("libgnutls"GNUTLS_SOPREFIX".so."STRINGIFY(GNUTLS_SONUM), functable);
#endif
#else
hmod = Sys_LoadLibrary("libgnutls"GNUTLS_SOPREFIX".so", functable); //hope and pray
gnutls.hmod = Sys_LoadLibrary("libgnutls"GNUTLS_SOPREFIX".so", functable); //hope and pray
#endif
if (!hmod)
if (!gnutls.hmod)
return false;
#ifdef HAVE_DTLS
qgnutls_set_default_priority_append = Sys_GetAddressForName(hmod, "gnutls_set_default_priority_append");
qgnutls_set_default_priority_append = Sys_GetAddressForName(gnutls.hmod, "gnutls_set_default_priority_append");
if (!qgnutls_set_default_priority_append)
qgnutls_set_default_priority_append = fallback_gnutls_set_default_priority_append;
#endif
#else
#define GNUTLS_FUNC(name) q##name = name;
#define GNUTLS_FUNCPTR(name) q##name = &name;
GNUTLS_FUNCS
#undef GNUTLS_FUNC
#undef GNUTLS_FUNCPTR
#endif
return true;
}
@ -567,6 +411,12 @@ static void SSL_Close(vfsfile_t *vfs)
qgnutls_deinit(file->session);
file->session = NULL;
}
if (file->certcred)
{
qgnutls_certificate_free_credentials(file->certcred);
file->certcred = NULL;
}
}
static qboolean QDECL SSL_CloseFile(vfsfile_t *vfs)
{
@ -1222,6 +1072,9 @@ static qboolean SSL_LoadPrivateCert(gnutls_certificate_credentials_t cred)
if (pub.size != VFS_READ(pubf, pub.data, pub.size))
pub.size = 0;
pub.data[pub.size] = 0;
VFS_CLOSE(privf);
VFS_CLOSE(pubf);
}
//FIXME: extend the expiration time if its old?
@ -1247,7 +1100,6 @@ static qboolean SSL_LoadPrivateCert(gnutls_certificate_credentials_t cred)
qboolean SSL_InitGlobal(qboolean isserver)
{
int err;
static int initstatus[2];
isserver = !!isserver;
if (COM_CheckParm("-notls"))
return false;
@ -1255,7 +1107,7 @@ qboolean SSL_InitGlobal(qboolean isserver)
if (com_resourcemutex)
Sys_LockMutex(com_resourcemutex);
#endif
if (!initstatus[isserver])
if (!gnutls.initstatus[isserver])
{
if (!Init_GNUTLS())
{
@ -1266,7 +1118,7 @@ qboolean SSL_InitGlobal(qboolean isserver)
Con_Printf("GnuTLS "GNUTLS_VERSION" library not available.\n");
return false;
}
initstatus[isserver] = true;
gnutls.initstatus[isserver] = true;
qgnutls_global_init ();
#ifdef HAVE_DTLS
@ -1309,7 +1161,7 @@ qboolean SSL_InitGlobal(qboolean isserver)
if (ret < 0)
{
Con_Printf(CON_ERROR"No certificate or key was found in %s and %s\n", certfile, keyfile);
initstatus[isserver] = -1;
gnutls.initstatus[isserver] = -1;
}
#endif
}
@ -1325,10 +1177,31 @@ qboolean SSL_InitGlobal(qboolean isserver)
#endif
}
if (initstatus[isserver] < 0)
if (gnutls.initstatus[isserver] < 0)
return false;
return true;
}
void GnuTLS_Shutdown(void)
{
int isserver;
for (isserver = 0; isserver < 2; isserver++)
if (gnutls.initstatus[isserver])
{
qgnutls_certificate_free_credentials(xcred[isserver]);
xcred[isserver] = NULL;
gnutls.initstatus[isserver] = false;
qgnutls_global_deinit(); //refcounted.
}
#ifdef GNUTLS_DYNAMIC
if (gnutls.hmod)
Sys_CloseLibrary(gnutls.hmod);
gnutls.hmod = NULL;
#endif
}
#ifdef HAVE_DTLS
static int GetPSKForUser(gnutls_session_t sess, const char *username, gnutls_datum_t * key)
{ //serverside. name must match what we expect (this isn't very secure), and we return the key we require for that user name.
@ -1506,6 +1379,7 @@ static int GNUTLS_GetChannelBinding(vfsfile_t *vf, qbyte *binddata, size_t *bind
}
//crypto: generates a signed blob
#ifdef HAVE_DTLS
static int GNUTLS_GenerateSignature(const qbyte *hashdata, size_t hashsize, qbyte *signdata, size_t signsizemax)
{
gnutls_datum_t hash = {(qbyte*)hashdata, hashsize};
@ -1535,6 +1409,9 @@ static int GNUTLS_GenerateSignature(const qbyte *hashdata, size_t hashsize, qbyt
memcpy(signdata, sign.data, sign.size);
return sign.size;
}
#else
#define GNUTLS_GenerateSignature NULL
#endif
//crypto: verifies a signed blob matches an authority's public cert. windows equivelent https://docs.microsoft.com/en-us/windows/win32/seccrypto/example-c-program-signing-a-hash-and-verifying-the-hash-signature
static enum hashvalidation_e GNUTLS_VerifyHash(const qbyte *hashdata, size_t hashsize, const qbyte *pubkeydata, size_t pubkeysize, const qbyte *signdata, size_t signsize)
@ -1563,6 +1440,8 @@ static enum hashvalidation_e GNUTLS_VerifyHash(const qbyte *hashdata, size_t has
#endif
r = qgnutls_pubkey_verify_hash2(pubkey, GNUTLS_SIGN_RSA_SHA512, 0, &hash, &sign);
qgnutls_x509_crt_deinit(cert);
qgnutls_pubkey_deinit(pubkey);
if (r < 0)
{
if (r == GNUTLS_E_PK_SIG_VERIFY_FAILED)
@ -1586,6 +1465,7 @@ static enum hashvalidation_e GNUTLS_VerifyHash(const qbyte *hashdata, size_t has
static void GNUDTLS_DestroyContext(void *ctx)
{
SSL_Close(ctx);
Z_Free(ctx);
}
static void *GNUDTLS_CreateContext(const dtlscred_t *credinfo, void *cbctx, neterr_t(*push)(void *cbctx, const qbyte *data, size_t datasize), qboolean isserver)
{
@ -1621,6 +1501,7 @@ static void *GNUDTLS_CreateContext(const dtlscred_t *credinfo, void *cbctx, nete
if (!SSL_InitConnection(newf, isserver, true))
{
SSL_Close(&newf->funcs);
Z_Free(newf);
return NULL;
}

View file

@ -9240,7 +9240,8 @@ void NET_Shutdown (void)
#ifdef HAVE_EPOLL
close(epoll_fd);
if (epoll_fd >= 0)
close(epoll_fd);
epoll_fd = -1;
stdin_epolling = false;
#endif

View file

@ -268,7 +268,7 @@ enum icemode_e
{
ICEM_RAW, //not actually interactive beyond a simple handshake.
ICEM_ICE, //rfc5245. meant to be able to holepunch, but not implemented properly yet.
ICEM_WEBRTC, //IP+UDP+ICE+DTLS+SCTP... no more layers? :o
ICEM_WEBRTC, //IP+UDP+((ICE/STUN/SDP)+(DTLS+SCTP))... no more layers? :o
};
enum icestate_e
{

View file

@ -190,6 +190,9 @@ static plugin_t *Plug_Load(const char *file)
return newplug;
}
if (COM_CheckParm("-noplugins"))
return NULL;
newplug = Z_Malloc(sizeof(plugin_t)+strlen(temp)+1);
newplug->name = (char*)(newplug+1);
strcpy(newplug->name, temp);

View file

@ -105,7 +105,7 @@ qboolean Sys_GetDesktopParameters(int *width, int *height, int *bpp, int *refres
#if defined(__GNUC__)
#define qatomic32_t qint32_t
#define FTE_Atomic32_Inc(ptr) __sync_add_and_fetch(ptr, 1) //returns the AFTER the operation.
#define FTE_Atomic32_Dec(ptr) __sync_add_and_fetch(ptr, 1) //returns the AFTER the operation.
#define FTE_Atomic32_Dec(ptr) __sync_add_and_fetch(ptr, -1) //returns the AFTER the operation.
#elif defined(_WIN32)
#define qatomic32_t long
#define FTE_Atomic32_Inc(ptr) _InterlockedIncrement(ptr)

View file

@ -872,7 +872,10 @@ qboolean R_ImportRTLights(const char *entlump, int importmode)
}
if (!importmode && !rerelease)
{
InfoBuf_Clear(&targets, true);
return false; //don't make it up from legacy ents.
}
for (entnum = 0; ;entnum++)
{
@ -1119,6 +1122,7 @@ qboolean R_ImportRTLights(const char *entlump, int importmode)
if (atoi(value))
{
okay = true;
InfoBuf_Clear(&targets, true);
return okay;
}
}

View file

@ -11880,7 +11880,7 @@ static BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs
{"log", PF_Logarithm, 0, 0, 0, 532, D("float(float v, optional float base)", "Determines the logarithm of the input value according to the specified base. This can be used to calculate how much something was shifted by.")},
{"soundupdate", PF_Fixme, 0, 0, 0, 0, D("float(entity e, float channel, string newsample, float volume, float attenuation, float pitchpct, float flags, float timeoffset)", "Changes the properties of the current sound being played on the given entity channel. newsample may be empty, and will be ignored in this case. timeoffset is relative to the current position (subtract the result of getsoundtime for absolute positions). Negative volume can be used to stop the sound. Return value is a fractional value based upon the number of audio devices that could be updated - test against TRUE rather than non-zero.")},
{"getsoundtime", PF_Ignore, 0, 0, 0, 533, D("float(entity e, float channel)", "Returns the current playback time of the sample on the given entity's channel. Beware CHAN_AUTO (in csqc, channels are not limited by network protocol).")},
{"getchannellevel", PF_Ignore, 0, 0, 0, 0, D("float(entity e, float channel)", "")},
{"getchannellevel", PF_Ignore, 0, 0, 0, 0, D("float(entity e, float channel)", "Reports how load the sound's sample is at its current offset.")},
{"soundlength", PF_Ignore, 0, 0, 0, 534, D("float(string sample)", "Provides a way to query the duration of a sound sample, allowing you to set up a timer to chain samples.")},
{"buf_loadfile", PF_buf_loadfile, 0, 0, 0, 535, D("float(string filename, strbuf bufhandle)", "Appends the named file into a string buffer (which must have been created in advance). The return value merely says whether the file was readable.")},
{"buf_writefile", PF_buf_writefile, 0, 0, 0, 536, D("float(filestream filehandle, strbuf bufhandle, optional float startpos, optional float numstrings)", "Writes the contents of a string buffer onto the end of the supplied filehandle (you must have already used fopen). Additional optional arguments permit you to constrain the writes to a subsection of the stringbuffer.")},

View file

@ -278,6 +278,10 @@ void SV_Shutdown (void)
Z_Free(lp);
}
#ifdef WEBCLIENT
HTTP_CL_Terminate();
#endif
#ifdef HEXEN2
T_FreeStrings();
#endif

View file

@ -54,13 +54,19 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "netinc.h"
#endif
#ifdef HAVE_GNUTLS
qboolean SSL_InitGlobal(qboolean isserver);
void GnuTLS_Shutdown(void);
#endif
// callbacks
void Sys_Linebuffer_Callback (struct cvar_s *var, char *oldvalue);
cvar_t sys_nostdout = CVAR("sys_nostdout","0");
cvar_t sys_extrasleep = CVAR("sys_extrasleep","0");
cvar_t sys_colorconsole = CVAR("sys_colorconsole", "1");
cvar_t sys_colorconsole = CVARD("sys_colorconsole", "1", "Parse colour escapes, with ansi colours on stdout.");
cvar_t sys_timestamps = CVARD("sys_timestamps", "0", "Show timesamps on stdout prints.");
cvar_t sys_linebuffer = CVARC("sys_linebuffer", "1", Sys_Linebuffer_Callback);
static qboolean stdin_ready;
@ -429,6 +435,7 @@ void Sys_Printf (char *fmt, ...)
conchar_t *e, *c;
conchar_t ctext[MAXPRINTMSG];
unsigned int codeflags, codepoint;
static qboolean wasnl = false;
e = COM_ParseFunString(CON_WHITEMASK, msg, ctext, sizeof(ctext), false);
for (c = ctext; c < e; )
{
@ -439,7 +446,17 @@ void Sys_Printf (char *fmt, ...)
if ((codeflags&CON_RICHFORECOLOUR) || (codepoint == '\n' && (codeflags&CON_NONCLEARBG)))
codeflags = CON_WHITEMASK; //make sure we don't get annoying backgrounds on other lines.
ApplyColour(codeflags);
if (wasnl && sys_timestamps.ival)
{
char buffer[64];
time_t unixtime = time(NULL);
strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S ", localtime(&unixtime));
for (w = 0; w < buffer[w]; w++)
putc(buffer[w], stdout);
}
w = codepoint;
wasnl = (w == '\n');
if (w >= 0xe000 && w < 0xe100)
{
/*not all quake chars are ascii compatible, so map those control chars to safe ones so we don't mess up anyone's xterm*/
@ -567,6 +584,12 @@ Sys_Quit
*/
void Sys_Quit (void)
{
#ifdef HAVE_SERVER
SV_Shutdown();
#endif
#ifdef HAVE_GNUTLS
GnuTLS_Shutdown();
#endif
if (!noconinput)
{
tcsetattr(STDIN_FILENO, TCSADRAIN, &orig);
@ -742,6 +765,7 @@ void Sys_Init (void)
Cvar_Register (&sys_extrasleep, "System configuration");
Cvar_Register (&sys_colorconsole, "System configuration");
Cvar_Register (&sys_timestamps, "System configuration");
Cvar_Register (&sys_linebuffer, "System configuration");
}
@ -830,9 +854,6 @@ static void Friendly_Crash_Handler(int sig, siginfo_t *info, void *vcontext)
}
#endif
#ifdef HAVE_GNUTLS
qboolean SSL_InitGlobal(qboolean isserver);
#endif
#ifdef SQL
#include "sv_sql.h"
#endif

View file

@ -264,14 +264,16 @@ static int OSSL_Verify_Peer(int preverify_ok, X509_STORE_CTX *x509_ctx)
qbyte *blob;
qbyte *end;
blobsize = i2d_X509(cert, NULL);
if (blobsize != knownsize)
return 0; //fail if the size doesn't match.
blob = alloca(blobsize);
end = blob;
i2d_X509(cert, &end);
if (memcmp(blob, knowndata, blobsize))
return 0;
return 1; //exact match to a known cert. yay. allow it.
if (blobsize == knownsize)
{ //sizes must match.
blob = alloca(blobsize);
end = blob;
i2d_X509(cert, &end);
if (!memcmp(blob, knowndata, blobsize))
preverify_ok = 1; //exact match to a known cert. yay. allow it.
}
plugfuncs->Free(knowndata);
return preverify_ok;
}
#ifdef HAVE_CLIENT
@ -1048,14 +1050,16 @@ static const dtlsfuncs_t *OSSL_InitServer(void)
static struct
{
qboolean inited;
qboolean init_success;
} ossl;
static qboolean OSSL_Init(void)
{
static qboolean inited;
static qboolean init_success;
if (inited)
return init_success;
inited = true;
if (ossl.inited)
return ossl.init_success;
ossl.inited = true;
#if 0//def LOADERTHREAD
Sys_LockMutex(com_resourcemutex);
if (inited) //now check again, just in case
@ -1084,7 +1088,7 @@ static qboolean OSSL_Init(void)
BIO_meth_set_create(biometh_vfs, OSSL_Bio_FCreate);
BIO_meth_set_destroy(biometh_vfs, OSSL_Bio_FDestroy);
BIO_meth_set_callback_ctrl(biometh_vfs, OSSL_Bio_FOtherCtrl);
init_success |= 1;
ossl.init_success |= 1;
}
biometh_dtls = BIO_meth_new(BIO_get_new_index()|BIO_TYPE_SOURCE_SINK|BIO_TYPE_DESCRIPTOR, "fte_dtls");
@ -1098,7 +1102,7 @@ static qboolean OSSL_Init(void)
BIO_meth_set_create(biometh_dtls, OSSL_Bio_DCreate);
BIO_meth_set_destroy(biometh_dtls, OSSL_Bio_DDestroy);
BIO_meth_set_callback_ctrl(biometh_dtls, OSSL_Bio_DOtherCtrl);
init_success |= 2;
ossl.init_success |= 2;
}
ossl_fte_certctx = SSL_get_ex_new_index(0, "ossl_fte_certctx", NULL, NULL, NULL);
@ -1106,7 +1110,7 @@ static qboolean OSSL_Init(void)
#if 0//def LOADERTHREAD
Sys_UnlockMutex(com_resourcemutex);
#endif
return init_success;
return ossl.init_success;
}
static enum hashvalidation_e OSSL_VerifyHash(const qbyte *hashdata, size_t hashsize, const qbyte *pubkeydata, size_t pubkeysize, const qbyte *signdata, size_t signsize)
@ -1151,12 +1155,32 @@ static ftecrypto_t crypto_openssl =
NULL,
};
static void OSSL_PluginShutdown(void)
{
ossl.inited = false;
ossl.init_success = false;
X509_free(vhost.servercert);
EVP_PKEY_free(vhost.privatekey);
BIO_meth_free(biometh_vfs);
BIO_meth_free(biometh_dtls);
}
static qboolean OSSL_PluginMayShutdown(void)
{
//the engine has a habit of holding on to handles without any refcounts, so don't allow it to die early.
return false;
}
qboolean Plug_Init(void)
{
fsfuncs = plugfuncs->GetEngineInterface(plugfsfuncs_name, sizeof(*fsfuncs));
netfuncs = plugfuncs->GetEngineInterface(plugnetfuncs_name, sizeof(*netfuncs));
if (!fsfuncs || !netfuncs)
return false;
plugfuncs->ExportFunction("Shutdown", OSSL_PluginShutdown);
plugfuncs->ExportFunction("MayUnload", OSSL_PluginMayShutdown);
pdtls_psk_hint = cvarfuncs->GetNVFDG("dtls_psk_hint", "", 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");