1 /***********************************************************************/
2 /* Open Visualization Data Explorer */
3 /* (C) Copyright IBM Corp. 1989,1999 */
4 /* ALL RIGHTS RESERVED */
5 /* This code licensed under the */
6 /* "IBM PUBLIC LICENSE - Open Visualization Data Explorer" */
7 /***********************************************************************/
8
9 #if defined(DXD_LICENSED_VERSION)
10 fjdasjfasjhsjasf
11 #endif
12
13 #include <dxconfig.h>
14
15
16 #include <DXStrings.h>
17
18 // This nonsense surrounds sys/types.h because its typedef for boolean conflicts
19 // with one from defines.h. Many includes are ifdef on ARCH because of the
20 // need for select().
21 #if defined(solaris)
22 #define boolean bool
23 #endif
24
25 #include <sys/types.h>
26
27 #if defined(solaris)
28 #undef boolean
29 #endif
30
31 #include <stdio.h>
32 #include <time.h>
33
34 #if defined(HAVE_UNISTD_H)
35 #include <unistd.h>
36 #endif
37
38 #if defined(sgi)
39 #include <bstring.h>
40 #endif
41
42 #if defined(ibm6000)
43 #include <sys/select.h>
44 #endif
45
46 #if defined(HAVE_SYS_UTSNAME_H)
47 #include <sys/utsname.h>
48 #endif
49
50 #if defined(HAVE_SYS_TIMEB_H)
51 #include <sys/timeb.h>
52 #elif defined(HAVE_SYS_TIME_H)
53 #include <sys/time.h>
54 #endif
55
56 #if defined(_AIX41)
57 #include <strings.h>
58 #endif
59
60 #if defined(aviion)
61 extern "C" { void bzero(char *, int); }
62 #endif
63
64 #include <X11/Intrinsic.h>
65
66 #include "IBMApplication.h"
67
68 #include "License.h"
69
70 #if defined(DXD_LICENSED_VERSION) && DXD_LICENSED_VERSION!=0
71 # define NEEDS_LICENSE_ROUTINES 1
72 #else
73 # define NEEDS_LICENSE_ROUTINES 0
74 #endif
75
76 #if NEEDS_LICENSE_ROUTINES
77
78 extern "C" {
79
80
81 #if (defined(sgi) && !( __mips > 1)) || defined(aviion)
82 const char *crypt(const char*, const char*);
83 #endif
84
85 #if defined(solaris)
86 #include <crypt.h>
87 #endif
88
89 #ifdef sun4
90 int gethostid();
91 int getdtablesize();
92 #endif
93
94
95 #ifdef sgi
96 unsigned sysid(unsigned char id[]);
97 int getdtablesize(void);
98 #endif
99
100
101 #if defined(aviion)
102 int gethostid();
103 int getdtablesize();
104 int gettimeofday(struct timeval*, struct timezone*);
105 #endif
106
107 #ifdef alphax
108 #include <crypt.h>
109 int getdtablesize();
110 #include <stdio.h> /* standard I/O */
111 #include <errno.h> /* error numbers */
112
113 #if defined(windows) && defined(HAVE_WINSOCK_H)
114 #include <winsock.h>
115 #elif defined(HAVE_CYGWIN_SOCKET_H)
116 #include <cygwin/socket.h>
117 #elif defined(HAVE_SYS_SOCKET_H)
118 #include <sys/socket.h>
119 #endif
120
121 #include <sys/ioctl.h> /* ioctls */
122 #include <net/if.h> /* generic interface structures */
123 #include <sys/systeminfo.h> /* maybe someday this will be implemented...arg! */
124 extern "C" int select(
125 int nfds,
126 fd_set *readfds,
127 fd_set *writefds,
128 fd_set *exceptfds,
129 struct timeval *timeout) ;
130 #endif
131
132 }
133 #define CRYPT(A,B) crypt((const char*)A, (const char*)B)
134
135 #define ANYWHERE_HOSTID "00000000"
136
137 #if defined(DXD_LICENSED_VERSION) && !defined(HAVE_CRYPT)
138 error: Can not run licensing routines without crypt()
139 #endif
140
141 static int checkexp(const char *root);
142
143 #endif // NEEDS_LICENSE_ROUTINES
144
145 #ifndef DXD_WIN
146
UIGetLicense(const char * root,XtInputCallbackProc lostLicense,LicenseTypeEnum * appLic,LicenseTypeEnum * funcLic)147 void UIGetLicense(const char *root,
148 XtInputCallbackProc lostLicense,
149 LicenseTypeEnum *appLic,
150 LicenseTypeEnum *funcLic)
151 {
152 #if !NEEDS_LICENSE_ROUTINES
153 *appLic = FullyLicensed;
154 *funcLic = FullFunctionLicense;
155 return;
156 #else
157
158 LicenseTypeEnum forcedFuncLic;
159 int i;
160 int child;
161 int child_in[2],child_out[2];
162 char remname[1024];
163 char auth_msg[AUTH_MSG_LEN];
164 char ckey[128];
165 char c_buf[128],p_buf[128]; /* hold crypted msgs for comaparison */
166 char envbuf[128];
167 char salt[32];
168 time_t ctime;
169
170
171 if (checkexp (root)) { /* check for an old syle trial license */
172 *appLic = NodeLockedLicense;
173 *funcLic = FullFunctionLicense;
174 return;
175 }
176
177
178 /* didn't find a trial license so spawn the NetLS licensing process */
179 *appLic = Unlicensed;
180 forcedFuncLic = *funcLic;
181 *funcLic = Unlicensed;
182
183 /* Set up two pipes */
184 if (pipe(child_in) < 0) {
185 perror("pipe(child_in)");
186 return;
187 }
188
189 if (pipe(child_out) < 0) {
190 perror("pipe(child_out)");
191 return ;
192 }
193
194 ctime=time(NULL);
195
196 sprintf(envbuf,"_DX_%d=",getpid());
197 sprintf(c_buf,"%x",ctime);
198 strcat(envbuf,c_buf+4);
199 putenv(DuplicateString(envbuf));
200
201
202 child = 0xffff&fork();
203
204
205 if (child == 0) { /* Child */
206
207 char arg1[512];
208 char arg2[512];
209 char arg3[512];
210 #ifdef hp700
211 int width = MAXFUPLIM;
212 #else
213 #ifdef solaris
214 int width = FD_SETSIZE;
215 #else
216 int width = getdtablesize();
217 #endif
218 #endif
219
220 close(child_in[1]);
221 close(child_out[0]);
222
223 if (dup2(child_in[0], 0) < 0)
224 exit(1);
225
226 if (dup2(child_out[1], 1) < 0)
227 exit(1);
228
229 /* close other file descriptors here */
230 #if !defined(__PURIFY__)
231 // purify uses some file descriptors
232 for (i=3 ; i<=width ; i++)
233 close(i);
234 #endif
235
236 char *s;
237 if (s = getenv("DXSHADOW"))
238 strcpy(remname,s);
239 else
240 sprintf(remname,"%s/bin_%s/dxshadow",root,DXD_ARCHNAME);
241
242 switch (forcedFuncLic) {
243 case RunTimeLicense: strcpy(arg1,"-rtonly"); break;
244 case DeveloperLicense: strcpy(arg1,"-devonly"); break;
245 default: strcpy(arg1,"-dev"); break;
246 }
247 int maj, min,mic;
248 theIBMApplication->getVersionNumbers(&maj,&min,&mic);
249 sprintf(arg3,"%d.%d.%d",maj,min,mic);
250
251 execlp(remname, "dxshadow", arg1, "-version", arg3, NULL);
252
253 //
254 // If we get here, we failed.
255 //
256 fprintf(stderr,"License Error: could not exec license process\n");
257 exit(1);
258 }
259
260 //
261 // Only the parent gets here
262 //
263 close (child_in[0]);
264 close (child_out[1]);
265
266 /* wait for response from the child */
267
268 #define USE_SUB_EVENT_LOOP 1
269 #if USE_SUB_EVENT_LOOP
270 // Instead of doing a blocking read... and instead of writing a communication
271 // subsystem, monitor all sockets of interest. When something arrives, service
272 // it. As a result, X Events still get processed and we achieve a little extra
273 // concurrency which should decrease startup time. According to Quantify,
274 // we were spending lots of time inside the call to read().
275 // The loop waits approximately 5 seconds. If dxshadow takes longer than that,
276 // then execution continues by sitting in the read() command as it used to.
277 fd_set rdfds;
278 XEvent event;
279 FD_ZERO(&rdfds);
280 Display *d = theApplication->getDisplay();
281 XtAppContext app = theApplication->getApplicationContext();
282 timeval tval, starttime;
283 gettimeofday (&starttime, NULL);
284 while (!FD_ISSET(child_out[0], &rdfds)) {
285 FD_SET (child_out[0], &rdfds);
286 FD_SET (ConnectionNumber(d), &rdfds);
287 tval.tv_sec = 1; tval.tv_usec = 0;
288 if (select (32, (SELECT_ARG_TYPE *)&rdfds, NULL, NULL, &tval) == -1) break;
289 XtInputMask mask;
290 while ((mask = XtAppPending (app)) & (XtIMXEvent|XtIMTimer)) {
291 if (XtIMXEvent & mask) {
292 XtAppNextEvent (app, &event);
293 theIBMApplication->passEventToHandler (&event);
294 }
295 if (XtIMTimer & mask) {
296 XtAppProcessEvent (app, XtIMTimer);
297 }
298 }
299 if (gettimeofday (&tval, NULL) == -1) break;
300 if ((tval.tv_sec - starttime.tv_sec) >= 10) break;
301 }
302 #endif
303 i = read(child_out[0],auth_msg,AUTH_MSG_LEN);
304
305 if (!i) {
306 fprintf(stderr,"License Error\n");
307 goto unlicensed;
308 }
309
310 /* decipher license message here */
311
312 child = (child<4096)?(child+4096):(child); /* forces to be 4 0x chars */
313
314 strcpy(ckey,c_buf+4);
315 sprintf(ckey+4,"%x",child);
316
317 salt[0] = '7';
318 salt[1] = 'q';
319 salt[2] = '\0';
320
321 strcpy(p_buf,CRYPT(ckey,salt));;
322
323 for(i=0;i<13;i++)
324 c_buf[i] = auth_msg[(i*29)+5];
325 c_buf[13] = '\0';
326
327 if (strcmp(c_buf,p_buf)) {
328
329 /* Bad message from child */
330
331 fprintf(stderr,"License error\n");
332 goto unlicensed;
333 }
334
335 /* valid message so we extract license type */
336
337 for(i=0;i<8;i++)
338 c_buf[i] = auth_msg[(i*3)+37];
339
340 c_buf[8] = '\0';
341
342 sscanf(c_buf,"%x",&i);
343 *appLic = (LicenseTypeEnum)(0xffff & (i^child));
344 i = i >> 16;
345 *funcLic = (LicenseTypeEnum)(0xffff & (i^child));
346 #if 000
347 fprintf(stderr,"c_buf = '%s', funcLic = 0x%x, appLic = 0x%x\n",
348 c_buf,*funcLic,*appLic);
349 #endif
350
351 const char* lic_name;
352 switch (*funcLic) {
353 case DeveloperLicense: lic_name = "DX development"; break;
354 case RunTimeLicense: lic_name = "DX run-time"; break;
355 default:
356 fprintf(stderr,"Unrecognized license\n");
357 goto unlicensed;
358 break;
359 }
360
361 switch (*appLic) {
362
363 case NodeLockedLicense:
364
365 #ifdef DEBUG
366 fprintf(stderr,"Got nodelocked %s license\n",lic_name);
367 #endif
368 return;
369
370 case ConcurrentLicense:
371
372 #ifdef DEBUG
373 fprintf(stderr,"Got concurrent %s license\n",lic_name);
374 #endif
375
376 XtAppAddInput(theIBMApplication->getApplicationContext(),
377 child_out[0],
378 (XtPointer)(XtInputReadMask),
379 lostLicense,
380 (XtPointer)NULL);
381
382 return ;
383
384
385 case Unlicensed:
386
387 #ifdef DEBUG
388 fprintf(stderr,"Could not get a license\n");
389 #endif
390 break;
391
392
393 default: /* invalid license type */
394 #ifdef DEBUG
395
396 fprintf(stderr,"License Error: Invalid License Type\n");
397 #endif
398 goto unlicensed;
399 }
400
401
402 unlicensed:
403 *appLic = Unlicensed;
404 *funcLic = Unlicensed;
405 return;
406
407 #endif // NEEDS_LICENSE_ROUTINES
408 }
409
410
411
412
413
414
415 /* This function creates the message which will tell the exec if it
416 * is OK to run without a license. inkey must be at least char[14]
417 * and should contain the key returned from the $getkey. type
418 * should be either ConcurrentLicense or NodeLockedLicense. On return
419 * inkey holds the string to send to the exec with $license.
420 * The returned string must be freed by the caller.
421 */
422
GenerateExecKey(const char * inkey,LicenseTypeEnum licenseType)423 char *GenerateExecKey(const char *inkey, LicenseTypeEnum licenseType)
424 {
425
426 #if NEEDS_LICENSE_ROUTINES
427
428 int i;
429 char keybuf[64];
430 char cryptbuf[64];
431 char salt[8];
432
433 for(i=0;i<4;i++)
434 keybuf[i*2]=inkey[i];
435
436 keybuf[1] = 'g';
437 keybuf[3] = '3';
438 keybuf[5] = '$';
439 keybuf[7] = 'Q';
440 keybuf[8] = '\0';
441
442 salt[0] = '4';
443 salt[1] = '.';
444 salt[2] = '\0';
445
446 strcpy(cryptbuf,CRYPT(keybuf,salt));
447
448 char *outkey = new char[64];
449 sprintf(outkey,"%s%hx",cryptbuf,
450 (unsigned short)licenseType ^
451 (*((unsigned char *)&cryptbuf[4])<<8)+(*((unsigned char *)&cryptbuf[5])));
452
453 return outkey;
454 #else
455 return NULL;
456 #endif // NEEDS_LICENSE_ROUTINES
457
458 }
459
460
461
462
463 #if NEEDS_LICENSE_ROUTINES
464
465 #define KEY1 "a9"
466 #define KEY2 "Pp"
467
468 #if defined(aviion) || defined(solaris)
469 #include <sys/systeminfo.h>
470 #if defined(aviion)
471 extern "C" {
472 long sysinfo (int command, char *buf, long count);
473 }
474 #endif
475 #endif
476
477 #ifdef alphax
478 extern "C" int gethostid(void);
479 #endif
480
checkexp(const char * root)481 static int checkexp(const char *root)
482 {
483 #if !DXD_HAS_CRYPT
484 return (1);
485 #else
486 int host_match;
487 char key[32];
488 char cryptHost[1024];
489 char cryptTime[1024];
490 char host[512];
491 time_t timeOut;
492 int i;
493 char *myCryptHost;
494 struct timeval sysTime;
495 #if defined(ibm6000) || defined(hp700)
496 struct utsname name;
497 #endif
498 #if defined(sgi) || defined(sun4) || defined (alphax)
499 long name;
500 #endif
501 time_t time;
502 char fileName[1024];
503 FILE *f;
504
505 for (i = 0; i < sizeof(key); ++i)
506 key[i] = '\0';
507
508 #ifdef ibm6000
509 #define FOUND_ID 1
510 uname(&name);
511 name.machine[10] = '\0';
512 strcpy(host, name.machine+2);
513 #endif
514 #if hp700
515 #define FOUND_ID 1
516 uname(&name);
517 name.idnumber[10] = '\0';
518 strcpy(host, name.idnumber+2);
519 #endif
520 #if sgi /* sgi does not like #if...#elif..#endif construct */
521 #define FOUND_ID 1
522 name = sysid(NULL);
523 sprintf(host, "%d", name);
524 strcpy(host, host+2);
525 #endif
526 #if sun4
527 #define FOUND_ID 1
528 name = gethostid();
529 sprintf(host, "%x", name);
530 #endif
531 #if aviion
532 #define FOUND_ID 1
533 sysinfo(SI_HW_SERIAL,host,301);
534 #endif
535 #if solaris
536 #define FOUND_ID 1
537 sysinfo(SI_HW_SERIAL,host,301);
538 sprintf(host, "%x", atol(host));
539 #endif
540 #if defined(alphax)
541 #ifdef SYSINFO_WORKS
542 // The man page for OSF/1 V2 says that SI_HW_SERIAL does not work. We'll use it
543 // for now even though it doesn't work. So far it looks like the only mechanism
544 // to get unique ids.
545 sysinfo(SI_HW_SERIAL,host,301);
546 sprintf(host, "%x", atol(host));
547 #else
548 {
549 char *device;
550 char *dflt_devices[] = {"tu0","ln0", NULL };
551 int s,i; /* On Alpha OSF/1 we use ethernet */;
552
553 /* Get a socket */
554 strcpy(host,"");
555 s = socket(AF_INET,SOCK_DGRAM,0);
556 if (s < 0) {
557 perror("socket");
558 } else {
559 for (i=0, device=(char*)getenv("DXKEYDEVICE"); dflt_devices[i]; i++) {
560 static struct ifdevea devea; /* MAC address from and ioctl() */
561 char *dev, buf[32];
562 if (!device)
563 dev = dflt_devices[i];
564 else
565 dev = device;
566 strcpy(devea.ifr_name,dev);
567 if (ioctl(s,SIOCRPHYSADDR,&devea) >= 0) {
568 strcpy(host,"");
569 for (i = 2; i < 6; i++){
570 sprintf(buf,"%x", devea.default_pa[i] );
571 strcat(host,buf);
572 }
573 break;
574 }
575 if (device) break;
576 }
577 close(s);
578 }
579 }
580
581 #endif
582 #define FOUND_ID 1
583 #endif
584 #if !defined(FOUND_ID)
585 Trial version not supported on this architecture.
586 #else
587 # undef FOUND_ID
588 #endif
589
590 gettimeofday(&sysTime, NULL);
591 time = sysTime.tv_sec;
592
593 if (getenv("DXTRIALKEY")) {
594 char *k = getenv("DXTRIALKEY");
595 fprintf(stderr, "Data Explorer trial password found in"
596 " DXTRIALKEY environment variable\n");
597 strncpy(key,k,27);
598 key[27] = '\0'; // Make sure it is terminated
599 } else {
600 char *fname;
601 fname = getenv("DXTRIALKEYFILE");
602 if (!fname) {
603 sprintf(fileName, "%s/expiration", root);
604 fname = fileName;
605 }
606 f = fopen(fname, "r");
607 if (f) {
608 fprintf(stderr, "Data Explorer trial password found in file %s\n",
609 fname);
610 fgets(key, 27, f);
611 fclose(f);
612 } else {
613 return 0;
614 }
615 }
616
617
618 if (strlen(key) != 26) {
619 fprintf(stderr, "You are running an expired Trial version of Data Explorer\n");
620 return(0);
621 }
622
623 for (i = 0; i < 13; ++i) {
624 cryptHost[i] = key[2 * i];
625 cryptTime[i] = key[2 * i + 1];
626 }
627 cryptHost[i] = key[2 * i] = '\0';
628 cryptTime[i] = key[2 * i + 1] = '\0';
629
630 if (cryptTime[0] != 'A' ||
631 cryptTime[10] != '9' ||
632 cryptTime[12] != 'D') {
633 fprintf(stderr, "You are running an Expired trial version of Data Explorer\n");
634 return(0);
635 }
636
637
638 myCryptHost = (char*)CRYPT(host,KEY1);
639 host_match = strcmp(cryptHost, myCryptHost) == 0;
640 if (!host_match) {
641 myCryptHost = (char*)CRYPT(ANYWHERE_HOSTID,KEY1);
642 host_match = strcmp(cryptHost, myCryptHost) == 0;
643 }
644 if (!host_match) {
645 fprintf(stderr,
646 "You are running a trial version of Data Explorer on an"
647 " unlicensed host\n");
648 return (0);
649 }
650
651 if(cryptTime[1]=='s')
652 sscanf(cryptTime, "As%08x95D", &timeOut);
653 else if (cryptTime[1]=='m')
654 sscanf(cryptTime, "Am%08x9lD", &timeOut);
655
656
657 timeOut ^= 0x12345678;
658
659 if (time > timeOut) {
660 fprintf(stderr, "You are running an expired trial version of Data Explorer\n");
661 fprintf(stderr,"This trial key expired on %s", ctime(&timeOut));
662 return (0);
663 }
664 fprintf(stderr,"This Data Explorer trial key will expire on %s",
665 ctime(&timeOut));
666 return (1);
667 #endif /* DXD_HAS_CRYPT */
668 }
669
670 #ifdef ibm6000
671 // Some very strange declarations that allow AIX 3.2.4 systems to link.
672 // These symbols are statics inside of "crypt.c" in /usr/lib/libc.a, but
673 // are referenced in the mapping defined for the shared library. Therefore,
674 // the system won't link without them.
675 extern "C" char __setkey[1024];
676 extern "C" char __crypt[1024];
677 extern "C" char __encrypt[1024];
678 char __setkey[1024];
679 char __crypt[1024];
680 char __encrypt[1024];
681 #endif
682
683 #endif // NEEDS_LICENSE_ROUTINES
684
685 #else // DXD_WIN
686 #if 0
687
688 #include <windows.h>
689 #include <math.h>
690
691 static int getregval(char *name, char *value)
692 {
693 char key[500];
694 int valtype;
695 unsigned long sizegot = 500;
696 int word;
697 char errstr[200];
698 HKEY hkey[10];
699 long rc;
700 int i, k=0;
701
702 #define iferror(s) \
703 if (rc != ERROR_SUCCESS) { \
704 strcpy(errstr, s); \
705 goto error; \
706 }
707
708 strcpy(value, "");
709 word = 0;
710 strcpy(key, "SOFTWARE");
711
712 rc = RegOpenKeyEx(HKEY_LOCAL_MACHINE, (LPCTSTR) key, 0,
713 KEY_QUERY_VALUE, &hkey[k++]);
714
715 strcat(key, "\\OpenDX");
716 rc = RegOpenKeyEx(HKEY_LOCAL_MACHINE, (LPCTSTR) key, 0,
717 KEY_QUERY_VALUE, &hkey[k++]);
718 iferror("Error opening key");
719
720 strcat(key, "\\Open Visualization Data Explorer");
721 rc = RegOpenKeyEx(HKEY_LOCAL_MACHINE, (LPCTSTR) key, 0,
722 KEY_QUERY_VALUE, &hkey[k++]);
723 iferror("Error opening key");
724
725 strcat(key, "\\CurrentVersion");
726 rc = RegOpenKeyEx(HKEY_LOCAL_MACHINE, (LPCTSTR) key, 0,
727 KEY_QUERY_VALUE, &hkey[k++]);
728 iferror("Error opening key");
729
730 rc = RegQueryValueEx(hkey[k-1], (LPTSTR) name, (LPDWORD) 0,
731 (LPDWORD) &valtype, (LPBYTE) value, &sizegot);
732 iferror("Query value failed");
733
734 for (i=k; i > 0; i--) {
735 rc = RegCloseKey(hkey[i-1]);
736 iferror("CloseKey failed");
737 }
738
739 switch(valtype) {
740 case REG_DWORD:
741 word = *((int *)value);
742 value = "";
743 break;
744 case REG_SZ:
745 break;
746 default:
747 return 0;
748 }
749
750 return 1;
751
752 error:
753 fprintf(stderr, "%s: rc = %d\n", errstr, rc);
754 return 0;
755 }
756
757 static int keyformat(char *k)
758 {
759 int i;
760 char buf[25];
761 char *p;
762
763 for (i=0, p=k; *p && i<20; p++) {
764 if (isalpha(*p))
765 buf[i++] = tolower(*p);
766 if (isdigit(*p))
767 buf[i++] = *p;
768 if (i==5 || i==10 || i==15)
769 buf[i++] = ' ';
770 }
771 buf[i] = '\0';
772 if (strlen(buf) != 20)
773 return 0;
774 strcpy(k, buf);
775 return 1;
776 }
777
778 int getuserinforeg(char *username, char *userco, char *keystr)
779 {
780 *username = '\0';
781 *userco = '\0';
782 *keystr = '\0';
783 getregval("UserName", username);
784 getregval("CompanyName", userco);
785 getregval("LicenseKey", keystr);
786 keyformat(keystr);
787 return 1;
788 }
789
790 static int gettimenow(int *m, int *d, int *y)
791 {
792 SYSTEMTIME t;
793 GetSystemTime(&t);
794 *m = t.wMonth;
795 *d = t.wDay;
796 *y = t.wYear;
797 return 1;
798 }
799
800 static int addtotime(int *m, int *d, int *y)
801 {
802 int mm, dd, yy;
803
804 gettimenow(&mm, &dd, &yy);
805 *y += yy;
806 *m += mm;
807 if (*m>12) {
808 *y += (*m-1)/12;
809 *m = *m%12 + 1;
810 }
811 *d += dd;
812 if (*d > 28) {
813 (*m)++;
814 *d = *d%31;
815 }
816 if (*m>12) {
817 *y += (*m-1)/12;
818 *m = *m%12 + 1;
819 }
820 return 1;
821 }
822
823 static int genkey(char *keystr, char *username, char *userco,
824 int m, int d, int y, char lictype)
825 {
826 char *p, *q;
827 unsigned int key, key1, key2, key3, prime;
828 int i;
829 char data[500];
830
831 data[0] = (char)(m + (int)'a');
832 if (d > 20)
833 data[0] = (char)((int)data[0] + 13);
834 data[1] = (char)(d%20 + (int)'b');
835 data[2] = (char)((y - 1994)/10 + (int)'g');
836 data[3] = (char)((y - 1994)%10 + (int)'m');
837 if (!lictype)
838 lictype = 't';
839 data[4] = lictype;
840
841 q = &data[5];
842 for (p=username; *p; p++)
843 if (!isspace(*p) && !ispunct(*p))
844 *(q++) = tolower(*p);
845 for (p=userco; *p; p++)
846 if (!isspace(*p) && !ispunct(*p))
847 *(q++) = tolower(*p);
848 *q = '\0';
849
850 key = 99;
851 key = key * 100 + 99;
852 key = key * 100 + 83;
853
854 prime = 4999;
855 prime = prime * 1000 + 999;
856
857 for (i = 0, p=data; *p; p++, i++)
858 key += (*p * (i + key)) * prime;
859
860 key %= 10000000000;
861 key1 = key/100000000;
862 key2 = key%100000000;
863 key2 /= 10000;
864 key3 = key%10000;
865 sprintf(keystr, "%c%c%c%c%c %04d %04d %04d", data[0],
866 data[1], data[2], data[3], data[4], key1, key2, key3);
867 return 1;
868 }
869
870 int getdatefromkey(char *keystr, int *m, int *d, int *y)
871 {
872 *m = (int)keystr[0] - (int)'a';
873 *d = (int)keystr[1] - (int)'b';
874 if (*m > 12) {
875 *m -= 13;
876 *d += 20;
877 }
878 if (*d < 1)
879 *d = 1;
880 if (*d > 31)
881 *d = 31;
882 *y = ((int)keystr[2] - (int)'g') * 10 +
883 (int)keystr[3] - (int)'m' + 1994;
884 return 1;
885 }
886
887 static int isexpired(char *keystr)
888 {
889 int m, d, y;
890 int ms, ds, ys;
891
892 gettimenow(&ms, &ds, &ys);
893 getdatefromkey(keystr, &m, &d, &y);
894 if (ys > y)
895 return 1;
896 if (ys == y && ms > m)
897 return 1;
898 if (ys == y && ms == m && ds > d)
899 return 1;
900 return 0;
901 }
902
903 void UIGetLicense(const char *root,
904 XtInputCallbackProc lostLicense,
905 LicenseTypeEnum *appLic,
906 LicenseTypeEnum *funcLic)
907 {
908 char username[200];
909 char userco[200];
910 char keystrreg[100];
911 char keystr[100];
912 char lictype;
913 int m;
914 int d;
915 int y;
916 int expired;
917
918 *appLic = Unlicensed;
919 *funcLic = Unlicensed;
920 getuserinforeg(username, userco, keystrreg);
921 if (strlen(username) + strlen(userco) < 6) {
922 fprintf(stderr, "Improper registration: short username and company\n");
923 return;
924 }
925 if (!keyformat(keystrreg)) {
926 fprintf(stderr, "Improper registration: registration key is not in proper format: %s\n",
927 keystrreg);
928 return;
929 }
930 fprintf(stderr, "Registered to %s of %s\n", username, userco);
931 getdatefromkey(keystrreg, &m, &d, &y);
932 lictype = keystrreg[4];
933 genkey(keystr, username, userco, m, d, y, lictype);
934 if (strcmp(keystr, keystrreg)) {
935 fprintf(stderr, "Improper registration: key does not match user setup\n");
936 return;
937 }
938 expired = isexpired(keystrreg);
939 if (expired) {
940 fprintf(stderr, "Registration expired %d/%d/%d\n", m, d, y);
941 return;
942 }
943 // Don't show expire date if license isn't beta or trial
944 if (lictype == 'b' || lictype == 't')
945 fprintf(stderr, "Registration expires %d/%d/%d\n", m, d, y);
946 if (lictype == 'r') {
947 *appLic = NodeLockedLicense;
948 *funcLic = RunTimeLicense;
949 } else {
950 *appLic = FullyLicensed;
951 *funcLic = DeveloperLicense;
952 }
953 return;
954 }
955
956 char *GenerateExecKey(const char *inkey, LicenseTypeEnum licenseType)
957 {
958 return "No License Generated";
959 }
960 #endif
961 #endif // DXD_WIN
962