We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Traceback appears in Status Bar, when trying to run Mitmproxy with --proxyauth ldap (ldaps) argument
##### Steps to reproduce the problem:

Run Mitmproxy with argument: `mitmproxy --proxyauth ldap` or `mitmproxy --proxyauth ldaps`

I am seeing:
![screenshot from 2018-01-06 15-41-10](https://user-images.githubusercontent.com/20267977/34640265-0d47714c-f2f8-11e7-91c6-9bfe3a0f9eb6.png)

##### Any other comments? What have you tried so far?
This issue is occured, because mitmproxy doesn't control the syntax of ldap authentication argument. 
https://github.com/mitmproxy/mitmproxy/blob/master/mitmproxy/addons/proxyauth.py#L147-L152

##### System information

Mitmproxy: 3.0.0.dev1101 (commit d9d4d15) binary
Python:    3.5.2
OpenSSL:   OpenSSL 1.1.0g  2 Nov 2017
Platform:  Linux-4.4.0-104-generic-x86_64-with-debian-stretch-sid
  

--- 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/addons/proxyauth.py`
Content:
```
1 import binascii
2 import weakref
3 import ldap3
4 from typing import Optional
5 from typing import MutableMapping  # noqa
6 from typing import Tuple
7 
8 import passlib.apache
9 
10 import mitmproxy.net.http
11 from mitmproxy import connections  # noqa
12 from mitmproxy import exceptions
13 from mitmproxy import http
14 from mitmproxy import ctx
15 from mitmproxy.net.http import status_codes
16 
17 REALM = "mitmproxy"
18 
19 
20 def mkauth(username: str, password: str, scheme: str = "basic") -> str:
21     """
22     Craft a basic auth string
23     """
24     v = binascii.b2a_base64(
25         (username + ":" + password).encode("utf8")
26     ).decode("ascii")
27     return scheme + " " + v
28 
29 
30 def parse_http_basic_auth(s: str) -> Tuple[str, str, str]:
31     """
32     Parse a basic auth header.
33     Raises a ValueError if the input is invalid.
34     """
35     scheme, authinfo = s.split()
36     if scheme.lower() != "basic":
37         raise ValueError("Unknown scheme")
38     try:
39         user, password = binascii.a2b_base64(authinfo.encode()).decode("utf8", "replace").split(":")
40     except binascii.Error as e:
41         raise ValueError(str(e))
42     return scheme, user, password
43 
44 
45 class ProxyAuth:
46     def __init__(self):
47         self.nonanonymous = False
48         self.htpasswd = None
49         self.singleuser = None
50         self.ldapconn = None
51         self.ldapserver = None
52         self.authenticated = weakref.WeakKeyDictionary()  # type: MutableMapping[connections.ClientConnection, Tuple[str, str]]
53         """Contains all connections that are permanently authenticated after an HTTP CONNECT"""
54 
55     def enabled(self) -> bool:
56         return any([self.nonanonymous, self.htpasswd, self.singleuser, self.ldapconn, self.ldapserver])
57 
58     def is_proxy_auth(self) -> bool:
59         """
60         Returns:
61             - True, if authentication is done as if mitmproxy is a proxy
62             - False, if authentication is done as if mitmproxy is a HTTP server
63         """
64         return ctx.options.mode == "regular" or ctx.options.mode.startswith("upstream:")
65 
66     def which_auth_header(self) -> str:
67         if self.is_proxy_auth():
68             return 'Proxy-Authorization'
69         else:
70             return 'Authorization'
71 
72     def auth_required_response(self) -> http.HTTPResponse:
73         if self.is_proxy_auth():
74             return http.make_error_response(
75                 status_codes.PROXY_AUTH_REQUIRED,
76                 headers=mitmproxy.net.http.Headers(Proxy_Authenticate='Basic realm="{}"'.format(REALM)),
77             )
78         else:
79             return http.make_error_response(
80                 status_codes.UNAUTHORIZED,
81                 headers=mitmproxy.net.http.Headers(WWW_Authenticate='Basic realm="{}"'.format(REALM)),
82             )
83 
84     def check(self, f: http.HTTPFlow) -> Optional[Tuple[str, str]]:
85         """
86         Check if a request is correctly authenticated.
87         Returns:
88             - a (username, password) tuple if successful,
89             - None, otherwise.
90         """
91         auth_value = f.request.headers.get(self.which_auth_header(), "")
92         try:
93             scheme, username, password = parse_http_basic_auth(auth_value)
94         except ValueError:
95             return None
96 
97         if self.nonanonymous:
98             return username, password
99         elif self.singleuser:
100             if self.singleuser == [username, password]:
101                 return username, password
102         elif self.htpasswd:
103             if self.htpasswd.check_password(username, password):
104                 return username, password
105         elif self.ldapconn:
106             if not username or not password:
107                 return None
108             self.ldapconn.search(ctx.options.proxyauth.split(':')[4], '(cn=' + username + ')')
109             if self.ldapconn.response:
110                 conn = ldap3.Connection(
111                     self.ldapserver,
112                     self.ldapconn.response[0]['dn'],
113                     password,
114                     auto_bind=True)
115                 if conn:
116                     return username, password
117         return None
118 
119     def authenticate(self, f: http.HTTPFlow) -> bool:
120         valid_credentials = self.check(f)
121         if valid_credentials:
122             f.metadata["proxyauth"] = valid_credentials
123             del f.request.headers[self.which_auth_header()]
124             return True
125         else:
126             f.response = self.auth_required_response()
127             return False
128 
129     # Handlers
130     def configure(self, updated):
131         if "proxyauth" in updated:
132             self.nonanonymous = False
133             self.singleuser = None
134             self.htpasswd = None
135             self.ldapserver = None
136             if ctx.options.proxyauth:
137                 if ctx.options.proxyauth == "any":
138                     self.nonanonymous = True
139                 elif ctx.options.proxyauth.startswith("@"):
140                     p = ctx.options.proxyauth[1:]
141                     try:
142                         self.htpasswd = passlib.apache.HtpasswdFile(p)
143                     except (ValueError, OSError) as v:
144                         raise exceptions.OptionsError(
145                             "Could not open htpasswd file: %s" % p
146                         )
147                 elif ctx.options.proxyauth.startswith("ldap"):
148                     parts = ctx.options.proxyauth.split(':')
149                     security = parts[0]
150                     ldap_server = parts[1]
151                     dn_baseauth = parts[2]
152                     password_baseauth = parts[3]
153                     if len(parts) != 5:
154                         raise exceptions.OptionsError(
155                             "Invalid ldap specification"
156                         )
157                     if security == "ldaps":
158                         server = ldap3.Server(ldap_server, use_ssl=True)
159                     elif security == "ldap":
160                         server = ldap3.Server(ldap_server)
161                     else:
162                         raise exceptions.OptionsError(
163                             "Invalid ldap specfication on the first part"
164                         )
165                     conn = ldap3.Connection(
166                         server,
167                         dn_baseauth,
168                         password_baseauth,
169                         auto_bind=True)
170                     self.ldapconn = conn
171                     self.ldapserver = server
172                 else:
173                     parts = ctx.options.proxyauth.split(':')
174                     if len(parts) != 2:
175                         raise exceptions.OptionsError(
176                             "Invalid single-user auth specification."
177                         )
178                     self.singleuser = parts
179         if self.enabled():
180             if ctx.options.mode == "transparent":
181                 raise exceptions.OptionsError(
182                     "Proxy Authentication not supported in transparent mode."
183                 )
184             if ctx.options.mode == "socks5":
185                 raise exceptions.OptionsError(
186                     "Proxy Authentication not supported in SOCKS mode. "
187                     "https://github.com/mitmproxy/mitmproxy/issues/738"
188                 )
189                 # TODO: check for multiple auth options
190 
191     def http_connect(self, f: http.HTTPFlow) -> None:
192         if self.enabled():
193             if self.authenticate(f):
194                 self.authenticated[f.client_conn] = f.metadata["proxyauth"]
195 
196     def requestheaders(self, f: http.HTTPFlow) -> None:
197         if self.enabled():
198             # Is this connection authenticated by a previous HTTP CONNECT?
199             if f.client_conn in self.authenticated:
200                 f.metadata["proxyauth"] = self.authenticated[f.client_conn]
201                 return
202             self.authenticate(f)
203
```
--- 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/addons/proxyauth.py b/mitmproxy/addons/proxyauth.py
--- a/mitmproxy/addons/proxyauth.py
+++ b/mitmproxy/addons/proxyauth.py
@@ -146,14 +146,14 @@
                         )
                 elif ctx.options.proxyauth.startswith("ldap"):
                     parts = ctx.options.proxyauth.split(':')
-                    security = parts[0]
-                    ldap_server = parts[1]
-                    dn_baseauth = parts[2]
-                    password_baseauth = parts[3]
                     if len(parts) != 5:
                         raise exceptions.OptionsError(
                             "Invalid ldap specification"
                         )
+                    security = parts[0]
+                    ldap_server = parts[1]
+                    dn_baseauth = parts[2]
+                    password_baseauth = parts[3]
                     if security == "ldaps":
                         server = ldap3.Server(ldap_server, use_ssl=True)
                     elif security == "ldap":

{"golden_diff": "diff --git a/mitmproxy/addons/proxyauth.py b/mitmproxy/addons/proxyauth.py\n--- a/mitmproxy/addons/proxyauth.py\n+++ b/mitmproxy/addons/proxyauth.py\n@@ -146,14 +146,14 @@\n                         )\n                 elif ctx.options.proxyauth.startswith(\"ldap\"):\n                     parts = ctx.options.proxyauth.split(':')\n-                    security = parts[0]\n-                    ldap_server = parts[1]\n-                    dn_baseauth = parts[2]\n-                    password_baseauth = parts[3]\n                     if len(parts) != 5:\n                         raise exceptions.OptionsError(\n                             \"Invalid ldap specification\"\n                         )\n+                    security = parts[0]\n+                    ldap_server = parts[1]\n+                    dn_baseauth = parts[2]\n+                    password_baseauth = parts[3]\n                     if security == \"ldaps\":\n                         server = ldap3.Server(ldap_server, use_ssl=True)\n                     elif security == \"ldap\":\n", "issue": "Traceback appears in Status Bar, when trying to run Mitmproxy with --proxyauth ldap (ldaps) argument\n##### Steps to reproduce the problem:\r\n\r\nRun Mitmproxy with argument: `mitmproxy --proxyauth ldap` or `mitmproxy --proxyauth ldaps`\r\n\r\nI am seeing:\r\n![screenshot from 2018-01-06 15-41-10](https://user-images.githubusercontent.com/20267977/34640265-0d47714c-f2f8-11e7-91c6-9bfe3a0f9eb6.png)\r\n\r\n##### Any other comments? What have you tried so far?\r\nThis issue is occured, because mitmproxy doesn't control the syntax of ldap authentication argument. \r\nhttps://github.com/mitmproxy/mitmproxy/blob/master/mitmproxy/addons/proxyauth.py#L147-L152\r\n\r\n##### System information\r\n\r\nMitmproxy: 3.0.0.dev1101 (commit d9d4d15) binary\r\nPython:    3.5.2\r\nOpenSSL:   OpenSSL 1.1.0g  2 Nov 2017\r\nPlatform:  Linux-4.4.0-104-generic-x86_64-with-debian-stretch-sid\r\n  \n", "before_files": [{"content": "import binascii\nimport weakref\nimport ldap3\nfrom typing import Optional\nfrom typing import MutableMapping  # noqa\nfrom typing import Tuple\n\nimport passlib.apache\n\nimport mitmproxy.net.http\nfrom mitmproxy import connections  # noqa\nfrom mitmproxy import exceptions\nfrom mitmproxy import http\nfrom mitmproxy import ctx\nfrom mitmproxy.net.http import status_codes\n\nREALM = \"mitmproxy\"\n\n\ndef mkauth(username: str, password: str, scheme: str = \"basic\") -> str:\n    \"\"\"\n    Craft a basic auth string\n    \"\"\"\n    v = binascii.b2a_base64(\n        (username + \":\" + password).encode(\"utf8\")\n    ).decode(\"ascii\")\n    return scheme + \" \" + v\n\n\ndef parse_http_basic_auth(s: str) -> Tuple[str, str, str]:\n    \"\"\"\n    Parse a basic auth header.\n    Raises a ValueError if the input is invalid.\n    \"\"\"\n    scheme, authinfo = s.split()\n    if scheme.lower() != \"basic\":\n        raise ValueError(\"Unknown scheme\")\n    try:\n        user, password = binascii.a2b_base64(authinfo.encode()).decode(\"utf8\", \"replace\").split(\":\")\n    except binascii.Error as e:\n        raise ValueError(str(e))\n    return scheme, user, password\n\n\nclass ProxyAuth:\n    def __init__(self):\n        self.nonanonymous = False\n        self.htpasswd = None\n        self.singleuser = None\n        self.ldapconn = None\n        self.ldapserver = None\n        self.authenticated = weakref.WeakKeyDictionary()  # type: MutableMapping[connections.ClientConnection, Tuple[str, str]]\n        \"\"\"Contains all connections that are permanently authenticated after an HTTP CONNECT\"\"\"\n\n    def enabled(self) -> bool:\n        return any([self.nonanonymous, self.htpasswd, self.singleuser, self.ldapconn, self.ldapserver])\n\n    def is_proxy_auth(self) -> bool:\n        \"\"\"\n        Returns:\n            - True, if authentication is done as if mitmproxy is a proxy\n            - False, if authentication is done as if mitmproxy is a HTTP server\n        \"\"\"\n        return ctx.options.mode == \"regular\" or ctx.options.mode.startswith(\"upstream:\")\n\n    def which_auth_header(self) -> str:\n        if self.is_proxy_auth():\n            return 'Proxy-Authorization'\n        else:\n            return 'Authorization'\n\n    def auth_required_response(self) -> http.HTTPResponse:\n        if self.is_proxy_auth():\n            return http.make_error_response(\n                status_codes.PROXY_AUTH_REQUIRED,\n                headers=mitmproxy.net.http.Headers(Proxy_Authenticate='Basic realm=\"{}\"'.format(REALM)),\n            )\n        else:\n            return http.make_error_response(\n                status_codes.UNAUTHORIZED,\n                headers=mitmproxy.net.http.Headers(WWW_Authenticate='Basic realm=\"{}\"'.format(REALM)),\n            )\n\n    def check(self, f: http.HTTPFlow) -> Optional[Tuple[str, str]]:\n        \"\"\"\n        Check if a request is correctly authenticated.\n        Returns:\n            - a (username, password) tuple if successful,\n            - None, otherwise.\n        \"\"\"\n        auth_value = f.request.headers.get(self.which_auth_header(), \"\")\n        try:\n            scheme, username, password = parse_http_basic_auth(auth_value)\n        except ValueError:\n            return None\n\n        if self.nonanonymous:\n            return username, password\n        elif self.singleuser:\n            if self.singleuser == [username, password]:\n                return username, password\n        elif self.htpasswd:\n            if self.htpasswd.check_password(username, password):\n                return username, password\n        elif self.ldapconn:\n            if not username or not password:\n                return None\n            self.ldapconn.search(ctx.options.proxyauth.split(':')[4], '(cn=' + username + ')')\n            if self.ldapconn.response:\n                conn = ldap3.Connection(\n                    self.ldapserver,\n                    self.ldapconn.response[0]['dn'],\n                    password,\n                    auto_bind=True)\n                if conn:\n                    return username, password\n        return None\n\n    def authenticate(self, f: http.HTTPFlow) -> bool:\n        valid_credentials = self.check(f)\n        if valid_credentials:\n            f.metadata[\"proxyauth\"] = valid_credentials\n            del f.request.headers[self.which_auth_header()]\n            return True\n        else:\n            f.response = self.auth_required_response()\n            return False\n\n    # Handlers\n    def configure(self, updated):\n        if \"proxyauth\" in updated:\n            self.nonanonymous = False\n            self.singleuser = None\n            self.htpasswd = None\n            self.ldapserver = None\n            if ctx.options.proxyauth:\n                if ctx.options.proxyauth == \"any\":\n                    self.nonanonymous = True\n                elif ctx.options.proxyauth.startswith(\"@\"):\n                    p = ctx.options.proxyauth[1:]\n                    try:\n                        self.htpasswd = passlib.apache.HtpasswdFile(p)\n                    except (ValueError, OSError) as v:\n                        raise exceptions.OptionsError(\n                            \"Could not open htpasswd file: %s\" % p\n                        )\n                elif ctx.options.proxyauth.startswith(\"ldap\"):\n                    parts = ctx.options.proxyauth.split(':')\n                    security = parts[0]\n                    ldap_server = parts[1]\n                    dn_baseauth = parts[2]\n                    password_baseauth = parts[3]\n                    if len(parts) != 5:\n                        raise exceptions.OptionsError(\n                            \"Invalid ldap specification\"\n                        )\n                    if security == \"ldaps\":\n                        server = ldap3.Server(ldap_server, use_ssl=True)\n                    elif security == \"ldap\":\n                        server = ldap3.Server(ldap_server)\n                    else:\n                        raise exceptions.OptionsError(\n                            \"Invalid ldap specfication on the first part\"\n                        )\n                    conn = ldap3.Connection(\n                        server,\n                        dn_baseauth,\n                        password_baseauth,\n                        auto_bind=True)\n                    self.ldapconn = conn\n                    self.ldapserver = server\n                else:\n                    parts = ctx.options.proxyauth.split(':')\n                    if len(parts) != 2:\n                        raise exceptions.OptionsError(\n                            \"Invalid single-user auth specification.\"\n                        )\n                    self.singleuser = parts\n        if self.enabled():\n            if ctx.options.mode == \"transparent\":\n                raise exceptions.OptionsError(\n                    \"Proxy Authentication not supported in transparent mode.\"\n                )\n            if ctx.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                # TODO: check for multiple auth options\n\n    def http_connect(self, f: http.HTTPFlow) -> None:\n        if self.enabled():\n            if self.authenticate(f):\n                self.authenticated[f.client_conn] = f.metadata[\"proxyauth\"]\n\n    def requestheaders(self, f: http.HTTPFlow) -> None:\n        if self.enabled():\n            # Is this connection authenticated by a previous HTTP CONNECT?\n            if f.client_conn in self.authenticated:\n                f.metadata[\"proxyauth\"] = self.authenticated[f.client_conn]\n                return\n            self.authenticate(f)\n", "path": "mitmproxy/addons/proxyauth.py"}], "after_files": [{"content": "import binascii\nimport weakref\nimport ldap3\nfrom typing import Optional\nfrom typing import MutableMapping  # noqa\nfrom typing import Tuple\n\nimport passlib.apache\n\nimport mitmproxy.net.http\nfrom mitmproxy import connections  # noqa\nfrom mitmproxy import exceptions\nfrom mitmproxy import http\nfrom mitmproxy import ctx\nfrom mitmproxy.net.http import status_codes\n\nREALM = \"mitmproxy\"\n\n\ndef mkauth(username: str, password: str, scheme: str = \"basic\") -> str:\n    \"\"\"\n    Craft a basic auth string\n    \"\"\"\n    v = binascii.b2a_base64(\n        (username + \":\" + password).encode(\"utf8\")\n    ).decode(\"ascii\")\n    return scheme + \" \" + v\n\n\ndef parse_http_basic_auth(s: str) -> Tuple[str, str, str]:\n    \"\"\"\n    Parse a basic auth header.\n    Raises a ValueError if the input is invalid.\n    \"\"\"\n    scheme, authinfo = s.split()\n    if scheme.lower() != \"basic\":\n        raise ValueError(\"Unknown scheme\")\n    try:\n        user, password = binascii.a2b_base64(authinfo.encode()).decode(\"utf8\", \"replace\").split(\":\")\n    except binascii.Error as e:\n        raise ValueError(str(e))\n    return scheme, user, password\n\n\nclass ProxyAuth:\n    def __init__(self):\n        self.nonanonymous = False\n        self.htpasswd = None\n        self.singleuser = None\n        self.ldapconn = None\n        self.ldapserver = None\n        self.authenticated = weakref.WeakKeyDictionary()  # type: MutableMapping[connections.ClientConnection, Tuple[str, str]]\n        \"\"\"Contains all connections that are permanently authenticated after an HTTP CONNECT\"\"\"\n\n    def enabled(self) -> bool:\n        return any([self.nonanonymous, self.htpasswd, self.singleuser, self.ldapconn, self.ldapserver])\n\n    def is_proxy_auth(self) -> bool:\n        \"\"\"\n        Returns:\n            - True, if authentication is done as if mitmproxy is a proxy\n            - False, if authentication is done as if mitmproxy is a HTTP server\n        \"\"\"\n        return ctx.options.mode == \"regular\" or ctx.options.mode.startswith(\"upstream:\")\n\n    def which_auth_header(self) -> str:\n        if self.is_proxy_auth():\n            return 'Proxy-Authorization'\n        else:\n            return 'Authorization'\n\n    def auth_required_response(self) -> http.HTTPResponse:\n        if self.is_proxy_auth():\n            return http.make_error_response(\n                status_codes.PROXY_AUTH_REQUIRED,\n                headers=mitmproxy.net.http.Headers(Proxy_Authenticate='Basic realm=\"{}\"'.format(REALM)),\n            )\n        else:\n            return http.make_error_response(\n                status_codes.UNAUTHORIZED,\n                headers=mitmproxy.net.http.Headers(WWW_Authenticate='Basic realm=\"{}\"'.format(REALM)),\n            )\n\n    def check(self, f: http.HTTPFlow) -> Optional[Tuple[str, str]]:\n        \"\"\"\n        Check if a request is correctly authenticated.\n        Returns:\n            - a (username, password) tuple if successful,\n            - None, otherwise.\n        \"\"\"\n        auth_value = f.request.headers.get(self.which_auth_header(), \"\")\n        try:\n            scheme, username, password = parse_http_basic_auth(auth_value)\n        except ValueError:\n            return None\n\n        if self.nonanonymous:\n            return username, password\n        elif self.singleuser:\n            if self.singleuser == [username, password]:\n                return username, password\n        elif self.htpasswd:\n            if self.htpasswd.check_password(username, password):\n                return username, password\n        elif self.ldapconn:\n            if not username or not password:\n                return None\n            self.ldapconn.search(ctx.options.proxyauth.split(':')[4], '(cn=' + username + ')')\n            if self.ldapconn.response:\n                conn = ldap3.Connection(\n                    self.ldapserver,\n                    self.ldapconn.response[0]['dn'],\n                    password,\n                    auto_bind=True)\n                if conn:\n                    return username, password\n        return None\n\n    def authenticate(self, f: http.HTTPFlow) -> bool:\n        valid_credentials = self.check(f)\n        if valid_credentials:\n            f.metadata[\"proxyauth\"] = valid_credentials\n            del f.request.headers[self.which_auth_header()]\n            return True\n        else:\n            f.response = self.auth_required_response()\n            return False\n\n    # Handlers\n    def configure(self, updated):\n        if \"proxyauth\" in updated:\n            self.nonanonymous = False\n            self.singleuser = None\n            self.htpasswd = None\n            self.ldapserver = None\n            if ctx.options.proxyauth:\n                if ctx.options.proxyauth == \"any\":\n                    self.nonanonymous = True\n                elif ctx.options.proxyauth.startswith(\"@\"):\n                    p = ctx.options.proxyauth[1:]\n                    try:\n                        self.htpasswd = passlib.apache.HtpasswdFile(p)\n                    except (ValueError, OSError) as v:\n                        raise exceptions.OptionsError(\n                            \"Could not open htpasswd file: %s\" % p\n                        )\n                elif ctx.options.proxyauth.startswith(\"ldap\"):\n                    parts = ctx.options.proxyauth.split(':')\n                    if len(parts) != 5:\n                        raise exceptions.OptionsError(\n                            \"Invalid ldap specification\"\n                        )\n                    security = parts[0]\n                    ldap_server = parts[1]\n                    dn_baseauth = parts[2]\n                    password_baseauth = parts[3]\n                    if security == \"ldaps\":\n                        server = ldap3.Server(ldap_server, use_ssl=True)\n                    elif security == \"ldap\":\n                        server = ldap3.Server(ldap_server)\n                    else:\n                        raise exceptions.OptionsError(\n                            \"Invalid ldap specfication on the first part\"\n                        )\n                    conn = ldap3.Connection(\n                        server,\n                        dn_baseauth,\n                        password_baseauth,\n                        auto_bind=True)\n                    self.ldapconn = conn\n                    self.ldapserver = server\n                else:\n                    parts = ctx.options.proxyauth.split(':')\n                    if len(parts) != 2:\n                        raise exceptions.OptionsError(\n                            \"Invalid single-user auth specification.\"\n                        )\n                    self.singleuser = parts\n        if self.enabled():\n            if ctx.options.mode == \"transparent\":\n                raise exceptions.OptionsError(\n                    \"Proxy Authentication not supported in transparent mode.\"\n                )\n            if ctx.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                # TODO: check for multiple auth options\n\n    def http_connect(self, f: http.HTTPFlow) -> None:\n        if self.enabled():\n            if self.authenticate(f):\n                self.authenticated[f.client_conn] = f.metadata[\"proxyauth\"]\n\n    def requestheaders(self, f: http.HTTPFlow) -> None:\n        if self.enabled():\n            # Is this connection authenticated by a previous HTTP CONNECT?\n            if f.client_conn in self.authenticated:\n                f.metadata[\"proxyauth\"] = self.authenticated[f.client_conn]\n                return\n            self.authenticate(f)\n", "path": "mitmproxy/addons/proxyauth.py"}]}