def handle(self): self.log("clientconnect", "info") root_layer = None try: root_layer = self._create_root_layer() root_layer = self.channel.ask("clientconnect", root_layer) root_layer() except exceptions.Kill: self.log("Connection killed", "info") except exceptions.ProtocolException as e: if isinstance(e, exceptions.ClientHandshakeException): self.log( "Client Handshake failed. " "The client {} may not trust the proxy's certificate for {}." .format(self.client_conn.address[0], e.server), "warn") self.log(repr(e), "debug") # ReCon / Mon(IoT)r Modification source_ip = self.client_conn.address[0] if source_ip[:7] == '::ffff:': source_ip = source_ip[7:] dest = e.server if dest[0] == '(': dest = dest[2:] dest = dest[:dest.index("'")] try: command = ctx.options.mitm_exception + " addauto " + source_ip + " " + dest self.log("Adding MITM exception: " + command, "info") subprocess.call(command, shell=True) except AttributeError as e2: pass elif isinstance(e, exceptions.InvalidServerCertificate): self.log(str(e), "warn") self.log( "Invalid certificate, closing connection. Pass --insecure to disable validation.", "warn") else: self.log(str(e), "warn") self.log(repr(e), "debug") # If an error propagates to the topmost level, # we send an HTTP error response, which is both # understandable by HTTP clients and humans. try: error_response = http.make_error_response(502, repr(e)) self.client_conn.send(http1.assemble_response(error_response)) except exceptions.TcpException: pass except Exception: self.log(traceback.format_exc(), "error") print(traceback.format_exc(), file=sys.stderr) print("mitmproxy has crashed!", file=sys.stderr) print( "Please lodge a bug report at: https://github.com/mitmproxy/mitmproxy", file=sys.stderr) self.log("clientdisconnect", "info") if root_layer is not None: self.channel.tell("clientdisconnect", root_layer) self.client_conn.finish()
def make_error_response( status_code: int, message: str = "", ) -> bytes: resp = http.Response.make( status_code, format_error(status_code, message), http.Headers( Server=version.MITMPROXY, Connection="close", Content_Type="text/html", )) return http1.assemble_response(resp)
def handle(self): self.log("clientconnect", "info") root_layer = None try: root_layer = self._create_root_layer() root_layer = self.channel.ask("clientconnect", root_layer) root_layer() except exceptions.Kill: self.log("Connection killed", "info") except exceptions.ProtocolException as e: if isinstance(e, exceptions.ClientHandshakeException): selfc.SelfCShared.writeFailedSSLDomain( str(e.server), "2*** Client Handshake failed. The client may not trust the proxy's certificate", self.client_conn.ip_address) self.log( "Client Handshake failed. " "The client may not trust the proxy's certificate for {}.". format(e.server), "warn") self.log(repr(e), "debug") elif isinstance(e, exceptions.InvalidServerCertificate): self.log(str(e), "warn") self.log( "Invalid certificate, closing connection. Pass --ssl-insecure to disable validation.", "warn") else: self.log(str(e), "warn") self.log(repr(e), "debug") # If an error propagates to the topmost level, # we send an HTTP error response, which is both # understandable by HTTP clients and humans. try: error_response = http.make_error_response(502, repr(e)) self.client_conn.send(http1.assemble_response(error_response)) except exceptions.TcpException: pass except Exception: self.log(traceback.format_exc(), "error") print(traceback.format_exc(), file=sys.stderr) print("mitmproxy has crashed!", file=sys.stderr) print( "Please lodge a bug report at: https://github.com/mitmproxy/mitmproxy", file=sys.stderr) self.log("clientdisconnect", "info") if root_layer is not None: self.channel.tell("clientdisconnect", root_layer) self.client_conn.finish()
def send(self, event: HttpEvent) -> layer.CommandGenerator[None]: assert event.stream_id == self.stream_id if isinstance(event, ResponseHeaders): self.response = response = event.response if response.is_http2: response = response.copy() # Convert to an HTTP/1 response. response.http_version = "HTTP/1.1" # not everyone supports empty reason phrases, so we better make up one. response.reason = status_codes.RESPONSES.get( response.status_code, "") # Shall we set a Content-Length header here if there is none? # For now, let's try to modify as little as possible. raw = http1.assemble_response_head(response) yield commands.SendData(self.conn, raw) elif isinstance(event, ResponseData): assert self.response if "chunked" in self.response.headers.get("transfer-encoding", "").lower(): raw = b"%x\r\n%s\r\n" % (len(event.data), event.data) else: raw = event.data if raw: yield commands.SendData(self.conn, raw) elif isinstance(event, ResponseEndOfMessage): assert self.response if "chunked" in self.response.headers.get("transfer-encoding", "").lower(): yield commands.SendData(self.conn, b"0\r\n\r\n") yield from self.mark_done(response=True) elif isinstance(event, ResponseProtocolError): if not self.response and event.code != status_codes.NO_RESPONSE: resp = http.Response.make( event.code, format_error(event.code, event.message), http.Headers( Server=version.MITMPROXY, Connection="close", Content_Type="text/html", )) raw = http1.assemble_response(resp) yield commands.SendData(self.conn, raw) if self.conn.state & ConnectionState.CAN_WRITE: yield commands.CloseConnection(self.conn) else: raise AssertionError(f"Unexpected event: {event}")
def handle(self): self.log("clientconnect", "info") root_layer = None try: root_layer = self._create_root_layer() root_layer = self.channel.ask("clientconnect", root_layer) root_layer() except exceptions.Kill: self.log("Connection killed", "info") except exceptions.ProtocolException as e: if isinstance(e, exceptions.ClientHandshakeException): self.log( "Client Handshake failed. " "The client may not trust the proxy's certificate for {}.".format(e.server), "warn" ) self.log(repr(e), "debug") elif isinstance(e, exceptions.InvalidServerCertificate): self.log(str(e), "warn") self.log("Invalid certificate, closing connection. Pass --insecure to disable validation.", "warn") else: self.log(str(e), "warn") self.log(repr(e), "debug") # If an error propagates to the topmost level, # we send an HTTP error response, which is both # understandable by HTTP clients and humans. try: error_response = http.make_error_response(502, repr(e)) self.client_conn.send(http1.assemble_response(error_response)) except exceptions.TcpException: pass except Exception: self.log(traceback.format_exc(), "error") print(traceback.format_exc(), file=sys.stderr) print("mitmproxy has crashed!", file=sys.stderr) print("Please lodge a bug report at: https://github.com/mitmproxy/mitmproxy", file=sys.stderr) self.log("clientdisconnect", "info") if root_layer is not None: self.channel.tell("clientdisconnect", root_layer) self.client_conn.finish()