mitmproxy/libmproxy/models/connections.py

162 lines
4.5 KiB
Python
Raw Normal View History

from __future__ import (absolute_import, print_function, division)
2015-08-15 15:43:46 +00:00
2014-03-09 20:13:08 +00:00
import copy
import os
2015-08-15 15:43:46 +00:00
from netlib import tcp, certutils
2014-03-09 20:13:08 +00:00
from .. import stateobject, utils
2014-03-09 20:51:24 +00:00
class ClientConnection(tcp.BaseHandler, stateobject.StateObject):
2016-01-27 09:12:18 +00:00
2014-03-09 20:13:08 +00:00
def __init__(self, client_connection, address, server):
2015-05-30 00:03:28 +00:00
# Eventually, this object is restored from state. We don't have a
# connection then.
if client_connection:
2015-08-29 23:21:58 +00:00
super(ClientConnection, self).__init__(client_connection, address, server)
2014-03-09 20:13:08 +00:00
else:
self.connection = None
self.server = None
self.wfile = None
self.rfile = None
self.address = None
self.clientcert = None
2014-08-17 23:47:39 +00:00
self.ssl_established = None
2014-03-09 20:13:08 +00:00
self.timestamp_start = utils.timestamp()
self.timestamp_end = None
self.timestamp_ssl_setup = None
self.protocol = None
2014-03-09 20:13:08 +00:00
2015-08-18 12:15:08 +00:00
def __nonzero__(self):
return bool(self.connection) and not self.finished
2014-08-17 22:55:30 +00:00
def __repr__(self):
return "<ClientConnection: {ssl}{address}>".format(
2014-08-17 22:55:30 +00:00
ssl="[ssl] " if self.ssl_established else "",
address=repr(self.address)
2014-08-17 22:55:30 +00:00
)
@property
def tls_established(self):
return self.ssl_established
2014-03-09 20:13:08 +00:00
_stateobject_attributes = dict(
2016-02-08 03:19:25 +00:00
address=tcp.Address,
clientcert=certutils.SSLCert,
2014-08-17 23:47:39 +00:00
ssl_established=bool,
2014-03-09 20:13:08 +00:00
timestamp_start=float,
timestamp_end=float,
timestamp_ssl_setup=float
)
def copy(self):
return copy.copy(self)
def send(self, message):
if isinstance(message, list):
message = b''.join(message)
2014-03-09 20:13:08 +00:00
self.wfile.write(message)
self.wfile.flush()
@classmethod
def from_state(cls, state):
2014-03-09 20:13:08 +00:00
f = cls(None, tuple(), None)
2016-02-08 03:19:25 +00:00
f.set_state(state)
2014-03-09 20:13:08 +00:00
return f
def convert_to_ssl(self, *args, **kwargs):
2015-08-29 23:21:58 +00:00
super(ClientConnection, self).convert_to_ssl(*args, **kwargs)
2014-03-09 20:13:08 +00:00
self.timestamp_ssl_setup = utils.timestamp()
def finish(self):
2015-08-29 23:21:58 +00:00
super(ClientConnection, self).finish()
2014-03-09 20:13:08 +00:00
self.timestamp_end = utils.timestamp()
class ServerConnection(tcp.TCPClient, stateobject.StateObject):
2016-01-27 09:12:18 +00:00
def __init__(self, address, source_address=None):
tcp.TCPClient.__init__(self, address, source_address)
2014-03-09 20:13:08 +00:00
2015-08-18 12:15:08 +00:00
self.via = None
2014-03-09 20:13:08 +00:00
self.timestamp_start = None
self.timestamp_end = None
self.timestamp_tcp_setup = None
self.timestamp_ssl_setup = None
self.protocol = None
2014-03-09 20:13:08 +00:00
2015-08-16 21:25:02 +00:00
def __nonzero__(self):
2015-08-18 12:15:08 +00:00
return bool(self.connection) and not self.finished
2015-08-16 21:25:02 +00:00
2014-08-17 22:55:30 +00:00
def __repr__(self):
if self.ssl_established and self.sni:
ssl = "[ssl: {0}] ".format(self.sni)
elif self.ssl_established:
ssl = "[ssl] "
else:
ssl = ""
return "<ServerConnection: {ssl}{address}>".format(
2014-08-17 22:55:30 +00:00
ssl=ssl,
address=repr(self.address)
2014-08-17 22:55:30 +00:00
)
@property
def tls_established(self):
return self.ssl_established
2014-03-09 20:13:08 +00:00
_stateobject_attributes = dict(
timestamp_start=float,
timestamp_end=float,
timestamp_tcp_setup=float,
timestamp_ssl_setup=float,
address=tcp.Address,
source_address=tcp.Address,
cert=certutils.SSLCert,
ssl_established=bool,
sni=str
)
@classmethod
def from_state(cls, state):
f = cls(tuple())
2016-02-08 03:19:25 +00:00
f.set_state(state)
2014-03-09 20:13:08 +00:00
return f
def copy(self):
return copy.copy(self)
def connect(self):
self.timestamp_start = utils.timestamp()
tcp.TCPClient.connect(self)
self.timestamp_tcp_setup = utils.timestamp()
def send(self, message):
if isinstance(message, list):
message = b''.join(message)
2014-03-09 20:13:08 +00:00
self.wfile.write(message)
self.wfile.flush()
def establish_ssl(self, clientcerts, sni, **kwargs):
2014-03-09 20:13:08 +00:00
clientcert = None
if clientcerts:
if os.path.isfile(clientcerts):
clientcert = clientcerts
else:
path = os.path.join(
clientcerts,
self.address.host.encode("idna")) + ".pem"
if os.path.exists(path):
clientcert = path
self.convert_to_ssl(cert=clientcert, sni=sni, **kwargs)
self.sni = sni
2014-09-02 16:13:18 +00:00
self.timestamp_ssl_setup = utils.timestamp()
2014-03-09 20:13:08 +00:00
def finish(self):
tcp.TCPClient.finish(self)
self.timestamp_end = utils.timestamp()
2015-08-18 12:15:08 +00:00
2015-08-30 13:27:29 +00:00
2015-08-19 13:23:52 +00:00
ServerConnection._stateobject_attributes["via"] = ServerConnection