def test_ip_untrusted_identification_same_connection(self):
        identification = IpBasedIdentification([])

        request_handler = mock_request_handler(ip='192.168.21.13')
        id1 = identification.identify(request_handler)
        id2 = identification.identify(request_handler)
        self.assertEqual(id1, id2)
    def test_proxied_ip_behind_untrusted(self):
        identification = IpBasedIdentification([])

        request_handler = mock_request_handler(ip='127.0.0.1', x_forwarded_for='192.168.21.13')
        id = identification.identify(request_handler)
        self.assertNotEqual('192.168.21.13', id)
        self.assertNotEqual('127.0.0.1', id)
    def test_ip_untrusted_identification_for_different_connections(self):
        identification = IpBasedIdentification([])

        ids = set()
        for _ in range(0, 100):
            ids.add(identification.identify(mock_request_handler(ip='192.168.21.13')))

        self.assertEqual(100, len(ids))
    def test_change_to_trusted(self):
        request_handler = mock_request_handler(ip='192.168.21.13')

        old_id = IpBasedIdentification([]).identify(request_handler)

        trusted_identification = IpBasedIdentification(['192.168.21.13'])
        new_id = trusted_identification.identify(request_handler)

        self.assertNotEqual(old_id, new_id)
        self.assertEqual(new_id, '192.168.21.13')
        self.assertIsNone(request_handler.get_cookie(COOKIE_KEY))
    def test_refresh_old_cookie_with_same_id(self):
        request_handler = mock_request_handler(ip='192.168.21.13')

        identification = IpBasedIdentification([])

        id = '1234567'
        token_expiry = str(date_utils.get_current_millis() + date_utils.days_to_ms(2))
        old_token = id + '&' + token_expiry
        request_handler.set_secure_cookie(COOKIE_KEY, old_token)

        new_id = identification.identify(request_handler)
        new_token = request_handler.get_cookie(COOKIE_KEY)

        self.assertEqual(new_id, id)
        self.assertNotEqual(old_token, new_token)
    def test_broken_token_structure(self):
        request_handler = mock_request_handler(ip='192.168.21.13')
        request_handler.set_secure_cookie(COOKIE_KEY, 'something')

        IpBasedIdentification([]).identify(request_handler)

        new_token = request_handler.get_cookie(COOKIE_KEY)

        self.assertNotEqual(new_token, 'something')
    def test_old_token_timestamp(self):
        request_handler = mock_request_handler(ip='192.168.21.13')
        request_handler.set_secure_cookie(COOKIE_KEY, 'something&100000')

        id = IpBasedIdentification([]).identify(request_handler)

        new_token = request_handler.get_cookie(COOKIE_KEY)

        self.assertNotEqual('something', id)
        self.assertNotEqual(new_token, 'something&100000')
예제 #8
0
    def test_broken_token_timestamp(self):
        request_handler = mock_request_handler(ip='192.168.21.13')
        request_handler.set_secure_cookie(COOKIE_KEY, 'something&hello')

        id = IpBasedIdentification(TrustedIpValidator([]), None).identify(request_handler)

        new_token = request_handler.get_cookie(COOKIE_KEY)

        self.assertNotEqual('something', id)
        self.assertNotEqual(new_token, 'something&hello')
