class HttpsServerCommunicator(SecureServerCommunicator): def __init__(self, remote, ctrl, communicator=None): (addr, self.ssl_ctx) = remote self.f_ctrl = ctrl self.http = HttpMessage(self) self.http_communicator = None SecureServerCommunicator.__init__(self, addr, communicator=communicator) self.parent_http = None if communicator is not None: self.parent_http = self.communicator.http def handle_read(self): # Read data in buffer SecureServerCommunicator.handle_read(self) # Fetch the Http request from parent communicator if (self.http_communicator is None) and (len( self.communicator.http_history) > 0): self.http_communicator = self.communicator.http_history.pop(0) if self.http_communicator.path in Config.force_buffering: Logger.debug("Force buffering : " + self.http_communicator.path) self.http.force_full_buffering = True if not self.http.is_ready(): # Parse it until ready if self.make_http_message(): # Now it is ready self._buffer = self.process() # Stream it self.http_communicator = None else: # Data is streamed "on-the-fly" self._buffer = self._buffer # Stream it if self.http.is_complete(): self.http = HttpMessage(self) def make_http_message(self): # Do we have headers ? if not self.http.have_headers(): if self.http.put_headers() is None: return False # Now we have valid headers # Push data self.http.put_body() return self.http.is_ready() def process(self): # in any case of redirection with HTTP protocol use if self.http.have_redirection(): location = self.http.get_header("Location") if location is not None and location.startswith("http://"): location = location.replace("http", "https", 1) self.http.set_header("Location", location) # XML rewriting on start request if (self.http_communicator is not None) and (self.http_communicator.path == "/ovd/client/start"): body = self.http.get_body() xml = self.rewrite_xml(body) self.http.set_body(xml) return self.http.show() def rewrite_xml(self, body): try: session = parser.XML(body) if session.tag.lower() != 'session': raise Exception("not a 'session' XML response") except Exception: Logger.exception("Gateway:: parsing XML session failed") return None session.set('mode_gateway', 'on') for server in session.findall('server'): port = Protocol.RDP if server.attrib.has_key("port"): try: port = int(server.attrib["port"]) except ValueError, err: Logger.warn( "Gateway:: Invalid protocol: server port attribute is not a digit (%s)" % (server.attrib["port"])) token = self.f_ctrl.send( ('insert_token', (server.attrib['fqdn'], port))) server.set('token', token) del server.attrib['fqdn'] if server.attrib.has_key("port"): del server.attrib["port"] for server in session.findall('webapp-server'): if server.attrib.has_key("webapps-url"): url = server.attrib["webapps-url"] if url is not None: token = self.f_ctrl.send(('assign_token', url)) host = self.parent_http.get_header("Host") server.attrib[ "webapps-url"] = "https://" + host + "/webapps-" + token return parser.tostring(session)
class HttpsServerCommunicator(SecureServerCommunicator): def __init__(self, remote, ctrl, communicator=None): (addr, self.ssl_ctx) = remote self.f_ctrl = ctrl self.http = HttpMessage(self) self.http_communicator = None SecureServerCommunicator.__init__(self, addr, communicator=communicator) self.parent_http = None if communicator is not None: self.parent_http = self.communicator.http def handle_read(self): # Read data in buffer SecureServerCommunicator.handle_read(self) # Fetch the Http request from parent communicator if (self.http_communicator is None) and (len(self.communicator.http_history) > 0): self.http_communicator = self.communicator.http_history.pop(0) if self.http_communicator.path in Config.force_buffering: Logger.debug("Force buffering : "+self.http_communicator.path) self.http.force_full_buffering = True if not self.http.is_ready(): # Parse it until ready if self.make_http_message(): # Now it is ready self._buffer = self.process() # Stream it self.http_communicator = None else: # Data is streamed "on-the-fly" self._buffer = self._buffer # Stream it if self.http.is_complete() : self.http = HttpMessage(self) def make_http_message(self): # Do we have headers ? if not self.http.have_headers(): if self.http.put_headers() is None: return False # Now we have valid headers # Push data self.http.put_body() return self.http.is_ready() def process(self): # in any case of redirection with HTTP protocol use if self.http.have_redirection(): location = self.http.get_header("Location") if location is not None and location.startswith("http://"): location = location.replace("http", "https", 1) self.http.set_header("Location", location) # XML rewriting on start request if (self.http_communicator is not None) and (self.http_communicator.path == "/ovd/client/start"): body = self.http.get_body() xml = self.rewrite_xml(body) self.http.set_body(xml) return self.http.show() def rewrite_xml(self, body): try: session = parser.XML(body) if session.tag.lower() != 'session': raise Exception("not a 'session' XML response") except Exception: Logger.exception("Gateway:: parsing XML session failed") return None session.set('mode_gateway', 'on') for server in session.findall('server'): port = Protocol.RDP if server.attrib.has_key("port"): try: port = int(server.attrib["port"]) except ValueError,err: Logger.warn("Gateway:: Invalid protocol: server port attribute is not a digit (%s)"%(server.attrib["port"])) token = self.f_ctrl.send(('insert_token', (server.attrib['fqdn'], port))) server.set('token', token) del server.attrib['fqdn'] if server.attrib.has_key("port"): del server.attrib["port"] for server in session.findall('webapp-server'): if server.attrib.has_key("webapps-url"): url = server.attrib["webapps-url"] if url is not None: token = self.f_ctrl.send(('assign_token', url)) host = self.parent_http.get_header("Host") server.attrib["webapps-url"] = "https://"+host+"/webapps-"+token return parser.tostring(session)