Database keeps different AppId (#50), restyling minimal info logging

This commit is contained in:
Matteo ℱan 2020-09-07 23:44:10 +02:00
parent 33cedce48c
commit 016a4c367f
No known key found for this signature in database
GPG Key ID: 3C30A05BC133D9B6
9 changed files with 101 additions and 83 deletions

View File

@ -166,7 +166,7 @@ The following are just some brief notes about parameters handling. For a more de
- To generate a random HWID use `-w` option: `python3 pykms_Server.py -w RANDOM`. - To generate a random HWID use `-w` option: `python3 pykms_Server.py -w RANDOM`.
- To get the HWID from any server use the client, for example type: `python3 pykms_Client.py :: 1688 -m Windows8.1 -V INFO`. - To get the HWID from any server use the client, for example type: `python3 pykms_Client.py :: 1688 -m Windows8.1 -V INFO`.
- To change your logfile path use `-F` option, for example: `python3 pykms_Server.py -F /path/to/your/logfile.log -V DEBUG`. - To change your logfile path use `-F` option, for example: `python3 pykms_Server.py -F /path/to/your/logfile.log -V DEBUG`.
- To view a minimal set of logging information use `-V MINI` option, for example: `python3 pykms_Server.py -F /path/to/your/logfile.log -V MINI`. - To view a minimal set of logging information use `-V MININFO` option, for example: `python3 pykms_Server.py -F /path/to/your/logfile.log -V MININFO`.
- To redirect logging on stdout use `-F STDOUT` option, for example: `python3 pykms_Server.py -F STDOUT -V DEBUG`. - To redirect logging on stdout use `-F STDOUT` option, for example: `python3 pykms_Server.py -F STDOUT -V DEBUG`.
- You can create logfile and view logging information on stdout at the same time with `-F FILESTDOUT` option, for example: `python3 pykms_Server.py -F FILESTDOUT /path/to/your/logfile.log -V DEBUG`. - You can create logfile and view logging information on stdout at the same time with `-F FILESTDOUT` option, for example: `python3 pykms_Server.py -F FILESTDOUT /path/to/your/logfile.log -V DEBUG`.
- With `-F STDOUTOFF` you disable all stdout messages (but a logfile will be created), for example: `python3 pykms_Server.py -F STDOUTOFF /path/to/your/logfile.log -V DEBUG`. - With `-F STDOUTOFF` you disable all stdout messages (but a logfile will be created), for example: `python3 pykms_Server.py -F STDOUTOFF /path/to/your/logfile.log -V DEBUG`.

View File

@ -66,7 +66,7 @@ Default setting is serve forever (no timeout).
the overhead involved becomes more expensive, so using this option you enable printing (pretty / logging) messages the overhead involved becomes more expensive, so using this option you enable printing (pretty / logging) messages
asynchronously reducing time-consuming. Deactivated by default. asynchronously reducing time-consuming. Deactivated by default.
-V or --loglevel <{CRITICAL, ERROR, WARNING, INFO, DEBUG, MINI}> -V or --loglevel <{CRITICAL, ERROR, WARNING, INFO, DEBUG, MININFO}>
> Use this flag to set a logging loglevel. The default is _ERROR_. > Use this flag to set a logging loglevel. The default is _ERROR_.
example: example:
``` ```
@ -162,7 +162,7 @@ You can also put further parameters as defined below:
-m or --mode <{WindowsVista, Windows7, Windows8, Windows8.1, Windows10, Office2010, Office2013, Office2016, Office2019}> -m or --mode <{WindowsVista, Windows7, Windows8, Windows8.1, Windows10, Office2010, Office2013, Office2016, Office2019}>
> Use this flag to manually specify a Microsoft _PRODUCTNAME_ for testing the KMS server. Default is Windows8.1. > Use this flag to manually specify a Microsoft _PRODUCTNAME_ for testing the KMS server. Default is Windows8.1.
-c or --cmid <CMID> -c or --cmid <CMID>
> Use this flag to manually specify a CMID to use. If no CMID is specified, a random one will be generated. > Use this flag to manually specify a CMID to use. If no CMID is specified, a random one will be generated.
The Microsoft KMS host machine identifies KMS clients with a unique Client Machine ID The Microsoft KMS host machine identifies KMS clients with a unique Client Machine ID
(CMID, example: ae3a27d1-b73a-4734-9878-70c949815218). For a KMS client to successfully activate, the KMS server (CMID, example: ae3a27d1-b73a-4734-9878-70c949815218). For a KMS client to successfully activate, the KMS server
@ -179,7 +179,7 @@ activate regardless of CMID being unique for a subset of specific machines or no
-y or --async-msg -y or --async-msg
> Prints pretty / logging messages asynchronously. Deactivated by default. > Prints pretty / logging messages asynchronously. Deactivated by default.
-V or --loglevel <{CRITICAL, ERROR, WARNING, INFO, DEBUG, MINI}> -V or --loglevel <{CRITICAL, ERROR, WARNING, INFO, DEBUG, MININFO}>
> Use this flag to set a logging loglevel. The default is _ERROR_. > Use this flag to set a logging loglevel. The default is _ERROR_.
-F or --logfile <LOGFILE> -F or --logfile <LOGFILE>

View File

@ -107,9 +107,6 @@ class kmsBase:
return 4 + (((~bodyLength & 3) + 1) & 3) return 4 + (((~bodyLength & 3) + 1) & 3)
def serverLogic(self, kmsRequest): def serverLogic(self, kmsRequest):
if self.srv_config['sqlite']:
sql_initialize(self.srv_config['sqlite'])
pretty_printer(num_text = 15, where = "srv") pretty_printer(num_text = 15, where = "srv")
kmsRequest = byterize(kmsRequest) kmsRequest = byterize(kmsRequest)
loggersrv.debug("KMS Request Bytes: \n%s\n" % justify(deco(binascii.b2a_hex(enco(str(kmsRequest), 'latin-1')), 'latin-1'))) loggersrv.debug("KMS Request Bytes: \n%s\n" % justify(deco(binascii.b2a_hex(enco(str(kmsRequest), 'latin-1')), 'latin-1')))
@ -205,17 +202,18 @@ could be detected as not genuine !{end}" %currentClientCount)
loggersrv.info("License Status: %s" % infoDict["licenseStatus"]) loggersrv.info("License Status: %s" % infoDict["licenseStatus"])
loggersrv.info("Request Time: %s" % local_dt.strftime('%Y-%m-%d %H:%M:%S %Z (UTC%z)')) loggersrv.info("Request Time: %s" % local_dt.strftime('%Y-%m-%d %H:%M:%S %Z (UTC%z)'))
if self.srv_config['loglevel'] == 'MINI': if self.srv_config['loglevel'] == 'MININFO':
loggersrv.mini("", extra = {'host': socket.gethostname() + " [" + self.srv_config["ip"] + "]", loggersrv.mininfo("", extra = {'host': str(self.srv_config['raddr']),
'status' : infoDict["licenseStatus"], 'status' : infoDict["licenseStatus"],
'product' : infoDict["skuId"]}) 'product' : infoDict["skuId"]})
# Create database.
if self.srv_config['sqlite']: if self.srv_config['sqlite']:
sql_initialize(self.srv_config['sqlite'])
sql_update(self.srv_config['sqlite'], infoDict) sql_update(self.srv_config['sqlite'], infoDict)
return self.createKmsResponse(kmsRequest, currentClientCount) return self.createKmsResponse(kmsRequest, currentClientCount, appName)
def createKmsResponse(self, kmsRequest, currentClientCount): def createKmsResponse(self, kmsRequest, currentClientCount, appName):
response = self.kmsResponseStruct() response = self.kmsResponseStruct()
response['versionMinor'] = kmsRequest['versionMinor'] response['versionMinor'] = kmsRequest['versionMinor']
response['versionMajor'] = kmsRequest['versionMajor'] response['versionMajor'] = kmsRequest['versionMajor']
@ -225,16 +223,17 @@ could be detected as not genuine !{end}" %currentClientCount)
self.srv_config["lcid"]).encode('utf-16le') self.srv_config["lcid"]).encode('utf-16le')
else: else:
response["kmsEpid"] = self.srv_config["epid"].encode('utf-16le') response["kmsEpid"] = self.srv_config["epid"].encode('utf-16le')
response['clientMachineId'] = kmsRequest['clientMachineId'] response['clientMachineId'] = kmsRequest['clientMachineId']
# rule: timeserver - 4h <= timeclient <= timeserver + 4h, check if is satisfied. # rule: timeserver - 4h <= timeclient <= timeserver + 4h, check if is satisfied (TODO).
response['responseTime'] = kmsRequest['requestTime'] response['responseTime'] = kmsRequest['requestTime']
response['currentClientCount'] = currentClientCount response['currentClientCount'] = currentClientCount
response['vLActivationInterval'] = self.srv_config["activation"] response['vLActivationInterval'] = self.srv_config["activation"]
response['vLRenewalInterval'] = self.srv_config["renewal"] response['vLRenewalInterval'] = self.srv_config["renewal"]
# Update database epid.
if self.srv_config['sqlite']: if self.srv_config['sqlite']:
response = sql_update_epid(self.srv_config['sqlite'], kmsRequest, response) sql_update_epid(self.srv_config['sqlite'], kmsRequest, response, appName)
loggersrv.info("Server ePID: %s" % response["kmsEpid"].decode('utf-16le')) loggersrv.info("Server ePID: %s" % response["kmsEpid"].decode('utf-16le'))

