def run(self): try: self._client.stop(self._agent_name) except Exception, e: logger.error('Error while stopping user:') logger.error(e) raise
def _wait_til_agent_is_up(self, agent_runtime): max_wait = TIMEOUT_WAIT_FOR_AGENT_TO_BE_UP waited = 0 agent_up = False port = agent_runtime['port'] url = 'http://127.0.0.1:%d/' % port logger.error('Checking for user agent on url %s' % url) start = time.time() while waited < max_wait: try: # define a callback for older tornado versions def _some_callback(response): pass response = yield AsyncHTTPClient(force_instance=True).fetch( tornado.httpclient.HTTPRequest( connect_timeout=REQUEST_TIMEOUT, request_timeout=REQUEST_TIMEOUT, url=url, allow_ipv6=False), _some_callback) if response.code == 200: logger.info('Got 200, agent seems to be up') waited = max_wait agent_up = True else: logger.error('Got response with status code %d' % response.code) except tornado.httpclient.HTTPError, e: logger.info( 'Got exception while checking for agent to be up: %s' % e) except Exception, e: logger.info( 'Got exception while checking for agent to be up: %s' % e)
def _wait_til_agent_is_up(self, agent_runtime): max_wait = TIMEOUT_WAIT_FOR_AGENT_TO_BE_UP waited = 0 agent_up = False port = agent_runtime['port'] url = 'http://127.0.0.1:%d/' % port logger.error('Checking for user agent on url %s' % url) start = time.time() while waited < max_wait: try: # define a callback for older tornado versions def _some_callback(response): pass response = yield AsyncHTTPClient(force_instance=True).fetch( tornado.httpclient.HTTPRequest( connect_timeout=REQUEST_TIMEOUT, request_timeout=REQUEST_TIMEOUT, url=url, allow_ipv6=False), _some_callback) if response.code == 200: logger.info('Got 200, agent seems to be up') waited = max_wait agent_up = True else: logger.error('Got response with status code %d' % response.code) except tornado.httpclient.HTTPError, e: logger.info('Got exception while checking for agent to be up: %s' % e) except Exception, e: logger.info('Got exception while checking for agent to be up: %s' % e)
def _can_authorize_with_leap_provider(self, username, password): srp_auth = SRPAuth(self.provider.api_uri, which_api_CA_bundle(self.provider)) try: auth = srp_auth.authenticate(username, password) return True except SRPAuthenticationError, e: logger.error('Failure while authenticating with LEAP: %s' % e) return False
def get(self): runtime = self._client.get_agent_runtime(self.current_user) if runtime['state'] == 'running': port = runtime['port'] self.forward(port, '127.0.0.1') else: logger.error('Agent for %s not running - redirecting user to logout' % self.current_user) self.redirect(u'/auth/logout')
def post(self): username = self.get_argument("username", "") password = self.get_argument("password", "") try: agent = self._client.get_agent(username) # now authenticate with server... self._client.authenticate(username, password) self.set_current_user(username) logger.info('Successful login of user %s' % username) logger.info('Starting agent for %s' % username) runtime = self._client.get_agent_runtime(username) if runtime['state'] != 'running': self._client.start(username) # wait til agent is running runtime = self._client.get_agent_runtime(username) max_wait_seconds = TIMEOUT_WAIT_FOR_AGENT_TO_BE_UP waited = 0 while runtime[ 'state'] != 'running' and waited < max_wait_seconds: yield gen.Task(tornado.ioloop.IOLoop.current().add_timeout, time.time() + TIMEOUT_WAIT_STEP) runtime = self._client.get_agent_runtime(username) waited += TIMEOUT_WAIT_STEP # wait till agent is up and serving if runtime['state'] == 'running': yield gen.Task(self._wait_til_agent_is_up, runtime) port = runtime['port'] self.redirect(u'/') else: logger.warn( 'Agent not running, redirecting user to login page') self.redirect(u'/auth/login') else: self.redirect(u'/') except PixelatedNotAvailableHTTPError: logger.error( 'Login attempt while service not available by user: %s' % username) self.set_cookie( 'error_msg', tornado.escape.url_escape('Service currently not available')) self.redirect(u'/auth/login') except PixelatedHTTPError, e: logger.warn('Login attempt with invalid credentials by user %s' % username) self.set_cookie('error_msg', tornado.escape.url_escape('Invalid credentials')) self.redirect(u'/auth/login')
def get(self): runtime = self._client.get_agent_runtime(self.current_user) if runtime['state'] == 'running': port = runtime['port'] self.forward(port, '127.0.0.1') else: self.logout() if _is_ajax_request(self.request): raise HTTPError(401) else: logger.error( 'Agent for %s not running - redirecting user to logout' % self.current_user) self.redirect(u'/auth/logout')
def handle_response(self, response): if response.error: logger.error('Got error from user %s agent: %s' % (self.current_user, response.error)) self.set_status(503) self.write("Could not connect to instance %s: %s\n" % (self.current_user, str(response.error))) self.finish() else: self.set_status(response.code) for header in ("Date", "Cache-Control", "Server", "Content-Type", "Location"): v = response.headers.get(header) if v: self.set_header(header, v) if response.body: self.write(response.body) self.finish()
def run(self): try: params = { 'stdin': True, 'stream': True, 'stdout': False, 'stderr': False} client = docker.Client(base_url=self._docker_url, version=DOCKER_API_VERSION) s = client.attach_socket(container=self._container_id, params=params) s.send("%s\n" % json.dumps({'leap_provider_hostname': self._leap_provider, 'user': self._user, 'password': self._password})) s.shutdown(socket.SHUT_WR) s.close() except Exception, e: logger.error('While passing credentials to container %s running on %s: %s' % (self._container_id, self._docker_url, str(e.message)))
class BaseHandler(tornado.web.RequestHandler): def initialize(self, client): self._client = client def prepare(self): # add some security headers self.set_header('Cache-Control', 'no-cache,no-store,must-revalidate,private') self.set_header('Pragma', 'no-cache') self.set_header('X-XSS-Protection', '1; mode=block') self.set_header('X-Frame-Options', 'SAMEORIGIN') self.set_header('X-Content-Type-Options', 'nosniff') self._add_header_if_is_download_attachment() if self._is_https(): self.set_header('Strict-Transport-Security', 'max-age=31536000; includeSubDomains') def _add_header_if_is_download_attachment(self): if self.request.arguments.get('filename'): self.add_header( 'Content-Disposition', 'attachment; filename=' + self.request.arguments.get('filename')[0]) def _is_https(self): return 'https' == self.request.protocol def get_current_user(self): cookie = self.get_secure_cookie(COOKIE_NAME) if cookie: return tornado.escape.json_decode(cookie) else: return None def forward(self, port=None, host=None): url = "%s://%s:%s%s" % ('http', host or "127.0.0.1", port or 80, self.request.uri) try: response = AsyncHTTPClient().fetch( tornado.httpclient.HTTPRequest( url=url, method=self.request.method, body=None if not self.request.body else self.request.body, headers=self.request.headers, follow_redirects=False, request_timeout=REQUEST_TIMEOUT), self.handle_response) return response except tornado.httpclient.HTTPError, x: if hasattr(x, 'response') and x.response: self.handle_response(x.response) except Exception, e: logger.error('Error forwarding request %s: %s' % (url, e.message)) self.set_status(500) self.write("Internal server error:\n" + ''.join(traceback.format_exception(*sys.exc_info()))) self.finish()
def handle_response(self, response): if response.error: logger.error('Got error from user %s agent: %s' % (self.current_user, response.error)) self.set_status(503) self.write("Could not connect to instance %s: %s\n" % (self.current_user, str(response.error))) self.finish() else: self.set_status(response.code) for header in ("Date", "Cache-Control", 'Pragma', "Server", "Content-Type", "Location", "Set-Cookie"): v = response.headers.get(header) if v: self.set_header(header, v) if response.body: self.write(response.body) self.finish()
def post(self): username = self.get_argument("username", "") password = self.get_argument("password", "") try: agent = self._client.get_agent(username) # now authenticate with server... self._client.authenticate(username, password) self.set_current_user(username) logger.info('Successful login of user %s' % username) logger.info('Starting agent for %s' % username) runtime = self._client.get_agent_runtime(username) if runtime['state'] != 'running': self._client.start(username) # wait til agent is running runtime = self._client.get_agent_runtime(username) max_wait_seconds = TIMEOUT_WAIT_FOR_AGENT_TO_BE_UP waited = 0 while runtime['state'] != 'running' and waited < max_wait_seconds: yield gen.Task(tornado.ioloop.IOLoop.current().add_timeout, time.time() + TIMEOUT_WAIT_STEP) runtime = self._client.get_agent_runtime(username) waited += TIMEOUT_WAIT_STEP # wait till agent is up and serving if runtime['state'] == 'running': yield gen.Task(self._wait_til_agent_is_up, runtime) port = runtime['port'] self.redirect(u'/') else: logger.warn('Agent not running, redirecting user to login page') self.redirect(u'/auth/login') else: self.redirect(u'/') except PixelatedNotAvailableHTTPError: logger.error('Login attempt while service not available by user: %s' % username) self.set_cookie('error_msg', tornado.escape.url_escape('Service currently not available')) self.redirect(u'/auth/login') except PixelatedHTTPError, e: logger.warn('Login attempt with invalid credentials by user %s' % username) self.set_cookie('error_msg', tornado.escape.url_escape('Invalid credentials')) self.redirect(u'/auth/login')
def _build_image(self, path, fileobj): stream = self._docker.build(path=path, fileobj=fileobj, tag='%s:latest' % self._adapter.docker_image_name()) lines = [] for event in stream: data = json.loads(event) if 'stream' in data: logger.debug(data['stream']) lines.append(data['stream']) if 'error' in data: logger.error('Whoops! Failed to build image: %s' % data['error']) logger.error('Replaying docker image build output') for line in lines: logger.error('Docker output: %s' % line) logger.error('Terminating process by sending TERM signal') os.kill(os.getpid(), signal.SIGTERM)
def _download_image(self, docker_image_name): stream = self._docker.pull(repository=docker_image_name, tag='latest', stream=True) lines = [] for event in stream: data = json.loads(event) if 'status' in data: logger.debug(data['status']) lines.append(data['status']) if 'error' in data: logger.error('Failed to pull image %s: %s' % (docker_image_name, data['error'])) logger.error('Replaying docker pull output') for line in lines: logger.error('Docker output: %s' % line) logger.error('Terminating process by sending TERM signal') os.kill(os.getpid(), signal.SIGTERM)
def wrapper(*args, **kwargs): try: return callback(*args, **kwargs) except Exception, e: logger.error('Error during request: %s' % e.message) raise
def _check_docker_connection(self): try: self._docker.info() except Exception, e: logger.error('Failed to talk to docker: %s' % e.message) raise
class AuthLoginHandler(BaseHandler): def initialize(self, client, banner): super(AuthLoginHandler, self).initialize(client) self._banner = banner def get(self): error_message = self.get_cookie('error_msg') if error_message: error_message = tornado.escape.url_unescape(error_message) self.clear_cookie('error_msg') status_message = self.get_cookie('status_msg') if status_message: status_message = tornado.escape.url_unescape(status_message) self.clear_cookie('status_msg') self.render('login.html', error=error_message, status=status_message, banner=self._banner) @tornado.web.asynchronous @gen.coroutine def post(self): username = self.get_argument("username", "") password = self.get_argument("password", "") try: agent = self._client.get_agent(username) # now authenticate with server... self._client.authenticate(username, password) self.set_current_user(username) logger.info('Successful login of user %s' % username) logger.info('Starting agent for %s' % username) runtime = self._client.get_agent_runtime(username) if runtime['state'] != 'running': self._client.start(username) # wait til agent is running runtime = self._client.get_agent_runtime(username) max_wait_seconds = TIMEOUT_WAIT_FOR_AGENT_TO_BE_UP waited = 0 while runtime[ 'state'] != 'running' and waited < max_wait_seconds: yield gen.Task(tornado.ioloop.IOLoop.current().add_timeout, time.time() + TIMEOUT_WAIT_STEP) runtime = self._client.get_agent_runtime(username) waited += TIMEOUT_WAIT_STEP # wait till agent is up and serving if runtime['state'] == 'running': yield gen.Task(self._wait_til_agent_is_up, runtime) port = runtime['port'] self.redirect(u'/') else: logger.warn( 'Agent not running, redirecting user to login page') self.redirect(u'/auth/login') else: self.redirect(u'/') except PixelatedNotAvailableHTTPError: logger.error( 'Login attempt while service not available by user: %s' % username) self.set_cookie( 'error_msg', tornado.escape.url_escape('Service currently not available')) self.redirect(u'/auth/login') except PixelatedHTTPError, e: logger.warn('Login attempt with invalid credentials by user %s' % username) self.set_cookie('error_msg', tornado.escape.url_escape('Invalid credentials')) self.redirect(u'/auth/login') except Exception, e: logger.error('Unexpected exception: %s' % e) raise