We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
synapse fails to start under Twisted >= 18.4
Looks like we are relying on a private identifier which has been removed in Twisted 18.4:

```
Traceback (most recent call last):
  File "/usr/lib/python2.7/runpy.py", line 174, in _run_module_as_main
    "__main__", fname, loader, pkg_name)
  File "/usr/lib/python2.7/runpy.py", line 72, in _run_code
    exec code in run_globals
  File "/home/rav/work/synapse/synapse/app/homeserver.py", line 31, in <module>
    from synapse.crypto import context_factory
  File "synapse/crypto/context_factory.py", line 17, in <module>
    from twisted.internet._sslverify import _OpenSSLECCurve, _defaultCurveName
ImportError: cannot import name _OpenSSLECCurve
```
synapse fails to start under Twisted >= 18.4
Looks like we are relying on a private identifier which has been removed in Twisted 18.4:

```
Traceback (most recent call last):
  File "/usr/lib/python2.7/runpy.py", line 174, in _run_module_as_main
    "__main__", fname, loader, pkg_name)
  File "/usr/lib/python2.7/runpy.py", line 72, in _run_code
    exec code in run_globals
  File "/home/rav/work/synapse/synapse/app/homeserver.py", line 31, in <module>
    from synapse.crypto import context_factory
  File "synapse/crypto/context_factory.py", line 17, in <module>
    from twisted.internet._sslverify import _OpenSSLECCurve, _defaultCurveName
ImportError: cannot import name _OpenSSLECCurve
```

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `synapse/crypto/context_factory.py`
Content:
```
1 # Copyright 2014-2016 OpenMarket Ltd
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 #     http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14 
15 from twisted.internet import ssl
16 from OpenSSL import SSL
17 from twisted.internet._sslverify import _OpenSSLECCurve, _defaultCurveName
18 
19 import logging
20 
21 logger = logging.getLogger(__name__)
22 
23 
24 class ServerContextFactory(ssl.ContextFactory):
25     """Factory for PyOpenSSL SSL contexts that are used to handle incoming
26     connections and to make connections to remote servers."""
27 
28     def __init__(self, config):
29         self._context = SSL.Context(SSL.SSLv23_METHOD)
30         self.configure_context(self._context, config)
31 
32     @staticmethod
33     def configure_context(context, config):
34         try:
35             _ecCurve = _OpenSSLECCurve(_defaultCurveName)
36             _ecCurve.addECKeyToContext(context)
37         except Exception:
38             logger.exception("Failed to enable elliptic curve for TLS")
39         context.set_options(SSL.OP_NO_SSLv2 | SSL.OP_NO_SSLv3)
40         context.use_certificate_chain_file(config.tls_certificate_file)
41 
42         if not config.no_tls:
43             context.use_privatekey(config.tls_private_key)
44 
45         context.load_tmp_dh(config.tls_dh_params_path)
46         context.set_cipher_list("!ADH:HIGH+kEDH:!AECDH:HIGH+kEECDH")
47 
48     def getContext(self):
49         return self._context
50
```

