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)
                     )''')
Example #4
0
    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))
Example #5
0
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))
Example #6
0
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()