How to disable check_hostname
Describe the bug Our VPN server modify Security certificates, and I would like to disable check for validity of the same, but when connection thru VPN i get error ValueError: Cannot set verify_mode to CERT_NONE when check_hostname is enabled.
To Reproduce script that I am using (with modified data for url, etc...)
from exchangelib.protocol import BaseProtocol, NoVerifyHTTPAdapter
from exchangelib import Account, Credentials, Configuration
BaseProtocol.HTTP_ADAPTER_CLS = NoVerifyHTTPAdapter
credentials = Credentials(username='DOMAIN\\user', password='pass')
config = Configuration(server='server.ba', credentials=credentials)
account = Account(primary_smtp_address='[email protected]', credentials=credentials, config=config, autodiscover=False)
Exception is raised on last line of code account = ...
Expected behavior A clear and concise description of what you expected to happen. If applicable, add links to EWS documentation on MSDN or other relevant source.
I would expect exchange lib to accept that certificate is not good, and to ignore it
Log output If applicable, add relevant output from debug logging .
Traceback (most recent call last):
File "c:\venv\Aplikacija\Lib\site-packages\exchangelib\protocol.py", line 242, in get_session
session = self._session_pool.get(block=False)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\user\AppData\Local\Programs\Python\Python311\Lib\queue.py", line 168, in get
raise Empty
_queue.Empty
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\Users\user\AppData\Local\Programs\Python\Python311\Lib\runpy.py", line 198, in _run_module_as_main
return _run_code(code, main_globals, None,
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\user\AppData\Local\Programs\Python\Python311\Lib\runpy.py", line 88, in _run_code
exec(code, run_globals)
File "c:\Users\user\.vscode\extensions\ms-python.debugpy-2024.6.0-win32-x64\bundled\libs\debugpy\adapter/../..\debugpy\launcher/../..\debugpy\__main__.py", line 39, in <module>
cli.main()
File "c:\Users\user\.vscode\extensions\ms-python.debugpy-2024.6.0-win32-x64\bundled\libs\debugpy\adapter/../..\debugpy\launcher/../..\debugpy/..\debugpy\server\cli.py", line 430, in main
run()
File "c:\Users\user\.vscode\extensions\ms-python.debugpy-2024.6.0-win32-x64\bundled\libs\debugpy\adapter/../..\debugpy\launcher/../..\debugpy/..\debugpy\server\cli.py", line 284, in run_file
runpy.run_path(target, run_name="__main__")
File "c:\Users\user\.vscode\extensions\ms-python.debugpy-2024.6.0-win32-x64\bundled\libs\debugpy\_vendored\pydevd\_pydevd_bundle\pydevd_runpy.py", line 321, in run_path
return _run_module_code(code, init_globals, run_name,
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "c:\Users\user\.vscode\extensions\ms-python.debugpy-2024.6.0-win32-x64\bundled\libs\debugpy\_vendored\pydevd\_pydevd_bundle\pydevd_runpy.py", line 135, in _run_module_code
_run_code(code, mod_globals, init_globals,
File "c:\Users\user\.vscode\extensions\ms-python.debugpy-2024.6.0-win32-x64\bundled\libs\debugpy\_vendored\pydevd\_pydevd_bundle\pydevd_runpy.py", line 124, in _run_code
exec(code, run_globals)
File "D:\OneDrive - Telekomunikacije RS a.d. Banja Luka\Python\PythonProjects\Aplikacija\ai_send.py", line 6, in <module>
account = Account(primary_smtp_address='[email protected]', credentials=credentials, config=config, autodiscover=False)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "c:\venv\Aplikacija\Lib\site-packages\exchangelib\account.py", line 205, in __init__
self.version = self.protocol.version.copy()
^^^^^^^^^^^^^^^^^^^^^
File "c:\venv\Aplikacija\Lib\site-packages\exchangelib\protocol.py", line 480, in version
self.config.version = Version.guess(self, api_version_hint=self.api_version_hint)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "c:\venv\Aplikacija\Lib\site-packages\exchangelib\version.py", line 202, in guess
list(ConvertId(protocol=protocol).call([AlternateId(id="DUMMY", format=EWS_ID, mailbox="DUMMY")], ENTRY_ID))
File "c:\venv\Aplikacija\Lib\site-packages\exchangelib\services\common.py", line 216, in _elems_to_objs
for elem in elems:
File "c:\venv\Aplikacija\Lib\site-packages\exchangelib\services\common.py", line 278, in _chunked_get_elements
yield from self._get_elements(payload=payload_func(chunk, **kwargs))
File "c:\venv\Aplikacija\Lib\site-packages\exchangelib\services\common.py", line 299, in _get_elements
yield from self._response_generator(payload=payload)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "c:\venv\Aplikacija\Lib\site-packages\exchangelib\services\common.py", line 262, in _response_generator
response = self._get_response_xml(payload=payload)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "c:\venv\Aplikacija\Lib\site-packages\exchangelib\services\common.py", line 395, in _get_response_xml
r = self._get_response(payload=payload, api_version=api_version)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "c:\venv\Aplikacija\Lib\site-packages\exchangelib\services\common.py", line 345, in _get_response
session = self.protocol.get_session()
^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "c:\venv\Aplikacija\Lib\site-packages\exchangelib\protocol.py", line 246, in get_session
self.increase_poolsize()
File "c:\venv\Aplikacija\Lib\site-packages\exchangelib\protocol.py", line 212, in increase_poolsize
self._session_pool.put(self.create_session(), block=False)
^^^^^^^^^^^^^^^^^^^^^
File "c:\venv\Aplikacija\Lib\site-packages\exchangelib\protocol.py", line 318, in create_session
if self.auth_type == NTLM and self.credentials.type == self.credentials.EMAIL:
^^^^^^^^^^^^^^
File "c:\venv\Aplikacija\Lib\site-packages\exchangelib\protocol.py", line 119, in auth_type
self.config.auth_type = self.get_auth_type()
^^^^^^^^^^^^^^^^^^^^
File "c:\venv\Aplikacija\Lib\site-packages\exchangelib\protocol.py", line 470, in get_auth_type
return get_service_authtype(protocol=self)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "c:\venv\Aplikacija\Lib\site-packages\exchangelib\transport.py", line 87, in get_service_authtype
r = s.post(
^^^^^^^
File "c:\venv\Aplikacija\Lib\site-packages\requests\sessions.py", line 637, in post
return self.request("POST", url, data=data, json=json, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "c:\venv\Aplikacija\Lib\site-packages\requests\sessions.py", line 589, in request
resp = self.send(prep, **send_kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "c:\venv\Aplikacija\Lib\site-packages\requests\sessions.py", line 703, in send
r = adapter.send(request, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "c:\venv\Aplikacija\Lib\site-packages\requests\adapters.py", line 589, in send
resp = conn.urlopen(
^^^^^^^^^^^^^
File "c:\venv\Aplikacija\Lib\site-packages\urllib3\connectionpool.py", line 793, in urlopen
response = self._make_request(
^^^^^^^^^^^^^^^^^^^
File "c:\venv\Aplikacija\Lib\site-packages\urllib3\connectionpool.py", line 467, in _make_request
self._validate_conn(conn)
File "c:\venv\Aplikacija\Lib\site-packages\urllib3\connectionpool.py", line 1099, in _validate_conn
conn.connect()
File "c:\venv\Aplikacija\Lib\site-packages\urllib3\connection.py", line 653, in connect
sock_and_verified = _ssl_wrap_socket_and_match_hostname(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "c:\venv\Aplikacija\Lib\site-packages\urllib3\connection.py", line 768, in _ssl_wrap_socket_and_match_hostname
context.verify_mode = resolve_cert_reqs(cert_reqs)
^^^^^^^^^^^^^^^^^^^
File "C:\Users\user\AppData\Local\Programs\Python\Python311\Lib\ssl.py", line 742, in verify_mode
super(SSLContext, SSLContext).verify_mode.__set__(self, value)
ValueError: Cannot set verify_mode to CERT_NONE when check_hostname is enabled.
Additional context For example, Python and exchangelib versions. Python is 3.11.9, exchangelib 5.4.0 (but I have tried other versions also)
If you need to customize the way exchangelib handles connections, you should create a custom HTTP adapter for requests. There's documentation for that at https://ecederstrand.github.io/exchangelib/#proxies-and-custom-tls-validation
I did try it, but I am lacking knowledge to do so :( I have tried:
class NoHostnameAdapter(HTTPAdapter):
# Disable check_hostname?!
def init_poolmanager(self, connections, maxsize, block=False):
self.poolmanager = PoolManager(num_pools=connections,
maxsize=maxsize,
block=block,
cert_reqs='CERT_NONE',
assert_hostname=False,
check_hostname=False)
class NoCertAdapter(NoHostnameAdapter):
def cert_verify(self, conn, url, verify, cert):
# pylint: disable=unused-argument
# We're overriding a method, so we have to keep the signature
super().cert_verify(conn=conn, url=url, verify=False, cert=cert)
BaseProtocol.HTTP_ADAPTER_CLS = NoCertAdapter
but it does not work.
P.S. request.get with verify=False works...
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
url = 'https://server.ba/ews/exchange.asmx'
auth = HttpNtlmAuth('DOMAIN\\'+username, password)
response = requests.get(url, auth=auth, verify=False)
I would suggest asking in a forum dedicated to requests instead. This is outside the scope of exchangelib as such.
Check requests package - if requests==2.32.0+ change version to 2.31.0
Closing as this issue concerns configuration or extension of requests, not exchangelib.