Establish TLS or DTLS between proxy and server.
(self, tls_start: tls.TlsData)
| 271 | tls_start.ssl_conn.set_accept_state() |
| 272 | |
| 273 | def tls_start_server(self, tls_start: tls.TlsData) -> None: |
| 274 | """Establish TLS or DTLS between proxy and server.""" |
| 275 | if tls_start.ssl_conn is not None: |
| 276 | return # a user addon has already provided the pyOpenSSL context. |
| 277 | |
| 278 | assert isinstance(tls_start.conn, connection.Server) |
| 279 | |
| 280 | client: connection.Client = tls_start.context.client |
| 281 | # tls_start.conn may be different from tls_start.context.server, e.g. an upstream HTTPS proxy. |
| 282 | server: connection.Server = tls_start.conn |
| 283 | assert server.address |
| 284 | |
| 285 | if ctx.options.ssl_insecure: |
| 286 | verify = net_tls.Verify.VERIFY_NONE |
| 287 | else: |
| 288 | verify = net_tls.Verify.VERIFY_PEER |
| 289 | |
| 290 | if server.sni is None: |
| 291 | server.sni = client.sni or server.address[0] |
| 292 | |
| 293 | if not server.alpn_offers: |
| 294 | if client.alpn_offers: |
| 295 | if ctx.options.http2: |
| 296 | # We would perfectly support HTTP/1 -> HTTP/2, but we want to keep things on the same protocol |
| 297 | # version. There are some edge cases where we want to mirror the regular server's behavior |
| 298 | # accurately, for example header capitalization. |
| 299 | server.alpn_offers = tuple(client.alpn_offers) |
| 300 | else: |
| 301 | server.alpn_offers = tuple( |
| 302 | x for x in client.alpn_offers if x != b"h2" |
| 303 | ) |
| 304 | else: |
| 305 | # We either have no client TLS or a client without ALPN. |
| 306 | # - If the client does use TLS but did not send an ALPN extension, we want to mirror that upstream. |
| 307 | # - If the client does not use TLS, there's no clear-cut answer. As a pragmatic approach, we also do |
| 308 | # not send any ALPN extension in this case, which defaults to whatever protocol we are speaking |
| 309 | # or falls back to HTTP. |
| 310 | server.alpn_offers = [] |
| 311 | |
| 312 | if not server.cipher_list and ctx.options.ciphers_server: |
| 313 | server.cipher_list = ctx.options.ciphers_server.split(":") |
| 314 | # don't assign to client.cipher_list, doesn't need to be stored. |
| 315 | cipher_list = server.cipher_list or _default_ciphers( |
| 316 | net_tls.Version[ctx.options.tls_version_server_min] |
| 317 | ) |
| 318 | |
| 319 | client_cert: str | None = None |
| 320 | if ctx.options.client_certs: |
| 321 | client_certs = os.path.expanduser(ctx.options.client_certs) |
| 322 | if os.path.isfile(client_certs): |
| 323 | client_cert = client_certs |
| 324 | else: |
| 325 | server_name: str = server.sni or server.address[0] |
| 326 | p = os.path.join(client_certs, f"{server_name}.pem") |
| 327 | if os.path.isfile(p): |
| 328 | client_cert = p |
| 329 | |
| 330 | ssl_ctx = net_tls.create_proxy_server_context( |