import random import sys #define constants #these constants depend on the bitness of the OS - the DRIS is 4 bytes bigger for 64-bit code if sys.maxsize > 2**32: DRIS_SIZE = 564 # DRIS size is bigger for 64-bit (it has an 8-byte pointer) python64 = 4 # so we can adjust structure offsets for 64-bit python else: DRIS_SIZE = 560 python64 = 0 #function values PROTECTION_CHECK = 1 # checks for dongle, check program params... EXECUTE_ALGORITHM = 2 # protection check + calculate answer for specified algorithm with specified inputs WRITE_DATA_AREA = 3 # protection check + writes dongle data area READ_DATA_AREA = 4 # protection check + reads dongle data area ENCRYPT_USER_DATA = 5 # protection check + the dongle will encrypt user data DECRYPT_USER_DATA = 6 # protection check + the dongle will decrypt user data FAST_PRESENCE_CHECK = 7 # checks for the presence of the correct dongle only with minimal security, no flags allowed. STOP_NET_USER = 8 # stops a network user (a protection check is NOT performed) # flags - can specify as many as you like DEC_ONE_EXEC = 1 # decrement execs by 1 DEC_MANY_EXECS = 2 # decrement execs by number specified in execs_decrement START_NET_USER = 4 # starts a network user USE_FUNCTION_ARGUMENT = 16 # use the extra argument in the function for pointers CHECK_LOCAL_FIRST = 32 # always look in local ports before looking in network ports CHECK_NETWORK_FIRST = 64 # always look on the network before looking in local ports USE_ALT_LICENCE_NAME = 128 # use name specified in alt_licence_name instead of the default one DONT_SET_MAXDAYS_EXPIRY = 256 # if the max days expiry date has not been calculated then do not do it this time MATCH_DONGLE_NUMBER = 512 # restrict the search to match the dongle number specified in the DRIS DONT_RETURN_FD_DRIVE = 1024 # if an FD dongle has been detected then don't return the flash drive/mount name # set 4 bytes in our DRIS byte array from an integer def set4bytes(data, offset, value): data[offset] = value & 0xff data[offset+1] = (value >> 8) & 0xff data[offset+2] = (value >> 16) & 0xff data[offset+3] = (value >> 24) & 0xff return # trunctates a value to 32-bit and converts to a signed integer def make_signed32bit(value): value = value & 0xffffffff if (value > (2**31)): value = value - (2**32) return value # get 4 bytes in our DRIS byte array and convert to an unsigned integer # this returns an unsigned value, which is useful for dongle number, features, etc... def get4bytes(data, offset): return (data[offset] + data[offset+1]*0x100 + data[offset+2]*0x10000 + data[offset+3]*0x1000000) # this returns a signed value, which is useful for alg_answer, expiry day... def get4bytes_signed(data, offset): value = data[offset] + data[offset+1]*0x100 + data[offset+2]*0x10000 + data[offset+3]*0x1000000 if (value > (2**31)): value = value - (2**32) return value # create the DRIS structure as a byte array, populate it with random values, initialise the header and size fields def create(): dris = bytearray(DRIS_SIZE) random.seed() for n in range(DRIS_SIZE): dris[n] = random.randint(0, 255) dris[0] = ord('D') dris[1] = ord('R') dris[2] = ord('I') dris[3] = ord('S') set4bytes(dris, 4, DRIS_SIZE) return dris # these functions set various values in the DRIS def set_function(dris, value): set4bytes(dris, 16, value) def set_flags(dris, value): set4bytes(dris, 20, value) def set_execs_decrement(dris, value): set4bytes(dris, 24, value) def set_data_crypt_key_num(dris, value): set4bytes(dris, 28, value) def set_rw_offset(dris, value): set4bytes(dris, 32, value) def set_rw_length(dris, value): set4bytes(dris, 36, value) def set_alt_licence_name(dris, licence_name): dris[44+python64:44+python64+len(licence_name)] = licence_name dris[44+python64+len(licence_name)] = 0 # null-terminate the string def set_var_a(dris, value): set4bytes(dris, 300+python64, value) def set_var_b(dris, value): set4bytes(dris, 304+python64, value) def set_var_c(dris, value): set4bytes(dris, 308+python64, value) def set_var_d(dris, value): set4bytes(dris, 312+python64, value) def set_var_e(dris, value): set4bytes(dris, 316+python64, value) def set_var_f(dris, value): set4bytes(dris, 320+python64, value) def set_var_g(dris, value): set4bytes(dris, 324+python64, value) def set_var_h(dris, value): set4bytes(dris, 328+python64, value) def set_alg_number(dris, value): set4bytes(dris, 332+python64, value) # these functions get values from the DRIS def get_ret_code(dris): return get4bytes(dris, 336+python64) def get_ext_err(dris): return get4bytes(dris, 340+python64) def get_type(dris): return get4bytes(dris, 344+python64) def get_model(dris): return get4bytes(dris, 348+python64) def get_sdsn(dris): return get4bytes(dris, 352+python64) def get_prodcode(dris): for n in range(356+python64,368+python64): if dris[n] == 0: break return dris[356+python64:n].decode("utf-8") def get_dongle_number(dris): return get4bytes(dris, 368+python64) def get_update_number(dris): return get4bytes(dris, 372+python64) def get_data_area_size(dris): return get4bytes(dris, 376+python64) def get_max_alg_num(dris): return get4bytes(dris, 380+python64) def get_execs(dris): return get4bytes(dris, 384+python64) def get_exp_day(dris): return get4bytes_signed(dris, 388+python64) def get_exp_month(dris): return get4bytes_signed(dris, 392+python64) def get_exp_year(dris): return get4bytes_signed(dris, 396+python64) def get_features(dris): return get4bytes(dris, 400+python64) def get_net_users(dris): return get4bytes(dris, 404+python64) def get_alg_answer(dris): return get4bytes_signed(dris, 408+python64) def get_fd_capacity(dris): return get4bytes(dris, 412+python64) def get_fd_drive(dris): for n in range(416+python64,544+python64): if dris[n] == 0: break return dris[416+python64:n].decode("utf-8") def get_swkey_type(dris): return get4bytes(dris, 544+python64) def get_swkey_exp_day(dris): return get4bytes(dris, 548+python64) def get_swkey_exp_month(dris): return get4bytes(dris, 552+python64) def get_swkey_exp_year(dris): return get4bytes(dris, 556+python64) # you may also want to retrieve var_a values that you already entered into the dris! def get_var_a(dris): return get4bytes_signed(dris, 300+python64) def get_var_b(dris): return get4bytes_signed(dris, 304+python64) def get_var_c(dris): return get4bytes_signed(dris, 308+python64) def get_var_d(dris): return get4bytes_signed(dris, 312+python64) def get_var_e(dris): return get4bytes_signed(dris, 316+python64) def get_var_f(dris): return get4bytes_signed(dris, 320+python64) def get_var_g(dris): return get4bytes_signed(dris, 324+python64) def get_var_h(dris): return get4bytes_signed(dris, 328+python64) # function to display the most common error codes. # You will want to change this with your own error messages def DisplayError(ret_code, extended_error): if (ret_code == 401): print("Error! No dongles detected!") elif (ret_code == 403): print("Error! The dongle detected has a different type to the one specified in DinkeyAdd.") elif (ret_code == 404): print("Error! The dongle detected has a different model to those specified in DinkeyAdd.") elif (ret_code == 409): print("Error! The dongle detected has not been programmed by DinkeyAdd.") elif (ret_code == 410): print("Error! The dongle detected has a different Product Code to the one specified in DinkeyAdd.") elif (ret_code == 411): print("Error! The dongle detected does not contain the licence associated with this program.") elif (ret_code == 413): print("Error! This program has not been protected by DinkeyAdd. For guidance please read the DinkeyAdd chapter of the Dinkey manual.") elif (ret_code == 417): print("Error! One or more of the parameters set in the DRIS is incorrect. This could be caused if you are encrypting the DRIS in your code but did not specify DRIS encryption in DinkeyAdd - or vice versa.") elif (ret_code == 423): print("Error! The number of network users has been exceeded.") elif (ret_code == 435): print("Error! DinkeyServer has not been detected on the network.") elif (ret_code == 922): print("Error! The Software Key has expired.") else: print("An error occurred checking the dongle.\nError: " + str(ret_code) + ", Extended Error: " + str(extended_error)) return