We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Can't view options
##### Steps to reproduce the problem:
1. `mitmproxy`
2. Press `o`
##### What is the expected behavior?

No Crash!
##### What went wrong?

mitmproxy crashed!

```
~/dev/mitmproxy (master) > env/bin/mitmproxy                                                                                                                                          03:29:44
Traceback (most recent call last):
  File "/home/dufferzafar/dev/mitmproxy/mitmproxy/console/master.py", line 537, in run
    self.loop.run()
  File "/home/dufferzafar/dev/mitmproxy/env/lib/python2.7/site-packages/urwid/main_loop.py", line 278, in run
    self._run()
  File "/home/dufferzafar/dev/mitmproxy/env/lib/python2.7/site-packages/urwid/main_loop.py", line 376, in _run
    self.event_loop.run()
  File "/home/dufferzafar/dev/mitmproxy/env/lib/python2.7/site-packages/urwid/main_loop.py", line 682, in run
    self._loop()
  File "/home/dufferzafar/dev/mitmproxy/env/lib/python2.7/site-packages/urwid/main_loop.py", line 719, in _loop
    self._watch_files[fd]()
  File "/home/dufferzafar/dev/mitmproxy/env/lib/python2.7/site-packages/urwid/raw_display.py", line 393, in <lambda>
    event_loop, callback, self.get_available_raw_input())
  File "/home/dufferzafar/dev/mitmproxy/env/lib/python2.7/site-packages/urwid/raw_display.py", line 493, in parse_input
    callback(processed, processed_codes)
  File "/home/dufferzafar/dev/mitmproxy/env/lib/python2.7/site-packages/urwid/main_loop.py", line 403, in _update
    self.process_input(keys)
  File "/home/dufferzafar/dev/mitmproxy/env/lib/python2.7/site-packages/urwid/main_loop.py", line 503, in process_input
    k = self._topmost_widget.keypress(self.screen_size, k)
  File "/home/dufferzafar/dev/mitmproxy/mitmproxy/console/window.py", line 89, in keypress
    self.master.view_options()
  File "/home/dufferzafar/dev/mitmproxy/mitmproxy/console/master.py", line 572, in view_options
    options.help_context,
  File "/home/dufferzafar/dev/mitmproxy/env/lib/python2.7/site-packages/blinker/base.py", line 267, in send
    for receiver in self.receivers_for(sender)]
  File "/home/dufferzafar/dev/mitmproxy/mitmproxy/console/master.py", line 333, in sig_push_view_state
    self.loop.draw_screen()
  File "/home/dufferzafar/dev/mitmproxy/env/lib/python2.7/site-packages/urwid/main_loop.py", line 578, in draw_screen
    canvas = self._topmost_widget.render(self.screen_size, focus=True)
  File "/home/dufferzafar/dev/mitmproxy/env/lib/python2.7/site-packages/urwid/widget.py", line 141, in cached_render
    canv = fn(self, size, focus=focus)
  File "/home/dufferzafar/dev/mitmproxy/env/lib/python2.7/site-packages/urwid/container.py", line 1083, in render
    focus and self.focus_part == 'body')
  File "/home/dufferzafar/dev/mitmproxy/env/lib/python2.7/site-packages/urwid/widget.py", line 141, in cached_render
    canv = fn(self, size, focus=focus)
  File "/home/dufferzafar/dev/mitmproxy/env/lib/python2.7/site-packages/urwid/decoration.py", line 225, in render
    canv = self._original_widget.render(size, focus=focus)
  File "/home/dufferzafar/dev/mitmproxy/env/lib/python2.7/site-packages/urwid/widget.py", line 141, in cached_render
    canv = fn(self, size, focus=focus)
  File "/home/dufferzafar/dev/mitmproxy/env/lib/python2.7/site-packages/urwid/widget.py", line 1751, in render
    canv = get_delegate(self).render(size, focus=focus)
  File "/home/dufferzafar/dev/mitmproxy/env/lib/python2.7/site-packages/urwid/widget.py", line 141, in cached_render
    canv = fn(self, size, focus=focus)
  File "/home/dufferzafar/dev/mitmproxy/env/lib/python2.7/site-packages/urwid/container.py", line 1083, in render
    focus and self.focus_part == 'body')
  File "/home/dufferzafar/dev/mitmproxy/env/lib/python2.7/site-packages/urwid/widget.py", line 141, in cached_render
    canv = fn(self, size, focus=focus)
  File "/home/dufferzafar/dev/mitmproxy/env/lib/python2.7/site-packages/urwid/listbox.py", line 457, in render
    (maxcol, maxrow), focus=focus)
  File "/home/dufferzafar/dev/mitmproxy/env/lib/python2.7/site-packages/urwid/listbox.py", line 339, in calculate_visible
    self._set_focus_complete( (maxcol, maxrow), focus )
  File "/home/dufferzafar/dev/mitmproxy/env/lib/python2.7/site-packages/urwid/listbox.py", line 704, in _set_focus_complete
    (maxcol,maxrow), focus)
  File "/home/dufferzafar/dev/mitmproxy/env/lib/python2.7/site-packages/urwid/listbox.py", line 674, in _set_focus_first_selectable
    (maxcol, maxrow), focus=focus)
  File "/home/dufferzafar/dev/mitmproxy/env/lib/python2.7/site-packages/urwid/listbox.py", line 402, in calculate_visible
    next, pos = self.body.get_next( pos )
  File "/home/dufferzafar/dev/mitmproxy/mitmproxy/console/select.py", line 57, in get_next
    return self.options[pos + 1].render(False), pos + 1
  File "/home/dufferzafar/dev/mitmproxy/mitmproxy/console/select.py", line 94, in render
    self.getstate(),
  File "/home/dufferzafar/dev/mitmproxy/mitmproxy/console/options.py", line 97, in <lambda>
    lambda: master.server.config.ssl_insecure,
AttributeError: ProxyConfig instance has no attribute 'ssl_insecure'

mitmproxy has crashed!
Please lodge a bug report at:
    https://github.com/mitmproxy/mitmproxy
Shutting down...
```


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `mitmproxy/proxy/config.py`
Content:
```
1 from __future__ import absolute_import, print_function, division
2 
3 import base64
4 import collections
5 import os
6 import re
7 from netlib import strutils
8 
9 import six
10 from OpenSSL import SSL, crypto
11 
12 from mitmproxy import exceptions
13 from netlib import certutils
14 from netlib import tcp
15 from netlib.http import authentication
16 from netlib.http import url
17 
18 CONF_BASENAME = "mitmproxy"
19 
20 
21 class HostMatcher(object):
22 
23     def __init__(self, patterns=tuple()):
24         self.patterns = list(patterns)
25         self.regexes = [re.compile(p, re.IGNORECASE) for p in self.patterns]
26 
27     def __call__(self, address):
28         if not address:
29             return False
30         address = tcp.Address.wrap(address)
31         host = "%s:%s" % (address.host, address.port)
32         if any(rex.search(host) for rex in self.regexes):
33             return True
34         else:
35             return False
36 
37     def __bool__(self):
38         return bool(self.patterns)
39 
40     if six.PY2:
41         __nonzero__ = __bool__
42 
43 
44 ServerSpec = collections.namedtuple("ServerSpec", "scheme address")
45 
46 
47 def parse_server_spec(spec):
48     try:
49         p = url.parse(spec)
50         if p[0] not in (b"http", b"https"):
51             raise ValueError()
52     except ValueError:
53         raise exceptions.OptionsError(
54             "Invalid server specification: %s" % spec
55         )
56     host, port = p[1:3]
57     address = tcp.Address((host.decode("ascii"), port))
58     scheme = p[0].decode("ascii").lower()
59     return ServerSpec(scheme, address)
60 
61 
62 def parse_upstream_auth(auth):
63     pattern = re.compile(".+:")
64     if pattern.search(auth) is None:
65         raise exceptions.OptionsError(
66             "Invalid upstream auth specification: %s" % auth
67         )
68     return b"Basic" + b" " + base64.b64encode(strutils.always_bytes(auth))
69 
70 
71 class ProxyConfig:
72 
73     def __init__(self, options):
74         self.options = options
75 
76         self.authenticator = None
77         self.check_ignore = None
78         self.check_tcp = None
79         self.certstore = None
80         self.clientcerts = None
81         self.openssl_verification_mode_server = None
82         self.configure(options, set(options.keys()))
83         options.changed.connect(self.configure)
84 
85     def configure(self, options, updated):
86         # type: (mitmproxy.options.Options, Any) -> None
87         if options.add_upstream_certs_to_client_chain and not options.ssl_insecure:
88             raise exceptions.OptionsError(
89                 "The verify-upstream-cert requires certificate verification to be disabled. "
90                 "If upstream certificates are verified then extra upstream certificates are "
91                 "not available for inclusion to the client chain."
92             )
93 
94         if options.ssl_insecure:
95             self.openssl_verification_mode_server = SSL.VERIFY_NONE
96         else:
97             self.openssl_verification_mode_server = SSL.VERIFY_PEER
98 
99         self.check_ignore = HostMatcher(options.ignore_hosts)
100         self.check_tcp = HostMatcher(options.tcp_hosts)
101 
102         self.openssl_method_client, self.openssl_options_client = \
103             tcp.sslversion_choices[options.ssl_version_client]
104         self.openssl_method_server, self.openssl_options_server = \
105             tcp.sslversion_choices[options.ssl_version_server]
106 
107         certstore_path = os.path.expanduser(options.cadir)
108         if not os.path.exists(os.path.dirname(certstore_path)):
109             raise exceptions.OptionsError(
110                 "Certificate Authority parent directory does not exist: %s" %
111                 os.path.dirname(options.cadir)
112             )
113         self.certstore = certutils.CertStore.from_store(
114             certstore_path,
115             CONF_BASENAME
116         )
117 
118         if options.clientcerts:
119             clientcerts = os.path.expanduser(options.clientcerts)
120             if not os.path.exists(clientcerts):
121                 raise exceptions.OptionsError(
122                     "Client certificate path does not exist: %s" %
123                     options.clientcerts
124                 )
125             self.clientcerts = clientcerts
126 
127         for spec, cert in options.certs:
128             cert = os.path.expanduser(cert)
129             if not os.path.exists(cert):
130                 raise exceptions.OptionsError(
131                     "Certificate file does not exist: %s" % cert
132                 )
133             try:
134                 self.certstore.add_cert_file(spec, cert)
135             except crypto.Error:
136                 raise exceptions.OptionsError(
137                     "Invalid certificate format: %s" % cert
138                 )
139 
140         self.upstream_server = None
141         self.upstream_auth = None
142         if options.upstream_server:
143             self.upstream_server = parse_server_spec(options.upstream_server)
144         if options.upstream_auth:
145             self.upstream_auth = parse_upstream_auth(options.upstream_auth)
146 
147         self.authenticator = authentication.NullProxyAuth(None)
148         needsauth = any(
149             [
150                 options.auth_nonanonymous,
151                 options.auth_singleuser,
152                 options.auth_htpasswd
153             ]
154         )
155         if needsauth:
156             if options.mode == "transparent":
157                 raise exceptions.OptionsError(
158                     "Proxy Authentication not supported in transparent mode."
159                 )
160             elif options.mode == "socks5":
161                 raise exceptions.OptionsError(
162                     "Proxy Authentication not supported in SOCKS mode. "
163                     "https://github.com/mitmproxy/mitmproxy/issues/738"
164                 )
165             elif options.auth_singleuser:
166                 parts = options.auth_singleuser.split(':')
167                 if len(parts) != 2:
168                     raise exceptions.OptionsError(
169                         "Invalid single-user specification. "
170                         "Please use the format username:password"
171                     )
172                 password_manager = authentication.PassManSingleUser(*parts)
173             elif options.auth_nonanonymous:
174                 password_manager = authentication.PassManNonAnon()
175             elif options.auth_htpasswd:
176                 try:
177                     password_manager = authentication.PassManHtpasswd(
178                         options.auth_htpasswd
179                     )
180                 except ValueError as v:
181                     raise exceptions.OptionsError(str(v))
182             self.authenticator = authentication.BasicProxyAuth(
183                 password_manager,
184                 "mitmproxy"
185             )
186
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/mitmproxy/proxy/config.py b/mitmproxy/proxy/config.py
--- a/mitmproxy/proxy/config.py
+++ b/mitmproxy/proxy/config.py
@@ -78,6 +78,7 @@
         self.check_tcp = None
         self.certstore = None
         self.clientcerts = None
+        self.ssl_insecure = False
         self.openssl_verification_mode_server = None
         self.configure(options, set(options.keys()))
         options.changed.connect(self.configure)

{"golden_diff": "diff --git a/mitmproxy/proxy/config.py b/mitmproxy/proxy/config.py\n--- a/mitmproxy/proxy/config.py\n+++ b/mitmproxy/proxy/config.py\n@@ -78,6 +78,7 @@\n         self.check_tcp = None\n         self.certstore = None\n         self.clientcerts = None\n+        self.ssl_insecure = False\n         self.openssl_verification_mode_server = None\n         self.configure(options, set(options.keys()))\n         options.changed.connect(self.configure)\n", "issue": "Can't view options\n##### Steps to reproduce the problem:\n1. `mitmproxy`\n2. Press `o`\n##### What is the expected behavior?\n\nNo Crash!\n##### What went wrong?\n\nmitmproxy crashed!\n\n```\n~/dev/mitmproxy (master) > env/bin/mitmproxy                                                                                                                                          03:29:44\nTraceback (most recent call last):\n  File \"/home/dufferzafar/dev/mitmproxy/mitmproxy/console/master.py\", line 537, in run\n    self.loop.run()\n  File \"/home/dufferzafar/dev/mitmproxy/env/lib/python2.7/site-packages/urwid/main_loop.py\", line 278, in run\n    self._run()\n  File \"/home/dufferzafar/dev/mitmproxy/env/lib/python2.7/site-packages/urwid/main_loop.py\", line 376, in _run\n    self.event_loop.run()\n  File \"/home/dufferzafar/dev/mitmproxy/env/lib/python2.7/site-packages/urwid/main_loop.py\", line 682, in run\n    self._loop()\n  File \"/home/dufferzafar/dev/mitmproxy/env/lib/python2.7/site-packages/urwid/main_loop.py\", line 719, in _loop\n    self._watch_files[fd]()\n  File \"/home/dufferzafar/dev/mitmproxy/env/lib/python2.7/site-packages/urwid/raw_display.py\", line 393, in <lambda>\n    event_loop, callback, self.get_available_raw_input())\n  File \"/home/dufferzafar/dev/mitmproxy/env/lib/python2.7/site-packages/urwid/raw_display.py\", line 493, in parse_input\n    callback(processed, processed_codes)\n  File \"/home/dufferzafar/dev/mitmproxy/env/lib/python2.7/site-packages/urwid/main_loop.py\", line 403, in _update\n    self.process_input(keys)\n  File \"/home/dufferzafar/dev/mitmproxy/env/lib/python2.7/site-packages/urwid/main_loop.py\", line 503, in process_input\n    k = self._topmost_widget.keypress(self.screen_size, k)\n  File \"/home/dufferzafar/dev/mitmproxy/mitmproxy/console/window.py\", line 89, in keypress\n    self.master.view_options()\n  File \"/home/dufferzafar/dev/mitmproxy/mitmproxy/console/master.py\", line 572, in view_options\n    options.help_context,\n  File \"/home/dufferzafar/dev/mitmproxy/env/lib/python2.7/site-packages/blinker/base.py\", line 267, in send\n    for receiver in self.receivers_for(sender)]\n  File \"/home/dufferzafar/dev/mitmproxy/mitmproxy/console/master.py\", line 333, in sig_push_view_state\n    self.loop.draw_screen()\n  File \"/home/dufferzafar/dev/mitmproxy/env/lib/python2.7/site-packages/urwid/main_loop.py\", line 578, in draw_screen\n    canvas = self._topmost_widget.render(self.screen_size, focus=True)\n  File \"/home/dufferzafar/dev/mitmproxy/env/lib/python2.7/site-packages/urwid/widget.py\", line 141, in cached_render\n    canv = fn(self, size, focus=focus)\n  File \"/home/dufferzafar/dev/mitmproxy/env/lib/python2.7/site-packages/urwid/container.py\", line 1083, in render\n    focus and self.focus_part == 'body')\n  File \"/home/dufferzafar/dev/mitmproxy/env/lib/python2.7/site-packages/urwid/widget.py\", line 141, in cached_render\n    canv = fn(self, size, focus=focus)\n  File \"/home/dufferzafar/dev/mitmproxy/env/lib/python2.7/site-packages/urwid/decoration.py\", line 225, in render\n    canv = self._original_widget.render(size, focus=focus)\n  File \"/home/dufferzafar/dev/mitmproxy/env/lib/python2.7/site-packages/urwid/widget.py\", line 141, in cached_render\n    canv = fn(self, size, focus=focus)\n  File \"/home/dufferzafar/dev/mitmproxy/env/lib/python2.7/site-packages/urwid/widget.py\", line 1751, in render\n    canv = get_delegate(self).render(size, focus=focus)\n  File \"/home/dufferzafar/dev/mitmproxy/env/lib/python2.7/site-packages/urwid/widget.py\", line 141, in cached_render\n    canv = fn(self, size, focus=focus)\n  File \"/home/dufferzafar/dev/mitmproxy/env/lib/python2.7/site-packages/urwid/container.py\", line 1083, in render\n    focus and self.focus_part == 'body')\n  File \"/home/dufferzafar/dev/mitmproxy/env/lib/python2.7/site-packages/urwid/widget.py\", line 141, in cached_render\n    canv = fn(self, size, focus=focus)\n  File \"/home/dufferzafar/dev/mitmproxy/env/lib/python2.7/site-packages/urwid/listbox.py\", line 457, in render\n    (maxcol, maxrow), focus=focus)\n  File \"/home/dufferzafar/dev/mitmproxy/env/lib/python2.7/site-packages/urwid/listbox.py\", line 339, in calculate_visible\n    self._set_focus_complete( (maxcol, maxrow), focus )\n  File \"/home/dufferzafar/dev/mitmproxy/env/lib/python2.7/site-packages/urwid/listbox.py\", line 704, in _set_focus_complete\n    (maxcol,maxrow), focus)\n  File \"/home/dufferzafar/dev/mitmproxy/env/lib/python2.7/site-packages/urwid/listbox.py\", line 674, in _set_focus_first_selectable\n    (maxcol, maxrow), focus=focus)\n  File \"/home/dufferzafar/dev/mitmproxy/env/lib/python2.7/site-packages/urwid/listbox.py\", line 402, in calculate_visible\n    next, pos = self.body.get_next( pos )\n  File \"/home/dufferzafar/dev/mitmproxy/mitmproxy/console/select.py\", line 57, in get_next\n    return self.options[pos + 1].render(False), pos + 1\n  File \"/home/dufferzafar/dev/mitmproxy/mitmproxy/console/select.py\", line 94, in render\n    self.getstate(),\n  File \"/home/dufferzafar/dev/mitmproxy/mitmproxy/console/options.py\", line 97, in <lambda>\n    lambda: master.server.config.ssl_insecure,\nAttributeError: ProxyConfig instance has no attribute 'ssl_insecure'\n\nmitmproxy has crashed!\nPlease lodge a bug report at:\n    https://github.com/mitmproxy/mitmproxy\nShutting down...\n```\n\n", "before_files": [{"content": "from __future__ import absolute_import, print_function, division\n\nimport base64\nimport collections\nimport os\nimport re\nfrom netlib import strutils\n\nimport six\nfrom OpenSSL import SSL, crypto\n\nfrom mitmproxy import exceptions\nfrom netlib import certutils\nfrom netlib import tcp\nfrom netlib.http import authentication\nfrom netlib.http import url\n\nCONF_BASENAME = \"mitmproxy\"\n\n\nclass HostMatcher(object):\n\n    def __init__(self, patterns=tuple()):\n        self.patterns = list(patterns)\n        self.regexes = [re.compile(p, re.IGNORECASE) for p in self.patterns]\n\n    def __call__(self, address):\n        if not address:\n            return False\n        address = tcp.Address.wrap(address)\n        host = \"%s:%s\" % (address.host, address.port)\n        if any(rex.search(host) for rex in self.regexes):\n            return True\n        else:\n            return False\n\n    def __bool__(self):\n        return bool(self.patterns)\n\n    if six.PY2:\n        __nonzero__ = __bool__\n\n\nServerSpec = collections.namedtuple(\"ServerSpec\", \"scheme address\")\n\n\ndef parse_server_spec(spec):\n    try:\n        p = url.parse(spec)\n        if p[0] not in (b\"http\", b\"https\"):\n            raise ValueError()\n    except ValueError:\n        raise exceptions.OptionsError(\n            \"Invalid server specification: %s\" % spec\n        )\n    host, port = p[1:3]\n    address = tcp.Address((host.decode(\"ascii\"), port))\n    scheme = p[0].decode(\"ascii\").lower()\n    return ServerSpec(scheme, address)\n\n\ndef parse_upstream_auth(auth):\n    pattern = re.compile(\".+:\")\n    if pattern.search(auth) is None:\n        raise exceptions.OptionsError(\n            \"Invalid upstream auth specification: %s\" % auth\n        )\n    return b\"Basic\" + b\" \" + base64.b64encode(strutils.always_bytes(auth))\n\n\nclass ProxyConfig:\n\n    def __init__(self, options):\n        self.options = options\n\n        self.authenticator = None\n        self.check_ignore = None\n        self.check_tcp = None\n        self.certstore = None\n        self.clientcerts = None\n        self.openssl_verification_mode_server = None\n        self.configure(options, set(options.keys()))\n        options.changed.connect(self.configure)\n\n    def configure(self, options, updated):\n        # type: (mitmproxy.options.Options, Any) -> None\n        if options.add_upstream_certs_to_client_chain and not options.ssl_insecure:\n            raise exceptions.OptionsError(\n                \"The verify-upstream-cert requires certificate verification to be disabled. \"\n                \"If upstream certificates are verified then extra upstream certificates are \"\n                \"not available for inclusion to the client chain.\"\n            )\n\n        if options.ssl_insecure:\n            self.openssl_verification_mode_server = SSL.VERIFY_NONE\n        else:\n            self.openssl_verification_mode_server = SSL.VERIFY_PEER\n\n        self.check_ignore = HostMatcher(options.ignore_hosts)\n        self.check_tcp = HostMatcher(options.tcp_hosts)\n\n        self.openssl_method_client, self.openssl_options_client = \\\n            tcp.sslversion_choices[options.ssl_version_client]\n        self.openssl_method_server, self.openssl_options_server = \\\n            tcp.sslversion_choices[options.ssl_version_server]\n\n        certstore_path = os.path.expanduser(options.cadir)\n        if not os.path.exists(os.path.dirname(certstore_path)):\n            raise exceptions.OptionsError(\n                \"Certificate Authority parent directory does not exist: %s\" %\n                os.path.dirname(options.cadir)\n            )\n        self.certstore = certutils.CertStore.from_store(\n            certstore_path,\n            CONF_BASENAME\n        )\n\n        if options.clientcerts:\n            clientcerts = os.path.expanduser(options.clientcerts)\n            if not os.path.exists(clientcerts):\n                raise exceptions.OptionsError(\n                    \"Client certificate path does not exist: %s\" %\n                    options.clientcerts\n                )\n            self.clientcerts = clientcerts\n\n        for spec, cert in options.certs:\n            cert = os.path.expanduser(cert)\n            if not os.path.exists(cert):\n                raise exceptions.OptionsError(\n                    \"Certificate file does not exist: %s\" % cert\n                )\n            try:\n                self.certstore.add_cert_file(spec, cert)\n            except crypto.Error:\n                raise exceptions.OptionsError(\n                    \"Invalid certificate format: %s\" % cert\n                )\n\n        self.upstream_server = None\n        self.upstream_auth = None\n        if options.upstream_server:\n            self.upstream_server = parse_server_spec(options.upstream_server)\n        if options.upstream_auth:\n            self.upstream_auth = parse_upstream_auth(options.upstream_auth)\n\n        self.authenticator = authentication.NullProxyAuth(None)\n        needsauth = any(\n            [\n                options.auth_nonanonymous,\n                options.auth_singleuser,\n                options.auth_htpasswd\n            ]\n        )\n        if needsauth:\n            if options.mode == \"transparent\":\n                raise exceptions.OptionsError(\n                    \"Proxy Authentication not supported in transparent mode.\"\n                )\n            elif options.mode == \"socks5\":\n                raise exceptions.OptionsError(\n                    \"Proxy Authentication not supported in SOCKS mode. \"\n                    \"https://github.com/mitmproxy/mitmproxy/issues/738\"\n                )\n            elif options.auth_singleuser:\n                parts = options.auth_singleuser.split(':')\n                if len(parts) != 2:\n                    raise exceptions.OptionsError(\n                        \"Invalid single-user specification. \"\n                        \"Please use the format username:password\"\n                    )\n                password_manager = authentication.PassManSingleUser(*parts)\n            elif options.auth_nonanonymous:\n                password_manager = authentication.PassManNonAnon()\n            elif options.auth_htpasswd:\n                try:\n                    password_manager = authentication.PassManHtpasswd(\n                        options.auth_htpasswd\n                    )\n                except ValueError as v:\n                    raise exceptions.OptionsError(str(v))\n            self.authenticator = authentication.BasicProxyAuth(\n                password_manager,\n                \"mitmproxy\"\n            )\n", "path": "mitmproxy/proxy/config.py"}], "after_files": [{"content": "from __future__ import absolute_import, print_function, division\n\nimport base64\nimport collections\nimport os\nimport re\nfrom netlib import strutils\n\nimport six\nfrom OpenSSL import SSL, crypto\n\nfrom mitmproxy import exceptions\nfrom netlib import certutils\nfrom netlib import tcp\nfrom netlib.http import authentication\nfrom netlib.http import url\n\nCONF_BASENAME = \"mitmproxy\"\n\n\nclass HostMatcher(object):\n\n    def __init__(self, patterns=tuple()):\n        self.patterns = list(patterns)\n        self.regexes = [re.compile(p, re.IGNORECASE) for p in self.patterns]\n\n    def __call__(self, address):\n        if not address:\n            return False\n        address = tcp.Address.wrap(address)\n        host = \"%s:%s\" % (address.host, address.port)\n        if any(rex.search(host) for rex in self.regexes):\n            return True\n        else:\n            return False\n\n    def __bool__(self):\n        return bool(self.patterns)\n\n    if six.PY2:\n        __nonzero__ = __bool__\n\n\nServerSpec = collections.namedtuple(\"ServerSpec\", \"scheme address\")\n\n\ndef parse_server_spec(spec):\n    try:\n        p = url.parse(spec)\n        if p[0] not in (b\"http\", b\"https\"):\n            raise ValueError()\n    except ValueError:\n        raise exceptions.OptionsError(\n            \"Invalid server specification: %s\" % spec\n        )\n    host, port = p[1:3]\n    address = tcp.Address((host.decode(\"ascii\"), port))\n    scheme = p[0].decode(\"ascii\").lower()\n    return ServerSpec(scheme, address)\n\n\ndef parse_upstream_auth(auth):\n    pattern = re.compile(\".+:\")\n    if pattern.search(auth) is None:\n        raise exceptions.OptionsError(\n            \"Invalid upstream auth specification: %s\" % auth\n        )\n    return b\"Basic\" + b\" \" + base64.b64encode(strutils.always_bytes(auth))\n\n\nclass ProxyConfig:\n\n    def __init__(self, options):\n        self.options = options\n\n        self.authenticator = None\n        self.check_ignore = None\n        self.check_tcp = None\n        self.certstore = None\n        self.clientcerts = None\n        self.ssl_insecure = False\n        self.openssl_verification_mode_server = None\n        self.configure(options, set(options.keys()))\n        options.changed.connect(self.configure)\n\n    def configure(self, options, updated):\n        # type: (mitmproxy.options.Options, Any) -> None\n        if options.add_upstream_certs_to_client_chain and not options.ssl_insecure:\n            raise exceptions.OptionsError(\n                \"The verify-upstream-cert requires certificate verification to be disabled. \"\n                \"If upstream certificates are verified then extra upstream certificates are \"\n                \"not available for inclusion to the client chain.\"\n            )\n\n        if options.ssl_insecure:\n            self.openssl_verification_mode_server = SSL.VERIFY_NONE\n        else:\n            self.openssl_verification_mode_server = SSL.VERIFY_PEER\n\n        self.check_ignore = HostMatcher(options.ignore_hosts)\n        self.check_tcp = HostMatcher(options.tcp_hosts)\n\n        self.openssl_method_client, self.openssl_options_client = \\\n            tcp.sslversion_choices[options.ssl_version_client]\n        self.openssl_method_server, self.openssl_options_server = \\\n            tcp.sslversion_choices[options.ssl_version_server]\n\n        certstore_path = os.path.expanduser(options.cadir)\n        if not os.path.exists(os.path.dirname(certstore_path)):\n            raise exceptions.OptionsError(\n                \"Certificate Authority parent directory does not exist: %s\" %\n                os.path.dirname(options.cadir)\n            )\n        self.certstore = certutils.CertStore.from_store(\n            certstore_path,\n            CONF_BASENAME\n        )\n\n        if options.clientcerts:\n            clientcerts = os.path.expanduser(options.clientcerts)\n            if not os.path.exists(clientcerts):\n                raise exceptions.OptionsError(\n                    \"Client certificate path does not exist: %s\" %\n                    options.clientcerts\n                )\n            self.clientcerts = clientcerts\n\n        for spec, cert in options.certs:\n            cert = os.path.expanduser(cert)\n            if not os.path.exists(cert):\n                raise exceptions.OptionsError(\n                    \"Certificate file does not exist: %s\" % cert\n                )\n            try:\n                self.certstore.add_cert_file(spec, cert)\n            except crypto.Error:\n                raise exceptions.OptionsError(\n                    \"Invalid certificate format: %s\" % cert\n                )\n\n        self.upstream_server = None\n        self.upstream_auth = None\n        if options.upstream_server:\n            self.upstream_server = parse_server_spec(options.upstream_server)\n        if options.upstream_auth:\n            self.upstream_auth = parse_upstream_auth(options.upstream_auth)\n\n        self.authenticator = authentication.NullProxyAuth(None)\n        needsauth = any(\n            [\n                options.auth_nonanonymous,\n                options.auth_singleuser,\n                options.auth_htpasswd\n            ]\n        )\n        if needsauth:\n            if options.mode == \"transparent\":\n                raise exceptions.OptionsError(\n                    \"Proxy Authentication not supported in transparent mode.\"\n                )\n            elif options.mode == \"socks5\":\n                raise exceptions.OptionsError(\n                    \"Proxy Authentication not supported in SOCKS mode. \"\n                    \"https://github.com/mitmproxy/mitmproxy/issues/738\"\n                )\n            elif options.auth_singleuser:\n                parts = options.auth_singleuser.split(':')\n                if len(parts) != 2:\n                    raise exceptions.OptionsError(\n                        \"Invalid single-user specification. \"\n                        \"Please use the format username:password\"\n                    )\n                password_manager = authentication.PassManSingleUser(*parts)\n            elif options.auth_nonanonymous:\n                password_manager = authentication.PassManNonAnon()\n            elif options.auth_htpasswd:\n                try:\n                    password_manager = authentication.PassManHtpasswd(\n                        options.auth_htpasswd\n                    )\n                except ValueError as v:\n                    raise exceptions.OptionsError(str(v))\n            self.authenticator = authentication.BasicProxyAuth(\n                password_manager,\n                \"mitmproxy\"\n            )\n", "path": "mitmproxy/proxy/config.py"}]}