/***********************************************************************/ /* Open Visualization Data Explorer */ /* (C) Copyright IBM Corp. 1989,1999 */ /* ALL RIGHTS RESERVED */ /* This code licensed under the */ /* "IBM PUBLIC LICENSE - Open Visualization Data Explorer" */ /***********************************************************************/ #include #if defined(DXD_LICENSED_VERSION) #include #include #include #include #include #ifndef DXD_DO_NOT_REQ_UNISTD_H #include #endif #if defined(ibm6000) extern "C" void gettimer (int, struct timestruc_t* ); #endif #include "defines.h" #include "Strings.h" #if defined(aviion) || defined(solaris) || defined(sgi) #include #endif #if defined(ibm6000) || defined(hp700) #include #if defined(ibm6000) && !defined(_AIX41) extern "C" const char *crypt(const char* , const char*); #else extern "C" char *crypt(const char* , const char*); #endif #endif #if defined(aviion) || defined(solaris) || defined(sgi) #include #endif #if defined(sgi) && !( __mips > 1) extern "C" unsigned sysid(unsigned char *id); #endif #if defined(aviion) extern "C" long sysinfo (int , char *, long ); #endif #if defined(aviion) extern "C" int gettimeofday(struct timeval *); #endif #if defined(sun4) extern "C" long gethostid(); #endif #ifdef alphax #include int getdtablesize(); #include /* standard I/O */ #include /* error numbers */ #include /* socket definitions */ #include /* ioctls */ #include /* generic interface structures */ #include /* maybe someday this will be implemented...arg! */ extern "C" int select(int , fd_set *, fd_set *, fd_set *, struct timeval *) ; #endif #include "UIConfig.h" #include "TemporaryLicense.h" const char * TemporaryLicense::MakeKey (enum Arch arch, char *hostId, int months, int days, time_t *newTime, enum DxType type) { char host[9]; #if defined(ibm6000) struct timestruc_t sysTime; #else timeval sysTime; #endif struct tm timeStruct; char cryptHost[301]; char cryptTime[301]; int i; static char key[100]; if (strlen(hostId) > 8 || arch == IBM6000 || arch == HP700 || arch == SGI) strncpy(host, hostId+2, 8); else strncpy(host, hostId, 8); host[8] = '\0'; #if defined(aviion) gettimeofday(&sysTime); #else #if defined(ibm6000) gettimer(TIMEOFDAY, &sysTime); #else gettimeofday(&sysTime, NULL); #endif #endif #if defined(ibm6000) || defined(hp700) time_t tvs = sysTime.tv_sec; timeStruct = *localtime(&tvs); sysTime.tv_sec = (unsigned long)tvs; #else timeStruct = *localtime(&sysTime.tv_sec); #endif timeStruct.tm_mday += days; timeStruct.tm_mon += timeStruct.tm_mday / 30; timeStruct.tm_mday = timeStruct.tm_mday % 30; timeStruct.tm_mon += months; timeStruct.tm_year += timeStruct.tm_mon / 12; timeStruct.tm_mon = timeStruct.tm_mon % 12; #if defined(sun4) *newTime = timelocal(&timeStruct); #else *newTime = mktime(&timeStruct); #endif *newTime ^= XOR_KEY; if (type == UP) sprintf(cryptTime, "As%08x95D", *newTime); else if (type == SMP) sprintf(cryptTime, "Am%08x9lD", *newTime); *newTime ^= XOR_KEY; strcpy(cryptHost, crypt(host, KEY1)); for (i = 0; i < strlen(cryptHost); ++i) { key[2*i] = cryptHost[i]; key[2*i+1] = cryptTime[i]; } key[2*i] = '\0'; return key; } // // Warn the user that we're about to go away. Set a timer. When the timer // goes off, bye bye. // static void LostLicense(XtPointer , int* fid, XtInputId*) { // // As of 3.1.4, we're going to try to read from the file descriptor. // If there is any byte at all we're going to just keep // on running. If we see error, or eof, then we'll assume that // dxshadow died and that we should die also. // char buff[256]; int bread; bread = read(*fid, buff, 256); if (bread > 0) { while (bread == 256) bread = read(*fid, buff, 256); } else { exit(1); } } void TemporaryLicense::determineUILicense(LicenseTypeEnum *app, LicenseTypeEnum *func) { *app = Unlicensed; UIGetLicense(this->getRootDir(), LostLicense, app,func); } void TemporaryLicense::initialize() { // // Find out what we've got for a license. // LicenseTypeEnum app_lic, func_lic; app_lic = TimedLicense; func_lic = Unlicensed; if (getenv("DXTRIALKEY")) { } else { this->determineUILicense(&app_lic, &func_lic); // // Problems: // - A UP license on an SMP machine gets full smp ability because // the trial key I'm generating is using the SMP flag. // - If the user replaces the dxui executable with something of his own // which simply prints out the environment, then he'll get to see his // trial key which will give him full developer, multi-user, smp // capability. // - If the user edits the dx.workerscript, he could thwart my attempt // to limit the functioning of dxui since I'm just passing cmd line args // to the script when I use DXLStartDX(). // // // If we got a floating developer license, then we'll go ahead an unleash // full use of the product. If the license is runtime or nodelocked, then // the product has to be restricted: // 1) to prevent the user from reconnecting to a remote exec which // would effectively allow unlimited use since you can run any number // of dxui's on one machine if the dxexec's are remote. // 2) to prevent editor access which turns a runtime into a developer license. // if ((func_lic == DeveloperLicense) && (getenv("DXTEST_RUNTIME") == NUL(char*)) && ((app_lic == NodeLockedLicense) || (app_lic == ConcurrentLicense)) ) { if (app_lic == NodeLockedLicense) { // // If you want to add something special for the case of nodelocked // developer license, this is the place. I originally used // -noConnectionMenus so that the user would be unable to send // the trial key to another machine which would effectively allow // unlimited use of the produce. Now, that trial key won't work // on another host, so -noConn isn't needed. // //this->setDxuiArgs(" -noConnectionMenus "); //this->limited_use = TRUE; } } else { this->setDxuiArgs(this->getLimitedArgs()); this->limited_use = TRUE; } if (func_lic != Unlicensed) { // // If we got a good license, then put a trial key into the environment // I think a reasonable alternative to the trial key would be encrypting // the time. Then the child app could do the same. (Excluding seconds) // Then if we gave the child app our encrypted time, she could compare // and know (authenticate) that the parent is in fact startup. Then // no licensing would be required. // // Security problems: If someone replaces the dxui executable, it would // be simple to print out the environment and obtain the trial key we're // using. // char host[64]; // S G I S G I S G I S G I S G I S G I S G I # if defined(sgi) # if ( __mips > 1) sysinfo (SI_HW_SERIAL, host, sizeof(host)); # else // this should really be an unsigned int because that's what sysid // returns, but it HAS to be long to be compatible with the UI and exec long name = (long)sysid(NULL); sprintf (host, "%d", name); strcpy (host, host+2); # endif # endif // H P 7 0 0 H P 7 0 0 H P 7 0 0 H P 7 0 0 H P 7 0 0 # if defined(hp700) struct utsname name; uname (&name); name.idnumber[10] = '\0'; strcpy (host, name.idnumber+2); # endif // S O L A R I S S O L A R I S S O L A R I S S O L A R I S # if defined(solaris) sysinfo(SI_HW_SERIAL,host,301); sprintf(host, "%x", atol(host)); # endif // A V I I O N A V I I O N A V I I O N A V I I O N # if defined(aviion) sysinfo(SI_HW_SERIAL,host,301); # endif // I B M 6 0 0 0 I B M 6 0 0 0 I B M 6 0 0 0 I B M 6 0 0 0 # if defined(ibm6000) struct utsname name; uname (&name); name.machine[10] = '\0'; strcpy (host, name.machine+2); # endif // S U N 4 S U N 4 S U N 4 S U N 4 S U N 4 S U N 4 # if defined(sun4) sprintf (host, "%x", gethostid()); # endif // A L P H A X A L P H A X A L P H A X A L P H A X # if defined(alphax) { char *dflt_devices[] = {"tu0","ln0", NULL }; char *device; int found, s,i /* On Alpha OSF/1 we use ethernet */; /* Get a socket */ s = socket(AF_INET,SOCK_DGRAM,0); if (s < 0) { perror("socket"); exit(1); } for (found=i=0, device=(char*)getenv("DXKEYDEVICE"); dflt_devices[i]; i++) { static struct ifdevea devea; /* MAC address from and ioctl() */ char *dev, buf[32]; if (!device) dev = dflt_devices[i]; else dev = device; strcpy(devea.ifr_name,dev); if (ioctl(s,SIOCRPHYSADDR,&devea) >= 0) { strcpy(host,""); for (i = 2; i < 6; i++){ sprintf(buf,"%x", devea.default_pa[i] ); strcat(host,buf); } found = 1; break; } if (device) break; } if (!found) { fprintf(stderr,"Could not find ethernet device.\n"); strcpy(host,"UNKNOWN"); } close(s); } # endif time_t tim; // // The use of ANY right here doesn't mean anything. It isn't an // "any" key, it's still nodelocked. We're just passing ANY because // the hostid has already been munged and MakeKey does not need to // munge it further as it would in the expire program. // const char* key = TemporaryLicense::MakeKey(ANY, host, 0, 1, &tim, SMP); char* cp = "DXTRIALKEY="; char *envsetting = new char[strlen(cp) + strlen(key) + 1]; sprintf (envsetting, "%s%s", cp,key); putenv (envsetting); cp = "DXSTARTUP=1"; envsetting = new char[strlen(cp) + 1]; strcpy (envsetting, cp); putenv (envsetting); } } } void TemporaryLicense::setDxuiArgs(const char* a) { if (dxui_args) delete dxui_args; if (a) dxui_args = DuplicateString(a); else dxui_args = NUL(char*); } const char* TemporaryLicense::getLimitedArgs() { return " -noConnectionMenus -noEditorAccess "; } #endif // DO NOT ADD ANYTHING AFTER THIS ENDIF