diff --git a/engine/Makefile b/engine/Makefile index 172822d29..93ccfbde1 100644 --- a/engine/Makefile +++ b/engine/Makefile @@ -1146,6 +1146,8 @@ ifeq ($(FTE_TARGET),bsd) MINGL_DIR=mingl_bsd endif ifneq (,$(findstring linux,$(FTE_TARGET))) + OGGVORBISLDFLAGS= + SV_DIR=sv_linux$(BITS) SV_EXE_NAME=../fteqw-sv$(BITS) SV_LDFLAGS= @@ -1163,7 +1165,7 @@ ifneq (,$(findstring linux,$(FTE_TARGET))) GL_EXE_NAME=../fteqw-gl$(BITS) GLCL_EXE_NAME=../fteqw-glcl$(BITS) GL_LDFLAGS=$(GLLDFLAGS) $(XLDFLAGS) $(OGGVORBISLDFLAGS) - GL_CFLAGS=$(GLCFLAGS) -I/usr/X11R6/include $(SPEEXCFLAGS) -DMULTITHREAD -DLIBVORBISFILE_STATIC -DDYNAMIC_LIBPNG -DDYNAMIC_LIBJPEG -DDYNAMIC_SDL + GL_CFLAGS=$(GLCFLAGS) -I/usr/X11R6/include $(SPEEXCFLAGS) -DMULTITHREAD -DDYNAMIC_LIBPNG -DDYNAMIC_LIBJPEG -DDYNAMIC_SDL GLB_DIR=gl_linux$(BITS) GLCL_DIR=glcl_linux$(BITS) @@ -1171,7 +1173,7 @@ ifneq (,$(findstring linux,$(FTE_TARGET))) VK_EXE_NAME=../fteqw-vk$(BITS) VKCL_EXE_NAME=../fteqw-vkcl$(BITS) VK_LDFLAGS=$(GLLDFLAGS) $(XLDFLAGS) $(OGGVORBISLDFLAGS) - VK_CFLAGS=$(VKCFLAGS) -I/usr/X11R6/include $(SPEEXCFLAGS) -DMULTITHREAD -DLIBVORBISFILE_STATIC -DDYNAMIC_LIBPNG -DDYNAMIC_LIBJPEG -DDYNAMIC_SDL + VK_CFLAGS=$(VKCFLAGS) -I/usr/X11R6/include $(SPEEXCFLAGS) -DMULTITHREAD -DDYNAMIC_LIBPNG -DDYNAMIC_LIBJPEG -DDYNAMIC_SDL VKB_DIR=vk_linux$(BITS) VKCL_DIR=vkcl_linux$(BITS) @@ -1960,6 +1962,7 @@ INSTALL ?= install INSTALL_PROGRAM ?= $(INSTALL) INSTALL_DATA ?= ${INSTALL} -m 644 install: sv-rel gl-rel mingl-rel qcc-rel - $(INSTALL_PROGRAM) $(RELEASE_DIR)/fteqw $(DESTDIR)$(bindir)/fteqw - $(INSTALL_PROGRAM) $(RELEASE_DIR)/fteqwsv $(DESTDIR)$(bindir)/fteqwsv + $(INSTALL_PROGRAM) $(RELEASE_DIR)/fteqw-gl $(DESTDIR)$(bindir)/fteqw-gl + $(INSTALL_PROGRAM) $(RELEASE_DIR)/fteqw-mingl $(DESTDIR)$(bindir)/fteqw-mingl + $(INSTALL_PROGRAM) $(RELEASE_DIR)/fteqw-sv $(DESTDIR)$(bindir)/fteqw-sv $(INSTALL_PROGRAM) $(RELEASE_DIR)/fteqcc $(DESTDIR)$(bindir)/fteqcc diff --git a/engine/client/image.c b/engine/client/image.c index 7308ed218..032092835 100644 --- a/engine/client/image.c +++ b/engine/client/image.c @@ -772,11 +772,11 @@ qboolean LibPNG_Init(void) {(void **) &qpng_set_gray_to_rgb, "png_set_gray_to_rgb"}, {(void **) &qpng_set_tRNS_to_alpha, "png_set_tRNS_to_alpha"}, {(void **) &qpng_get_valid, "png_get_valid"}, - #if PNG_LIBPNG_VER > 10400 +#if PNG_LIBPNG_VER > 10400 {(void **) &qpng_set_expand_gray_1_2_4_to_8, "png_set_expand_gray_1_2_4_to_8"}, - #else +#else {(void **) &qpng_set_gray_1_2_4_to_8, "png_set_gray_1_2_4_to_8"}, - #endif +#endif {(void **) &qpng_set_bgr, "png_set_bgr"}, {(void **) &qpng_set_filler, "png_set_filler"}, {(void **) &qpng_set_palette_to_rgb, "png_set_palette_to_rgb"}, @@ -810,18 +810,31 @@ qboolean LibPNG_Init(void) if (!LIBPNG_LOADED()) { - char *libname; + char *libnames[] = + { #ifdef _WIN32 - libname = va("libpng%i", PNG_LIBPNG_VER_DLLNUM); + va("libpng%i", PNG_LIBPNG_VER_DLLNUM); #else - if (PNG_LIBPNG_VER_SONUM == 0) - libname = "libpng.so"; - else - libname = va("libpng.so.%i", PNG_LIBPNG_VER_SONUM); + //linux... + //lsb uses 'libpng12.so' specifically, so make sure that works. + "libpng" STRINGIFY(PNG_LIBPNG_VER_MAJOR) STRINGIFY(PNG_LIBPNG_VER_MINOR) ".so." STRINGIFY(PNG_LIBPNG_VER_SONUM), + "libpng" STRINGIFY(PNG_LIBPNG_VER_MAJOR) STRINGIFY(PNG_LIBPNG_VER_MINOR) ".so", + "libpng.so." STRINGIFY(PNG_LIBPNG_VER_SONUM) + "libpng.so", #endif - libpng_handle = Sys_LoadLibrary(libname, pngfuncs); + }; + size_t i; + for (i = 0; i < countof(libnames); i++) + { + if (libnames[i]) + { + libpng_handle = Sys_LoadLibrary(libnames[i], pngfuncs); + if (libpng_handle) + break; + } + } if (!libpng_handle) - Con_Printf("Unable to load %s\n", libname); + Con_Printf("Unable to load %s\n", libnames[0]); } // if (!LIBPNG_LOADED()) @@ -881,8 +894,8 @@ qbyte *ReadPNGFile(qbyte *buf, int length, int *width, int *height, const char * png_uint_32 pngwidth, pngheight; struct pngerr errctx; - if (!LibPNG_Init()) - return NULL; + if (!LibPNG_Init()) + return NULL; memcpy(header, buf, 8); diff --git a/engine/client/in_generic.c b/engine/client/in_generic.c index 51d13edad..25c751aff 100644 --- a/engine/client/in_generic.c +++ b/engine/client/in_generic.c @@ -421,6 +421,11 @@ void IN_Commands(void) case IEV_JOYAXIS: if (ev->devid < MAXJOYSTICKS && ev->joy.axis < MAXJOYAXIS) { +#ifdef MENU_DAT + if (MP_JoystickAxis(ev->joy.axis, ev->joy.value, ev->devid)) + joy[ev->devid].axis[ev->joy.axis] = 0; + else +#endif #ifdef CSQC_DAT if (CSQC_JoystickAxis(ev->joy.axis, ev->joy.value, ev->devid)) joy[ev->devid].axis[ev->joy.axis] = 0; @@ -659,23 +664,43 @@ void IN_MoveMouse(struct mouse_s *mouse, float *movements, int pnum, float frame strafe_y = !((in_mlook.state[pnum] & 1) && !(in_strafe.state[pnum] & 1)); } -#ifdef PEXT_CSQC if (mouse->type == M_TOUCH) { +#ifdef MENU_DAT + if (!runningindepphys && MP_MousePosition(mouse->oldpos[0], mouse->oldpos[1], mouse->qdeviceid)) + { + mx = 0; + my = 0; + } +#endif +#ifdef PEXT_CSQC if (!runningindepphys && CSQC_MousePosition(mouse->oldpos[0], mouse->oldpos[1], mouse->qdeviceid)) { mx = 0; my = 0; } +#endif } else { +#ifdef MENU_DAT + if (Key_Dest_Has(kdm_gmenu)) + if (mx || my) + if (!runningindepphys && MP_MouseMove(mx, my, mouse->qdeviceid)) + { + mx = 0; + my = 0; + } +#endif + +#ifdef PEXT_CSQC if (mx || my) if (!runningindepphys && CSQC_MouseMove(mx, my, mouse->qdeviceid)) { mx = 0; my = 0; } +#endif //if game is not focused, kill any mouse look if (Key_Dest_Has(~kdm_game)) @@ -684,7 +709,6 @@ void IN_MoveMouse(struct mouse_s *mouse, float *movements, int pnum, float frame my = 0; } } -#endif if (m_filter.value) { diff --git a/engine/client/keys.c b/engine/client/keys.c index 8c13f9480..d58bf091a 100644 --- a/engine/client/keys.c +++ b/engine/client/keys.c @@ -2421,7 +2421,7 @@ void Key_Event (unsigned int devid, int key, unsigned int unicode, qboolean down { #ifdef MENU_DAT if (Key_Dest_Has(kdm_gmenu) && !Key_Dest_Has(kdm_editor|kdm_console|kdm_cwindows)) - MP_Keyup (key, unicode); + MP_Keyup (key, unicode, devid); #endif return; } @@ -2447,7 +2447,7 @@ void Key_Event (unsigned int devid, int key, unsigned int unicode, qboolean down M_Keydown (key, unicode); #ifdef MENU_DAT else if (Key_Dest_Has(kdm_gmenu)) - MP_Keydown (key, unicode); + MP_Keydown (key, unicode, devid); #endif else if (Key_Dest_Has(kdm_message)) Key_Dest_Remove(kdm_message); @@ -2492,7 +2492,7 @@ void Key_Event (unsigned int devid, int key, unsigned int unicode, qboolean down M_Keyup (key, unicode); #ifdef MENU_DAT if (Key_Dest_Has(kdm_gmenu)) - MP_Keyup (key, unicode); + MP_Keyup (key, unicode, devid); #endif #ifndef NOMEDIA if (Media_PlayingFullScreen()) @@ -2583,8 +2583,8 @@ void Key_Event (unsigned int devid, int key, unsigned int unicode, qboolean down #ifdef MENU_DAT if (Key_Dest_Has(kdm_gmenu)) { - MP_Keydown (key, unicode); - return; + if (MP_Keydown (key, unicode, devid)) + return; } #endif if (Key_Dest_Has(kdm_message)) diff --git a/engine/client/menu.h b/engine/client/menu.h index 1f299a148..56ec77f15 100644 --- a/engine/client/menu.h +++ b/engine/client/menu.h @@ -468,8 +468,11 @@ void MP_Shutdown (void); qboolean MP_Toggle(int mode); void MP_Draw(void); void MP_RegisterCvarsAndCmds(void); -void MP_Keydown(int key, int unicode); -void MP_Keyup(int key, int unicode); +qboolean MP_Keydown(int key, int unicode, unsigned int devid); +void MP_Keyup(int key, int unicode, unsigned int devid); +qboolean MP_MouseMove(float x, float y, unsigned int devid); +qboolean MP_MousePosition(float x, float y, unsigned int devid); +qboolean MP_JoystickAxis(int axis, float value, unsigned int devid); int MP_BuiltinValid(char *name, int num); qboolean MP_ConsoleCommand(char *cmdtext); #endif diff --git a/engine/client/pr_menu.c b/engine/client/pr_menu.c index 598700278..6ca0258cb 100644 --- a/engine/client/pr_menu.c +++ b/engine/client/pr_menu.c @@ -2382,6 +2382,7 @@ func_t mp_shutdown_function; func_t mp_draw_function; func_t mp_keydown_function; func_t mp_keyup_function; +func_t mp_inputevent_function; func_t mp_toggle_function; func_t mp_consolecommand_function; @@ -2598,6 +2599,7 @@ qboolean MP_Init (void) mp_init_function = PR_FindFunction(menu_world.progs, "m_init", PR_ANY); mp_shutdown_function = PR_FindFunction(menu_world.progs, "m_shutdown", PR_ANY); mp_draw_function = PR_FindFunction(menu_world.progs, "m_draw", PR_ANY); + mp_inputevent_function = PR_FindFunction(menu_world.progs, "Menu_InputEvent", PR_ANY); mp_keydown_function = PR_FindFunction(menu_world.progs, "m_keydown", PR_ANY); mp_keyup_function = PR_FindFunction(menu_world.progs, "m_keyup", PR_ANY); mp_toggle_function = PR_FindFunction(menu_world.progs, "m_toggle", PR_ANY); @@ -2753,17 +2755,18 @@ void MP_Draw(void) } -void MP_Keydown(int key, int unicode) +qboolean MP_Keydown(int key, int unicode, unsigned int devid) { + qboolean result = false; extern qboolean keydown[K_MAX]; #ifdef TEXTEDITOR if (editormodal) - return; + return true; #endif if (setjmp(mp_abort)) - return; + return true; if (key == 'c') { @@ -2771,7 +2774,7 @@ void MP_Keydown(int key, int unicode) { MP_Shutdown(); M_Init_Internal(); - return; + return true; } } @@ -2782,7 +2785,17 @@ void MP_Keydown(int key, int unicode) *menu_world.g.time = menutime; inmenuprogs++; - if (mp_keydown_function) + if (mp_inputevent_function) + { + void *pr_globals = PR_globals(menu_world.progs, PR_CURRENT); + G_FLOAT(OFS_PARM0) = CSIE_KEYDOWN; + G_FLOAT(OFS_PARM1) = MP_TranslateFTEtoQCCodes(key); + G_FLOAT(OFS_PARM2) = unicode; + G_FLOAT(OFS_PARM3) = devid; + PR_ExecuteProgram(menu_world.progs, mp_inputevent_function); + result = G_FLOAT(OFS_RETURN); + } + else if (mp_keydown_function) { void *pr_globals = PR_globals(menu_world.progs, PR_CURRENT); G_FLOAT(OFS_PARM0) = MP_TranslateFTEtoQCCodes(key); @@ -2790,9 +2803,10 @@ void MP_Keydown(int key, int unicode) PR_ExecuteProgram(menu_world.progs, mp_keydown_function); } inmenuprogs--; + return result; } -void MP_Keyup(int key, int unicode) +void MP_Keyup(int key, int unicode, unsigned int devid) { #ifdef TEXTEDITOR if (editormodal) @@ -2811,7 +2825,16 @@ void MP_Keyup(int key, int unicode) *menu_world.g.time = menutime; inmenuprogs++; - if (mp_keyup_function) + if (mp_inputevent_function) + { + void *pr_globals = PR_globals(menu_world.progs, PR_CURRENT); + G_FLOAT(OFS_PARM0) = CSIE_KEYUP; + G_FLOAT(OFS_PARM1) = MP_TranslateFTEtoQCCodes(key); + G_FLOAT(OFS_PARM2) = unicode; + G_FLOAT(OFS_PARM3) = devid; + PR_ExecuteProgram(menu_world.progs, mp_inputevent_function); + } + else if (mp_keyup_function) { void *pr_globals = PR_globals(menu_world.progs, PR_CURRENT); G_FLOAT(OFS_PARM0) = MP_TranslateFTEtoQCCodes(key); @@ -2821,6 +2844,63 @@ void MP_Keyup(int key, int unicode) inmenuprogs--; } +qboolean MP_MousePosition(float xabs, float yabs, unsigned int devid) +{ + void *pr_globals; + + if (!menu_world.progs || !mp_inputevent_function) + return false; + + if (setjmp(mp_abort)) + return false; + inmenuprogs++; + pr_globals = PR_globals(menu_world.progs, PR_CURRENT); + G_FLOAT(OFS_PARM0) = CSIE_MOUSEABS; + G_FLOAT(OFS_PARM1) = (xabs * vid.width) / vid.pixelwidth; + G_FLOAT(OFS_PARM2) = (yabs * vid.height) / vid.pixelheight; + G_FLOAT(OFS_PARM3) = devid; + PR_ExecuteProgram (menu_world.progs, mp_inputevent_function); + inmenuprogs--; + return G_FLOAT(OFS_RETURN); +} +qboolean MP_MouseMove(float xdelta, float ydelta, unsigned int devid) +{ + void *pr_globals; + + if (!menu_world.progs || !mp_inputevent_function) + return false; + + if (setjmp(mp_abort)) + return false; + inmenuprogs++; + pr_globals = PR_globals(menu_world.progs, PR_CURRENT); + G_FLOAT(OFS_PARM0) = CSIE_MOUSEDELTA; + G_FLOAT(OFS_PARM1) = (xdelta * vid.width) / vid.pixelwidth; + G_FLOAT(OFS_PARM2) = (ydelta * vid.height) / vid.pixelheight; + G_FLOAT(OFS_PARM3) = devid; + PR_ExecuteProgram (menu_world.progs, mp_inputevent_function); + inmenuprogs--; + return G_FLOAT(OFS_RETURN); +} + +qboolean MP_JoystickAxis(int axis, float value, unsigned int devid) +{ + void *pr_globals; + if (!menu_world.progs || !mp_inputevent_function) + return false; + if (setjmp(mp_abort)) + return false; + inmenuprogs++; + pr_globals = PR_globals(menu_world.progs, PR_CURRENT); + G_FLOAT(OFS_PARM0) = CSIE_JOYAXIS; + G_FLOAT(OFS_PARM1) = axis; + G_FLOAT(OFS_PARM2) = value; + G_FLOAT(OFS_PARM3) = devid; + PR_ExecuteProgram (menu_world.progs, mp_inputevent_function); + inmenuprogs--; + return G_FLOAT(OFS_RETURN); +} + qboolean MP_Toggle(int mode) { if (!menu_world.progs) diff --git a/engine/client/snd_ov.c b/engine/client/snd_ov.c index 3a13f6947..ec61a6c40 100644 --- a/engine/client/snd_ov.c +++ b/engine/client/snd_ov.c @@ -417,7 +417,9 @@ static qboolean OV_StartDecode(unsigned char *start, unsigned long length, ovdec } #else { - oggvorbislibrary = Sys_LoadLibrary("libvorbisfile", funcs); + oggvorbislibrary = Sys_LoadLibrary("libvorbisfile.so.3", funcs); + if (!oggvorbislibrary) + oggvorbislibrary = Sys_LoadLibrary("libvorbisfile", funcs); if (!oggvorbislibrary) Con_Printf("Couldn't load library: \"libvorbisfile\".\n"); } diff --git a/engine/client/snd_sdl.c b/engine/client/snd_sdl.c index 043ad031d..c2edb5867 100644 --- a/engine/client/snd_sdl.c +++ b/engine/client/snd_sdl.c @@ -79,7 +79,9 @@ static qboolean SSDL_InitAudio(void) static dllhandle_t *libsdl; if (!libsdl) { - libsdl = Sys_LoadLibrary("libSDL2.so", funcs); + libsdl = Sys_LoadLibrary("libSDL2-2.0.so.0", funcs); + if (!libsdl) + libsdl = Sys_LoadLibrary("libSDL2.so", funcs); //maybe they have a dev package installed that fixes this mess. if (libsdl) SDL_Init(SDL_INIT_NOPARACHUTE); else diff --git a/engine/client/sys_win.c b/engine/client/sys_win.c index ab2faf73c..84491463d 100644 --- a/engine/client/sys_win.c +++ b/engine/client/sys_win.c @@ -3672,9 +3672,12 @@ qboolean Sys_RunInstaller(void) #define RESLANG MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_UK) static const char *Sys_FindManifest(void) { + const char *fmf; HRSRC hdl = FindResource(NULL, MAKEINTRESOURCE(1), RT_RCDATA); HGLOBAL hgl = LoadResource(NULL, hdl); - return LockResource(hgl); + fmf = LockResource(hgl); +// MessageBox(NULL, fmf, "Embedded manifest", 0); + return fmf; } //size info that microsoft recommends @@ -3685,9 +3688,9 @@ static const struct int bpp; } icosizes[] = { // {96, 96, 32}, - {48, 48, 32}, - {32, 32, 32}, - {16, 16, 32}, +// {48, 48, 32}, +// {32, 32, 32}, +// {16, 16, 32}, // {16, 16, 4}, // {48, 48, 4}, // {32, 32, 4}, diff --git a/engine/common/common.c b/engine/common/common.c index 3be87f02f..ddcffef58 100644 --- a/engine/common/common.c +++ b/engine/common/common.c @@ -4450,10 +4450,15 @@ void COM_ParsePlusSets (qboolean docbuf) } else { - if (!strcmp(com_argv[i], "+set")) - Cvar_Get(com_argv[i+1], com_argv[i+2], 0, "Cvars set on commandline"); - else if (!strcmp(com_argv[i], "+seta")) - Cvar_Get(com_argv[i+1], com_argv[i+2], CVAR_ARCHIVE, "Cvars set on commandline"); + if (!strcmp(com_argv[i], "+set") || !strcmp(com_argv[i], "+seta")) + { +#if defined(Q2CLIENT) || defined(Q2SERVER) + if (!strcmp("basedir", com_argv[i+1])) + host_parms.basedir = com_argv[i]; + else +#endif + Cvar_Get(com_argv[i+1], com_argv[i+2], (!strcmp(com_argv[i], "+seta"))?CVAR_ARCHIVE:0, "Cvars set on commandline"); + } } i+=2; } diff --git a/engine/common/fs.c b/engine/common/fs.c index 849f566cd..b6202d33a 100644 --- a/engine/common/fs.c +++ b/engine/common/fs.c @@ -4830,6 +4830,7 @@ qboolean FS_ChangeGame(ftemanifest_t *man, qboolean allowreloadconfigs, qboolean int i, j; char realpath[MAX_OSPATH-1]; char newbasedir[MAX_OSPATH]; + char *olddownloadsurl; qboolean fixedbasedir; qboolean reloadconfigs = false; qboolean builtingame = false; @@ -4911,6 +4912,11 @@ qboolean FS_ChangeGame(ftemanifest_t *man, qboolean allowreloadconfigs, qboolean Sys_Error("couldn't generate dataless manifest\n"); } + if (fs_manifest && fs_manifest->downloadsurl) + olddownloadsurl = Z_StrDup(fs_manifest->downloadsurl); + else + olddownloadsurl = NULL; + if (man == fs_manifest) { //don't close anything. theoretically nothing is changing, and we don't want to load new defaults either. @@ -4929,6 +4935,14 @@ qboolean FS_ChangeGame(ftemanifest_t *man, qboolean allowreloadconfigs, qboolean } fs_manifest = man; + if (!man->doinstall) + { //make sure we only fuck over the user if this is a 'secure' manifest, and not hacked in some way. + Z_Free(man->downloadsurl); + man->downloadsurl = olddownloadsurl; + } + else + Z_Free(olddownloadsurl); + if (man->installation && *man->installation) { for (i = 0; gamemode_info[i].argname; i++) diff --git a/engine/common/net_ssl_gnutls.c b/engine/common/net_ssl_gnutls.c index 53b03a1b5..fb44dc055 100644 --- a/engine/common/net_ssl_gnutls.c +++ b/engine/common/net_ssl_gnutls.c @@ -6,7 +6,11 @@ #ifdef HAVE_GNUTLS -#if 1//defined(_WIN32) && !defined(MINGW) +#if defined(_WIN32) && !defined(MINGW) + +#define GNUTLS_VERSION "2.12.23" +#define GNUTLS_SOPREFIX "" +#define GNUTLS_SONUM 26 #ifdef _MSC_VER #if SIZE_MAX == ULONG_MAX @@ -21,9 +25,9 @@ //also this helps get around the whole msvc/mingw thing. struct DSTRUCT; -typedef struct DSTRUCT* gnutls_certificate_credentials; -typedef gnutls_certificate_credentials gnutls_certificate_client_credentials; -typedef struct DSTRUCT* gnutls_anon_client_credentials; +typedef struct DSTRUCT* gnutls_certificate_credentials_t; +typedef gnutls_certificate_credentials_t gnutls_certificate_client_credentials_t; +typedef struct DSTRUCT* gnutls_anon_client_credentials_t; struct gnutls_session_int; typedef struct gnutls_session_int* gnutls_session_t; typedef void * gnutls_transport_ptr_t; @@ -65,126 +69,219 @@ typedef enum GNUTLS_CERT_SIGNER_CONSTRAINTS_FAILURE = 1<<16, GNUTLS_CERT_MISMATCH = 1<<17, } gnutls_certificate_status_t; -typedef enum gnutls_connection_end { GNUTLS_SERVER=1, GNUTLS_CLIENT } gnutls_connection_end; -typedef enum gnutls_credentials_type { GNUTLS_CRD_CERTIFICATE=1, GNUTLS_CRD_ANON, GNUTLS_CRD_SRP } gnutls_credentials_type; -typedef enum gnutls_close_request { GNUTLS_SHUT_RDWR=0, GNUTLS_SHUT_WR=1 } gnutls_close_request; +typedef enum gnutls_connection_end { GNUTLS_SERVER=1, GNUTLS_CLIENT } gnutls_connection_end_t; +typedef enum gnutls_credentials_type { GNUTLS_CRD_CERTIFICATE=1, GNUTLS_CRD_ANON, GNUTLS_CRD_SRP } gnutls_credentials_type_t; +typedef enum gnutls_close_request { GNUTLS_SHUT_RDWR=0, GNUTLS_SHUT_WR=1 } gnutls_close_request_t; typedef ssize_t (*gnutls_pull_func) (gnutls_transport_ptr_t, void *, size_t); typedef ssize_t (*gnutls_push_func) (gnutls_transport_ptr_t, const void *, size_t); #define GNUTLS_E_AGAIN -28 #define GNUTLS_E_CERTIFICATE_ERROR -43 #define GNUTLS_E_INTERRUPTED -52 +#define GNUTLS_E_PREMATURE_TERMINATION -110 typedef enum { GNUTLS_NAME_DNS = 1 } gnutls_server_name_type_t; -static int (VARGS *gnutls_bye)(gnutls_session_t session, gnutls_close_request how); -static void (VARGS *gnutls_perror)(int error); -static int (VARGS *gnutls_handshake)(gnutls_session_t session); -static void (VARGS *gnutls_transport_set_ptr)(gnutls_session_t session, gnutls_transport_ptr_t ptr); -static void (VARGS *gnutls_transport_set_push_function)(gnutls_session_t session, gnutls_push_func push_func); -static void (VARGS *gnutls_transport_set_pull_function)(gnutls_session_t session, gnutls_pull_func pull_func); -static void (VARGS *gnutls_transport_set_errno)(gnutls_session_t session, int err); -static int (VARGS *gnutls_error_is_fatal)(int error); -static int (VARGS *gnutls_credentials_set)(gnutls_session_t, gnutls_credentials_type type, void* cred); -static int (VARGS *gnutls_kx_set_priority)(gnutls_session_t session, const int*); -static int (VARGS *gnutls_init)(gnutls_session_t * session, gnutls_connection_end con_end); -static int (VARGS *gnutls_set_default_priority)(gnutls_session_t session); -static int (VARGS *gnutls_certificate_allocate_credentials)(gnutls_certificate_credentials *sc); -static int (VARGS *gnutls_certificate_type_set_priority)(gnutls_session_t session, const int*); -static int (VARGS *gnutls_anon_allocate_client_credentials)(gnutls_anon_client_credentials *sc); -static int (VARGS *gnutls_global_init)(void); -static int (VARGS *gnutls_record_send)(gnutls_session_t session, const void *data, size_t sizeofdata); -static int (VARGS *gnutls_record_recv)(gnutls_session_t session, void *data, size_t sizeofdata); +typedef int (VARGS gnutls_certificate_verify_function)(gnutls_session_t session); -static int (VARGS *gnutls_certificate_set_verify_function)(); -static void *(VARGS *gnutls_session_get_ptr)(gnutls_session_t session); -static void (VARGS *gnutls_session_set_ptr)(gnutls_session_t session, void *ptr); -#if GNUTLS_VERSION_3_0_0_PLUS -static int (VARGS *gnutls_certificate_set_x509_system_trust)(gnutls_certificate_credentials cred); #else -static int (VARGS *gnutls_certificate_set_x509_trust_file)(gnutls_certificate_credentials cred, const char * cafile, gnutls_x509_crt_fmt_t type); +#include +#define gnutls_connection_end_t unsigned int + + #if GNUTLS_VERSION_MAJOR < 3 || (GNUTLS_VERSION_MAJOR == 3 && GNUTLS_VERSION_MINOR < 3) + #define GNUTLS_SONUM 26 //cygwin or something. + #endif + #if GNUTLS_VERSION_MAJOR == 3 && GNUTLS_VERSION_MINOR == 3 + #define GNUTLS_SOPREFIX "-deb0" //not sure what this is about. + #define GNUTLS_SONUM 28 //debian jessie + #endif + #if GNUTLS_VERSION_MAJOR == 3 && GNUTLS_VERSION_MINOR == 4 + #define GNUTLS_SONUM 30 //ubuntu 16.04 + #endif + #if GNUTLS_VERSION_MAJOR == 3 && GNUTLS_VERSION_MINOR == 5 + #define GNUTLS_SONUM 30 //debian stretch + #endif + #if GNUTLS_VERSION_MAJOR == 3 && GNUTLS_VERSION_MINOR > 5 + #define GNUTLS_SONUM 30 //no idea what the future holds. maybe we'll be lucky... + #endif + #ifndef GNUTLS_SONUM + #pragma message "GNUTLS version not recognised. Will probably not be loadable." + #endif + #ifndef GNUTLS_SOPREFIX + #define GNUTLS_SOPREFIX + #endif #endif -#if GNUTLS_VERSION_3_1_4_PLUS -static int (VARGS *gnutls_certificate_verify_peers3)(gnutls_session_t session, const char* hostname, unsigned int * status); -static int (VARGS *gnutls_certificate_verification_status_print)(unsigned int status, gnutls_certificate_type_t type, gnutls_datum_t * out, unsigned int flags); + +#if GNUTLS_VERSION_MAJOR >= 3 + #define GNUTLS_VERSION_3_0_0_PLUS +#endif +#if GNUTLS_VERSION_MAJOR >= 4 || (GNUTLS_VERSION_MAJOR == 3 && (GNUTLS_VERSION_MINOR > 1 || (GNUTLS_VERSION_MINOR == 1 && GNUTLS_VERSION_PATCH >= 1))) + #define GNUTLS_VERSION_3_1_4_PLUS +#endif + +static int (VARGS *qgnutls_bye)(gnutls_session_t session, gnutls_close_request_t how); +static void (VARGS *qgnutls_perror)(int error); +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 int (VARGS *qgnutls_set_default_priority)(gnutls_session_t session); +static int (VARGS *qgnutls_certificate_allocate_credentials)(gnutls_certificate_credentials_t *sc); +static int (VARGS *qgnutls_certificate_type_set_priority)(gnutls_session_t session, const int*); +static int (VARGS *qgnutls_anon_allocate_client_credentials)(gnutls_anon_client_credentials_t *sc); +static int (VARGS *qgnutls_global_init)(void); +static int (VARGS *qgnutls_record_send)(gnutls_session_t session, const void *data, size_t sizeofdata); +static int (VARGS *qgnutls_record_recv)(gnutls_session_t session, void *data, size_t sizeofdata); + +static int (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); +#ifdef GNUTLS_VERSION_3_0_0_PLUS +static int (VARGS *qgnutls_certificate_set_x509_system_trust)(gnutls_certificate_credentials_t cred); #else -static int (VARGS *gnutls_certificate_verify_peers2)(gnutls_session_t session, unsigned int * status); -static int (VARGS *gnutls_x509_crt_check_hostname)(gnutls_x509_crt_t cert, const char * hostname); -static int (VARGS *gnutls_x509_crt_init)(gnutls_x509_crt_t * cert); -static int (VARGS *gnutls_x509_crt_import)(gnutls_x509_crt_t cert, const gnutls_datum_t *data, gnutls_x509_crt_fmt_t format); -static const gnutls_datum_t *(VARGS *gnutls_certificate_get_peers)(gnutls_session_t session, unsigned int * list_size); +static int (VARGS *qgnutls_certificate_set_x509_trust_file)(gnutls_certificate_credentials_t cred, const char * cafile, gnutls_x509_crt_fmt_t type); #endif -static gnutls_certificate_type_t (VARGS *gnutls_certificate_type_get)(gnutls_session_t session); -static void (VARGS *gnutls_free)(void * ptr); -static int (VARGS *gnutls_server_name_set)(gnutls_session_t session, gnutls_server_name_type_t type, const void * name, size_t name_length); +#ifdef GNUTLS_VERSION_3_1_4_PLUS +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); +#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); +static const gnutls_datum_t *(VARGS *qgnutls_certificate_get_peers)(gnutls_session_t session, unsigned int * list_size); +#endif +static gnutls_certificate_type_t (VARGS *qgnutls_certificate_type_get)(gnutls_session_t session); +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); static qboolean Init_GNUTLS(void) { +#ifdef GNUTLS_VERSION_3_0_0_PLUS + #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_VERSION_3_1_4_PLUS + #define GNUTLS_VERIFYFUNCS \ + GNUTLS_FUNC(gnutls_certificate_verify_peers3) \ + GNUTLS_FUNC(gnutls_certificate_verification_status_print) +#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 + + +#define GNUTLS_FUNCS \ + GNUTLS_FUNC(gnutls_bye) \ + 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_certificate_type_set_priority) \ + GNUTLS_FUNC(gnutls_credentials_set) \ + GNUTLS_FUNC(gnutls_kx_set_priority) \ + GNUTLS_FUNC(gnutls_init) \ + 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_VERIFYFUNCS \ + GNUTLS_FUNC(gnutls_certificate_type_get) \ + GNUTLS_FUNC(gnutls_free) \ + GNUTLS_FUNC(gnutls_server_name_set) \ + +#if 1 //GNUTLS_DYNAMIC dllhandle_t *hmod; dllfunction_t functable[] = { - {(void**)&gnutls_bye, "gnutls_bye"}, - {(void**)&gnutls_perror, "gnutls_perror"}, - {(void**)&gnutls_handshake, "gnutls_handshake"}, - {(void**)&gnutls_transport_set_ptr, "gnutls_transport_set_ptr"}, - {(void**)&gnutls_transport_set_push_function, "gnutls_transport_set_push_function"}, - {(void**)&gnutls_transport_set_pull_function, "gnutls_transport_set_pull_function"}, - {(void**)&gnutls_transport_set_errno, "gnutls_transport_set_errno"}, - {(void**)&gnutls_error_is_fatal, "gnutls_error_is_fatal"}, - {(void**)&gnutls_certificate_type_set_priority, "gnutls_certificate_type_set_priority"}, - {(void**)&gnutls_credentials_set, "gnutls_credentials_set"}, - {(void**)&gnutls_kx_set_priority, "gnutls_kx_set_priority"}, - {(void**)&gnutls_init, "gnutls_init"}, - {(void**)&gnutls_set_default_priority, "gnutls_set_default_priority"}, - {(void**)&gnutls_certificate_allocate_credentials, "gnutls_certificate_allocate_credentials"}, - {(void**)&gnutls_anon_allocate_client_credentials, "gnutls_anon_allocate_client_credentials"}, - {(void**)&gnutls_global_init, "gnutls_global_init"}, - {(void**)&gnutls_record_send, "gnutls_record_send"}, - {(void**)&gnutls_record_recv, "gnutls_record_recv"}, +//#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_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_certificate_type_set_priority, "gnutls_certificate_type_set_priority"}, + {(void**)&qgnutls_credentials_set, "gnutls_credentials_set"}, + {(void**)&qgnutls_kx_set_priority, "gnutls_kx_set_priority"}, + {(void**)&qgnutls_init, "gnutls_init"}, + {(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**)&gnutls_certificate_set_verify_function, "gnutls_certificate_set_verify_function"}, - {(void**)&gnutls_session_get_ptr, "gnutls_session_get_ptr"}, - {(void**)&gnutls_session_set_ptr, "gnutls_session_set_ptr"}, -#if GNUTLS_VERSION_3_0_0_PLUS - {(void**)&gnutls_certificate_set_x509_system_trust, "gnutls_certificate_set_x509_system_trust"}, + {(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"}, +#ifdef GNUTLS_VERSION_3_0_0_PLUS + {(void**)&qgnutls_certificate_set_x509_system_trust, "gnutls_certificate_set_x509_system_trust"}, #else - {(void**)&gnutls_certificate_set_x509_trust_file, "gnutls_certificate_set_x509_trust_file"}, + {(void**)&qgnutls_certificate_set_x509_trust_file, "gnutls_certificate_set_x509_trust_file"}, #endif -#if GNUTLS_VERSION_3_1_4_PLUS - {(void**)&gnutls_certificate_verify_peers3, "gnutls_certificate_verify_peers3"}, - {(void**)&gnutls_certificate_verification_status_print, "gnutls_certificate_verification_status_print"}, +#ifdef GNUTLS_VERSION_3_1_4_PLUS + {(void**)&qgnutls_certificate_verify_peers3, "gnutls_certificate_verify_peers3"}, + {(void**)&qgnutls_certificate_verification_status_print, "gnutls_certificate_verification_status_print"}, #else - {(void**)&gnutls_certificate_verify_peers2, "gnutls_certificate_verify_peers2"}, - {(void**)&gnutls_x509_crt_init, "gnutls_x509_crt_init"}, - {(void**)&gnutls_x509_crt_import, "gnutls_x509_crt_import"}, - {(void**)&gnutls_certificate_get_peers, "gnutls_certificate_get_peers"}, - {(void**)&gnutls_x509_crt_check_hostname, "gnutls_x509_crt_check_hostname"}, + {(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_certificate_get_peers, "gnutls_certificate_get_peers"}, + {(void**)&qgnutls_x509_crt_check_hostname, "gnutls_x509_crt_check_hostname"}, #endif - {(void**)&gnutls_certificate_type_get, "gnutls_certificate_type_get"}, - {(void**)&gnutls_free, "gnutls_free"}, - {(void**)&gnutls_server_name_set, "gnutls_server_name_set"}, + {(void**)&qgnutls_certificate_type_get, "gnutls_certificate_type_get"}, + {(void**)&qgnutls_free, "gnutls_free"}, + {(void**)&qgnutls_server_name_set, "gnutls_server_name_set"}, {NULL, NULL} }; -#ifdef __CYGWIN__ - hmod = Sys_LoadLibrary("cyggnutls-26.dll", functable); +#ifdef GNUTLS_SONUM + #ifdef __CYGWIN__ + hmod = Sys_LoadLibrary("cyggnutls"GNUTLS_SOPREFIX"-"STRINGIFY(GNUTLS_SONUM)".dll", functable); + #else + hmod = Sys_LoadLibrary("libgnutls"GNUTLS_SOPREFIX".so."STRINGIFY(GNUTLS_SONUM), functable); + #endif #else - hmod = Sys_LoadLibrary("libgnutls.so.26", functable); + hmod = Sys_LoadLibrary("libgnutls"GNUTLS_SOPREFIX".so", functable); //hope and pray #endif if (!hmod) return false; +#else + #define GNUTLS_FUNC(name) q##name = name; + GNUTLS_FUNCS + #undef GNUTLS_FUNC +#endif return true; } -#else -#include -static qboolean Init_GNUTLS(void) {return true;} -#endif - struct sslbuf { char data[8192]; @@ -216,7 +313,7 @@ static qboolean QDECL SSL_Close(vfsfile_t *vfs) file->handshaking = true; if (file->session) - gnutls_bye (file->session, file->datagram?GNUTLS_SHUT_WR:GNUTLS_SHUT_RDWR); + qgnutls_bye (file->session, file->datagram?GNUTLS_SHUT_WR:GNUTLS_SHUT_RDWR); file->session = NULL; if (file->stream) VFS_CLOSE(file->stream); @@ -225,12 +322,12 @@ static qboolean QDECL SSL_Close(vfsfile_t *vfs) } static int QDECL SSL_CheckCert(gnutls_session_t session) { - gnutlsfile_t *file = gnutls_session_get_ptr (session); + gnutlsfile_t *file = qgnutls_session_get_ptr (session); unsigned int certstatus; cvar_t *tls_ignorecertificateerrors; -#if GNUTLS_VERSION_3_1_4_PLUS - if (gnutls_certificate_verify_peers3(session, file->certname, &certstatus) >= 0) +#ifdef GNUTLS_VERSION_3_1_4_PLUS + if (qgnutls_certificate_verify_peers3(session, file->certname, &certstatus) >= 0) { { gnutls_datum_t out; @@ -238,25 +335,25 @@ static int QDECL SSL_CheckCert(gnutls_session_t session) if (certstatus == 0) return 0; - type = gnutls_certificate_type_get (session); - if (gnutls_certificate_verification_status_print(certstatus, type, &out, 0) >= 0) + type = qgnutls_certificate_type_get (session); + if (qgnutls_certificate_verification_status_print(certstatus, type, &out, 0) >= 0) { Con_Printf("%s: %s\n", file->certname, out.data); - gnutls_free(out.data); + qgnutls_free(out.data); #else - if (gnutls_certificate_verify_peers2(session, &certstatus) >= 0) + if (qgnutls_certificate_verify_peers2(session, &certstatus) >= 0) { int certslen; //grab the certificate - const gnutls_datum_t *const certlist = gnutls_certificate_get_peers(session, &certslen); + const gnutls_datum_t *const certlist = qgnutls_certificate_get_peers(session, &certslen); if (certlist && certslen) { //and make sure the hostname on it actually makes sense. gnutls_x509_crt_t cert; - gnutls_x509_crt_init(&cert); - gnutls_x509_crt_import(cert, certlist, GNUTLS_X509_FMT_DER); - if (gnutls_x509_crt_check_hostname(cert, file->certname)) + qgnutls_x509_crt_init(&cert); + qgnutls_x509_crt_import(cert, certlist, GNUTLS_X509_FMT_DER); + if (qgnutls_x509_crt_check_hostname(cert, file->certname)) { if (certstatus == 0) return 0; @@ -297,15 +394,15 @@ int SSL_DoHandshake(gnutlsfile_t *file) if (!file->session) return -1; - err = gnutls_handshake (file->session); + err = qgnutls_handshake (file->session); if (err < 0) { //non-fatal errors can just handshake again the next time the caller checks to see if there's any data yet //(e_again or e_intr) - if (!gnutls_error_is_fatal(err)) + if (!qgnutls_error_is_fatal(err)) return 0; //certificate errors etc -// gnutls_perror (err); +// qgnutls_perror (err); SSL_Close(&file->funcs); // Con_Printf("%s: abort\n", file->certname); @@ -327,10 +424,20 @@ static int QDECL SSL_Read(struct vfsfile_s *f, void *buffer, int bytestoread) return read; } - read = gnutls_record_recv(file->session, buffer, bytestoread); + read = qgnutls_record_recv(file->session, buffer, bytestoread); if (read < 0) { - if (!gnutls_error_is_fatal(read)) + if (read == GNUTLS_E_PREMATURE_TERMINATION) + { + Con_Printf("TLS Premature Termination\n"); + return -1; + } + else if (read == GNUTLS_E_REHANDSHAKE) + { + file->handshaking = false;//gnutls_safe_renegotiation_status(); + //if false, 'recommended' to send an GNUTLS_A_NO_RENEGOTIATION alert, no idea how. + } + else if (!qgnutls_error_is_fatal(read)) return 0; else { @@ -354,10 +461,10 @@ static int QDECL SSL_Write(struct vfsfile_s *f, const void *buffer, int bytestow return written; } - written = gnutls_record_send(file->session, buffer, bytestowrite); + written = qgnutls_record_send(file->session, buffer, bytestowrite); if (written < 0) { - if (!gnutls_error_is_fatal(written)) + if (!qgnutls_error_is_fatal(written)) return 0; else { @@ -392,12 +499,12 @@ static ssize_t SSL_Push(gnutls_transport_ptr_t p, const void *data, size_t size) int done = VFS_WRITE(file->stream, data, size); if (!done) { - gnutls_transport_set_errno(file->session, EAGAIN); + qgnutls_transport_set_errno(file->session, EAGAIN); return -1; } if (done < 0) return 0; - gnutls_transport_set_errno(file->session, done<0?errno:0); + qgnutls_transport_set_errno(file->session, done<0?errno:0); return done; } /*static ssize_t SSL_PushV(gnutls_transport_ptr_t p, giovec_t *iov, int iovcnt) @@ -417,10 +524,10 @@ static ssize_t SSL_Push(gnutls_transport_ptr_t p, const void *data, size_t size) } if (!total) { - gnutls_transport_set_errno(file->session, EAGAIN); + qgnutls_transport_set_errno(file->session, EAGAIN); return -1; } - gnutls_transport_set_errno(file->session, 0); + qgnutls_transport_set_errno(file->session, 0); return total; }*/ static ssize_t SSL_Pull(gnutls_transport_ptr_t p, void *data, size_t size) @@ -429,14 +536,14 @@ static ssize_t SSL_Pull(gnutls_transport_ptr_t p, void *data, size_t size) int done = VFS_READ(file->stream, data, size); if (!done) { - gnutls_transport_set_errno(file->session, EAGAIN); + qgnutls_transport_set_errno(file->session, EAGAIN); return -1; } if (done < 0) { return 0; } - gnutls_transport_set_errno(file->session, done<0?errno:0); + qgnutls_transport_set_errno(file->session, done<0?errno:0); return done; } @@ -445,8 +552,8 @@ vfsfile_t *FS_OpenSSL(const char *hostname, vfsfile_t *source, qboolean server, gnutlsfile_t *newf; qboolean anon = false; - static gnutls_anon_client_credentials anoncred; - static gnutls_certificate_credentials xcred; + static gnutls_anon_client_credentials_t anoncred; + static gnutls_certificate_credentials_t xcred; // long _false = false; // long _true = true; @@ -455,9 +562,15 @@ vfsfile_t *FS_OpenSSL(const char *hostname, vfsfile_t *source, qboolean server, const int kx_prio[] = {GNUTLS_KX_ANON_DH, 0}; const int cert_type_priority[3] = {GNUTLS_CRT_X509, 0}; - if (!source || datagram) + if (!source) return NULL; + if (datagram) + { + VFS_CLOSE(source); + return NULL; + } + #ifdef GNUTLS_DATAGRAM if (datagram) return NULL; @@ -469,21 +582,21 @@ vfsfile_t *FS_OpenSSL(const char *hostname, vfsfile_t *source, qboolean server, { if (!Init_GNUTLS()) { - Con_Printf("GnuTLS library not available.\n"); + Con_Printf("GnuTLS "GNUTLS_VERSION" library not available.\n"); VFS_CLOSE(source); return NULL; } - gnutls_global_init (); + qgnutls_global_init (); - gnutls_anon_allocate_client_credentials (&anoncred); - gnutls_certificate_allocate_credentials (&xcred); + qgnutls_anon_allocate_client_credentials (&anoncred); + qgnutls_certificate_allocate_credentials (&xcred); #ifdef GNUTLS_VERSION_3_0_0_PLUS - gnutls_certificate_set_x509_system_trust (xcred); + qgnutls_certificate_set_x509_system_trust (xcred); #else - gnutls_certificate_set_x509_trust_file (xcred, CAFILE, GNUTLS_X509_FMT_PEM); + qgnutls_certificate_set_x509_trust_file (xcred, CAFILE, GNUTLS_X509_FMT_PEM); #endif - gnutls_certificate_set_verify_function (xcred, SSL_CheckCert); + qgnutls_certificate_set_verify_function (xcred, SSL_CheckCert); needinit = false; } @@ -508,35 +621,48 @@ vfsfile_t *FS_OpenSSL(const char *hostname, vfsfile_t *source, qboolean server, Q_strncpyz(newf->certname, hostname, sizeof(newf->certname)); // Initialize TLS session - gnutls_init (&newf->session, GNUTLS_CLIENT/*|(datagram?GNUTLS_DATAGRAM:0)*/); + qgnutls_init (&newf->session, GNUTLS_CLIENT/*|(datagram?GNUTLS_DATAGRAM:0)*/); - gnutls_server_name_set(newf->session, GNUTLS_NAME_DNS, newf->certname, strlen(newf->certname)); + qgnutls_server_name_set(newf->session, GNUTLS_NAME_DNS, newf->certname, strlen(newf->certname)); - gnutls_session_set_ptr(newf->session, newf); + qgnutls_session_set_ptr(newf->session, newf); // Use default priorities - gnutls_set_default_priority (newf->session); + qgnutls_set_default_priority (newf->session); if (anon) { - gnutls_kx_set_priority (newf->session, kx_prio); - gnutls_credentials_set (newf->session, GNUTLS_CRD_ANON, anoncred); + qgnutls_kx_set_priority (newf->session, kx_prio); + qgnutls_credentials_set (newf->session, GNUTLS_CRD_ANON, anoncred); } else { - gnutls_certificate_type_set_priority (newf->session, cert_type_priority); - gnutls_credentials_set (newf->session, GNUTLS_CRD_CERTIFICATE, xcred); +//#if GNUTLS_VERSION_MAJOR >= 3 + //gnutls_priority_set_direct(); +//#else + qgnutls_certificate_type_set_priority (newf->session, cert_type_priority); +//#endif + qgnutls_credentials_set (newf->session, GNUTLS_CRD_CERTIFICATE, xcred); } // tell gnutls how to send/receive data - gnutls_transport_set_ptr (newf->session, newf); - gnutls_transport_set_push_function(newf->session, SSL_Push); - //gnutls_transport_set_vec_push_function(newf->session, SSL_PushV); - gnutls_transport_set_pull_function(newf->session, SSL_Pull); - //gnutls_transport_set_pull_timeout_function(newf->session, NULL); + qgnutls_transport_set_ptr (newf->session, newf); + qgnutls_transport_set_push_function(newf->session, SSL_Push); + //qgnutls_transport_set_vec_push_function(newf->session, SSL_PushV); + qgnutls_transport_set_pull_function(newf->session, SSL_Pull); + //qgnutls_transport_set_pull_timeout_function(newf->session, NULL); newf->handshaking = true; return &newf->funcs; } + +/* +vfsfile_t *FS_OpenSSL(const char *hostname, vfsfile_t *source, qboolean server, qboolean datagram) +{ + if (source) + VFS_CLOSE(source); + return NULL; +} +*/ #endif diff --git a/engine/common/net_wins.c b/engine/common/net_wins.c index 624ab026d..1567bf854 100644 --- a/engine/common/net_wins.c +++ b/engine/common/net_wins.c @@ -3617,7 +3617,7 @@ handshakeerror: st->inlen = 0; #ifdef HAVE_SSL - if (con->tls) //if we're meant to be using tls, wrap the stream in a tls connection + if (con->tls && st->clientstream) //if we're meant to be using tls, wrap the stream in a tls connection { st->clientstream = FS_OpenSSL(NULL, st->clientstream, true, false); /*sockadr doesn't contain transport info, so fix that up here*/ diff --git a/engine/http/iwebiface.c b/engine/http/iwebiface.c index 8b6b21923..30405f8c5 100644 --- a/engine/http/iwebiface.c +++ b/engine/http/iwebiface.c @@ -120,7 +120,7 @@ int main(int argc, char **argv) #ifdef _WIN32 Sleep(1); #else - usleep(1000000); + usleep(10000); #endif } }