0

I have been trying to access a mailbox within my Organisation's exchange server with the following code :

from exchangelib import Credentials, Account, DELEGATE, Configuration,NTLM, IMPERSONATION, FaultTolerance,EWSDateTime,EWSTimeZone,Message,Q
import datetime 
import getpass
import logging
logging.basicConfig(level=logging.DEBUG)

 
user_name = 'Test.Helpdesk'
new_password = getpass.getpass(prompt='Password: ', stream=None)

try:
    credentials = Credentials(username = user_name, password = new_password)
    config = Configuration(server ='example.com', credentials = credentials)
    account = Account(primary_smtp_address = "Test.Helpdesk@example.com", credentials = credentials, config = config, autodiscover = False)
    print("Success")

except Exception as e:
    print(e)

I keep getting the same error every-time :

HTTPSConnectionPool(host='example.com', port=443): Max retries exceeded with url: /EWS/Exchange.asmx (Caused by NewConnectionError('<urllib3.connection.VerifiedHTTPSConnection object at 0x00000178A6AD8608>: Failed to establish a new connection: [Errno 11001] getaddrinfo failed'))

I tried to follow the following SO post:

SSL: CERTIFICATE_VERIFY_FAILED when connecting to a company Exchange Server

This :

import requests
print (requests.certs.where())

Gave me the directory path where I found a .pem file.

Then this :

import ssl

context = ssl.create_default_context()
der_certs = context.get_ca_certs(binary_form=True)
pem_certs = [ssl.DER_cert_to_PEM_cert(der) for der in der_certs]

with open('wincacerts.pem', 'w') as outfile:
    for pem in pem_certs:
        outfile.write(pem + '\n')

I replaced the name "wincacerts" to "cacerts", since that is the name of the file I found in the directory that the previous code pointed me to.

Then this :

import os
import requests

root_path = os.getcwd()
path_pem=os.path.join(".....\\cacerts.pem")
requests.get('https://example.com', verify=path_pem

Gave me : <Response [401]> I'm not sure what this means.

Now finally, according to the solution from the SO post (link given above), I am supposed to use the following code and make changes according to my needs :

#EXAMPLE FROM ANOTHER SO. POST

root_path = os.getcwd()
path_pem=os.path.join(root_path, 'files', 'wincacerts.crt')

class RootCAAdapter(requests.adapters.HTTPAdapter):
    # An HTTP adapter that uses a custom root CA certificate at a hard coded location
    def cert_verify(self, conn, url, verify, cert):
        cert_file = {
            'mail.ourserver.loc': path_pem,
            'mail.internal': '/path/to/mail.internal.crt'
            }[urlparse(url).hostname]
        super(RootCAAdapter, self).cert_verify(conn=conn, url=url, verify=cert_file, cert=cert)

# Tell exchangelib to use this adapter class instead of the default
BaseProtocol.HTTP_ADAPTER_CLS = RootCAAdapter

The problem is that I do not have knowledge about SSL and Certificates and how they work, so I don't know what changes to do in the above code that would work for me. Also, I have been informed that the servers at my organisation work only on TLS 1.2.

These are the exact lines from my Network Dept. :

Make sure your application configure TLS1.2. Server supports only TLS 1.2.

Is there an way to configure TLS to 1.2 in the exchangelib code ?

Update

I came across this link https://github.com/ecederstrand/exchangelib/issues/155 and it mentions that the issue can be solved using the HTTPAdapter class.

It would be of great help if someone could shed some light of how the class works and the variables that need to be changed according to personal requirements.

Not much is discussed in the documentation, https://ecederstrand.github.io/exchangelib/

Diptarka
  • 3
  • 5
  • How do you conclude that this is a TLS verification issue? The original error message `getaddrinfo failed` usually means that your DNS server cannot resolve the hostname. – Erik Cederstrand Aug 25 '20 at 09:48
  • For anyone who wants to follow this topic, pls click [here](https://github.com/ecederstrand/exchangelib/issues/798) – Diptarka Aug 25 '20 at 10:43

0 Answers0