예제 #9
0
    def setUp(self):
        super().setUp()

        self.socket = None

        application = tornado.web.Application(
            [(r'/scripts/([^/]*)', ScriptConfigSocket)],
            login_url='/login.html',
            cookie_secret='12345')
        application.auth = TornadoAuth(None)
        application.authorizer = Authorizer(ANY_USER, [], [],
                                            EmptyGroupProvider())
        application.identification = IpBasedIdentification(
            TrustedIpValidator(['127.0.0.1']), None)
        application.config_service = ConfigService(application.authorizer,
                                                   test_utils.temp_folder)

        server = httpserver.HTTPServer(application)
        socket, self.port = testing.bind_unused_port()
        server.add_socket(socket)

        test_utils.setup()

        for dir in ['x', 'y', 'z']:
            for file in range(1, 4):
                filename = dir + str(file) + '.txt'
                test_utils.create_file(
                    os.path.join('test1_files', dir, filename))

        test1_files_path = os.path.join(test_utils.temp_folder, 'test1_files')
        test_utils.write_script_config(
            {
                'name':
                'Test script 1',
                'script_path':
                'ls',
                'parameters': [
                    test_utils.create_script_param_config('text 1',
                                                          required=True),
                    test_utils.create_script_param_config(
                        'list 1', type='list', allowed_values=['A', 'B', 'C']),
                    test_utils.create_script_param_config(
                        'file 1',
                        type='server_file',
                        file_dir=test1_files_path),
                    test_utils.create_script_param_config(
                        'list 2',
                        type='list',
                        values_script='ls ' + test1_files_path + '/${file 1}')
                ]
            }, 'test_script_1')
def mock_request_handler(ip=None,
                         x_forwarded_for=None,
                         x_real_ip=None,
                         saved_token=None,
                         user_header_name=None,
                         user_header_name_value=None):
    handler_mock = mock_object()

    handler_mock.application = mock_object()
    handler_mock.application.auth = TornadoAuth(None)
    handler_mock.application.identification = IpBasedIdentification(
        ['127.0.0.1'], user_header_name)

    handler_mock.request = mock_object()
    handler_mock.request.headers = {}

    handler_mock.request.remote_ip = ip

    if x_forwarded_for:
        handler_mock.request.headers['X-Forwarded-For'] = x_forwarded_for

    if x_real_ip:
        handler_mock.request.headers['X-Real-IP'] = x_real_ip

    if user_header_name and user_header_name_value:
        handler_mock.request.headers[user_header_name] = user_header_name_value

    cookies = {COOKIE_KEY: saved_token}

    def get_secure_cookie(name):
        values = cookies[name]
        if values is not None:
            return values.encode('utf8')
        return None

    def set_secure_cookie(key, value, expires_days=30):
        cookies[key] = value

    def clear_cookie(key):
        if cookies[key] is not None:
            cookies[key] = None

    handler_mock.get_cookie = lambda key: cookies[key]
    handler_mock.get_secure_cookie = get_secure_cookie
    handler_mock.set_secure_cookie = set_secure_cookie
    handler_mock.clear_cookie = clear_cookie

    return handler_mock
    def test_no_cookie_change_for_same_user(self):
        request_handler = mock_request_handler(ip='192.168.21.13')

        identification = IpBasedIdentification([])

        identification.identify(request_handler)
        cookie1 = request_handler.get_cookie(COOKIE_KEY)
        identification.identify(request_handler)
        cookie2 = request_handler.get_cookie(COOKIE_KEY)

        self.assertEqual(cookie1, cookie2)
