mirror of
https://github.com/Grasscutters/mitmproxy.git
synced 2024-11-23 00:01:36 +00:00
Merge pull request #870 from bazzinotti/master
[docs/libmproxy/test] Support single client-side cert file
This commit is contained in:
commit
7b093b46b6
@ -175,10 +175,21 @@ no such file exists, it will be generated automatically.
|
||||
Using a client side certificate
|
||||
-------------------------------
|
||||
|
||||
You can use a client certificate by passing the ``--client-certs DIRECTORY`` option to mitmproxy.
|
||||
You can use a client certificate by passing the ``--client-certs DIRECTORY|FILE``
|
||||
option to mitmproxy. Using a directory allows certs to be selected based on
|
||||
hostname, while using a filename allows a single specific certificate to be used for
|
||||
all SSL connections. Certificate files must be in the PEM format and should
|
||||
contain both the unencrypted private key and the certificate.
|
||||
|
||||
Multiple certs by Hostname
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
If you've specified a directory to ``--client-certs``, then the following
|
||||
behavior will be taken:
|
||||
|
||||
If you visit example.org, mitmproxy looks for a file named ``example.org.pem`` in the specified
|
||||
directory and uses this as the client cert. The certificate file needs to be in the PEM format and
|
||||
should contain both the unencrypted private key and the certificate.
|
||||
directory and uses this as the client cert.
|
||||
|
||||
|
||||
|
||||
.. _Certificate Pinning: http://security.stackexchange.com/questions/29988/what-is-certificate-pinning/
|
@ -407,7 +407,7 @@ def proxy_ssl_options(parser):
|
||||
group.add_argument(
|
||||
"--client-certs", action="store",
|
||||
type=str, dest="clientcerts", default=None,
|
||||
help="Client certificate directory."
|
||||
help="Client certificate file or directory."
|
||||
)
|
||||
group.add_argument(
|
||||
"--no-upstream-cert", default=False,
|
||||
|
@ -174,11 +174,14 @@ class ServerConnection(tcp.TCPClient, stateobject.StateObject):
|
||||
def establish_ssl(self, clientcerts, sni, **kwargs):
|
||||
clientcert = None
|
||||
if clientcerts:
|
||||
path = os.path.join(
|
||||
clientcerts,
|
||||
self.address.host.encode("idna")) + ".pem"
|
||||
if os.path.exists(path):
|
||||
clientcert = path
|
||||
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
|
||||
|
@ -133,10 +133,9 @@ def process_proxy_options(parser, options):
|
||||
|
||||
if options.clientcerts:
|
||||
options.clientcerts = os.path.expanduser(options.clientcerts)
|
||||
if not os.path.exists(options.clientcerts) or not os.path.isdir(options.clientcerts):
|
||||
if not os.path.exists(options.clientcerts):
|
||||
return parser.error(
|
||||
"Client certificate directory does not exist or is not a directory: %s" %
|
||||
options.clientcerts
|
||||
"Client certificate path does not exist: %s" % options.clientcerts
|
||||
)
|
||||
|
||||
if options.auth_nonanonymous or options.auth_singleuser or options.auth_htpasswd:
|
||||
|
@ -1,3 +1,4 @@
|
||||
import os
|
||||
import mock
|
||||
from OpenSSL import SSL
|
||||
|
||||
@ -99,8 +100,11 @@ class TestProcessProxyOptions:
|
||||
def test_client_certs(self):
|
||||
with tutils.tmpdir() as cadir:
|
||||
self.assert_noerr("--client-certs", cadir)
|
||||
self.assert_noerr(
|
||||
"--client-certs",
|
||||
os.path.join(tutils.test_data.path("data/clientcert"), "client.pem"))
|
||||
self.assert_err(
|
||||
"directory does not exist",
|
||||
"path does not exist",
|
||||
"--client-certs",
|
||||
"nonexistent")
|
||||
|
||||
|
@ -1,3 +1,4 @@
|
||||
import os
|
||||
import socket
|
||||
import time
|
||||
from OpenSSL import SSL
|
||||
@ -313,13 +314,24 @@ class TestHTTPAuth(tservers.HTTPProxTest):
|
||||
class TestHTTPS(tservers.HTTPProxTest, CommonMixin, TcpMixin):
|
||||
ssl = True
|
||||
ssloptions = pathod.SSLOptions(request_client_cert=True)
|
||||
clientcerts = True
|
||||
|
||||
def test_clientcert(self):
|
||||
f = self.pathod("304")
|
||||
assert f.status_code == 304
|
||||
assert self.server.last_log()["request"]["clientcert"]["keyinfo"]
|
||||
|
||||
def test_clientcert_file(self):
|
||||
try:
|
||||
self.config.clientcerts = os.path.join(
|
||||
tutils.test_data.path("data/clientcert"), "client.pem")
|
||||
f = self.pathod("304")
|
||||
assert f.status_code == 304
|
||||
assert self.server.last_log()["request"]["clientcert"]["keyinfo"]
|
||||
finally:
|
||||
self.config.clientcerts = None
|
||||
def test_clientcert_dir(self):
|
||||
try:
|
||||
self.config.clientcerts = tutils.test_data.path("data/clientcert")
|
||||
f = self.pathod("304")
|
||||
assert f.status_code == 304
|
||||
assert self.server.last_log()["request"]["clientcert"]["keyinfo"]
|
||||
finally:
|
||||
self.config.clientcerts = None
|
||||
def test_error_post_connect(self):
|
||||
p = self.pathoc()
|
||||
assert p.request("get:/:i0,'invalid\r\n\r\n'").status_code == 400
|
||||
|
@ -83,7 +83,6 @@ class ProxTestBase(object):
|
||||
# Test Configuration
|
||||
ssl = None
|
||||
ssloptions = False
|
||||
clientcerts = False
|
||||
no_upstream_cert = False
|
||||
authenticator = None
|
||||
masterclass = TestMaster
|
||||
@ -130,7 +129,6 @@ class ProxTestBase(object):
|
||||
no_upstream_cert = cls.no_upstream_cert,
|
||||
cadir = cls.cadir,
|
||||
authenticator = cls.authenticator,
|
||||
clientcerts = tutils.test_data.path("data/clientcert") if cls.clientcerts else None
|
||||
)
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user