View File

@ -62,7 +62,7 @@ will be generated.', 'def' : None, 'des' : "machine"},
'asyncmsg' : {'help' : 'Prints pretty / logging messages asynchronously. Deactivated by default.', 'asyncmsg' : {'help' : 'Prints pretty / logging messages asynchronously. Deactivated by default.',
'def' : False, 'des' : "asyncmsg"}, 'def' : False, 'des' : "asyncmsg"},
'llevel' : {'help' : 'Use this option to set a log level. The default is \"ERROR\".', 'def' : "ERROR", 'des' : "loglevel", 'llevel' : {'help' : 'Use this option to set a log level. The default is \"ERROR\".', 'def' : "ERROR", 'des' : "loglevel",
'choi' : ["CRITICAL", "ERROR", "WARNING", "INFO", "DEBUG", "MINI"]}, 'choi' : ["CRITICAL", "ERROR", "WARNING", "INFO", "DEBUG", "MININFO"]},
'lfile' : {'help' : 'Use this option to set an output log file. The default is \"pykms_logclient.log\". \ 'lfile' : {'help' : 'Use this option to set an output log file. The default is \"pykms_logclient.log\". \
Type \"STDOUT\" to view log info on stdout. Type \"FILESTDOUT\" to combine previous actions. \ Type \"STDOUT\" to view log info on stdout. Type \"FILESTDOUT\" to combine previous actions. \
Use \"STDOUTOFF\" to disable stdout messages. Use \"FILEOFF\" if you not want to create logfile.', Use \"STDOUTOFF\" to disable stdout messages. Use \"FILEOFF\" if you not want to create logfile.',
@ -168,7 +168,7 @@ def client_update():
def client_create(): def client_create():
loggerclt.info("Connecting to %s on port %d..." % (clt_config['ip'], clt_config['port'])) loggerclt.info("Connecting to %s on port %d..." % (clt_config['ip'], clt_config['port']))
try: try:
s = socket.create_connection((clt_config['ip'], clt_config['port'])) clt_sock = socket.create_connection((clt_config['ip'], clt_config['port']))
loggerclt.info("Connection successful !") loggerclt.info("Connection successful !")
except (socket.gaierror, socket.error) as e: except (socket.gaierror, socket.error) as e:
pretty_printer(log_obj = loggerclt.error, to_exit = True, where = "clt", pretty_printer(log_obj = loggerclt.error, to_exit = True, where = "clt",
@ -181,12 +181,12 @@ def client_create():
try: try:
loggerclt.info("Sending RPC bind request...") loggerclt.info("Sending RPC bind request...")
pretty_printer(num_text = [-1, 1], where = "clt") pretty_printer(num_text = [-1, 1], where = "clt")
s.send(RPC_Bind) clt_sock.send(RPC_Bind)
except socket.error as e: except socket.error as e:
pretty_printer(log_obj = loggerclt.error, to_exit = True, where = "clt", pretty_printer(log_obj = loggerclt.error, to_exit = True, where = "clt",
put_text = "{reverse}{red}{bold}While sending: %s{end}" %str(e)) put_text = "{reverse}{red}{bold}While sending: %s{end}" %str(e))
try: try:
bindResponse = s.recv(1024) bindResponse = clt_sock.recv(1024)
if bindResponse == '' or not bindResponse: if bindResponse == '' or not bindResponse:
pretty_printer(log_obj = loggerclt.warning, to_exit = True, where = "clt", pretty_printer(log_obj = loggerclt.warning, to_exit = True, where = "clt",
put_text = "{reverse}{yellow}{bold}No data received.{end}") put_text = "{reverse}{yellow}{bold}No data received.{end}")
@ -206,12 +206,12 @@ def client_create():
loggerclt.info("Sending RPC activation request...") loggerclt.info("Sending RPC activation request...")
RPC_Actv = enco(str(requester.generateRequest()), 'latin-1') RPC_Actv = enco(str(requester.generateRequest()), 'latin-1')
pretty_printer(num_text = [-1, 12], where = "clt") pretty_printer(num_text = [-1, 12], where = "clt")
s.send(RPC_Actv) clt_sock.send(RPC_Actv)
except socket.error as e: except socket.error as e:
pretty_printer(log_obj = loggerclt.error, to_exit = True, where = "clt", pretty_printer(log_obj = loggerclt.error, to_exit = True, where = "clt",
put_text = "{reverse}{red}{bold}While sending: %s{end}" %str(e)) put_text = "{reverse}{red}{bold}While sending: %s{end}" %str(e))
try: try:
response = s.recv(1024) response = clt_sock.recv(1024)
pretty_printer(num_text = [-4, 20], where = "clt") pretty_printer(num_text = [-4, 20], where = "clt")
except socket.error as e: except socket.error as e:
pretty_printer(log_obj = loggerclt.error, to_exit = True, where = "clt", pretty_printer(log_obj = loggerclt.error, to_exit = True, where = "clt",
@ -232,10 +232,10 @@ def client_create():
loggerclt.info("KMS VL Activation Interval: %s" % kmsResp['vLActivationInterval']) loggerclt.info("KMS VL Activation Interval: %s" % kmsResp['vLActivationInterval'])
loggerclt.info("KMS VL Renewal Interval: %s" % kmsResp['vLRenewalInterval']) loggerclt.info("KMS VL Renewal Interval: %s" % kmsResp['vLRenewalInterval'])
if clt_config['loglevel'] == 'MINI': if clt_config['loglevel'] == 'MININFO':
loggerclt.mini("", extra = {'host': socket.gethostname() + " [" + clt_config["ip"] + "]", loggerclt.mininfo("", extra = {'host': str(clt_sock.getpeername()),
'status' : "Activated", 'status' : kmsBase.licenseStates[requester.srv_config['KMSClientLicenseStatus']],
'product' : clt_config["mode"]}) 'product' : clt_config["mode"]})
pretty_printer(num_text = 21, where = "clt") pretty_printer(num_text = 21, where = "clt")
@ -280,7 +280,7 @@ def createKmsRequestBase():
pretty_printer(num_text = 9, where = "clt") pretty_printer(num_text = 9, where = "clt")
requestDict = byterize(requestDict) requestDict = byterize(requestDict)
loggerclt.debug("Request Base Dictionary: \n%s\n" % justify(requestDict.dump(print_to_stdout = False))) loggerclt.debug("Request Base Dictionary: \n%s\n" % justify(requestDict.dump(print_to_stdout = False)))
return requestDict return requestDict
def createKmsRequest(): def createKmsRequest():

View File

@ -54,14 +54,15 @@ def justify(astring, indent = 35, break_every = 100):
return justy return justy
##---------------------------------------------------------------------------------------------------------------------------------------------------- ##----------------------------------------------------------------------------------------------------------------------------------------------------
ColorMap = {'gray' : '\x1b[90m', ColorMap = {'black' : '\x1b[90m',
'red' : '\x1b[91m', 'red' : '\x1b[91m',
'green' : '\x1b[92m', 'green' : '\x1b[38;2;0;238;118m', # '\x1b[92m'
'yellow' : '\x1b[93m', 'yellow' : '\x1b[93m',
'blue' : '\x1b[94m', 'blue' : '\x1b[94m',
'magenta' : '\x1b[95m', 'magenta' : '\x1b[38;2;205;0;205m', # '\x1b[95m'
'cyan' : '\x1b[96m', 'cyan' : '\x1b[96m',
'white' : '\x1b[97m' 'white' : '\x1b[97m',
'orange' : '\x1b[38;2;255;165;0m'
} }
ExtraMap = {'end' : '\x1b[0m', ExtraMap = {'end' : '\x1b[0m',

View File

@ -80,9 +80,9 @@ class KmsGui(tk.Tk):
self.customcolors = { 'black' : '#000000', self.customcolors = { 'black' : '#000000',
'white' : '#FFFFFF', 'white' : '#FFFFFF',
'green' : '#90EE90', 'green' : '#00EE76',
'yellow' : '#FFFF00', 'yellow' : '#FFFF00',
'magenta' : '#DA70D6', 'magenta' : '#CD00CD',
'orange' : '#FFA500', 'orange' : '#FFA500',
'red' : '#FF4500', 'red' : '#FF4500',
'blue' : '#1E90FF', 'blue' : '#1E90FF',

View File

@ -66,8 +66,8 @@ class LevelFormatter(logging.Formatter):
self.formatters[loglevel] = logging.Formatter(formats[loglevel], datefmt = self.dfmt) self.formatters[loglevel] = logging.Formatter(formats[loglevel], datefmt = self.dfmt)
def colorize(self, formats, loglevel): def colorize(self, formats, loglevel):
if loglevel == logging.MINI: if loglevel == logging.MININFO:
frmt = '{gray}' + formats[loglevel] + '{end}' frmt = '{orange}' + formats[loglevel] + '{end}'
elif loglevel == logging.CRITICAL: elif loglevel == logging.CRITICAL:
frmt = '{magenta}{bold}' + formats[loglevel] + '{end}' frmt = '{magenta}{bold}' + formats[loglevel] + '{end}'
elif loglevel == logging.ERROR: elif loglevel == logging.ERROR:
@ -153,7 +153,8 @@ class MultiProcessingLogHandler(logging.Handler):
def logger_create(log_obj, config, mode = 'a'): def logger_create(log_obj, config, mode = 'a'):
# Create new level. # Create new level.
add_logging_level('MINI', logging.CRITICAL + 10) num_lvl_mininfo = 25
add_logging_level('MININFO', num_lvl_mininfo)
log_handlers = [] log_handlers = []
# Configure visualization. # Configure visualization.
@ -188,13 +189,19 @@ def logger_create(log_obj, config, mode = 'a'):
levelnum = [k for k in levelnames if k != 0] levelnum = [k for k in levelnames if k != 0]
frmt_gen = '%(asctime)s %(levelname)-8s %(message)s' frmt_gen = '%(asctime)s %(levelname)-8s %(message)s'
frmt_std = '%(name)s %(asctime)s %(levelname)-8s %(message)s' frmt_std = '%(asctime)s %(levelname)-8s %(message)s'
frmt_min = '[%(asctime)s] [%(levelname)-8s] %(host)s %(status)s %(product)s %(message)s' frmt_min = '%(asctime)s %(levelname)-8s %(host)s %(status)s %(product)s %(message)s'
frmt_name = '%(name)s '
from pykms_Server import serverthread
if serverthread.with_gui:
frmt_std = frmt_name + frmt_std
frmt_min = frmt_name + frmt_min
def apply_formatter(levelnum, formats, handler, color = False): def apply_formatter(levelnum, formats, handler, color = False):
levelformdict = {} levelformdict = {}
for num in levelnum: for num in levelnum:
if num != logging.CRITICAL + 10: if num != num_lvl_mininfo:
levelformdict[num] = formats[0] levelformdict[num] = formats[0]
else: else:
levelformdict[num] = formats[1] levelformdict[num] = formats[1]
@ -220,25 +227,32 @@ def logger_create(log_obj, config, mode = 'a'):
log_obj.setLevel(config['loglevel']) log_obj.setLevel(config['loglevel'])
#------------------------------------------------------------------------------------------------------------------------------------------------------------ #------------------------------------------------------------------------------------------------------------------------------------------------------------
def check_dir(path, where, log_obj = None, argument = '-F/--logfile', typefile = '.log'):
filename = os.path.basename(path)
pathname = os.path.dirname(path)
extension = os.path.splitext(filename)[1]
if pathname == os.sep:
pathname += filename
msg_dir = "{reverse}{red}{bold}argument `%s`: invalid directory: '%s'. Exiting...{end}"
msg_fil = "{reverse}{red}{bold}argument `%s`: not a %s file, invalid extension: '%s'. Exiting...{end}"
if not os.path.isdir(pathname):
if path.count('/') == 0:
pathname = filename
pretty_printer(log_obj = log_obj, where = where, to_exit = True,
put_text = msg_dir %(argument, pathname))
elif not extension.lower() == typefile:
pretty_printer(log_obj = log_obj, where = where, to_exit = True,
put_text = msg_fil %(argument, typefile, extension))
def check_logfile(optionlog, defaultlog, where): def check_logfile(optionlog, defaultlog, where):
if not isinstance(optionlog, list): if not isinstance(optionlog, list):
optionlog = [optionlog] optionlog = [optionlog]
lenopt = len(optionlog) lenopt = len(optionlog)
msg_dir = "{reverse}{red}{bold}argument `-F/--logfile`: invalid directory: '%s'. Exiting...{end}"
msg_long = "{reverse}{red}{bold}argument `-F/--logfile`: too much arguments. Exiting...{end}" msg_long = "{reverse}{red}{bold}argument `-F/--logfile`: too much arguments. Exiting...{end}"
msg_log = "{reverse}{red}{bold}argument `-F/--logfile`: not a log file, invalid extension: '%s'. Exiting...{end}"
def checkdir(path):
filename = os.path.basename(path)
pathname = os.path.dirname(path)
if not os.path.isdir(pathname):
if path.count('/') == 0:
pathname = filename
pretty_printer(put_text = msg_dir %pathname, where = where, to_exit = True)
elif not filename.lower().endswith('.log'):
pretty_printer(put_text = msg_log %filename, where = where, to_exit = True)
if lenopt > 2: if lenopt > 2:
pretty_printer(put_text = msg_long, where = where, to_exit = True) pretty_printer(put_text = msg_long, where = where, to_exit = True)
@ -249,13 +263,13 @@ def check_logfile(optionlog, defaultlog, where):
optionlog.append(defaultlog) optionlog.append(defaultlog)
elif lenopt == 2: elif lenopt == 2:
# check directory path. # check directory path.
checkdir(optionlog[1]) check_dir(optionlog[1], where)
else: else:
if lenopt == 2: if lenopt == 2:
pretty_printer(put_text = msg_long, where = where, to_exit = True) pretty_printer(put_text = msg_long, where = where, to_exit = True)
elif lenopt == 1 and (any(opt not in ['STDOUT', 'FILEOFF'] for opt in optionlog)): elif lenopt == 1 and (any(opt not in ['STDOUT', 'FILEOFF'] for opt in optionlog)):
# check directory path. # check directory path.
checkdir(optionlog[0]) check_dir(optionlog[0], where)
return optionlog return optionlog

View File

@ -19,7 +19,7 @@ import ipaddress
import pykms_RpcBind, pykms_RpcRequest import pykms_RpcBind, pykms_RpcRequest
from pykms_RpcBase import rpcBase from pykms_RpcBase import rpcBase
from pykms_Dcerpc import MSRPCHeader from pykms_Dcerpc import MSRPCHeader
from pykms_Misc import check_setup, check_lcid from pykms_Misc import check_setup, check_lcid, check_dir
from pykms_Misc import KmsParser, KmsParserException, KmsParserHelp from pykms_Misc import KmsParser, KmsParserException, KmsParserHelp
from pykms_Misc import kms_parser_get, kms_parser_check_optionals, kms_parser_check_positionals from pykms_Misc import kms_parser_get, kms_parser_check_optionals, kms_parser_check_positionals
from pykms_Format import enco, deco, pretty_printer from pykms_Format import enco, deco, pretty_printer
@ -198,7 +198,7 @@ The default is \"364F463A8863D35F\" or type \"RANDOM\" to auto generate the HWID
'asyncmsg' : {'help' : 'Prints pretty / logging messages asynchronously. Deactivated by default.', 'asyncmsg' : {'help' : 'Prints pretty / logging messages asynchronously. Deactivated by default.',
'def' : False, 'des' : "asyncmsg"}, 'def' : False, 'des' : "asyncmsg"},
'llevel' : {'help' : 'Use this option to set a log level. The default is \"ERROR\".', 'def' : "ERROR", 'des' : "loglevel", 'llevel' : {'help' : 'Use this option to set a log level. The default is \"ERROR\".', 'def' : "ERROR", 'des' : "loglevel",
'choi' : ["CRITICAL", "ERROR", "WARNING", "INFO", "DEBUG", "MINI"]}, 'choi' : ["CRITICAL", "ERROR", "WARNING", "INFO", "DEBUG", "MININFO"]},
'lfile' : {'help' : 'Use this option to set an output log file. The default is \"pykms_logserver.log\". \ 'lfile' : {'help' : 'Use this option to set an output log file. The default is \"pykms_logserver.log\". \
Type \"STDOUT\" to view log info on stdout. Type \"FILESTDOUT\" to combine previous actions. \ Type \"STDOUT\" to view log info on stdout. Type \"FILESTDOUT\" to combine previous actions. \
Use \"STDOUTOFF\" to disable stdout messages. Use \"FILEOFF\" if you not want to create logfile.', Use \"STDOUTOFF\" to disable stdout messages. Use \"FILEOFF\" if you not want to create logfile.',
@ -395,16 +395,16 @@ def server_check():
# Check sqlite. # Check sqlite.
if srv_config['sqlite']: if srv_config['sqlite']:
if (isinstance(srv_config['sqlite'], str)) and (not srv_config['sqlite'].lower().endswith('.db')): if isinstance(srv_config['sqlite'], str):
pretty_printer(log_obj = loggersrv.error, to_exit = True, check_dir(srv_config['sqlite'], 'srv', log_obj = loggersrv.error, argument = '-s/--sqlite', typefile = '.db')
put_text = "{reverse}{red}{bold}Not a sqlite file (.db).{end}") elif srv_config['sqlite'] is True:
srv_config['sqlite'] = os.path.join('.', 'pykms_database.db')
try: try:
import sqlite3 import sqlite3
if isinstance(srv_config['sqlite'], bool):
srv_config['sqlite'] = os.path.join('.', 'pykms_database.db')
except ImportError: except ImportError:
pretty_printer(log_obj = loggersrv.warning, pretty_printer(log_obj = loggersrv.warning,
put_text = "{reverse}{yellow}{bold}Module 'sqlite3' is not installed, database support disabled.{end}") put_text = "{reverse}{yellow}{bold}Module 'sqlite3' not installed, database support disabled.{end}")
srv_config['sqlite'] = False srv_config['sqlite'] = False
# Check other specific server options. # Check other specific server options.
@ -498,6 +498,7 @@ def server_main_no_terminal():
class kmsServerHandler(socketserver.BaseRequestHandler): class kmsServerHandler(socketserver.BaseRequestHandler):
def setup(self): def setup(self):
loggersrv.info("Connection accepted: %s:%d" %(self.client_address[0], self.client_address[1])) loggersrv.info("Connection accepted: %s:%d" %(self.client_address[0], self.client_address[1]))
srv_config['raddr'] = self.client_address
def handle(self): def handle(self):
while True: while True:

View File

@ -27,7 +27,7 @@ licenseStatus TEXT, lastRequestTime INTEGER, kmsEpid TEXT, requestCount INTEGER)
except sqlite3.Error as e: except sqlite3.Error as e:
pretty_printer(log_obj = loggersrv.error, to_exit = True, pretty_printer(log_obj = loggersrv.error, to_exit = True,
put_text = "{reverse}{red}{bold}%s. Exiting...{end}" %str(e)) put_text = "{reverse}{red}{bold}Sqlite Error: %s. Exiting...{end}" %str(e))
finally: finally:
if con: if con:
con.commit() con.commit()
@ -38,7 +38,7 @@ def sql_update(dbName, infoDict):
try: try:
con = sqlite3.connect(dbName) con = sqlite3.connect(dbName)
cur = con.cursor() cur = con.cursor()
cur.execute("SELECT * FROM clients WHERE clientMachineId=:clientMachineId;", infoDict) cur.execute("SELECT * FROM clients WHERE clientMachineId=:clientMachineId AND applicationId=:appId;", infoDict)
try: try:
data = cur.fetchone() data = cur.fetchone()
if not data: if not data:
@ -48,51 +48,54 @@ skuId, licenseStatus, lastRequestTime, requestCount) VALUES (:clientMachineId, :
else: else:
# Update data. # Update data.
if data[1] != infoDict["machineName"]: if data[1] != infoDict["machineName"]:
cur.execute("UPDATE clients SET machineName=:machineName WHERE clientMachineId=:clientMachineId;", infoDict) cur.execute("UPDATE clients SET machineName=:machineName WHERE \
clientMachineId=:clientMachineId AND applicationId=:appId;", infoDict)
if data[2] != infoDict["appId"]: if data[2] != infoDict["appId"]:
cur.execute("UPDATE clients SET applicationId=:appId WHERE clientMachineId=:clientMachineId;", infoDict) cur.execute("UPDATE clients SET applicationId=:appId WHERE \
clientMachineId=:clientMachineId AND applicationId=:appId;", infoDict)
if data[3] != infoDict["skuId"]: if data[3] != infoDict["skuId"]:
cur.execute("UPDATE clients SET skuId=:skuId WHERE clientMachineId=:clientMachineId;", infoDict) cur.execute("UPDATE clients SET skuId=:skuId WHERE \
clientMachineId=:clientMachineId AND applicationId=:appId;", infoDict)
if data[4] != infoDict["licenseStatus"]: if data[4] != infoDict["licenseStatus"]:
cur.execute("UPDATE clients SET licenseStatus=:licenseStatus WHERE clientMachineId=:clientMachineId;", infoDict) cur.execute("UPDATE clients SET licenseStatus=:licenseStatus WHERE \
clientMachineId=:clientMachineId AND applicationId=:appId;", infoDict)
if data[5] != infoDict["requestTime"]: if data[5] != infoDict["requestTime"]:
cur.execute("UPDATE clients SET lastRequestTime=:requestTime WHERE clientMachineId=:clientMachineId;", infoDict) cur.execute("UPDATE clients SET lastRequestTime=:requestTime WHERE \
clientMachineId=:clientMachineId AND applicationId=:appId;", infoDict)
# Increment requestCount # Increment requestCount
cur.execute("UPDATE clients SET requestCount=requestCount+1 WHERE clientMachineId=:clientMachineId;", infoDict) cur.execute("UPDATE clients SET requestCount=requestCount+1 WHERE \
clientMachineId=:clientMachineId AND applicationId=:appId;", infoDict)
except sqlite3.Error as e: except sqlite3.Error as e:
pretty_printer(log_obj = loggersrv.error, to_exit = True, pretty_printer(log_obj = loggersrv.error, to_exit = True,
put_text = "{reverse}{red}{bold}%s. Exiting...{end}" %str(e)) put_text = "{reverse}{red}{bold}Sqlite Error: %s. Exiting...{end}" %str(e))
except sqlite3.Error as e: except sqlite3.Error as e:
pretty_printer(log_obj = loggersrv.error, to_exit = True, pretty_printer(log_obj = loggersrv.error, to_exit = True,
put_text = "{reverse}{red}{bold}%s. Exiting...{end}" %str(e)) put_text = "{reverse}{red}{bold}Sqlite Error: %s. Exiting...{end}" %str(e))
finally: finally:
if con: if con:
con.commit() con.commit()
con.close() con.close()
def sql_update_epid(dbName, kmsRequest, response): def sql_update_epid(dbName, kmsRequest, response, appName):
cmid = str(kmsRequest['clientMachineId'].get()) cmid = str(kmsRequest['clientMachineId'].get())
con = None con = None
try: try:
con = sqlite3.connect(dbName) con = sqlite3.connect(dbName)
cur = con.cursor() cur = con.cursor()
cur.execute("SELECT * FROM clients WHERE clientMachineId=?;", [cmid]) cur.execute("SELECT * FROM clients WHERE clientMachineId=? AND applicationId=?;", (cmid, appName))
try: try:
data = cur.fetchone() data = cur.fetchone()
if data[6]: cur.execute("UPDATE clients SET kmsEpid=? WHERE \
response["kmsEpid"] = data[6].encode('utf-16le') clientMachineId=? AND applicationId=?;", (str(response["kmsEpid"].decode('utf-16le')), cmid, appName))
else:
cur.execute("UPDATE clients SET kmsEpid=? WHERE clientMachineId=?;", (str(response["kmsEpid"].decode('utf-16le')),
cmid))
except sqlite3.Error as e: except sqlite3.Error as e:
pretty_printer(log_obj = loggersrv.error, to_exit = True, pretty_printer(log_obj = loggersrv.error, to_exit = True,
put_text = "{reverse}{red}{bold}%s. Exiting...{end}" %str(e)) put_text = "{reverse}{red}{bold}Sqlite Error: %s. Exiting...{end}" %str(e))
except sqlite3.Error as e: except sqlite3.Error as e:
pretty_printer(log_obj = loggersrv.error, to_exit = True, pretty_printer(log_obj = loggersrv.error, to_exit = True,
put_text = "{reverse}{red}{bold}%s. Exiting...{end}" %str(e)) put_text = "{reverse}{red}{bold}Sqlite Error: %s. Exiting...{end}" %str(e))
finally: finally:
if con: if con:
con.commit() con.commit()
con.close() con.close()
return response