From 83a59b3584da1f8d4610d7a19401d4aef14dc2c6 Mon Sep 17 00:00:00 2001
From: Pg <pg.developper.fr@gmail.com>
Date: Sat, 30 Mar 2019 21:27:59 +0100
Subject: [PATCH 1/2] Create .gitignore

Create a gitignore following the github reference : https://github.com/github/gitignore/blob/master/Python.gitignore
---
 .gitignore | 128 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 128 insertions(+)
 create mode 100644 .gitignore

diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..6cbedd5
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,128 @@
+# App files
+py2kms_server.log*
+py3kms_server.log*
+
+# Byte-compiled / optimized / DLL files
+__pycache__/
+*.py[cod]
+*$py.class
+
+# C extensions
+*.so
+
+# Distribution / packaging
+.Python
+build/
+develop-eggs/
+dist/
+downloads/
+eggs/
+.eggs/
+lib/
+lib64/
+parts/
+sdist/
+var/
+wheels/
+pip-wheel-metadata/
+share/python-wheels/
+*.egg-info/
+.installed.cfg
+*.egg
+MANIFEST
+
+# PyInstaller
+#  Usually these files are written by a python script from a template
+#  before PyInstaller builds the exe, so as to inject date/other infos into it.
+*.manifest
+*.spec
+
+# Installer logs
+pip-log.txt
+pip-delete-this-directory.txt
+
+# Unit test / coverage reports
+htmlcov/
+.tox/
+.nox/
+.coverage
+.coverage.*
+.cache
+nosetests.xml
+coverage.xml
+*.cover
+.hypothesis/
+.pytest_cache/
+
+# Translations
+*.mo
+*.pot
+
+# Django stuff:
+*.log
+local_settings.py
+db.sqlite3
+
+# Flask stuff:
+instance/
+.webassets-cache
+
+# Scrapy stuff:
+.scrapy
+
+# Sphinx documentation
+docs/_build/
+
+# PyBuilder
+target/
+
+# Jupyter Notebook
+.ipynb_checkpoints
+
+# IPython
+profile_default/
+ipython_config.py
+
+# pyenv
+.python-version
+
+# pipenv
+#   According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
+#   However, in case of collaboration, if having platform-specific dependencies or dependencies
+#   having no cross-platform support, pipenv may install dependencies that don’t work, or not
+#   install all needed dependencies.
+#Pipfile.lock
+
+# celery beat schedule file
+celerybeat-schedule
+
+# SageMath parsed files
+*.sage.py
+
+# Environments
+.env
+.venv
+env/
+venv/
+ENV/
+env.bak/
+venv.bak/
+
+# Spyder project settings
+.spyderproject
+.spyproject
+
+# Rope project settings
+.ropeproject
+
+# mkdocs documentation
+/site
+
+# mypy
+.mypy_cache/
+.dmypy.json
+dmypy.json
+
+# Pyre type checker
+.pyre/
+

From 96ac35104f30224291cd7d75d96b3a48a158ee77 Mon Sep 17 00:00:00 2001
From: Pg <pg.developper.fr@gmail.com>
Date: Sat, 30 Mar 2019 21:28:51 +0100
Subject: [PATCH 2/2] Add the logsize option

Add -S or --logsize to define a maximum size for the logs.
---
 py2-kms/kmsBase.py      | 42 ++++++++++++++++----------------
 py2-kms/kmsRequestV4.py | 10 ++++----
 py2-kms/kmsRequestV5.py | 10 ++++----
 py2-kms/rpcBind.py      | 14 ++++++-----
 py2-kms/rpcRequest.py   | 14 ++++++-----
 py2-kms/server.py       | 51 ++++++++++++++++++++++++---------------
 py3-kms/kmsBase.py      | 42 ++++++++++++++++----------------
 py3-kms/kmsRequestV4.py | 10 ++++----
 py3-kms/kmsRequestV5.py | 10 ++++----
 py3-kms/rpcBind.py      | 14 ++++++-----
 py3-kms/rpcRequest.py   | 14 ++++++-----
 py3-kms/server.py       | 53 +++++++++++++++++++++++++----------------
 12 files changed, 165 insertions(+), 119 deletions(-)

diff --git a/py2-kms/kmsBase.py b/py2-kms/kmsBase.py
index 0c27e64..c3ce92a 100644
--- a/py2-kms/kmsBase.py
+++ b/py2-kms/kmsBase.py
@@ -19,6 +19,8 @@ try:
 except ImportError:
 	pass
 
+logger = logging.getLogger('root')
+
 class UUID(Structure):
 	commonHdr = ()
 	structure = (
@@ -131,7 +133,7 @@ class kmsBase:
 skuId TEXT, licenseStatus TEXT, lastRequestTime INTEGER, kmsEpid TEXT, requestCount INTEGER)")
 
 				except sqlite3.Error, e:
-                                        logging.error("Error %s:" % e.args[0])
+                                        logger.error("Error %s:" % e.args[0])
 					sys.exit(1)
 
 				finally:
@@ -140,8 +142,8 @@ skuId TEXT, licenseStatus TEXT, lastRequestTime INTEGER, kmsEpid TEXT, requestCo
 						con.close()
 
 		shell_message(nshell = 15)
-                logging.debug("KMS Request Bytes: \n%s\n" % justify(binascii.b2a_hex(str(kmsRequest))))
-                logging.debug("KMS Request: \n%s\n" % justify(kmsRequest.dump(print_to_stdout = False)))
+                logger.debug("KMS Request Bytes: \n%s\n" % justify(binascii.b2a_hex(str(kmsRequest))))
+                logger.debug("KMS Request: \n%s\n" % justify(kmsRequest.dump(print_to_stdout = False)))
 			
 		clientMachineId = kmsRequest['clientMachineId'].get()
 		applicationId = kmsRequest['applicationId'].get()
@@ -156,10 +158,10 @@ skuId TEXT, licenseStatus TEXT, lastRequestTime INTEGER, kmsEpid TEXT, requestCo
                                 tz = get_localzone()
                                 local_dt = tz.localize(requestDatetime)
                         except UnknownTimeZoneError:
-                                logging.warning('Unknown time zone ! Request time not localized.')
+                                logger.warning('Unknown time zone ! Request time not localized.')
                                 local_dt = requestDatetime
                 except ImportError:
-                        logging.warning('Module "tzlocal" not available ! Request time not localized.')
+                        logger.warning('Module "tzlocal" not available ! Request time not localized.')
                         local_dt = requestDatetime
 
 		# Get SkuId, AppId and client threshold.
@@ -206,12 +208,12 @@ skuId TEXT, licenseStatus TEXT, lastRequestTime INTEGER, kmsEpid TEXT, requestCo
 			"kmsEpid" : None
 		}
 
-                logging.info("Machine Name: %s" % infoDict["machineName"])
-                logging.info("Client Machine ID: %s" % infoDict["clientMachineId"])
-                logging.info("Application ID: %s" % infoDict["appId"])
-                logging.info("SKU ID: %s" % infoDict["skuId"])
-                logging.info("License Status: %s" % infoDict["licenseStatus"])
-                logging.info("Request Time: %s" % local_dt.strftime('%Y-%m-%d %H:%M:%S %Z (UTC%z)'))
+                logger.info("Machine Name: %s" % infoDict["machineName"])
+                logger.info("Client Machine ID: %s" % infoDict["clientMachineId"])
+                logger.info("Application ID: %s" % infoDict["appId"])
+                logger.info("SKU ID: %s" % infoDict["skuId"])
+                logger.info("License Status: %s" % infoDict["licenseStatus"])
+                logger.info("Request Time: %s" % local_dt.strftime('%Y-%m-%d %H:%M:%S %Z (UTC%z)'))
 
 		if self.config['sqlite'] and self.config['dbSupport']:
 			con = None
@@ -247,10 +249,10 @@ clientMachineId=:clientMachineId;", infoDict)
 clientMachineId=:clientMachineId;", infoDict)
 
 				except sqlite3.Error, e:
-                                        logging.error("Error %s:" % e.args[0])
+                                        logger.error("Error %s:" % e.args[0])
 					
 			except sqlite3.Error, e:
-                                logging.error("Error %s:" % e.args[0])
+                                logger.error("Error %s:" % e.args[0])
 				sys.exit(1)
 			finally:
 				if con:
@@ -292,17 +294,17 @@ clientMachineId=:clientMachineId;", infoDict)
                                                             (str(response["kmsEpid"].decode('utf-16le')), str(kmsRequest['clientMachineId'].get())))
 
 				except sqlite3.Error, e:
-                                        logging.error("Error %s:" % e.args[0])
+                                        logger.error("Error %s:" % e.args[0])
 					
 			except sqlite3.Error, e:
-                                logging.error("Error %s:" % e.args[0])
+                                logger.error("Error %s:" % e.args[0])
                                 sys.exit(1)
 			finally:
 				if con:
 					con.commit()
 					con.close()
 
-                logging.info("Server ePID: %s" % response["kmsEpid"].decode('utf-16le').encode('utf-8'))
+                logger.info("Server ePID: %s" % response["kmsEpid"].decode('utf-16le').encode('utf-8'))
                         
 		return response
 
@@ -314,16 +316,16 @@ def generateKmsResponseData(data, config):
 	currentDate = time.strftime("%a %b %d %H:%M:%S %Y")
 
 	if version == 4:
-		logging.info("Received V%d request on %s." % (version, currentDate))
+		logger.info("Received V%d request on %s." % (version, currentDate))
 		messagehandler = kmsRequestV4.kmsRequestV4(data, config)	
 	elif version == 5:
-		logging.info("Received V%d request on %s." % (version, currentDate))
+		logger.info("Received V%d request on %s." % (version, currentDate))
 		messagehandler = kmsRequestV5.kmsRequestV5(data, config)
 	elif version == 6:
-		logging.info("Received V%d request on %s." % (version, currentDate))
+		logger.info("Received V%d request on %s." % (version, currentDate))
 		messagehandler = kmsRequestV6.kmsRequestV6(data, config)
 	else:
-		logging.info("Unhandled KMS version V%d." % version)
+		logger.info("Unhandled KMS version V%d." % version)
 		messagehandler = kmsRequestUnknown.kmsRequestUnknown(data, config)
 		
 	return messagehandler.executeRequestLogic()
diff --git a/py2-kms/kmsRequestV4.py b/py2-kms/kmsRequestV4.py
index 28981fd..a91e9cb 100644
--- a/py2-kms/kmsRequestV4.py
+++ b/py2-kms/kmsRequestV4.py
@@ -9,6 +9,8 @@ from structure import Structure
 from aes import AES
 from formatText import shell_message, justify
 
+logger = logging.getLogger('root')
+
 # v4 AES Key
 key = bytearray([0x05, 0x3D, 0x83, 0x07, 0xF9, 0xE5, 0xF0, 0x88, 0xEB, 0x5E, 0xA6, 0x68, 0x6C, 0xF0, 0x37, 0xC7, 0xE4, 0xEF, 0xD2, 0xD6])
 
@@ -102,8 +104,8 @@ class kmsRequestV4(kmsBase):
 
 		## Debug stuff.
 		shell_message(nshell = 16)                
-                logging.debug("KMS V4 Response: \n%s\n" % justify(response.dump(print_to_stdout = False)))
-                logging.debug("KMS V4 Response Bytes: \n%s\n" % justify(binascii.b2a_hex(str(response))))
+                logger.debug("KMS V4 Response: \n%s\n" % justify(response.dump(print_to_stdout = False)))
+                logger.debug("KMS V4 Response Bytes: \n%s\n" % justify(binascii.b2a_hex(str(response))))
 			
 		return str(response)
 
@@ -120,7 +122,7 @@ class kmsRequestV4(kmsBase):
 
 		## Debug stuff.
 		shell_message(nshell = 10)                
-                logging.debug("Request V4 Data: \n%s\n" % justify(request.dump(print_to_stdout = False)))
-                logging.debug("Request V4: \n%s\n" % justify(binascii.b2a_hex(str(request))))
+                logger.debug("Request V4 Data: \n%s\n" % justify(request.dump(print_to_stdout = False)))
+                logger.debug("Request V4: \n%s\n" % justify(binascii.b2a_hex(str(request))))
                         
 		return request
diff --git a/py2-kms/kmsRequestV5.py b/py2-kms/kmsRequestV5.py
index 824c55b..a6a14eb 100644
--- a/py2-kms/kmsRequestV5.py
+++ b/py2-kms/kmsRequestV5.py
@@ -10,6 +10,8 @@ from kmsBase import kmsBase
 from structure import Structure
 from formatText import justify, shell_message
 