Path: `synapse/python_dependencies.py`
Content:
```
1 # Copyright 2015, 2016 OpenMarket Ltd
2 # Copyright 2017 Vector Creations Ltd
3 # Copyright 2018 New Vector Ltd
4 #
5 # Licensed under the Apache License, Version 2.0 (the "License");
6 # you may not use this file except in compliance with the License.
7 # You may obtain a copy of the License at
8 #
9 #     http://www.apache.org/licenses/LICENSE-2.0
10 #
11 # Unless required by applicable law or agreed to in writing, software
12 # distributed under the License is distributed on an "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 # See the License for the specific language governing permissions and
15 # limitations under the License.
16 
17 import logging
18 from distutils.version import LooseVersion
19 
20 logger = logging.getLogger(__name__)
21 
22 # this dict maps from python package name to a list of modules we expect it to
23 # provide.
24 #
25 # the key is a "requirement specifier", as used as a parameter to `pip
26 # install`[1], or an `install_requires` argument to `setuptools.setup` [2].
27 #
28 # the value is a sequence of strings; each entry should be the name of the
29 # python module, optionally followed by a version assertion which can be either
30 # ">=<ver>" or "==<ver>".
31 #
32 # [1] https://pip.pypa.io/en/stable/reference/pip_install/#requirement-specifiers.
33 # [2] https://setuptools.readthedocs.io/en/latest/setuptools.html#declaring-dependencies
34 REQUIREMENTS = {
35     "jsonschema>=2.5.1": ["jsonschema>=2.5.1"],
36     "frozendict>=0.4": ["frozendict"],
37     "unpaddedbase64>=1.1.0": ["unpaddedbase64>=1.1.0"],
38     "canonicaljson>=1.1.3": ["canonicaljson>=1.1.3"],
39     "signedjson>=1.0.0": ["signedjson>=1.0.0"],
40     "pynacl>=1.2.1": ["nacl>=1.2.1", "nacl.bindings"],
41     "service_identity>=1.0.0": ["service_identity>=1.0.0"],
42 
43     # we break under Twisted 18.4
44     # (https://github.com/matrix-org/synapse/issues/3135)
45     "Twisted>=16.0.0,<18.4": ["twisted>=16.0.0"],
46 
47     "pyopenssl>=0.14": ["OpenSSL>=0.14"],
48     "pyyaml": ["yaml"],
49     "pyasn1": ["pyasn1"],
50     "daemonize": ["daemonize"],
51     "bcrypt": ["bcrypt>=3.1.0"],
52     "pillow": ["PIL"],
53     "pydenticon": ["pydenticon"],
54     "blist": ["blist"],
55     "pysaml2>=3.0.0": ["saml2>=3.0.0"],
56     "pymacaroons-pynacl": ["pymacaroons"],
57     "msgpack-python>=0.3.0": ["msgpack"],
58     "phonenumbers>=8.2.0": ["phonenumbers"],
59     "six": ["six"],
60 }
61 CONDITIONAL_REQUIREMENTS = {
62     "web_client": {
63         "matrix_angular_sdk>=0.6.8": ["syweb>=0.6.8"],
64     },
65     "preview_url": {
66         "netaddr>=0.7.18": ["netaddr"],
67     },
68     "email.enable_notifs": {
69         "Jinja2>=2.8": ["Jinja2>=2.8"],
70         "bleach>=1.4.2": ["bleach>=1.4.2"],
71     },
72     "matrix-synapse-ldap3": {
73         "matrix-synapse-ldap3>=0.1": ["ldap_auth_provider"],
74     },
75     "psutil": {
76         "psutil>=2.0.0": ["psutil>=2.0.0"],
77     },
78     "affinity": {
79         "affinity": ["affinity"],
80     },
81 }
82 
83 
84 def requirements(config=None, include_conditional=False):
85     reqs = REQUIREMENTS.copy()
86     if include_conditional:
87         for _, req in CONDITIONAL_REQUIREMENTS.items():
88             reqs.update(req)
89     return reqs
90 
91 
92 def github_link(project, version, egg):
93     return "https://github.com/%s/tarball/%s/#egg=%s" % (project, version, egg)
94 
95 
96 DEPENDENCY_LINKS = {
97 }
98 
99 
100 class MissingRequirementError(Exception):
101     def __init__(self, message, module_name, dependency):
102         super(MissingRequirementError, self).__init__(message)
103         self.module_name = module_name
104         self.dependency = dependency
105 
106 
107 def check_requirements(config=None):
108     """Checks that all the modules needed by synapse have been correctly
109     installed and are at the correct version"""
110     for dependency, module_requirements in (
111             requirements(config, include_conditional=False).items()):
112         for module_requirement in module_requirements:
113             if ">=" in module_requirement:
114                 module_name, required_version = module_requirement.split(">=")
115                 version_test = ">="
116             elif "==" in module_requirement:
117                 module_name, required_version = module_requirement.split("==")
118                 version_test = "=="
119             else:
120                 module_name = module_requirement
121                 version_test = None
122 
123             try:
124                 module = __import__(module_name)
125             except ImportError:
126                 logging.exception(
127                     "Can't import %r which is part of %r",
128                     module_name, dependency
129                 )
130                 raise MissingRequirementError(
131                     "Can't import %r which is part of %r"
132                     % (module_name, dependency), module_name, dependency
133                 )
134             version = getattr(module, "__version__", None)
135             file_path = getattr(module, "__file__", None)
136             logger.info(
137                 "Using %r version %r from %r to satisfy %r",
138                 module_name, version, file_path, dependency
139             )
140 
141             if version_test == ">=":
142                 if version is None:
143                     raise MissingRequirementError(
144                         "Version of %r isn't set as __version__ of module %r"
145                         % (dependency, module_name), module_name, dependency
146                     )
147                 if LooseVersion(version) < LooseVersion(required_version):
148                     raise MissingRequirementError(
149                         "Version of %r in %r is too old. %r < %r"
150                         % (dependency, file_path, version, required_version),
151                         module_name, dependency
152                     )
153             elif version_test == "==":
154                 if version is None:
155                     raise MissingRequirementError(
156                         "Version of %r isn't set as __version__ of module %r"
157                         % (dependency, module_name), module_name, dependency
158                     )
159                 if LooseVersion(version) != LooseVersion(required_version):
160                     raise MissingRequirementError(
161                         "Unexpected version of %r in %r. %r != %r"
162                         % (dependency, file_path, version, required_version),
163                         module_name, dependency
164                     )
165 
166 
167 def list_requirements():
168     result = []
169     linked = []
170     for link in DEPENDENCY_LINKS.values():
171         egg = link.split("#egg=")[1]
172         linked.append(egg.split('-')[0])
173         result.append(link)
174     for requirement in requirements(include_conditional=True):
175         is_linked = False
176         for link in linked:
177             if requirement.replace('-', '_').startswith(link):
178                 is_linked = True
179         if not is_linked:
180             result.append(requirement)
181     return result
182 
183 
184 if __name__ == "__main__":
185     import sys
186     sys.stdout.writelines(req + "\n" for req in list_requirements())
187
```
--- 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/synapse/crypto/context_factory.py b/synapse/crypto/context_factory.py
--- a/synapse/crypto/context_factory.py
+++ b/synapse/crypto/context_factory.py
@@ -13,8 +13,8 @@
 # limitations under the License.
 
 from twisted.internet import ssl
-from OpenSSL import SSL
-from twisted.internet._sslverify import _OpenSSLECCurve, _defaultCurveName
+from OpenSSL import SSL, crypto
+from twisted.internet._sslverify import _defaultCurveName
 
 import logging
 
@@ -32,8 +32,9 @@
     @staticmethod
     def configure_context(context, config):
         try:
-            _ecCurve = _OpenSSLECCurve(_defaultCurveName)
-            _ecCurve.addECKeyToContext(context)
+            _ecCurve = crypto.get_elliptic_curve(_defaultCurveName)
+            context.set_tmp_ecdh(_ecCurve)
+
         except Exception:
             logger.exception("Failed to enable elliptic curve for TLS")
         context.set_options(SSL.OP_NO_SSLv2 | SSL.OP_NO_SSLv3)
diff --git a/synapse/python_dependencies.py b/synapse/python_dependencies.py
--- a/synapse/python_dependencies.py
+++ b/synapse/python_dependencies.py
@@ -39,12 +39,11 @@
     "signedjson>=1.0.0": ["signedjson>=1.0.0"],
     "pynacl>=1.2.1": ["nacl>=1.2.1", "nacl.bindings"],
     "service_identity>=1.0.0": ["service_identity>=1.0.0"],
+    "Twisted>=16.0.0": ["twisted>=16.0.0"],
 
-    # we break under Twisted 18.4
-    # (https://github.com/matrix-org/synapse/issues/3135)
-    "Twisted>=16.0.0,<18.4": ["twisted>=16.0.0"],
+    # We use crypto.get_elliptic_curve which is only supported in >=0.15
+    "pyopenssl>=0.15": ["OpenSSL>=0.15"],
 
-    "pyopenssl>=0.14": ["OpenSSL>=0.14"],
     "pyyaml": ["yaml"],
     "pyasn1": ["pyasn1"],
     "daemonize": ["daemonize"],

{"golden_diff": "diff --git a/synapse/crypto/context_factory.py b/synapse/crypto/context_factory.py\n--- a/synapse/crypto/context_factory.py\n+++ b/synapse/crypto/context_factory.py\n@@ -13,8 +13,8 @@\n # limitations under the License.\n \n from twisted.internet import ssl\n-from OpenSSL import SSL\n-from twisted.internet._sslverify import _OpenSSLECCurve, _defaultCurveName\n+from OpenSSL import SSL, crypto\n+from twisted.internet._sslverify import _defaultCurveName\n \n import logging\n \n@@ -32,8 +32,9 @@\n     @staticmethod\n     def configure_context(context, config):\n         try:\n-            _ecCurve = _OpenSSLECCurve(_defaultCurveName)\n-            _ecCurve.addECKeyToContext(context)\n+            _ecCurve = crypto.get_elliptic_curve(_defaultCurveName)\n+            context.set_tmp_ecdh(_ecCurve)\n+\n         except Exception:\n             logger.exception(\"Failed to enable elliptic curve for TLS\")\n         context.set_options(SSL.OP_NO_SSLv2 | SSL.OP_NO_SSLv3)\ndiff --git a/synapse/python_dependencies.py b/synapse/python_dependencies.py\n--- a/synapse/python_dependencies.py\n+++ b/synapse/python_dependencies.py\n@@ -39,12 +39,11 @@\n     \"signedjson>=1.0.0\": [\"signedjson>=1.0.0\"],\n     \"pynacl>=1.2.1\": [\"nacl>=1.2.1\", \"nacl.bindings\"],\n     \"service_identity>=1.0.0\": [\"service_identity>=1.0.0\"],\n+    \"Twisted>=16.0.0\": [\"twisted>=16.0.0\"],\n \n-    # we break under Twisted 18.4\n-    # (https://github.com/matrix-org/synapse/issues/3135)\n-    \"Twisted>=16.0.0,<18.4\": [\"twisted>=16.0.0\"],\n+    # We use crypto.get_elliptic_curve which is only supported in >=0.15\n+    \"pyopenssl>=0.15\": [\"OpenSSL>=0.15\"],\n \n-    \"pyopenssl>=0.14\": [\"OpenSSL>=0.14\"],\n     \"pyyaml\": [\"yaml\"],\n     \"pyasn1\": [\"pyasn1\"],\n     \"daemonize\": [\"daemonize\"],\n", "issue": "synapse fails to start under Twisted >= 18.4\nLooks like we are relying on a private identifier which has been removed in Twisted 18.4:\r\n\r\n```\r\nTraceback (most recent call last):\r\n  File \"/usr/lib/python2.7/runpy.py\", line 174, in _run_module_as_main\r\n    \"__main__\", fname, loader, pkg_name)\r\n  File \"/usr/lib/python2.7/runpy.py\", line 72, in _run_code\r\n    exec code in run_globals\r\n  File \"/home/rav/work/synapse/synapse/app/homeserver.py\", line 31, in <module>\r\n    from synapse.crypto import context_factory\r\n  File \"synapse/crypto/context_factory.py\", line 17, in <module>\r\n    from twisted.internet._sslverify import _OpenSSLECCurve, _defaultCurveName\r\nImportError: cannot import name _OpenSSLECCurve\r\n```\nsynapse fails to start under Twisted >= 18.4\nLooks like we are relying on a private identifier which has been removed in Twisted 18.4:\r\n\r\n```\r\nTraceback (most recent call last):\r\n  File \"/usr/lib/python2.7/runpy.py\", line 174, in _run_module_as_main\r\n    \"__main__\", fname, loader, pkg_name)\r\n  File \"/usr/lib/python2.7/runpy.py\", line 72, in _run_code\r\n    exec code in run_globals\r\n  File \"/home/rav/work/synapse/synapse/app/homeserver.py\", line 31, in <module>\r\n    from synapse.crypto import context_factory\r\n  File \"synapse/crypto/context_factory.py\", line 17, in <module>\r\n    from twisted.internet._sslverify import _OpenSSLECCurve, _defaultCurveName\r\nImportError: cannot import name _OpenSSLECCurve\r\n```\n", "before_files": [{"content": "# Copyright 2014-2016 OpenMarket Ltd\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\nfrom twisted.internet import ssl\nfrom OpenSSL import SSL\nfrom twisted.internet._sslverify import _OpenSSLECCurve, _defaultCurveName\n\nimport logging\n\nlogger = logging.getLogger(__name__)\n\n\nclass ServerContextFactory(ssl.ContextFactory):\n    \"\"\"Factory for PyOpenSSL SSL contexts that are used to handle incoming\n    connections and to make connections to remote servers.\"\"\"\n\n    def __init__(self, config):\n        self._context = SSL.Context(SSL.SSLv23_METHOD)\n        self.configure_context(self._context, config)\n\n    @staticmethod\n    def configure_context(context, config):\n        try:\n            _ecCurve = _OpenSSLECCurve(_defaultCurveName)\n            _ecCurve.addECKeyToContext(context)\n        except Exception:\n            logger.exception(\"Failed to enable elliptic curve for TLS\")\n        context.set_options(SSL.OP_NO_SSLv2 | SSL.OP_NO_SSLv3)\n        context.use_certificate_chain_file(config.tls_certificate_file)\n\n        if not config.no_tls:\n            context.use_privatekey(config.tls_private_key)\n\n        context.load_tmp_dh(config.tls_dh_params_path)\n        context.set_cipher_list(\"!ADH:HIGH+kEDH:!AECDH:HIGH+kEECDH\")\n\n    def getContext(self):\n        return self._context\n", "path": "synapse/crypto/context_factory.py"}, {"content": "# Copyright 2015, 2016 OpenMarket Ltd\n# Copyright 2017 Vector Creations Ltd\n# Copyright 2018 New Vector Ltd\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\nimport logging\nfrom distutils.version import LooseVersion\n\nlogger = logging.getLogger(__name__)\n\n# this dict maps from python package name to a list of modules we expect it to\n# provide.\n#\n# the key is a \"requirement specifier\", as used as a parameter to `pip\n# install`[1], or an `install_requires` argument to `setuptools.setup` [2].\n#\n# the value is a sequence of strings; each entry should be the name of the\n# python module, optionally followed by a version assertion which can be either\n# \">=<ver>\" or \"==<ver>\".\n#\n# [1] https://pip.pypa.io/en/stable/reference/pip_install/#requirement-specifiers.\n# [2] https://setuptools.readthedocs.io/en/latest/setuptools.html#declaring-dependencies\nREQUIREMENTS = {\n    \"jsonschema>=2.5.1\": [\"jsonschema>=2.5.1\"],\n    \"frozendict>=0.4\": [\"frozendict\"],\n    \"unpaddedbase64>=1.1.0\": [\"unpaddedbase64>=1.1.0\"],\n    \"canonicaljson>=1.1.3\": [\"canonicaljson>=1.1.3\"],\n    \"signedjson>=1.0.0\": [\"signedjson>=1.0.0\"],\n    \"pynacl>=1.2.1\": [\"nacl>=1.2.1\", \"nacl.bindings\"],\n    \"service_identity>=1.0.0\": [\"service_identity>=1.0.0\"],\n\n    # we break under Twisted 18.4\n    # (https://github.com/matrix-org/synapse/issues/3135)\n    \"Twisted>=16.0.0,<18.4\": [\"twisted>=16.0.0\"],\n\n    \"pyopenssl>=0.14\": [\"OpenSSL>=0.14\"],\n    \"pyyaml\": [\"yaml\"],\n    \"pyasn1\": [\"pyasn1\"],\n    \"daemonize\": [\"daemonize\"],\n    \"bcrypt\": [\"bcrypt>=3.1.0\"],\n    \"pillow\": [\"PIL\"],\n    \"pydenticon\": [\"pydenticon\"],\n    \"blist\": [\"blist\"],\n    \"pysaml2>=3.0.0\": [\"saml2>=3.0.0\"],\n    \"pymacaroons-pynacl\": [\"pymacaroons\"],\n    \"msgpack-python>=0.3.0\": [\"msgpack\"],\n    \"phonenumbers>=8.2.0\": [\"phonenumbers\"],\n    \"six\": [\"six\"],\n}\nCONDITIONAL_REQUIREMENTS = {\n    \"web_client\": {\n        \"matrix_angular_sdk>=0.6.8\": [\"syweb>=0.6.8\"],\n    },\n    \"preview_url\": {\n        \"netaddr>=0.7.18\": [\"netaddr\"],\n    },\n    \"email.enable_notifs\": {\n        \"Jinja2>=2.8\": [\"Jinja2>=2.8\"],\n        \"bleach>=1.4.2\": [\"bleach>=1.4.2\"],\n    },\n    \"matrix-synapse-ldap3\": {\n        \"matrix-synapse-ldap3>=0.1\": [\"ldap_auth_provider\"],\n    },\n    \"psutil\": {\n        \"psutil>=2.0.0\": [\"psutil>=2.0.0\"],\n    },\n    \"affinity\": {\n        \"affinity\": [\"affinity\"],\n    },\n}\n\n\ndef requirements(config=None, include_conditional=False):\n    reqs = REQUIREMENTS.copy()\n    if include_conditional:\n        for _, req in CONDITIONAL_REQUIREMENTS.items():\n            reqs.update(req)\n    return reqs\n\n\ndef github_link(project, version, egg):\n    return \"https://github.com/%s/tarball/%s/#egg=%s\" % (project, version, egg)\n\n\nDEPENDENCY_LINKS = {\n}\n\n\nclass MissingRequirementError(Exception):\n    def __init__(self, message, module_name, dependency):\n        super(MissingRequirementError, self).__init__(message)\n        self.module_name = module_name\n        self.dependency = dependency\n\n\ndef check_requirements(config=None):\n    \"\"\"Checks that all the modules needed by synapse have been correctly\n    installed and are at the correct version\"\"\"\n    for dependency, module_requirements in (\n            requirements(config, include_conditional=False).items()):\n        for module_requirement in module_requirements:\n            if \">=\" in module_requirement:\n                module_name, required_version = module_requirement.split(\">=\")\n                version_test = \">=\"\n            elif \"==\" in module_requirement:\n                module_name, required_version = module_requirement.split(\"==\")\n                version_test = \"==\"\n            else:\n                module_name = module_requirement\n                version_test = None\n\n            try:\n                module = __import__(module_name)\n            except ImportError:\n                logging.exception(\n                    \"Can't import %r which is part of %r\",\n                    module_name, dependency\n                )\n                raise MissingRequirementError(\n                    \"Can't import %r which is part of %r\"\n                    % (module_name, dependency), module_name, dependency\n                )\n            version = getattr(module, \"__version__\", None)\n            file_path = getattr(module, \"__file__\", None)\n            logger.info(\n                \"Using %r version %r from %r to satisfy %r\",\n                module_name, version, file_path, dependency\n            )\n\n            if version_test == \">=\":\n                if version is None:\n                    raise MissingRequirementError(\n                        \"Version of %r isn't set as __version__ of module %r\"\n                        % (dependency, module_name), module_name, dependency\n                    )\n                if LooseVersion(version) < LooseVersion(required_version):\n                    raise MissingRequirementError(\n                        \"Version of %r in %r is too old. %r < %r\"\n                        % (dependency, file_path, version, required_version),\n                        module_name, dependency\n                    )\n            elif version_test == \"==\":\n                if version is None:\n                    raise MissingRequirementError(\n                        \"Version of %r isn't set as __version__ of module %r\"\n                        % (dependency, module_name), module_name, dependency\n                    )\n                if LooseVersion(version) != LooseVersion(required_version):\n                    raise MissingRequirementError(\n                        \"Unexpected version of %r in %r. %r != %r\"\n                        % (dependency, file_path, version, required_version),\n                        module_name, dependency\n                    )\n\n\ndef list_requirements():\n    result = []\n    linked = []\n    for link in DEPENDENCY_LINKS.values():\n        egg = link.split(\"#egg=\")[1]\n        linked.append(egg.split('-')[0])\n        result.append(link)\n    for requirement in requirements(include_conditional=True):\n        is_linked = False\n        for link in linked:\n            if requirement.replace('-', '_').startswith(link):\n                is_linked = True\n        if not is_linked:\n            result.append(requirement)\n    return result\n\n\nif __name__ == \"__main__\":\n    import sys\n    sys.stdout.writelines(req + \"\\n\" for req in list_requirements())\n", "path": "synapse/python_dependencies.py"}], "after_files": [{"content": "# Copyright 2014-2016 OpenMarket Ltd\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\nfrom twisted.internet import ssl\nfrom OpenSSL import SSL, crypto\nfrom twisted.internet._sslverify import _defaultCurveName\n\nimport logging\n\nlogger = logging.getLogger(__name__)\n\n\nclass ServerContextFactory(ssl.ContextFactory):\n    \"\"\"Factory for PyOpenSSL SSL contexts that are used to handle incoming\n    connections and to make connections to remote servers.\"\"\"\n\n    def __init__(self, config):\n        self._context = SSL.Context(SSL.SSLv23_METHOD)\n        self.configure_context(self._context, config)\n\n    @staticmethod\n    def configure_context(context, config):\n        try:\n            _ecCurve = crypto.get_elliptic_curve(_defaultCurveName)\n            context.set_tmp_ecdh(_ecCurve)\n\n        except Exception:\n            logger.exception(\"Failed to enable elliptic curve for TLS\")\n        context.set_options(SSL.OP_NO_SSLv2 | SSL.OP_NO_SSLv3)\n        context.use_certificate_chain_file(config.tls_certificate_file)\n\n        if not config.no_tls:\n            context.use_privatekey(config.tls_private_key)\n\n        context.load_tmp_dh(config.tls_dh_params_path)\n        context.set_cipher_list(\"!ADH:HIGH+kEDH:!AECDH:HIGH+kEECDH\")\n\n    def getContext(self):\n        return self._context\n", "path": "synapse/crypto/context_factory.py"}, {"content": "# Copyright 2015, 2016 OpenMarket Ltd\n# Copyright 2017 Vector Creations Ltd\n# Copyright 2018 New Vector Ltd\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\nimport logging\nfrom distutils.version import LooseVersion\n\nlogger = logging.getLogger(__name__)\n\n# this dict maps from python package name to a list of modules we expect it to\n# provide.\n#\n# the key is a \"requirement specifier\", as used as a parameter to `pip\n# install`[1], or an `install_requires` argument to `setuptools.setup` [2].\n#\n# the value is a sequence of strings; each entry should be the name of the\n# python module, optionally followed by a version assertion which can be either\n# \">=<ver>\" or \"==<ver>\".\n#\n# [1] https://pip.pypa.io/en/stable/reference/pip_install/#requirement-specifiers.\n# [2] https://setuptools.readthedocs.io/en/latest/setuptools.html#declaring-dependencies\nREQUIREMENTS = {\n    \"jsonschema>=2.5.1\": [\"jsonschema>=2.5.1\"],\n    \"frozendict>=0.4\": [\"frozendict\"],\n    \"unpaddedbase64>=1.1.0\": [\"unpaddedbase64>=1.1.0\"],\n    \"canonicaljson>=1.1.3\": [\"canonicaljson>=1.1.3\"],\n    \"signedjson>=1.0.0\": [\"signedjson>=1.0.0\"],\n    \"pynacl>=1.2.1\": [\"nacl>=1.2.1\", \"nacl.bindings\"],\n    \"service_identity>=1.0.0\": [\"service_identity>=1.0.0\"],\n    \"Twisted>=16.0.0\": [\"twisted>=16.0.0\"],\n\n    # We use crypto.get_elliptic_curve which is only supported in >=0.15\n    \"pyopenssl>=0.15\": [\"OpenSSL>=0.15\"],\n\n    \"pyyaml\": [\"yaml\"],\n    \"pyasn1\": [\"pyasn1\"],\n    \"daemonize\": [\"daemonize\"],\n    \"bcrypt\": [\"bcrypt>=3.1.0\"],\n    \"pillow\": [\"PIL\"],\n    \"pydenticon\": [\"pydenticon\"],\n    \"blist\": [\"blist\"],\n    \"pysaml2>=3.0.0\": [\"saml2>=3.0.0\"],\n    \"pymacaroons-pynacl\": [\"pymacaroons\"],\n    \"msgpack-python>=0.3.0\": [\"msgpack\"],\n    \"phonenumbers>=8.2.0\": [\"phonenumbers\"],\n    \"six\": [\"six\"],\n}\nCONDITIONAL_REQUIREMENTS = {\n    \"web_client\": {\n        \"matrix_angular_sdk>=0.6.8\": [\"syweb>=0.6.8\"],\n    },\n    \"preview_url\": {\n        \"netaddr>=0.7.18\": [\"netaddr\"],\n    },\n    \"email.enable_notifs\": {\n        \"Jinja2>=2.8\": [\"Jinja2>=2.8\"],\n        \"bleach>=1.4.2\": [\"bleach>=1.4.2\"],\n    },\n    \"matrix-synapse-ldap3\": {\n        \"matrix-synapse-ldap3>=0.1\": [\"ldap_auth_provider\"],\n    },\n    \"psutil\": {\n        \"psutil>=2.0.0\": [\"psutil>=2.0.0\"],\n    },\n    \"affinity\": {\n        \"affinity\": [\"affinity\"],\n    },\n}\n\n\ndef requirements(config=None, include_conditional=False):\n    reqs = REQUIREMENTS.copy()\n    if include_conditional:\n        for _, req in CONDITIONAL_REQUIREMENTS.items():\n            reqs.update(req)\n    return reqs\n\n\ndef github_link(project, version, egg):\n    return \"https://github.com/%s/tarball/%s/#egg=%s\" % (project, version, egg)\n\n\nDEPENDENCY_LINKS = {\n}\n\n\nclass MissingRequirementError(Exception):\n    def __init__(self, message, module_name, dependency):\n        super(MissingRequirementError, self).__init__(message)\n        self.module_name = module_name\n        self.dependency = dependency\n\n\ndef check_requirements(config=None):\n    \"\"\"Checks that all the modules needed by synapse have been correctly\n    installed and are at the correct version\"\"\"\n    for dependency, module_requirements in (\n            requirements(config, include_conditional=False).items()):\n        for module_requirement in module_requirements:\n            if \">=\" in module_requirement:\n                module_name, required_version = module_requirement.split(\">=\")\n                version_test = \">=\"\n            elif \"==\" in module_requirement:\n                module_name, required_version = module_requirement.split(\"==\")\n                version_test = \"==\"\n            else:\n                module_name = module_requirement\n                version_test = None\n\n            try:\n                module = __import__(module_name)\n            except ImportError:\n                logging.exception(\n                    \"Can't import %r which is part of %r\",\n                    module_name, dependency\n                )\n                raise MissingRequirementError(\n                    \"Can't import %r which is part of %r\"\n                    % (module_name, dependency), module_name, dependency\n                )\n            version = getattr(module, \"__version__\", None)\n            file_path = getattr(module, \"__file__\", None)\n            logger.info(\n                \"Using %r version %r from %r to satisfy %r\",\n                module_name, version, file_path, dependency\n            )\n\n            if version_test == \">=\":\n                if version is None:\n                    raise MissingRequirementError(\n                        \"Version of %r isn't set as __version__ of module %r\"\n                        % (dependency, module_name), module_name, dependency\n                    )\n                if LooseVersion(version) < LooseVersion(required_version):\n                    raise MissingRequirementError(\n                        \"Version of %r in %r is too old. %r < %r\"\n                        % (dependency, file_path, version, required_version),\n                        module_name, dependency\n                    )\n            elif version_test == \"==\":\n                if version is None:\n                    raise MissingRequirementError(\n                        \"Version of %r isn't set as __version__ of module %r\"\n                        % (dependency, module_name), module_name, dependency\n                    )\n                if LooseVersion(version) != LooseVersion(required_version):\n                    raise MissingRequirementError(\n                        \"Unexpected version of %r in %r. %r != %r\"\n                        % (dependency, file_path, version, required_version),\n                        module_name, dependency\n                    )\n\n\ndef list_requirements():\n    result = []\n    linked = []\n    for link in DEPENDENCY_LINKS.values():\n        egg = link.split(\"#egg=\")[1]\n        linked.append(egg.split('-')[0])\n        result.append(link)\n    for requirement in requirements(include_conditional=True):\n        is_linked = False\n        for link in linked:\n            if requirement.replace('-', '_').startswith(link):\n                is_linked = True\n        if not is_linked:\n            result.append(requirement)\n    return result\n\n\nif __name__ == \"__main__\":\n    import sys\n    sys.stdout.writelines(req + \"\\n\" for req in list_requirements())\n", "path": "synapse/python_dependencies.py"}]}