def __init__(self, guid, psk): self._guid = str(guid) self._alias = str(guid) self._info = None self.address = None self.checkin_time = None self.crypto = ECDHE(psk=psk) self.jobs = Jobs(self) self.logger = logging.getLogger(f"session:{str(self._guid)}") self.logger.propagate = False self.logger.setLevel(logging.DEBUG) try: os.mkdir(os.path.join(get_path_in_artic2("logs"), f"{self._guid}")) except FileExistsError: pass formatter = logging.Formatter('%(asctime)s - %(message)s') fh = logging.FileHandler(os.path.join( get_path_in_artic2("logs"), f"{self._guid}/{self._guid}.log"), encoding='UTF-8') fh.setLevel(logging.DEBUG) fh.setFormatter(formatter) self.logger.addHandler(fh)
def run(self): """ While we could use the standard decorators to register these routes, using add_url_rule() allows us to create diffrent endpoint names programmatically and pass the classes self object to the routes """ config = Config() config.accesslog = os.path.join(get_path_in_artic2("logs"), "access.log") config.bind = f"{self['BindIP']}:{self['Port']}" config.insecure_bind = True config.include_server_header = False config.use_reloader = False config.debug = False http_blueprint = Blueprint(__name__, 'http') http_blueprint.before_request(self.check_if_naughty) http_blueprint.add_url_rule('/<uuid:GUID>', 'key_exchange', self.key_exchange, methods=['POST']) http_blueprint.add_url_rule('/<uuid:GUID>', 'stage', self.stage, methods=['GET']) http_blueprint.add_url_rule('/<uuid:GUID>/jobs', 'jobs', self.jobs, methods=['GET']) http_blueprint.add_url_rule('/<uuid:GUID>/jobs/<job_id>', 'job_result', self.job_result, methods=['POST']) http_blueprint.add_url_rule('/', 'unknown_path', self.unknown_path, defaults={'path': ''}) http_blueprint.add_url_rule('/<path:path>', 'unknown_path', self.unknown_path, methods=['GET', 'POST']) self.app = Quart(__name__) self.app.register_blueprint(http_blueprint) asyncio.run(serve(self.app, config))
async def create_db_and_schema(db_path=get_path_in_artic2("artic2.db")): with sqlite3.connect(db_path) as db: db.execute('''CREATE TABLE "sessions" ( "id" integer PRIMARY KEY, "guid" text, "psk" text, "location" text, UNIQUE(guid,psk) )''')
def run(self): if (self['Key'] == f'{self.certs_path}/artic2_private.key') and ( self['Cert'] == f'{self.certs_path}/artic2_cert.pem'): if not os.path.exists(get_path_in_data_folder( "artic2_private.key")) or not os.path.exists( get_path_in_data_folder( "artic2_cert.pem")) or self['RegenCert']: create_self_signed_cert() config = Config() config.ciphers = 'ALL' config.accesslog = os.path.join(get_path_in_artic2("logs"), "access.log") config.bind = f"{self['BindIP']}:{self['Port']}" config.certfile = os.path.expanduser(self['Cert']) config.keyfile = os.path.expanduser(self['Key']) config.include_server_header = False config.use_reloader = False config.debug = False """ While we could use the standard decorators to register these routes, using add_url_rule() allows us to create diffrent endpoint names programmatically and pass the classes self object to the routes """ http_blueprint = Blueprint(__name__, 'https') http_blueprint.before_request(self.check_if_naughty) http_blueprint.add_url_rule('/<uuid:GUID>', 'key_exchange', self.key_exchange, methods=['POST']) http_blueprint.add_url_rule('/<uuid:GUID>', 'stage', self.stage, methods=['GET']) http_blueprint.add_url_rule('/<uuid:GUID>/jobs', 'jobs', self.jobs, methods=['GET']) http_blueprint.add_url_rule('/<uuid:GUID>/jobs/<job_id>', 'job_result', self.job_result, methods=['POST']) http_blueprint.add_url_rule('/', 'unknown_path', self.unknown_path, defaults={'path': ''}) http_blueprint.add_url_rule('/<path:path>', 'unknown_path', self.unknown_path, methods=['GET', 'POST']) self.app = Quart(__name__) self.app.register_blueprint(http_blueprint) asyncio.run(serve(self.app, config))
def start(args): if not os.path.exists(get_path_in_artic2('logs')): logging.info("First time use detected, creating data folder") os.mkdir(get_path_in_artic2('logs')) loop = asyncio.get_event_loop() #wss_digest = hmac.new(args['<password>'].encode(), msg=b'at0m1cR3dT3amInt3ll1g3nc3C2', digestmod=sha512).hexdigest() wss_digest = hmac.new(args['<password>'].encode(), msg=b'blackbot', digestmod=sha512).hexdigest() stop = asyncio.Future() for sig in (signal.SIGINT, signal.SIGTERM): loop.add_signal_handler(sig, stop.set_result, None) if args['--insecure']: logging.warning( 'SECURITY WARNING: --insecure flag passed, communication between client and server will be in cleartext!' ) loop.run_until_complete(server(stop, args, wss_digest))
async def server(stop, args, wss_digest): if not os.path.exists(get_path_in_artic2("artic2.db")): logging.info('Creating database') await AsyncARTIC2db.create_db_and_schema() ts = WSS() ssl_context = None if not args['--insecure']: ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER) try: ssl_context.load_cert_chain( get_path_in_data_folder("artic2_chain.pem")) except FileNotFoundError: create_self_signed_cert() ssl_context.load_cert_chain( get_path_in_data_folder("artic2_chain.pem")) server_cert_fingerprint = get_cert_fingerprint( get_path_in_data_folder("artic2_cert.pem")) logging.warning( (f"{colored('WSS certificate fingerprint:', 'yellow')} " f"{colored(server_cert_fingerprint.hex(), 'red')}")) ARTIC2WebSocketServerProtocol.wss_digest = wss_digest async with websockets.serve(ts.connection_handler, host=args['<host>'], port=int(args['--port']), create_protocol=ARTIC2WebSocketServerProtocol, ssl=ssl_context, ping_interval=None, ping_timeout=None): logging.info( colored(f"WSS started on {args['<host>']}:{args['--port']}", "yellow")) await stop
def __init__(self, db_path=get_path_in_artic2("artic2.db")): self.db_path = db_path
def write(self): path = get_path_in_artic2("/blackbot/core/wss/pid.txt") print(path) f = open(path, "w") f.write(str(getpid())) f.close()