mirror of
https://github.com/Grasscutters/mitmproxy.git
synced 2024-11-26 02:10:59 +00:00
Merge branch 'master' into docs-tutorials
This commit is contained in:
commit
bfa6467e4c
@ -13,6 +13,7 @@ Unreleased: mitmproxy next
|
|||||||
* Add ASGI support for embedded apps (@mhils)
|
* Add ASGI support for embedded apps (@mhils)
|
||||||
* Updated raw exports to not remove headers (@wchasekelley)
|
* Updated raw exports to not remove headers (@wchasekelley)
|
||||||
* Fix file unlinking before external viewer finishes loading (@wchasekelley)
|
* Fix file unlinking before external viewer finishes loading (@wchasekelley)
|
||||||
|
* Add --cert-passphrase command line argument (@mirosyn)
|
||||||
* Add interactive tutorials to the documentation (@mplattner)
|
* Add interactive tutorials to the documentation (@mplattner)
|
||||||
|
|
||||||
* --- TODO: add new PRs above this line ---
|
* --- TODO: add new PRs above this line ---
|
||||||
|
@ -196,7 +196,7 @@ class CertStore:
|
|||||||
return dh
|
return dh
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_store(cls, path, basename, key_size):
|
def from_store(cls, path, basename, key_size, passphrase: typing.Optional[bytes] = None):
|
||||||
ca_path = os.path.join(path, basename + "-ca.pem")
|
ca_path = os.path.join(path, basename + "-ca.pem")
|
||||||
if not os.path.exists(ca_path):
|
if not os.path.exists(ca_path):
|
||||||
key, ca = cls.create_store(path, basename, key_size)
|
key, ca = cls.create_store(path, basename, key_size)
|
||||||
@ -208,7 +208,8 @@ class CertStore:
|
|||||||
raw)
|
raw)
|
||||||
key = OpenSSL.crypto.load_privatekey(
|
key = OpenSSL.crypto.load_privatekey(
|
||||||
OpenSSL.crypto.FILETYPE_PEM,
|
OpenSSL.crypto.FILETYPE_PEM,
|
||||||
raw)
|
raw,
|
||||||
|
passphrase)
|
||||||
dh_path = os.path.join(path, basename + "-dhparam.pem")
|
dh_path = os.path.join(path, basename + "-dhparam.pem")
|
||||||
dh = cls.load_dhparam(dh_path)
|
dh = cls.load_dhparam(dh_path)
|
||||||
return cls(key, ca, ca_path, dh)
|
return cls(key, ca, ca_path, dh)
|
||||||
@ -280,7 +281,7 @@ class CertStore:
|
|||||||
|
|
||||||
return key, ca
|
return key, ca
|
||||||
|
|
||||||
def add_cert_file(self, spec: str, path: str) -> None:
|
def add_cert_file(self, spec: str, path: str, passphrase: typing.Optional[bytes] = None) -> None:
|
||||||
with open(path, "rb") as f:
|
with open(path, "rb") as f:
|
||||||
raw = f.read()
|
raw = f.read()
|
||||||
cert = Cert(
|
cert = Cert(
|
||||||
@ -290,7 +291,8 @@ class CertStore:
|
|||||||
try:
|
try:
|
||||||
privatekey = OpenSSL.crypto.load_privatekey(
|
privatekey = OpenSSL.crypto.load_privatekey(
|
||||||
OpenSSL.crypto.FILETYPE_PEM,
|
OpenSSL.crypto.FILETYPE_PEM,
|
||||||
raw)
|
raw,
|
||||||
|
passphrase)
|
||||||
except Exception:
|
except Exception:
|
||||||
privatekey = self.default_privatekey
|
privatekey = self.default_privatekey
|
||||||
self.add_cert(
|
self.add_cert(
|
||||||
|
@ -47,6 +47,10 @@ class Options(optmanager.OptManager):
|
|||||||
certificate as the first entry.
|
certificate as the first entry.
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
|
self.add_option(
|
||||||
|
"cert_passphrase", Optional[str], None,
|
||||||
|
"Passphrase for decrypting the private key provided in the --cert option."
|
||||||
|
)
|
||||||
self.add_option(
|
self.add_option(
|
||||||
"ciphers_client", Optional[str], None,
|
"ciphers_client", Optional[str], None,
|
||||||
"Set supported ciphers for client connections using OpenSSL syntax."
|
"Set supported ciphers for client connections using OpenSSL syntax."
|
||||||
|
@ -62,10 +62,12 @@ class ProxyConfig:
|
|||||||
os.path.dirname(certstore_path)
|
os.path.dirname(certstore_path)
|
||||||
)
|
)
|
||||||
key_size = options.key_size
|
key_size = options.key_size
|
||||||
|
passphrase = options.cert_passphrase.encode("utf-8") if options.cert_passphrase else None
|
||||||
self.certstore = certs.CertStore.from_store(
|
self.certstore = certs.CertStore.from_store(
|
||||||
certstore_path,
|
certstore_path,
|
||||||
moptions.CONF_BASENAME,
|
moptions.CONF_BASENAME,
|
||||||
key_size
|
key_size,
|
||||||
|
passphrase
|
||||||
)
|
)
|
||||||
|
|
||||||
for c in options.certs:
|
for c in options.certs:
|
||||||
@ -79,7 +81,7 @@ class ProxyConfig:
|
|||||||
"Certificate file does not exist: %s" % cert
|
"Certificate file does not exist: %s" % cert
|
||||||
)
|
)
|
||||||
try:
|
try:
|
||||||
self.certstore.add_cert_file(parts[0], cert)
|
self.certstore.add_cert_file(parts[0], cert, passphrase)
|
||||||
except crypto.Error:
|
except crypto.Error:
|
||||||
raise exceptions.OptionsError(
|
raise exceptions.OptionsError(
|
||||||
"Invalid certificate format: %s" % cert
|
"Invalid certificate format: %s" % cert
|
||||||
|
@ -67,6 +67,7 @@ def common_options(parser, opts):
|
|||||||
# Proxy SSL options
|
# Proxy SSL options
|
||||||
group = parser.add_argument_group("SSL")
|
group = parser.add_argument_group("SSL")
|
||||||
opts.make_parser(group, "certs", metavar="SPEC")
|
opts.make_parser(group, "certs", metavar="SPEC")
|
||||||
|
opts.make_parser(group, "cert_passphrase", metavar="PASS")
|
||||||
opts.make_parser(group, "ssl_insecure", short="k")
|
opts.make_parser(group, "ssl_insecure", short="k")
|
||||||
opts.make_parser(group, "key_size", metavar="KEY_SIZE")
|
opts.make_parser(group, "key_size", metavar="KEY_SIZE")
|
||||||
|
|
||||||
|
51
test/mitmproxy/data/mitmproxy.pem
Normal file
51
test/mitmproxy/data/mitmproxy.pem
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
-----BEGIN ENCRYPTED PRIVATE KEY-----
|
||||||
|
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
|
||||||
|
S9rWCU2k/woEUOv3hssY5w==
|
||||||
|
-----END ENCRYPTED PRIVATE KEY-----
|
||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIDdTCCAl2gAwIBAgIURm3Wk48Uc3RtqZ0FFxCaE33TvjcwDQYJKoZIhvcNAQEL
|
||||||
|
BQAwSTELMAkGA1UEBhMCVVMxDTALBgNVBAgMBENhbGkxDTALBgNVBAcMBHRlc3Qx
|
||||||
|
DTALBgNVBAoMBHRlc3QxDTALBgNVBAMMBHRlc3QwIBcNMjAwODI4MTIyNDU4WhgP
|
||||||
|
MjI5NDA2MTIxMjI0NThaMEkxCzAJBgNVBAYTAlVTMQ0wCwYDVQQIDARDYWxpMQ0w
|
||||||
|
CwYDVQQHDAR0ZXN0MQ0wCwYDVQQKDAR0ZXN0MQ0wCwYDVQQDDAR0ZXN0MIIBIjAN
|
||||||
|
BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvyrgqfiwRh2EcPYk/GFMgF2k8yJq
|
||||||
|
4mkQcjpWlowp/fL99W/c33ySEtV/LyMJ6LtPAIKN4SambUFcx97pEgJi9YEDLRGW
|
||||||
|
aN9jznss5AAe03uXN2gizpq9LmdPxr/vmH1DnqdI5MKwa8g9phpe9tT6ik3f2qkm
|
||||||
|
1V9Ka38GlkHbB+w743ytz20jM6ifTtrX0SuDqDbAppandv5Ix3CHdlllRS/MKNEw
|
||||||
|
LAs7LVkct0UNTp+soTIhGcASmbf24dvJnO+Msfuqw60mHJpoUP/xDcRGcXnjsgAZ
|
||||||
|
zAi0UXlV9QiItQeOKxLBHIlMSAEd9oEejPCi6uN+zjKb3De7LUD2Vxu7iwIDAQAB
|
||||||
|
o1MwUTAdBgNVHQ4EFgQU6tvbiSgA6pujKJBSFw/j+QRZOiwwHwYDVR0jBBgwFoAU
|
||||||
|
6tvbiSgA6pujKJBSFw/j+QRZOiwwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0B
|
||||||
|
AQsFAAOCAQEAgVa/jUdGqElv3EzxzSqtYkGxmeY5m2aLPKgsUl2zOPWwgyE1Synu
|
||||||
|
TuFS+B5pyTT1KZ6IDwRQ+hA9jOnEopNK33lVelz7XBuw7485qVidG4o6QH1uo/J9
|
||||||
|
GlxjM5SCY6yQ4frCI8lCY6+LA0NbI05qtVNTS1zgdOBnC/IOlMFpp0oDaf5FZHxc
|
||||||
|
Ci1I/g32ES3rvKiAGBY2m6hy138GzYpZTXnKS03MaTfUCFfsOvqq/z2KBCeCd4mH
|
||||||
|
VDO7adjhw4I7EYYXjmly2um6NaqyXtT6/AARY3JuQgFoW7W3XBV6TCsYmsGSeUTH
|
||||||
|
JrhnGnHiNi06IuBwOXYZDID+orBMr9NDKw==
|
||||||
|
-----END CERTIFICATE-----
|
@ -204,3 +204,9 @@ class TestCert:
|
|||||||
x = certs.Cert('')
|
x = certs.Cert('')
|
||||||
x.set_state(a)
|
x.set_state(a)
|
||||||
assert x == c
|
assert x == c
|
||||||
|
|
||||||
|
def test_from_store_with_passphrase(self, tdata, tmpdir):
|
||||||
|
ca = certs.CertStore.from_store(str(tmpdir), "mitmproxy", 2048, "password")
|
||||||
|
ca.add_cert_file("*", tdata.path("mitmproxy/data/mitmproxy.pem"), "password")
|
||||||
|
|
||||||
|
assert ca.get_cert(b"foo", [])
|
||||||
|
@ -42,11 +42,10 @@ class TestProcessProxyOptions:
|
|||||||
assert self.p()
|
assert self.p()
|
||||||
|
|
||||||
def test_certs(self, tdata):
|
def test_certs(self, tdata):
|
||||||
self.assert_noerr(
|
with pytest.raises(Exception, match="ambiguous option"):
|
||||||
"--cert",
|
self.assert_noerr(
|
||||||
tdata.path("mitmproxy/data/testkey.pem"))
|
"--cert",
|
||||||
with pytest.raises(Exception, match="does not exist"):
|
tdata.path("mitmproxy/data/testkey.pem"))
|
||||||
self.p("--cert", "nonexistent")
|
|
||||||
|
|
||||||
|
|
||||||
class TestProxyServer:
|
class TestProxyServer:
|
||||||
|
Loading…
Reference in New Issue
Block a user