예제 #12
0
def init(server_config: ServerConfig, authenticator, authorizer,
         execution_service: ExecutionService,
         execution_logging_service: ExecutionLoggingService,
         config_service: ConfigService, alerts_service: AlertsService,
         file_upload_feature: FileUploadFeature,
         file_download_feature: FileDownloadFeature, secret, server_version):
    ssl_context = None
    if server_config.is_ssl():
        ssl_context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
        ssl_context.load_cert_chain(server_config.get_ssl_cert_path(),
                                    server_config.get_ssl_key_path())

    auth = TornadoAuth(authenticator)
    if auth.is_enabled():
        identification = AuthBasedIdentification(auth)
    else:
        identification = IpBasedIdentification(server_config.trusted_ips,
                                               server_config.user_header_name)

    downloads_folder = file_download_feature.get_result_files_folder()

    handlers = [
        (r'/conf', GetServerConf), (r'/scripts', GetScripts),
        (r'/scripts/([^/]*)', ScriptConfigSocket),
        (r'/scripts/([^/]*)/([^/]*)/list-files', ScriptParameterListFiles),
        (r'/executions/start', ScriptExecute),
        (r'/executions/stop/(.*)', ScriptStop),
        (r'/executions/kill/(.*)', ScriptKill),
        (r'/executions/io/(.*)', ScriptStreamSocket),
        (r'/executions/active', GetActiveExecutionIds),
        (r'/executions/config/(.*)', GetExecutingScriptConfig),
        (r'/executions/cleanup/(.*)', CleanupExecutingScript),
        (r'/executions/status/(.*)', GetExecutionStatus),
        (r'/admin/execution_log/short', GetShortHistoryEntriesHandler),
        (r'/admin/execution_log/long/(.*)', GetLongHistoryEntryHandler),
        (r'/auth/info', AuthInfoHandler),
        (r'/result_files/(.*)', DownloadResultFile, {
            'path': downloads_folder
        }), (r"/", ProxiedRedirectHandler, {
            "url": "/index.html"
        })
    ]

    if auth.is_enabled():
        handlers.append((r'/login', LoginHandler))
        handlers.append((r'/auth/config', AuthConfigHandler))
        handlers.append((r'/logout', LogoutHandler))

    handlers.append((r"/(.*)", AuthorizedStaticFileHandler, {"path": "web"}))

    settings = {
        "cookie_secret": secret,
        "login_url": "/login.html",
        'websocket_ping_interval': 30,
        'websocket_ping_timeout': 300
    }

    application = tornado.web.Application(handlers, **settings)

    application.auth = auth

    application.server_config = server_config
    application.server_version = server_version
    application.authorizer = authorizer
    application.downloads_folder = downloads_folder
    application.file_download_feature = file_download_feature
    application.file_upload_feature = file_upload_feature
    application.execution_service = execution_service
    application.execution_logging_service = execution_logging_service
    application.config_service = config_service
    application.alerts_service = alerts_service
    application.identification = identification
    application.max_request_size_mb = server_config.max_request_size_mb

    io_loop = tornado.ioloop.IOLoop.current()

    http_server = httpserver.HTTPServer(application,
                                        ssl_options=ssl_context,
                                        max_buffer_size=10 * BYTES_IN_MB)
    http_server.listen(server_config.port, address=server_config.address)

    intercept_stop_when_running_scripts(io_loop, execution_service)

    http_protocol = 'https' if server_config.ssl else 'http'
    print('Server is running on: %s://%s:%s' %
          (http_protocol, server_config.address, server_config.port))
    io_loop.start()
