diff options
Diffstat (limited to 'src/lib/win_glue.c')
| -rw-r--r-- | src/lib/win_glue.c | 471 |
1 files changed, 471 insertions, 0 deletions
diff --git a/src/lib/win_glue.c b/src/lib/win_glue.c new file mode 100644 index 0000000000000..3d6dd7206f9c4 --- /dev/null +++ b/src/lib/win_glue.c @@ -0,0 +1,471 @@ +#include "k5-int.h" + +#ifdef KRB5 +#include "krb5_err.h" +#include "kv5m_err.h" +#include "asn1_err.h" +#include "kdb5_err.h" +#include "profile.h" +extern void krb5_stdcc_shutdown(); +#endif +#ifdef GSSAPI +#include "gssapi/generic/gssapi_err_generic.h" +#include "gssapi/krb5/gssapi_err_krb5.h" +#endif + + +/* + * #defines for MIT-specific time-based timebombs and/or version + * server for the Kerberos DLL. + */ + +#ifdef SAP_TIMEBOMB +#define TIMEBOMB 865141200 /* 1-Jun-97 */ +#define TIMEBOMB_PRODUCT "SAPGUI" +#define TIMEBOMB_WARN 15 +#define TIMEBOMB_INFO " Please see the web page at:\nhttp://web.mit.edu/reeng/www/saphelp for more information" +#define TIMEBOMB_ERROR KRB5_APPL_EXPIRED +#endif + +#ifdef KRB_TIMEBOMB +#define TIMEBOMB 865141200 /* 1-Jun-97 */ +#define TIMEBOMB_PRODUCT "Kerberos V5" +#define TIMEBOMB_WARN 15 +#define TIMEBOMB_INFO " Please see the web page at:\nhttp://web.mit.edu/reeng/www/saphelp for more information" +#define TIMEBOMB_ERROR KRB5_LIB_EXPIRED +#endif + +/* + * #defines for using MIT's version server DLL + */ +#ifdef SAP_VERSERV +#define APP_TITLE "KRB5-SAP" +#define APP_VER "3.0f" +#define APP_INI "krb5sap.ini" +#define VERSERV_ERROR KRB5_APPL_EXPIRED +#endif + +#ifdef VERSERV +#define WINDOWS +#include <ver.h> +#include <vs.h> +#include <v.h> + + +/* + * This function will get the version resource information from the + * application using the DLL. This allows us to Version Serve + * arbitrary third party applications. If there is an error, or we + * decide that we should not version check the calling application + * then VSflag will be FALSE when the function returns. + * + * The buffers passed into this function must be at least + * APPVERINFO_SIZE bytes long. + */ + +#define APPVERINFO_SIZE 256 + +void GetCallingAppVerInfo( char *AppTitle, char *AppVer, char *AppIni, + BOOL *VSflag) +{ + char CallerFilename[_MAX_PATH]; + LONG *lpLangInfo; + DWORD hVersionInfoID, size; + GLOBALHANDLE hVersionInfo; + LPSTR lpVersionInfo; + int dumint, retval; + char *cp; + char *revAppTitle; + char szVerQ[90]; + LPBYTE locAppTitle; + LPBYTE locAppVer; + char locAppIni[_MAX_PATH]; +#ifndef _WIN32 + WORD wStackSeg; +#endif /* !_WIN32 */ + + /* first we need to get the calling module's filename */ +#ifndef _WIN32 + _asm { + mov wStackSeg, ss + }; + retval = GetModuleFileName((HMODULE)wStackSeg, CallerFilename, + _MAX_PATH); +#else + /* + * Note: this may only work for single threaded applications, + * we'll live and learn ... + */ + retval = GetModuleFileName( NULL, CallerFilename, _MAX_PATH); +#endif + + if ( retval == 0 ) { + VSflag = FALSE; + return; + } + + size = GetFileVersionInfoSize( CallerFilename, &hVersionInfoID); + + if( size == 0 ) { + /* + * hey , I bet we don't have a version resource, let's + * punt + */ +#if 0 + /* let's see what we have? (1813 means no resource) */ + size = GetLastError(); /* WIN32 only */ +#endif + *VSflag = FALSE; + return; + } + + hVersionInfo = GlobalAlloc(GHND, size); + lpVersionInfo = GlobalLock(hVersionInfo); + + retval = GetFileVersionInfo( CallerFilename, hVersionInfoID, size, + lpVersionInfo); + + retval = VerQueryValue(lpVersionInfo, "\\VarFileInfo\\Translation", + (LPSTR *)&lpLangInfo, &dumint); + wsprintf(szVerQ, + "\\StringFileInfo\\%04x%04x\\", + LOWORD(*lpLangInfo), HIWORD(*lpLangInfo)); + + cp = szVerQ + lstrlen(szVerQ); + + lstrcpy(cp, "ProductName"); + + + /* try a localAppTitle and then a strcpy 4/2/97 */ + + locAppTitle = 0; + locAppVer = 0; + + retval = VerQueryValue(lpVersionInfo, szVerQ, &locAppTitle, + &dumint); + + lstrcpy(cp, "ProductVersion"); + + + retval = VerQueryValue(lpVersionInfo, szVerQ, &locAppVer, + &dumint); + + if (!locAppTitle || !locAppVer) { + /* Punt, we don't have the right version resource records */ + *VSflag = FALSE; + return; + } + + /* + * We don't have a way to determine that INI file of the + * application at the moment so let's just use krb5.ini + */ + strncpy( locAppIni, KERBEROS_INI, sizeof(locAppIni) - 1 ); + locAppIni[ sizeof(locAppIni) - 1 ] = '\0'; + + strncpy( AppTitle, locAppTitle, APPVERINFO_SIZE); + AppTitle[APPVERINFO_SIZE - 1] = '\0'; + strncpy( AppVer, locAppVer, APPVERINFO_SIZE); + AppVer[APPVERINFO_SIZE - 1] = '\0'; + strncpy( AppIni, locAppIni, APPVERINFO_SIZE); + AppIni[APPVERINFO_SIZE - 1] = '\0'; + + /* + * We also need to determine if we want to suppress version + * checking of this application. Does the tail of the + * AppTitle end in a "-v" ? + */ + revAppTitle = _strrev( _strdup(AppTitle)); + if( revAppTitle[0] == 'v' || revAppTitle[0] == 'V' && + revAppTitle[1] == '-' ) { + VSflag = FALSE; + } + return; +} + + +/* + * Use the version server to give us some control on distribution and usage + * We're going to test track as well + */ +static int CallVersionServer(app_title, app_version, app_ini, code_cover) + char *app_title; + char *app_version; + char *app_ini; + char *code_cover; +{ + VS_Request vrequest; + VS_Status vstatus; + + SetCursor(LoadCursor(NULL, IDC_WAIT)); + + /* + * We should be able to pass in code_cover below, but things + * are breaking under Windows 16 for no good reason. + */ + vrequest = VSFormRequest((LPSTR) app_title, (LPSTR) app_version, + (LPSTR) app_ini, + NULL /* code_cover */, NULL, + V_CHECK_AND_LOG); + + SetCursor(LoadCursor(NULL, IDC_ARROW)); + /* + * If the user presses cancel when registering the test + * tracker, we'll let them continue. + */ + if (ReqStatus(vrequest) == V_E_CANCEL) { + VSDestroyRequest(vrequest); + return 0; + } + vstatus = VSProcessRequest(vrequest); + /* + * Only complain periodically, if the test tracker isn't + * working... + */ + if (v_complain(vstatus, app_ini)) { + WinVSReportRequest(vrequest, NULL, + "Version Server Status Report"); + } + if (vstatus == V_REQUIRED) { + SetCursor(LoadCursor(NULL, IDC_WAIT)); + VSDestroyRequest(vrequest); + return( -1 ); + } + VSDestroyRequest(vrequest); + return (0); +} +#endif + +#ifdef TIMEBOMB +static krb5_error_code do_timebomb() +{ + char buf[1024]; + long timeleft; + static first_time = 1; + + timeleft = TIMEBOMB - time(0); + if (timeleft <= 0) { + if (first_time) { + sprintf(buf, "Your version of %s has expired.\n", + TIMEBOMB_PRODUCT); + buf[sizeof(buf) - 1] = '\0'; + strncat(buf, "Please upgrade it.", sizeof(buf) - 1 - strlen(buf)); +#ifdef TIMEBOMB_INFO + strncat(buf, TIMEBOMB_INFO, sizeof(buf) - 1 - strlen(buf)); +#endif + MessageBox(NULL, buf, "", MB_OK); + first_time = 0; + } + return TIMEBOMB_ERROR; + } + timeleft = timeleft / ((long) 60*60*24); + if (timeleft < TIMEBOMB_WARN) { + if (first_time) { + sprintf(buf, "Your version of %s will expire in %ld days.\n", + TIMEBOMB_PRODUCT, timeleft); + strncat(buf, "Please upgrade it soon.", sizeof(buf) - 1 - strlen(buf)); +#ifdef TIMEBOMB_INFO + strncat(buf, TIMEBOMB_INFO, sizeof(buf) - 1 - strlen(buf)); +#endif + MessageBox(NULL, buf, "", MB_OK); + first_time = 0; + } + } + return 0; +} +#endif + +/* + * This was originally called from LibMain; unfortunately, Windows 3.1 + * doesn't allow you to make messaging calls from LibMain. So, we now + * do the timebomb/version server stuff from krb5_init_context(). + */ +krb5_error_code krb5_vercheck() +{ + static int verchecked = 0; + if (verchecked) + return 0; +#ifdef TIMEBOMB + krb5_error_code retval = do_timebomb(); + if (retval) + return retval; +#endif +#ifdef VERSERV +#if 0 + /* Check library ? */ + if (CallVersionServer(APP_TITLE, APP_VER, APP_INI, NULL)) + return KRB5_LIB_EXPIRED; +#endif + { +#ifdef APP_TITLE + if (CallVersionServer(APP_TITLE, APP_VER, APP_INI, NULL)) + return VERSERV_ERROR; +#else + char AppTitle[APPVERINFO_SIZE]; + char AppVer[APPVERINFO_SIZE]; + char AppIni[APPVERINFO_SIZE]; + BOOL VSflag=TRUE; + + GetCallingAppVerInfo( AppTitle, AppVer, AppIni, &VSflag); + + if (VSflag) { + if (CallVersionServer(AppTitle, AppVer, AppIni, NULL)) + return KRB5_APPL_EXPIRED; + } +#endif + + } +#endif + verchecked = 1; + return 0; +} + + +static HINSTANCE hlibinstance; + +HINSTANCE get_lib_instance() +{ + return hlibinstance; +} + +#define DLL_STARTUP 0 +#define DLL_SHUTDOWN 1 + +static int +control(int mode) +{ + switch(mode) { + case DLL_STARTUP: + break; + + case DLL_SHUTDOWN: +#ifdef KRB5 + krb5_stdcc_shutdown(); +#endif + break; + +#if defined(ENABLE_THREADS) && defined(SUPPORTLIB) + case DLL_THREAD_DETACH: + krb5int_thread_detach_hook(); + return 0; +#endif + + default: + return -1; + } + +#if defined KRB5 + switch (mode) { + case DLL_STARTUP: + profile_library_initializer__auxinit(); + cryptoint_initialize_library__auxinit(); + krb5int_lib_init__auxinit(); + break; + case DLL_SHUTDOWN: + krb5int_lib_fini(); + cryptoint_cleanup_library(); + profile_library_finalizer(); + break; + } +#elif defined GSSAPI + switch (mode) { + case DLL_STARTUP: + gssint_mechglue_init__auxinit(); + break; + case DLL_SHUTDOWN: + gssint_mechglue_fini(); + break; + } +#elif defined COMERR + switch (mode) { + case DLL_STARTUP: + com_err_initialize__auxinit(); + break; + case DLL_SHUTDOWN: + com_err_terminate(); + break; + } +#elif defined PROFILELIB + switch (mode) { + case DLL_STARTUP: + profile_library_initializer__auxinit(); + break; + case DLL_SHUTDOWN: + profile_library_finalizer(); + break; + } +#elif defined SUPPORTLIB + switch (mode) { + case DLL_STARTUP: + krb5int_thread_support_init__auxinit(); + break; + case DLL_SHUTDOWN: + krb5int_thread_support_fini(); + break; + } +#else +# error "Don't know the init/fini functions for this library." +#endif + + return 0; +} + +#ifdef _WIN32 + +BOOL WINAPI DllMain (HANDLE hModule, DWORD fdwReason, LPVOID lpReserved) +{ + switch (fdwReason) + { + case DLL_PROCESS_ATTACH: + hlibinstance = (HINSTANCE) hModule; + if (control(DLL_STARTUP)) + return FALSE; + break; + + case DLL_THREAD_ATTACH: + break; + + case DLL_THREAD_DETACH: + if (control(DLL_THREAD_DETACH)) + return FALSE; + break; + + case DLL_PROCESS_DETACH: + if (control(DLL_SHUTDOWN)) + return FALSE; + break; + + default: + return FALSE; + } + + return TRUE; // successful DLL_PROCESS_ATTACH +} + +#else + +BOOL CALLBACK +LibMain (hInst, wDataSeg, cbHeap, CmdLine) +HINSTANCE hInst; +WORD wDataSeg; +WORD cbHeap; +LPSTR CmdLine; +{ + hlibinstance = hInst; + if (control(DLL_STARTUP)) + return 0; + else + return 1; +} + +int CALLBACK __export +WEP(nParam) + int nParam; +{ + if (control(DLL_SHUTDOWN)) + return 0; + else + return 1; +} + +#endif |
