import datetime, os, setuptools, socketserver, ssltools, sys, syslog, threading SYSLOG = 0 STDOUT = 1 STDDEB = 2 # STDOUT + Debug SILENT = 9 # Quiet mode SSL = 0 PORT = 1 exec("logging = %s or STDOUT" % setuptools.getSetting("Log", "sink")) def logger(message, prio=syslog.LOG_INFO, sink=logging): if sink in (STDOUT, STDDEB): if prio not in (syslog.LOG_NOTICE, syslog.LOG_INFO, syslog.LOG_DEBUG): print(message) sys.stderr.write(message) elif prio != syslog.LOG_DEBUG or sink == STDDEB: print(message) elif sink == SYSLOG: syslog.openlog("KumiStatusServer", syslog.LOG_PID) syslog.syslog(prio, message) elif sink != SILENT: try: sys.stderr.write("Unknown logging level %s, assuming STDOUT from now on." % str(sink)) except: pass logging = STDOUT logger(message, prio, logging) def listIncluded(host, section): for i in setuptools.getListSetting("SSL" if section == 0 else "Ports", "hosts"): if i[0].lower() == host.lower(): return True return False class TCPHandler(socketserver.StreamRequestHandler): def readString(self): return self.rfile.readline().strip() def sendString(self, string): self.request.sendall((string + "\n").encode('utf8')) def requestHandler(self, request): pass def worker(self, message): content = message.split() command = content[0].lower() try: if command in ("hi"): return "HI: Kumi Status v0.8.15 (KSP)" elif command in ("heartbeat", "hb", "ping"): return "OK: Still here? Wow." elif command in ("stat", "status"): return "UA: Not currently implemented." elif command in ("ssl", "tls"): try: if listIncluded(str(content[1]), SSL): try: expiry = ssltools.getRemoteExpiry(str(content[1]), int(content[2])) except: expiry = ssltools.getRemoteExpiry(str(content[1]), 443) if expiry > datetime.datetime.now(): dm = "%s certificate is valid until: %s" % (content[1], expiry) try: delta = int(content[3]) except: delta = 0 if expiry < datetime.datetime.now() + datetime.timedelta(days=delta): return "AL: %s" % dm return "OK: %s" % dm else: return "AL: %s certificate has expired! Please renew ASAP! - %s" % (content[1], expiry) else: return "NM: %s is not being monitored!" % content[1] except TypeError: raise except: return "ER: Could not verify SSL certificate on %s:%i. Is the server down?" % (content[1], content[2]) elif command == "port": return "UA: Not currently implemented." elif command in ("req", "request"): return "NI: Requesting monitoring is not yet implemented." elif command == "help": return "UA: Not currently implemented." else: return "IM: Unknown command %s." % command except TypeError: return "IM: Invalid values passed to %s. Try HELP %s." % (command, command) except IndexError: return "IM: Invalid values passed to %s. Try HELP %s." % (command, command) def handle(self): remote = self.client_address[0] + ":" + str(self.client_address[1]) logger("New connection from %s." % remote, syslog.LOG_INFO) self.sendString(self.worker("hi")) while True: message = self.readString().decode('utf8') if not message: logger("Connection from %s closed." % remote, syslog.LOG_DEBUG) break logger("%s said: %s" % (remote, message)) response = self.worker(message) if response: self.sendString(response) logger("Sent to %s: %s" % (remote, response), syslog.LOG_DEBUG) class TCPServer(socketserver.ThreadingMixIn, socketserver.TCPServer): pass def shutdown(reboot = False, status = 0): if reboot: args = sys.argv[:] args.insert(0, sys.executable) try: os.execv(sys.executable, args) except: logger("Restart failed. Shutting down.") exit(status)