+logger = logging.getLogger('root')
+
 class kmsRequestV5(kmsBase):
         class RequestV5(Structure):
                 class Message(Structure):
@@ -135,8 +137,8 @@ class kmsRequestV5(kmsBase):
                 response['padding'] = bytearray(self.getPadding(bodyLength))
                 
                 shell_message(nshell = 16)
-                logging.info("KMS V%d Response: \n%s\n" % (self.ver, justify(response.dump(print_to_stdout = False))))
-                logging.info("KMS V%d Structure Bytes: \n%s\n" % (self.ver, justify(binascii.b2a_hex(str(response)))))
+                logger.info("KMS V%d Response: \n%s\n" % (self.ver, justify(response.dump(print_to_stdout = False))))
+                logger.info("KMS V%d Structure Bytes: \n%s\n" % (self.ver, justify(binascii.b2a_hex(str(response)))))
                         
                 return str(response)
 
@@ -166,7 +168,7 @@ class kmsRequestV5(kmsBase):
                 request['message'] = message
 
                 shell_message(nshell = 10)
-                logging.info("Request V%d Data: \n%s\n" % (self.ver, justify(request.dump(print_to_stdout = False))))
-                logging.info("Request V%d: \n%s\n" % (self.ver, justify(binascii.b2a_hex(str(request)))))
+                logger.info("Request V%d Data: \n%s\n" % (self.ver, justify(request.dump(print_to_stdout = False))))
+                logger.info("Request V%d: \n%s\n" % (self.ver, justify(binascii.b2a_hex(str(request)))))
                                 
                 return request
diff --git a/py2-kms/rpcBind.py b/py2-kms/rpcBind.py
index 42f1a62..cf0e0cb 100644
--- a/py2-kms/rpcBind.py
+++ b/py2-kms/rpcBind.py
@@ -9,6 +9,8 @@ from dcerpc import MSRPCHeader, MSRPCBindAck
 from structure import Structure
 from formatText import shell_message, justify
 
+logger = logging.getLogger('root')
+
 uuidNDR32 = uuid.UUID('8a885d04-1ceb-11c9-9fe8-08002b104860')
 uuidNDR64 = uuid.UUID('71710533-beba-4937-8319-b5dbef9ccc36')
 uuidTime = uuid.UUID('6cb71c2c-9812-4540-0300-000000000000')
@@ -74,8 +76,8 @@ class handler(rpcBase.rpcBase):
         def parseRequest(self):
                 request = MSRPCHeader(self.data)
                 shell_message(nshell = 3)