예제 #13
0
def init(server_config: ServerConfig,
         authenticator,
         authorizer,
         execution_service: ExecutionService,
         schedule_service: ScheduleService,
         execution_logging_service: ExecutionLoggingService,
         config_service: ConfigService,
         alerts_service: AlertsService,
         file_upload_feature: FileUploadFeature,
         file_download_feature: FileDownloadFeature,
         secret,
         server_version,
         conf_folder,
         *,
         start_server=True):
    ssl_context = None
    if server_config.is_ssl():
        ssl_context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
        ssl_context.load_cert_chain(server_config.get_ssl_cert_path(),
                                    server_config.get_ssl_key_path())

    auth = TornadoAuth(authenticator)
    if auth.is_enabled():
        identification = AuthBasedIdentification(auth)
    else:
        identification = IpBasedIdentification(server_config.ip_validator, server_config.user_header_name)

    downloads_folder = file_download_feature.get_result_files_folder()

    handlers = [(r'/conf', GetServerConf),
                (r'/scripts', GetScripts),
                (r'/scripts/([^/]*)', ScriptConfigSocket),
                (r'/scripts/([^/]*)/([^/]*)/list-files', ScriptParameterListFiles),
                (r'/executions/start', ScriptExecute),
                (r'/executions/stop/(.*)', ScriptStop),
                (r'/executions/kill/(.*)', ScriptKill),
                (r'/executions/io/(.*)', ScriptStreamSocket),
                (r'/executions/active', GetActiveExecutionIds),
                (r'/executions/config/(.*)', GetExecutingScriptConfig),
                (r'/executions/cleanup/(.*)', CleanupExecutingScript),
                (r'/executions/status/(.*)', GetExecutionStatus),
                (r'/history/execution_log/short', GetShortHistoryEntriesHandler),
                (r'/history/execution_log/long/(.*)', GetLongHistoryEntryHandler),
                (r'/schedule', AddSchedule),
                (r'/auth/info', AuthInfoHandler),
                (r'/result_files/(.*)',
                 DownloadResultFile,
                 {'path': downloads_folder}),
                (r'/admin/scripts', AdminUpdateScriptEndpoint),
                (r'/admin/scripts/(.*)', AdminGetScriptEndpoint),
                (r"/", ProxiedRedirectHandler, {"url": "/index.html"})]

    if auth.is_enabled():
        handlers.append((r'/login', LoginHandler))
        handlers.append((r'/auth/config', AuthConfigHandler))
        handlers.append((r'/logout', LogoutHandler))

    handlers.append((r'/theme/(.*)', ThemeStaticFileHandler, {'path': os.path.join(conf_folder, 'theme')}))
    handlers.append((r"/(.*)", AuthorizedStaticFileHandler, {"path": "web"}))

    settings = {
        "cookie_secret": secret,
        "login_url": "/login.html",
        'websocket_ping_interval': 30,
        'websocket_ping_timeout': 300,
        'compress_response': True,
        'xsrf_cookies': server_config.xsrf_protection != XSRF_PROTECTION_DISABLED,
    }

    application = tornado.web.Application(handlers, **settings)
    autoapply_xheaders(application)

    application.auth = auth

    application.server_config = server_config
    application.server_version = server_version
    application.authorizer = authorizer
    application.downloads_folder = downloads_folder
    application.file_download_feature = file_download_feature
    application.file_upload_feature = file_upload_feature
    application.execution_service = execution_service
    application.schedule_service = schedule_service
    application.execution_logging_service = execution_logging_service
    application.config_service = config_service
    application.alerts_service = alerts_service
    application.identification = identification
    application.max_request_size_mb = server_config.max_request_size_mb

    if os_utils.is_win() and env_utils.is_min_version('3.8'):
        asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
    io_loop = tornado.ioloop.IOLoop.current()

    global _http_server
    _http_server = httpserver.HTTPServer(
        application,
        ssl_options=ssl_context,
        max_buffer_size=10 * BYTES_IN_MB)
    _http_server.listen(server_config.port, address=server_config.address)

    intercept_stop_when_running_scripts(io_loop, execution_service)

    http_protocol = 'https' if server_config.ssl else 'http'
    print('Server is running on: %s://%s:%s' % (http_protocol, server_config.address, server_config.port))

    if start_server:
        io_loop.start()
 def test_some_ip_trusted_identification(self):
     identification = IpBasedIdentification(['192.168.21.13'], None)
     id = identification.identify(mock_request_handler(ip='192.168.21.13'))
     self.assertEqual('192.168.21.13', id)
 def test_ip_untrusted_identification(self):
     identification = IpBasedIdentification([])
     id = identification.identify(mock_request_handler(ip='192.168.21.13'))
     self.assertNotEqual('192.168.21.13', id)
 def test_localhost_ip_trusted_identification(self):
     identification = IpBasedIdentification(['127.0.0.1'])
     id = identification.identify(mock_request_handler(ip='127.0.0.1'))
     self.assertEqual('127.0.0.1', id)
예제 #17
0
    def test_proxied_ip_behind_trusted(self):
        identification = IpBasedIdentification(TrustedIpValidator(['127.0.0.1']), None)

        request_handler = mock_request_handler(ip='127.0.0.1', x_forwarded_for='192.168.21.13')
        id = identification.identify(request_handler)
        self.assertEqual('192.168.21.13', id)