1 #include "k5-int.h"
2
3 #ifdef KRB5
4 #include "krb5_err.h"
5 #include "kv5m_err.h"
6 #include "asn1_err.h"
7 #include "kdb5_err.h"
8 #include "profile.h"
9 extern void krb5_stdcc_shutdown();
10 #endif
11 #ifdef GSSAPI
12 #include "gssapi/generic/gssapi_err_generic.h"
13 #include "gssapi/krb5/gssapi_err_krb5.h"
14 #endif
15
16
17 /*
18 * #defines for MIT-specific time-based timebombs and/or version
19 * server for the Kerberos DLL.
20 */
21
22 #ifdef SAP_TIMEBOMB
23 #define TIMEBOMB 865141200 /* 1-Jun-97 */
24 #define TIMEBOMB_PRODUCT "SAPGUI"
25 #define TIMEBOMB_WARN 15
26 #define TIMEBOMB_INFO " Please see the web page at:\nhttp://web.mit.edu/reeng/www/saphelp for more information"
27 #define TIMEBOMB_ERROR KRB5_APPL_EXPIRED
28 #endif
29
30 #ifdef KRB_TIMEBOMB
31 #define TIMEBOMB 865141200 /* 1-Jun-97 */
32 #define TIMEBOMB_PRODUCT "Kerberos V5"
33 #define TIMEBOMB_WARN 15
34 #define TIMEBOMB_INFO " Please see the web page at:\nhttp://web.mit.edu/reeng/www/saphelp for more information"
35 #define TIMEBOMB_ERROR KRB5_LIB_EXPIRED
36 #endif
37
38 /*
39 * #defines for using MIT's version server DLL
40 */
41 #ifdef SAP_VERSERV
42 #define APP_TITLE "KRB5-SAP"
43 #define APP_VER "3.0f"
44 #define APP_INI "krb5sap.ini"
45 #define VERSERV_ERROR KRB5_APPL_EXPIRED
46 #endif
47
48 #ifdef VERSERV
49 #define WINDOWS
50 #include <ver.h>
51 #include <vs.h>
52 #include <v.h>
53
54
55 /*
56 * This function will get the version resource information from the
57 * application using the DLL. This allows us to Version Serve
58 * arbitrary third party applications. If there is an error, or we
59 * decide that we should not version check the calling application
60 * then VSflag will be FALSE when the function returns.
61 *
62 * The buffers passed into this function must be at least
63 * APPVERINFO_SIZE bytes long.
64 */
65
66 #define APPVERINFO_SIZE 256
67
GetCallingAppVerInfo(char * AppTitle,char * AppVer,char * AppIni,BOOL * VSflag)68 void GetCallingAppVerInfo( char *AppTitle, char *AppVer, char *AppIni,
69 BOOL *VSflag)
70 {
71 char CallerFilename[_MAX_PATH];
72 LONG *lpLangInfo;
73 DWORD hVersionInfoID, size;
74 GLOBALHANDLE hVersionInfo;
75 LPSTR lpVersionInfo;
76 int dumint, retval;
77 char *cp;
78 char *revAppTitle;
79 char szVerQ[90];
80 LPBYTE locAppTitle;
81 LPBYTE locAppVer;
82 char locAppIni[_MAX_PATH];
83 #ifndef _WIN32
84 WORD wStackSeg;
85 #endif /* !_WIN32 */
86
87 /* first we need to get the calling module's filename */
88 #ifndef _WIN32
89 _asm {
90 mov wStackSeg, ss
91 };
92 retval = GetModuleFileName((HMODULE)wStackSeg, CallerFilename,
93 _MAX_PATH);
94 #else
95 /*
96 * Note: this may only work for single threaded applications,
97 * we'll live and learn ...
98 */
99 retval = GetModuleFileName( NULL, CallerFilename, _MAX_PATH);
100 #endif
101
102 if ( retval == 0 ) {
103 VSflag = FALSE;
104 return;
105 }
106
107 size = GetFileVersionInfoSize( CallerFilename, &hVersionInfoID);
108
109 if( size == 0 ) {
110 /*
111 * hey , I bet we don't have a version resource, let's
112 * punt
113 */
114 *VSflag = FALSE;
115 return;
116 }
117
118 hVersionInfo = GlobalAlloc(GHND, size);
119 lpVersionInfo = GlobalLock(hVersionInfo);
120
121 retval = GetFileVersionInfo( CallerFilename, hVersionInfoID, size,
122 lpVersionInfo);
123
124 retval = VerQueryValue(lpVersionInfo, "\\VarFileInfo\\Translation",
125 (LPSTR *)&lpLangInfo, &dumint);
126 wsprintf(szVerQ,
127 "\\StringFileInfo\\%04x%04x\\",
128 LOWORD(*lpLangInfo), HIWORD(*lpLangInfo));
129
130 cp = szVerQ + lstrlen(szVerQ);
131
132 lstrcpy(cp, "ProductName");
133
134
135 /* try a localAppTitle and then a strcpy 4/2/97 */
136
137 locAppTitle = 0;
138 locAppVer = 0;
139
140 retval = VerQueryValue(lpVersionInfo, szVerQ, &locAppTitle,
141 &dumint);
142
143 lstrcpy(cp, "ProductVersion");
144
145
146 retval = VerQueryValue(lpVersionInfo, szVerQ, &locAppVer,
147 &dumint);
148
149 if (!locAppTitle || !locAppVer) {
150 /* Punt, we don't have the right version resource records */
151 *VSflag = FALSE;
152 return;
153 }
154
155 /*
156 * We don't have a way to determine that INI file of the
157 * application at the moment so let's just use krb5.ini
158 */
159 strncpy( locAppIni, KERBEROS_INI, sizeof(locAppIni) - 1 );
160 locAppIni[ sizeof(locAppIni) - 1 ] = '\0';
161
162 strncpy( AppTitle, locAppTitle, APPVERINFO_SIZE);
163 AppTitle[APPVERINFO_SIZE - 1] = '\0';
164 strncpy( AppVer, locAppVer, APPVERINFO_SIZE);
165 AppVer[APPVERINFO_SIZE - 1] = '\0';
166 strncpy( AppIni, locAppIni, APPVERINFO_SIZE);
167 AppIni[APPVERINFO_SIZE - 1] = '\0';
168
169 /*
170 * We also need to determine if we want to suppress version
171 * checking of this application. Does the tail of the
172 * AppTitle end in a "-v" ?
173 */
174 revAppTitle = _strrev( _strdup(AppTitle));
175 if( revAppTitle[0] == 'v' || revAppTitle[0] == 'V' &&
176 revAppTitle[1] == '-' ) {
177 VSflag = FALSE;
178 }
179 return;
180 }
181
182
183 /*
184 * Use the version server to give us some control on distribution and usage
185 * We're going to test track as well
186 */
CallVersionServer(app_title,app_version,app_ini,code_cover)187 static int CallVersionServer(app_title, app_version, app_ini, code_cover)
188 char *app_title;
189 char *app_version;
190 char *app_ini;
191 char *code_cover;
192 {
193 VS_Request vrequest;
194 VS_Status vstatus;
195
196 SetCursor(LoadCursor(NULL, IDC_WAIT));
197
198 /*
199 * We should be able to pass in code_cover below, but things
200 * are breaking under Windows 16 for no good reason.
201 */
202 vrequest = VSFormRequest((LPSTR) app_title, (LPSTR) app_version,
203 (LPSTR) app_ini,
204 NULL /* code_cover */, NULL,
205 V_CHECK_AND_LOG);
206
207 SetCursor(LoadCursor(NULL, IDC_ARROW));
208 /*
209 * If the user presses cancel when registering the test
210 * tracker, we'll let them continue.
211 */
212 if (ReqStatus(vrequest) == V_E_CANCEL) {
213 VSDestroyRequest(vrequest);
214 return 0;
215 }
216 vstatus = VSProcessRequest(vrequest);
217 /*
218 * Only complain periodically, if the test tracker isn't
219 * working...
220 */
221 if (v_complain(vstatus, app_ini)) {
222 WinVSReportRequest(vrequest, NULL,
223 "Version Server Status Report");
224 }
225 if (vstatus == V_REQUIRED) {
226 SetCursor(LoadCursor(NULL, IDC_WAIT));
227 VSDestroyRequest(vrequest);
228 return( -1 );
229 }
230 VSDestroyRequest(vrequest);
231 return (0);
232 }
233 #endif
234
235 #ifdef TIMEBOMB
do_timebomb()236 static krb5_error_code do_timebomb()
237 {
238 char buf[1024];
239 long timeleft;
240 static first_time = 1;
241
242 timeleft = TIMEBOMB - time(0);
243 if (timeleft <= 0) {
244 if (first_time) {
245 sprintf(buf, "Your version of %s has expired.\n",
246 TIMEBOMB_PRODUCT);
247 buf[sizeof(buf) - 1] = '\0';
248 strncat(buf, "Please upgrade it.", sizeof(buf) - 1 - strlen(buf));
249 #ifdef TIMEBOMB_INFO
250 strncat(buf, TIMEBOMB_INFO, sizeof(buf) - 1 - strlen(buf));
251 #endif
252 MessageBox(NULL, buf, "", MB_OK);
253 first_time = 0;
254 }
255 return TIMEBOMB_ERROR;
256 }
257 timeleft = timeleft / ((long) 60*60*24);
258 if (timeleft < TIMEBOMB_WARN) {
259 if (first_time) {
260 sprintf(buf, "Your version of %s will expire in %ld days.\n",
261 TIMEBOMB_PRODUCT, timeleft);
262 strncat(buf, "Please upgrade it soon.", sizeof(buf) - 1 - strlen(buf));
263 #ifdef TIMEBOMB_INFO
264 strncat(buf, TIMEBOMB_INFO, sizeof(buf) - 1 - strlen(buf));
265 #endif
266 MessageBox(NULL, buf, "", MB_OK);
267 first_time = 0;
268 }
269 }
270 return 0;
271 }
272 #endif
273
274 /*
275 * This was originally called from LibMain; unfortunately, Windows 3.1
276 * doesn't allow you to make messaging calls from LibMain. So, we now
277 * do the timebomb/version server stuff from krb5_init_context().
278 */
krb5_vercheck()279 krb5_error_code krb5_vercheck()
280 {
281 static int verchecked = 0;
282 if (verchecked)
283 return 0;
284 #ifdef TIMEBOMB
285 krb5_error_code retval = do_timebomb();
286 if (retval)
287 return retval;
288 #endif
289 #ifdef VERSERV
290 {
291 #ifdef APP_TITLE
292 if (CallVersionServer(APP_TITLE, APP_VER, APP_INI, NULL))
293 return VERSERV_ERROR;
294 #else
295 char AppTitle[APPVERINFO_SIZE];
296 char AppVer[APPVERINFO_SIZE];
297 char AppIni[APPVERINFO_SIZE];
298 BOOL VSflag=TRUE;
299
300 GetCallingAppVerInfo( AppTitle, AppVer, AppIni, &VSflag);
301
302 if (VSflag) {
303 if (CallVersionServer(AppTitle, AppVer, AppIni, NULL))
304 return KRB5_APPL_EXPIRED;
305 }
306 #endif
307
308 }
309 #endif
310 verchecked = 1;
311 return 0;
312 }
313
314
315 static HINSTANCE hlibinstance;
316
get_lib_instance()317 HINSTANCE get_lib_instance()
318 {
319 return hlibinstance;
320 }
321
322 #define DLL_STARTUP 0
323 #define DLL_SHUTDOWN 1
324
325 static int
control(int mode)326 control(int mode)
327 {
328 switch(mode) {
329 case DLL_STARTUP:
330 break;
331
332 case DLL_SHUTDOWN:
333 #ifdef KRB5
334 krb5_stdcc_shutdown();
335 #endif
336 break;
337
338 #if defined(ENABLE_THREADS) && defined(SUPPORTLIB)
339 case DLL_THREAD_DETACH:
340 krb5int_thread_detach_hook();
341 return 0;
342 #endif
343
344 default:
345 return -1;
346 }
347
348 #if defined KRB5
349 switch (mode) {
350 case DLL_STARTUP:
351 profile_library_initializer__auxinit();
352 krb5int_lib_init__auxinit();
353 break;
354 case DLL_SHUTDOWN:
355 krb5int_lib_fini();
356 profile_library_finalizer();
357 break;
358 }
359 #elif defined GSSAPI
360 switch (mode) {
361 case DLL_STARTUP:
362 gssint_mechglue_init__auxinit();
363 break;
364 case DLL_SHUTDOWN:
365 gssint_mechglue_fini();
366 break;
367 }
368 #elif defined COMERR
369 switch (mode) {
370 case DLL_STARTUP:
371 com_err_initialize__auxinit();
372 break;
373 case DLL_SHUTDOWN:
374 com_err_terminate();
375 break;
376 }
377 #elif defined PROFILELIB
378 switch (mode) {
379 case DLL_STARTUP:
380 profile_library_initializer__auxinit();
381 break;
382 case DLL_SHUTDOWN:
383 profile_library_finalizer();
384 break;
385 }
386 #elif defined SUPPORTLIB
387 switch (mode) {
388 case DLL_STARTUP:
389 krb5int_thread_support_init__auxinit();
390 break;
391 case DLL_SHUTDOWN:
392 krb5int_thread_support_fini();
393 break;
394 }
395 #else
396 # error "Don't know the init/fini functions for this library."
397 #endif
398
399 return 0;
400 }
401
402 #ifdef _WIN32
403
DllMain(HANDLE hModule,DWORD fdwReason,LPVOID lpReserved)404 BOOL WINAPI DllMain (HANDLE hModule, DWORD fdwReason, LPVOID lpReserved)
405 {
406 switch (fdwReason)
407 {
408 case DLL_PROCESS_ATTACH:
409 hlibinstance = (HINSTANCE) hModule;
410 if (control(DLL_STARTUP))
411 return FALSE;
412 break;
413
414 case DLL_THREAD_ATTACH:
415 break;
416
417 case DLL_THREAD_DETACH:
418 if (control(DLL_THREAD_DETACH))
419 return FALSE;
420 break;
421
422 case DLL_PROCESS_DETACH:
423 if (control(DLL_SHUTDOWN))
424 return FALSE;
425 break;
426
427 default:
428 return FALSE;
429 }
430
431 return TRUE; // successful DLL_PROCESS_ATTACH
432 }
433
434 #else
435
436 BOOL CALLBACK
LibMain(hInst,wDataSeg,cbHeap,CmdLine)437 LibMain (hInst, wDataSeg, cbHeap, CmdLine)
438 HINSTANCE hInst;
439 WORD wDataSeg;
440 WORD cbHeap;
441 LPSTR CmdLine;
442 {
443 hlibinstance = hInst;
444 if (control(DLL_STARTUP))
445 return 0;
446 else
447 return 1;
448 }
449
450 int CALLBACK __export
WEP(nParam)451 WEP(nParam)
452 int nParam;
453 {
454 if (control(DLL_SHUTDOWN))
455 return 0;
456 else
457 return 1;
458 }
459
460 #endif
461