-                logging.debug("RPC Bind Request Bytes: \n%s\n" % justify(binascii.b2a_hex(self.data)))
-                logging.debug("RPC Bind Request: \n%s\n%s\n" % (justify(request.dump(print_to_stdout = False)),
+                logger.debug("RPC Bind Request Bytes: \n%s\n" % justify(binascii.b2a_hex(self.data)))
+                logger.debug("RPC Bind Request: \n%s\n%s\n" % (justify(request.dump(print_to_stdout = False)),
                                                                 justify(MSRPCBind(request['pduData']).dump(print_to_stdout = False))))
                 
                 return request
@@ -117,8 +119,8 @@ class handler(rpcBase.rpcBase):
                         response['ctx_items'] += str(resp)
 
                 shell_message(nshell = 4)       
-                logging.debug("RPC Bind Response: \n%s\n" % justify(response.dump(print_to_stdout = False)))
-                logging.debug("RPC Bind Response Bytes: \n%s\n" % justify(binascii.b2a_hex(str(response))))
+                logger.debug("RPC Bind Response: \n%s\n" % justify(response.dump(print_to_stdout = False)))
+                logger.debug("RPC Bind Response Bytes: \n%s\n" % justify(binascii.b2a_hex(str(response))))
 
                 return response
 
@@ -157,9 +159,9 @@ class handler(rpcBase.rpcBase):
                 request['pduData'] = str(bind)
 
                 shell_message(nshell = 0)
-                logging.debug("RPC Bind Request: \n%s\n%s\n" % (justify(request.dump(print_to_stdout = False)),
+                logger.debug("RPC Bind Request: \n%s\n%s\n" % (justify(request.dump(print_to_stdout = False)),
                                                                 justify(MSRPCBind(request['pduData']).dump(print_to_stdout = False))))
-                logging.debug("RPC Bind Request Bytes: \n%s\n" % justify(binascii.b2a_hex(str(request))))
+                logger.debug("RPC Bind Request Bytes: \n%s\n" % justify(binascii.b2a_hex(str(request))))
 
                 return request
 
diff --git a/py2-kms/rpcRequest.py b/py2-kms/rpcRequest.py
index 63b2c4a..e7a29dc 100644
--- a/py2-kms/rpcRequest.py
+++ b/py2-kms/rpcRequest.py
@@ -8,12 +8,14 @@ import kmsBase
 import rpcBase
 from formatText import justify, shell_message
 
+logger = logging.getLogger('root')
+
 class handler(rpcBase.rpcBase):
         def parseRequest(self):
                 request = MSRPCRequestHeader(self.data)
                 shell_message(nshell = 14)
-                logging.debug("RPC Message Request Bytes: \n%s\n" % justify(binascii.b2a_hex(self.data)))
-                logging.debug("RPC Message Request: \n%s\n" % justify(request.dump(print_to_stdout = False)))
+                logger.debug("RPC Message Request Bytes: \n%s\n" % justify(binascii.b2a_hex(self.data)))
+                logger.debug("RPC Message Request: \n%s\n" % justify(request.dump(print_to_stdout = False)))
                 
                 return request
 
@@ -36,8 +38,8 @@ class handler(rpcBase.rpcBase):
                 response['pduData'] = responseData
 
                 shell_message(nshell = 17)
-                logging.debug("RPC Message Response: \n%s\n" % justify(response.dump(print_to_stdout = False)))
-                logging.debug("RPC Message Response Bytes: \n%s\n" % justify(binascii.b2a_hex(str(response))))
+                logger.debug("RPC Message Response: \n%s\n" % justify(response.dump(print_to_stdout = False)))
+                logger.debug("RPC Message Response Bytes: \n%s\n" % justify(binascii.b2a_hex(str(response))))
 
                 return response
 
@@ -54,8 +56,8 @@ class handler(rpcBase.rpcBase):
                 request['pduData'] = str(self.data)
 
                 shell_message(nshell = 11)
-                logging.debug("RPC Message Request: \n%s\n" % justify(request.dump(print_to_stdout = False)))
-                logging.debug("RPC Message Request Bytes: \n%s\n" % justify(binascii.b2a_hex(str(request))))
+                logger.debug("RPC Message Request: \n%s\n" % justify(request.dump(print_to_stdout = False)))
+                logger.debug("RPC Message Request Bytes: \n%s\n" % justify(binascii.b2a_hex(str(request))))
 
                 return request
 
diff --git a/py2-kms/server.py b/py2-kms/server.py
index 950d830..721a075 100644
--- a/py2-kms/server.py
+++ b/py2-kms/server.py
@@ -15,9 +15,12 @@ import rpcBind, rpcRequest
 from dcerpc import MSRPCHeader
 from rpcBase import rpcBase
 from formatText import shell_message
+from logging.handlers import RotatingFileHandler
 
 config = {}
 
+logger = logging.getLogger('root')
+
 # Valid language identifiers to be used in the EPID (see "kms.c" in vlmcsd)
 ValidLcid = [1025, 1026, 1027, 1028, 1029,
              1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039,
@@ -39,6 +42,15 @@ ValidLcid = [1025, 1026, 1027, 1028, 1029,
              10241, 10249, 10250, 11265, 11273, 11274, 12289, 12297, 12298,
              13313, 13321, 13322, 14337, 14346, 15361, 15370, 16385, 16394, 17418, 18442, 19466, 20490]
 
+def createLogger(config):
+        logger.setLevel(config['loglevel'])
+
+        log_formatter = logging.Formatter('%(asctime)s %(levelname)-8s %(message)s', '%a, %d %b %Y %H:%M:%S')
+        log_handler = RotatingFileHandler(filename=config['logfile'], mode='a', maxBytes=int(config['logsize']*1024*512), backupCount=1, encoding=None, delay=0)
+        print int(config['logsize']*1024*512)
+        log_handler.setFormatter(log_formatter)
+        
+        logger.addHandler(log_handler)
 
 def main():
         parser = argparse.ArgumentParser(description='py2-kms: KMS Server Emulator written in Python2', epilog="version: py2-kms_2018-11-15")
@@ -66,12 +78,13 @@ The default is \"364F463A8863D35F\" or type \"random\" to auto generate the HWID
                             help='Use this flag to set a Loglevel. The default is \"ERROR\".', type=str)
         parser.add_argument("-f", "--logfile", dest="logfile", action="store", default=os.path.dirname(os.path.abspath( __file__ )) + "/py2kms_server.log",
                             help='Use this flag to set an output Logfile. The default is \"pykms_server.log\".', type=str)
+        parser.add_argument("-S", "--logsize", dest="logsize", action="store", default=0,
+                            help='Use this flag to set a maximum size (in MB) to the output Logfile. Desactivated by default.', type=float)
         
         config.update(vars(parser.parse_args()))
 
-        logging.basicConfig(level=config['loglevel'], format='%(asctime)s %(levelname)-8s %(message)s',
-                            datefmt='%a, %d %b %Y %H:%M:%S', filename=config['logfile'], filemode='w')
-        
+        createLogger(config)
+
         # Random HWID.
         if config['hwid'] == "random":
                 randomhwid = uuid.uuid4().hex
@@ -81,13 +94,13 @@ The default is \"364F463A8863D35F\" or type \"random\" to auto generate the HWID
         try:
                 config['hwid'] = binascii.a2b_hex(re.sub(r'[^0-9a-fA-F]', '', config['hwid'].strip('0x')))
                 if len(binascii.b2a_hex(config['hwid'])) < 16:
-                        logging.error("Error: HWID \"%s\" is invalid. Hex string is too short." % binascii.b2a_hex(config['hwid']).upper())
+                        logger.error("Error: HWID \"%s\" is invalid. Hex string is too short." % binascii.b2a_hex(config['hwid']).upper())
                         return
                 elif len(binascii.b2a_hex(config['hwid'])) > 16:
-                        logging.error("Error: HWID \"%s\" is invalid. Hex string is too long." % binascii.b2a_hex(config['hwid']).upper())
+                        logger.error("Error: HWID \"%s\" is invalid. Hex string is too long." % binascii.b2a_hex(config['hwid']).upper())
                         return
         except TypeError:
-                logging.error("Error: HWID \"%s\" is invalid. Odd-length hex string." % binascii.b2a_hex(config['hwid']).upper())
+                logger.error("Error: HWID \"%s\" is invalid. Odd-length hex string." % binascii.b2a_hex(config['hwid']).upper())
                 return
         
         # Check LCID.
@@ -110,21 +123,21 @@ The default is \"364F463A8863D35F\" or type \"random\" to auto generate the HWID
         try:
                 import sqlite3            
         except:
-                logging.warning("Module \"sqlite3\" is not installed, database support disabled.")
+                logger.warning("Module \"sqlite3\" is not installed, database support disabled.")
                 config['dbSupport'] = False
         else:
                 config['dbSupport'] = True
                 
         server = SocketServer.TCPServer((config['ip'], config['port']), kmsServer)
         server.timeout = 5
-        logging.info("TCP server listening at %s on port %d." % (config['ip'], config['port']))
-        logging.info("HWID: %s" % binascii.b2a_hex(config['hwid']).upper())
+        logger.info("TCP server listening at %s on port %d." % (config['ip'], config['port']))
+        logger.info("HWID: %s" % binascii.b2a_hex(config['hwid']).upper())
         server.serve_forever()
         
 
 class kmsServer(SocketServer.BaseRequestHandler):
         def setup(self):
-                logging.info("Connection accepted: %s:%d" % (self.client_address[0], self.client_address[1]))
+                logger.info("Connection accepted: %s:%d" % (self.client_address[0], self.client_address[1]))
 
         def handle(self):
                 while True:
@@ -133,42 +146,42 @@ class kmsServer(SocketServer.BaseRequestHandler):
                                 data = self.request.recv(1024)
                         except socket.error, e:
                                 if e.errno == errno.ECONNRESET:
-                                        logging.error("Connection reset by peer.")
+                                        logger.error("Connection reset by peer.")
                                         break
                                 else:
                                         raise
                         if not data:
-                                logging.warning("No data received !")
+                                logger.warning("No data received !")
                                 break
                         # data = bytearray(self.data.strip())
-                        # logging.debug(binascii.b2a_hex(str(data)))
+                        # logger.debug(binascii.b2a_hex(str(data)))
                         packetType = MSRPCHeader(data)['type']
                         if packetType == rpcBase.packetType['bindReq']:
-                                logging.info("RPC bind request received.")
+                                logger.info("RPC bind request received.")
                                 shell_message(nshell = [-2, 2])
                                 handler = rpcBind.handler(data, config)
                         elif packetType == rpcBase.packetType['request']:
-                                logging.info("Received activation request.")
+                                logger.info("Received activation request.")
                                 shell_message(nshell = [-2, 13])
                                 handler = rpcRequest.handler(data, config)
                         else:
-                                logging.error("Error: Invalid RPC request type ", packetType)
+                                logger.error("Error: Invalid RPC request type ", packetType)
                                 break
 
                         res = str(handler.populate())
                         self.request.send(res)
 
                         if packetType == rpcBase.packetType['bindReq']:
-                                logging.info("RPC bind acknowledged.")
+                                logger.info("RPC bind acknowledged.")
                                 shell_message(nshell = [-3, 5, 6])
                         elif packetType == rpcBase.packetType['request']:
-                                logging.info("Responded to activation request.")
+                                logger.info("Responded to activation request.")
                                 shell_message(nshell = [-3, 18, 19])
                                 break
 
         def finish(self):
                 self.request.close()
-                logging.info("Connection closed: %s:%d" % (self.client_address[0], self.client_address[1]))
+                logger.info("Connection closed: %s:%d" % (self.client_address[0], self.client_address[1]))
                 
 if __name__ == "__main__":
         main()
diff --git a/py3-kms/kmsBase.py b/py3-kms/kmsBase.py
index 7c002ab..bdc19d8 100644
--- a/py3-kms/kmsBase.py
+++ b/py3-kms/kmsBase.py
@@ -19,6 +19,8 @@ try:
 except ImportError:
         pass
 
+logger = logging.getLogger('root')
+
 class UUID(Structure):
         commonHdr = ()
         structure = (
@@ -130,7 +132,7 @@ class kmsBase:
 skuId TEXT, licenseStatus TEXT, lastRequestTime INTEGER, kmsEpid TEXT, requestCount INTEGER)")
 
                                 except sqlite3.Error as e:
-                                        logging.error("Error %s:" % e.args[0])
+                                        logger.error("Error %s:" % e.args[0])
                                         sys.exit(1)
 
                                 finally:
@@ -140,8 +142,8 @@ skuId TEXT, licenseStatus TEXT, lastRequestTime INTEGER, kmsEpid TEXT, requestCo
 
                 shell_message(nshell = 15)
                 kmsRequest = byterize(kmsRequest)
-                logging.debug("KMS Request Bytes: \n%s\n" % justify(binascii.b2a_hex(str(kmsRequest).encode('latin-1')).decode('utf-8')))                         
-                logging.debug("KMS Request: \n%s\n" % justify(kmsRequest.dump(print_to_stdout = False)))
+                logger.debug("KMS Request Bytes: \n%s\n" % justify(binascii.b2a_hex(str(kmsRequest).encode('latin-1')).decode('utf-8')))                         
+                logger.debug("KMS Request: \n%s\n" % justify(kmsRequest.dump(print_to_stdout = False)))
                                         
                 clientMachineId = kmsRequest['clientMachineId'].get()
                 applicationId = kmsRequest['applicationId'].get()
@@ -156,10 +158,10 @@ skuId TEXT, licenseStatus TEXT, lastRequestTime INTEGER, kmsEpid TEXT, requestCo
                                 tz = get_localzone()
                                 local_dt = tz.localize(requestDatetime)
                         except UnknownTimeZoneError:
-                                logging.warning('Unknown time zone ! Request time not localized.')
+                                logger.warning('Unknown time zone ! Request time not localized.')
                                 local_dt = requestDatetime
                 except ImportError:
-                        logging.warning('Module "tzlocal" not available ! Request time not localized.')
+                        logger.warning('Module "tzlocal" not available ! Request time not localized.')
                         local_dt = requestDatetime
                         
                 # Get SkuId, AppId and client threshold.
@@ -205,12 +207,12 @@ skuId TEXT, licenseStatus TEXT, lastRequestTime INTEGER, kmsEpid TEXT, requestCo
                 }
 
                 #print infoDict
-                logging.info("Machine Name: %s" % infoDict["machineName"])
-                logging.info("Client Machine ID: %s" % infoDict["clientMachineId"])
-                logging.info("Application ID: %s" % infoDict["appId"])
-                logging.info("SKU ID: %s" % infoDict["skuId"])
-                logging.info("License Status: %s" % infoDict["licenseStatus"])
-                logging.info("Request Time: %s" % local_dt.strftime('%Y-%m-%d %H:%M:%S %Z (UTC%z)'))
+                logger.info("Machine Name: %s" % infoDict["machineName"])
+                logger.info("Client Machine ID: %s" % infoDict["clientMachineId"])
+                logger.info("Application ID: %s" % infoDict["appId"])
+                logger.info("SKU ID: %s" % infoDict["skuId"])
+                logger.info("License Status: %s" % infoDict["licenseStatus"])
+                logger.info("Request Time: %s" % local_dt.strftime('%Y-%m-%d %H:%M:%S %Z (UTC%z)'))
 
                 if self.config['sqlite'] and self.config['dbSupport']:
                         con = None
@@ -246,10 +248,10 @@ clientMachineId=:clientMachineId;", infoDict)
 clientMachineId=:clientMachineId;", infoDict)
 
                                 except sqlite3.Error as e:
-                                        logging.error("Error %s:" % e.args[0])
+                                        logger.error("Error %s:" % e.args[0])
                                         
                         except sqlite3.Error as e:
-                                logging.error("Error %s:" % e.args[0])
+                                logger.error("Error %s:" % e.args[0])
                                 sys.exit(1)
                         finally:
                                 if con:
@@ -290,17 +292,17 @@ clientMachineId=:clientMachineId;", infoDict)
                                                             (str(response["kmsEpid"].decode('utf-16le')), str(kmsRequest['clientMachineId'].get())))
 
                                 except sqlite3.Error as e:
-                                        logging.error("Error %s:" % e.args[0])
+                                        logger.error("Error %s:" % e.args[0])
                                         
                         except sqlite3.Error as e:
-                                logging.error("Error %s:" % e.args[0])
+                                logger.error("Error %s:" % e.args[0])
                                 sys.exit(1)
                         finally:
                                 if con:
                                         con.commit()
                                         con.close()
 
-                logging.info("Server ePID: %s" % response["kmsEpid"].decode('utf-16le'))
+                logger.info("Server ePID: %s" % response["kmsEpid"].decode('utf-16le'))
                         
                 return response
 
@@ -312,16 +314,16 @@ def generateKmsResponseData(data, config):
         currentDate = time.strftime("%a %b %d %H:%M:%S %Y")
 
         if version == 4:
-                logging.info("Received V%d request on %s." % (version, currentDate))
+                logger.info("Received V%d request on %s." % (version, currentDate))
                 messagehandler = kmsRequestV4.kmsRequestV4(data, config)     
         elif version == 5:
-                logging.info("Received V%d request on %s." % (version, currentDate))
+                logger.info("Received V%d request on %s." % (version, currentDate))
                 messagehandler = kmsRequestV5.kmsRequestV5(data, config)
         elif version == 6:
-                logging.info("Received V%d request on %s." % (version, currentDate))
+                logger.info("Received V%d request on %s." % (version, currentDate))
                 messagehandler = kmsRequestV6.kmsRequestV6(data, config)
         else:
-                logging.info("Unhandled KMS version V%d." % version)
+                logger.info("Unhandled KMS version V%d." % version)
                 messagehandler = kmsRequestUnknown.kmsRequestUnknown(data, config)
                 
         return messagehandler.executeRequestLogic()
diff --git a/py3-kms/kmsRequestV4.py b/py3-kms/kmsRequestV4.py
index 3bc8370..263822c 100644
--- a/py3-kms/kmsRequestV4.py
+++ b/py3-kms/kmsRequestV4.py
@@ -9,6 +9,8 @@ from structure import Structure
 from aes import AES
 from formatText import shell_message, justify, byterize
 
+logger = logging.getLogger('root')
+
 # v4 AES Key
 key = bytearray([0x05, 0x3D, 0x83, 0x07, 0xF9, 0xE5, 0xF0, 0x88, 0xEB, 0x5E, 0xA6, 0x68, 0x6C, 0xF0, 0x37, 0xC7, 0xE4, 0xEF, 0xD2, 0xD6])
 
@@ -103,8 +105,8 @@ class kmsRequestV4(kmsBase):
                 ## Debug stuff.
                 shell_message(nshell = 16)
                 response = byterize(response)
-                logging.debug("KMS V4 Response: \n%s\n" % justify(response.dump(print_to_stdout = False)))
-                logging.debug("KMS V4 Response Bytes: \n%s\n" % justify(binascii.b2a_hex(str(response).encode('latin-1')).decode('utf-8')))
+                logger.debug("KMS V4 Response: \n%s\n" % justify(response.dump(print_to_stdout = False)))
+                logger.debug("KMS V4 Response Bytes: \n%s\n" % justify(binascii.b2a_hex(str(response).encode('latin-1')).decode('utf-8')))
                         
                 return str(response)
 
@@ -122,7 +124,7 @@ class kmsRequestV4(kmsBase):
                 ## Debug stuff.
                 shell_message(nshell = 10)
                 request = byterize(request)
-                logging.debug("Request V4 Data: \n%s\n" % justify(request.dump(print_to_stdout = False)))
-                logging.debug("Request V4: \n%s\n" % justify(binascii.b2a_hex(str(request).encode('latin-1')).decode('utf-8')))
+                logger.debug("Request V4 Data: \n%s\n" % justify(request.dump(print_to_stdout = False)))
+                logger.debug("Request V4: \n%s\n" % justify(binascii.b2a_hex(str(request).encode('latin-1')).decode('utf-8')))
                                 
                 return request
diff --git a/py3-kms/kmsRequestV5.py b/py3-kms/kmsRequestV5.py
index 450e1a5..1f260c0 100644
--- a/py3-kms/kmsRequestV5.py
+++ b/py3-kms/kmsRequestV5.py
@@ -10,6 +10,8 @@ from kmsBase import kmsBase
 from structure import Structure
 from formatText import justify, shell_message, byterize
 
+logger = logging.getLogger('root')
+
 class kmsRequestV5(kmsBase):
         class RequestV5(Structure):
                 class Message(Structure):
@@ -138,8 +140,8 @@ class kmsRequestV5(kmsBase):
                 
                 shell_message(nshell = 16)
                 response = byterize(response) 
-                logging.info("KMS V%d Response: \n%s\n" % (self.ver, justify(response.dump(print_to_stdout = False))))
-                logging.info("KMS V%d Structure Bytes: \n%s\n" % (self.ver, justify(binascii.b2a_hex(str(response).encode('latin-1')).decode('utf-8'))))
+                logger.info("KMS V%d Response: \n%s\n" % (self.ver, justify(response.dump(print_to_stdout = False))))
+                logger.info("KMS V%d Structure Bytes: \n%s\n" % (self.ver, justify(binascii.b2a_hex(str(response).encode('latin-1')).decode('utf-8'))))
                                                         
                 return str(response)
         
@@ -170,7 +172,7 @@ class kmsRequestV5(kmsBase):
 
                 shell_message(nshell = 10)
                 request = byterize(request)
-                logging.info("Request V%d Data: \n%s\n" % (self.ver, justify(request.dump(print_to_stdout = False))))
-                logging.info("Request V%d: \n%s\n" % (self.ver, justify(binascii.b2a_hex(str(request).encode('latin-1')).decode('utf-8'))))
+                logger.info("Request V%d Data: \n%s\n" % (self.ver, justify(request.dump(print_to_stdout = False))))
+                logger.info("Request V%d: \n%s\n" % (self.ver, justify(binascii.b2a_hex(str(request).encode('latin-1')).decode('utf-8'))))
                 
                 return request
diff --git a/py3-kms/rpcBind.py b/py3-kms/rpcBind.py
index d30428d..f48c8f1 100644
--- a/py3-kms/rpcBind.py
+++ b/py3-kms/rpcBind.py
@@ -9,6 +9,8 @@ from dcerpc import MSRPCHeader, MSRPCBindAck
 from structure import Structure
 from formatText import shell_message, justify, byterize
 
+logger = logging.getLogger('root')
+
 uuidNDR32 = uuid.UUID('8a885d04-1ceb-11c9-9fe8-08002b104860')
 uuidNDR64 = uuid.UUID('71710533-beba-4937-8319-b5dbef9ccc36')
 uuidTime = uuid.UUID('6cb71c2c-9812-4540-0300-000000000000')
@@ -75,8 +77,8 @@ class handler(rpcBase.rpcBase):
                 request = MSRPCHeader(self.data)
                 shell_message(nshell = 3)
                 request = byterize(request)
-                logging.debug("RPC Bind Request Bytes: \n%s\n" % justify(binascii.b2a_hex(self.data).decode('utf-8')))
-                logging.debug("RPC Bind Request: \n%s\n%s\n" % (justify(request.dump(print_to_stdout = False)),
+                logger.debug("RPC Bind Request Bytes: \n%s\n" % justify(binascii.b2a_hex(self.data).decode('utf-8')))
+                logger.debug("RPC Bind Request: \n%s\n%s\n" % (justify(request.dump(print_to_stdout = False)),
                                                                 justify(MSRPCBind(request['pduData']).dump(print_to_stdout = False))))
                 
                 return request
@@ -119,8 +121,8 @@ class handler(rpcBase.rpcBase):
                                                 
                 shell_message(nshell = 4)
                 response = byterize(response)
-                logging.debug("RPC Bind Response: \n%s\n" % justify(response.dump(print_to_stdout = False)))
-                logging.debug("RPC Bind Response Bytes: \n%s\n" % justify(binascii.b2a_hex(str(response).encode('latin-1')).decode('utf-8')))
+                logger.debug("RPC Bind Response: \n%s\n" % justify(response.dump(print_to_stdout = False)))
+                logger.debug("RPC Bind Response Bytes: \n%s\n" % justify(binascii.b2a_hex(str(response).encode('latin-1')).decode('utf-8')))
                 
                 return response
 
@@ -161,9 +163,9 @@ class handler(rpcBase.rpcBase):
                 shell_message(nshell = 0)
                 bind = byterize(bind)
                 request = byterize(request)
-                logging.debug("RPC Bind Request: \n%s\n%s\n" % (justify(request.dump(print_to_stdout = False)),
+                logger.debug("RPC Bind Request: \n%s\n%s\n" % (justify(request.dump(print_to_stdout = False)),
                                                                 justify(MSRPCBind(request['pduData']).dump(print_to_stdout = False))))
-                logging.debug("RPC Bind Request Bytes: \n%s\n" % justify(binascii.b2a_hex(str(request).encode('latin-1')).decode('utf-8')))
+                logger.debug("RPC Bind Request Bytes: \n%s\n" % justify(binascii.b2a_hex(str(request).encode('latin-1')).decode('utf-8')))
                                 
                 return request
 
diff --git a/py3-kms/rpcRequest.py b/py3-kms/rpcRequest.py
index 155fc01..2ff7738 100644
--- a/py3-kms/rpcRequest.py
+++ b/py3-kms/rpcRequest.py
@@ -8,13 +8,15 @@ import kmsBase
 import rpcBase
 from formatText import justify, shell_message, byterize
 
+logger = logging.getLogger('root')
+
 class handler(rpcBase.rpcBase):
         def parseRequest(self):
                 request = MSRPCRequestHeader(self.data)
                 shell_message(nshell = 14)
                 request = byterize(request)
-                logging.debug("RPC Message Request Bytes: \n%s\n" % justify(binascii.b2a_hex(self.data).decode('utf-8')))
-                logging.debug("RPC Message Request: \n%s\n" % justify(request.dump(print_to_stdout = False)))
+                logger.debug("RPC Message Request Bytes: \n%s\n" % justify(binascii.b2a_hex(self.data).decode('utf-8')))
+                logger.debug("RPC Message Request: \n%s\n" % justify(request.dump(print_to_stdout = False)))
                                 
                 return request
 
@@ -38,8 +40,8 @@ class handler(rpcBase.rpcBase):
 
                 shell_message(nshell = 17)
                 response = byterize(response)
-                logging.debug("RPC Message Response: \n%s\n" % justify(response.dump(print_to_stdout = False)))
-                logging.debug("RPC Message Response Bytes: \n%s\n" % justify(binascii.b2a_hex(str(response).encode('latin-1')).decode('utf-8')))
+                logger.debug("RPC Message Response: \n%s\n" % justify(response.dump(print_to_stdout = False)))
+                logger.debug("RPC Message Response Bytes: \n%s\n" % justify(binascii.b2a_hex(str(response).encode('latin-1')).decode('utf-8')))
                 
                 return response
 
@@ -57,8 +59,8 @@ class handler(rpcBase.rpcBase):
 
                 shell_message(nshell = 11)
                 request = byterize(request)
-                logging.debug("RPC Message Request: \n%s\n" % justify(request.dump(print_to_stdout = False)))
-                logging.debug("RPC Message Request Bytes: \n%s\n" % justify(binascii.b2a_hex(str(request).encode('latin-1')).decode('utf-8')))
+                logger.debug("RPC Message Request: \n%s\n" % justify(request.dump(print_to_stdout = False)))
+                logger.debug("RPC Message Request Bytes: \n%s\n" % justify(binascii.b2a_hex(str(request).encode('latin-1')).decode('utf-8')))
                 
                 return request
 
diff --git a/py3-kms/server.py b/py3-kms/server.py
index 629d9ff..7290d48 100644
--- a/py3-kms/server.py
+++ b/py3-kms/server.py
@@ -15,6 +15,9 @@ import rpcBind, rpcRequest
 from dcerpc import MSRPCHeader
 from rpcBase import rpcBase
 from formatText import shell_message
+from logging.handlers import RotatingFileHandler
+
+logger = logging.getLogger('root')
 
 config = {}
 
@@ -39,6 +42,14 @@ ValidLcid = [1025, 1026, 1027, 1028, 1029,
              10241, 10249, 10250, 11265, 11273, 11274, 12289, 12297, 12298,
              13313, 13321, 13322, 14337, 14346, 15361, 15370, 16385, 16394, 17418, 18442, 19466, 20490]
 
+def createLogger(config):
+        logger.setLevel(config['loglevel'])
+
+        log_formatter = logging.Formatter('%(asctime)s %(levelname)-8s %(message)s', '%a, %d %b %Y %H:%M:%S')
+        log_handler = RotatingFileHandler(filename=config['logfile'], mode='a', maxBytes=int(config['logsize']*1024*512), backupCount=1, encoding=None, delay=0)
+        log_handler.setFormatter(log_formatter)
+        
+        logger.addHandler(log_handler)
 
 def main():
         parser = argparse.ArgumentParser(description='py3-kms: KMS Server Emulator written in Python3', epilog="version: py3-kms_2018-11-15")
@@ -66,11 +77,13 @@ The default is \"364F463A8863D35F\" or type \"random\" to auto generate the HWID
                             help='Use this flag to set a Loglevel. The default is \"ERROR\".', type=str)
         parser.add_argument("-f", "--logfile", dest="logfile", action="store", default=os.path.dirname(os.path.abspath( __file__ )) + "/py3kms_server.log",
                             help='Use this flag to set an output Logfile. The default is \"pykms_server.log\".', type=str)
-        
-        config.update(vars(parser.parse_args()))
+        parser.add_argument("-S", "--logsize", dest="logsize", action="store", default=0,
+                            help='Use this flag to set a maximum size (in MB) to the output Logfile. Desactivated by default.', type=float)
+
+        config.update(vars(parser.parse_args()))
+        
+        createLogger(config)
 
-        logging.basicConfig(level=config['loglevel'], format='%(asctime)s %(levelname)-8s %(message)s',
-                            datefmt='%a, %d %b %Y %H:%M:%S', filename=config['logfile'], filemode='w')
         # Random HWID.
         if config['hwid'] == "random":
                 randomhwid = uuid.uuid4().hex
@@ -80,13 +93,13 @@ The default is \"364F463A8863D35F\" or type \"random\" to auto generate the HWID
         try:
                 config['hwid'] = binascii.a2b_hex(re.sub(r'[^0-9a-fA-F]', '', config['hwid'].strip('0x')))
                 if len(binascii.b2a_hex(config['hwid'])) < 16:
-                        logging.error("Error: HWID \"%s\" is invalid. Hex string is too short." % binascii.b2a_hex(config['hwid']).decode('utf-8').upper())
+                        logger.error("Error: HWID \"%s\" is invalid. Hex string is too short." % binascii.b2a_hex(config['hwid']).decode('utf-8').upper())
                         return
                 elif len(binascii.b2a_hex(config['hwid'])) > 16:
-                        logging.error("Error: HWID \"%s\" is invalid. Hex string is too long." % binascii.b2a_hex(config['hwid']).decode('utf-8').upper())
+                        logger.error("Error: HWID \"%s\" is invalid. Hex string is too long." % binascii.b2a_hex(config['hwid']).decode('utf-8').upper())
                         return
         except TypeError:
-                logging.error("Error: HWID \"%s\" is invalid. Odd-length hex string." % binascii.b2a_hex(config['hwid']).decode('utf-8').upper())
+                logger.error("Error: HWID \"%s\" is invalid. Odd-length hex string." % binascii.b2a_hex(config['hwid']).decode('utf-8').upper())
                 return
 
         # Check LCID.
@@ -109,21 +122,21 @@ The default is \"364F463A8863D35F\" or type \"random\" to auto generate the HWID
         try:
                 import sqlite3            
         except:
-                logging.warning("Module \"sqlite3\" is not installed, database support disabled.")
+                logger.warning("Module \"sqlite3\" is not installed, database support disabled.")
                 config['dbSupport'] = False
         else:
                 config['dbSupport'] = True
                 
         server = socketserver.TCPServer((config['ip'], config['port']), kmsServer)
         server.timeout = 5
-        logging.info("TCP server listening at %s on port %d." % (config['ip'], config['port']))
-        logging.info("HWID: %s" % binascii.b2a_hex(config['hwid']).decode('utf-8').upper())
+        logger.info("TCP server listening at %s on port %d." % (config['ip'], config['port']))
+        logger.info("HWID: %s" % binascii.b2a_hex(config['hwid']).decode('utf-8').upper())
         server.serve_forever()
 
 
 class kmsServer(socketserver.BaseRequestHandler):
         def setup(self):
-                logging.info("Connection accepted: %s:%d" % (self.client_address[0], self.client_address[1]))
+                logger.info("Connection accepted: %s:%d" % (self.client_address[0], self.client_address[1]))
 
         def handle(self):
                 while True:
@@ -132,42 +145,42 @@ class kmsServer(socketserver.BaseRequestHandler):
                                 self.data = self.request.recv(1024)
                         except socket.error as e:
                                 if e.errno == errno.ECONNRESET:
-                                        logging.error("Connection reset by peer.")
+                                        logger.error("Connection reset by peer.")
                                         break
                                 else:
                                         raise
                         if self.data == '' or not self.data:
-                                logging.warning("No data received !")
+                                logger.warning("No data received !")
                                 break
                         # data = bytearray(self.data.strip())
-                        # logging.debug(binascii.b2a_hex(str(data)))
+                        # logger.debug(binascii.b2a_hex(str(data)))
                         packetType = MSRPCHeader(self.data)['type']
                         if packetType == rpcBase.packetType['bindReq']:
-                                logging.info("RPC bind request received.") 
+                                logger.info("RPC bind request received.") 
                                 shell_message(nshell = [-2, 2])
                                 handler = rpcBind.handler(self.data, config)
                         elif packetType == rpcBase.packetType['request']:
-                                logging.info("Received activation request.")
+                                logger.info("Received activation request.")
                                 shell_message(nshell = [-2, 13])
                                 handler = rpcRequest.handler(self.data, config)
                         else:
-                                logging.error("Error: Invalid RPC request type ", packetType)
+                                logger.error("Error: Invalid RPC request type ", packetType)
                                 break                        
                        
                         res = str(handler.populate()).encode('latin-1')
                         self.request.send(res)
 
                         if packetType == rpcBase.packetType['bindReq']:
-                                logging.info("RPC bind acknowledged.")
+                                logger.info("RPC bind acknowledged.")
                                 shell_message(nshell = [-3, 5, 6])
                         elif packetType == rpcBase.packetType['request']:
-                                logging.info("Responded to activation request.")
+                                logger.info("Responded to activation request.")
                                 shell_message(nshell = [-3, 18, 19])
                                 break
 
         def finish(self):
                 self.request.close()
-                logging.info("Connection closed: %s:%d" % (self.client_address[0], self.client_address[1]))
+                logger.info("Connection closed: %s:%d" % (self.client_address[0], self.client_address[1]))
                 
 if __name__ == "__main__":
         main()