I am trying to develop a python script to send an email using a GMail account and seem to be encountering an SSL Certificate issue. I have enabled the option to let less secure apps access my gmail account. Could anyone please help me to identify what I am doing wrong as I am getting this error:
ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:997) - Detailed stack trace is below.
import smtplib, ssl
class Mail:
def __init__(self):
self.port = 465
self.smtp_server_domain_name = "smtp.gmail.com"
self.sender_mail = "some.email#gmail.com"
self.password = "Password#123"
def send(self, emails, subject, content):
ssl_context = ssl.create_default_context()
service = smtplib.SMTP_SSL(self.smtp_server_domain_name, self.port, context=ssl_context)
service.login(self.sender_mail, self.password)
for email in emails:
result = service.sendmail(self.sender_mail, email, f"Subject: {subject}\n{content}")
service.quit()
if __name__ == '__main__':
mails = input("Enter emails: ").split()
subject = input("Enter subject: ")
content = input("Enter content: ")
mail = Mail()
mail.send(mails, subject, content)
Stacktrace is below:
Traceback (most recent call last):
File "/Users/prashanth/PycharmProjects/pythonTools/Mail.py", line 29, in <module>
mail.send(mails, subject, content)
File "/Users/prashanth/PycharmProjects/pythonTools/Mail.py", line 14, in send
service = smtplib.SMTP_SSL(self.smtp_server_domain_name, self.port, context=ssl_context)
File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/smtplib.py", line 1050, in __init__
SMTP.__init__(self, host, port, local_hostname, timeout,
File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/smtplib.py", line 255, in __init__
(code, msg) = self.connect(host, port)
File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/smtplib.py", line 341, in connect
self.sock = self._get_socket(host, port, self.timeout)
File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/smtplib.py", line 1057, in _get_socket
new_socket = self.context.wrap_socket(new_socket,
File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/ssl.py", line 512, in wrap_socket
return self.sslsocket_class._create(
File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/ssl.py", line 1070, in _create
self.do_handshake()
File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/ssl.py", line 1341, in do_handshake
self._sslobj.do_handshake()
ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:997)
Process finished with exit code 1
My Environment:
MacOS Big Sur 11.6.5
Python : 3.10
Related
I am trying to send the email using smtp with django application. It is working on my local environment, but not working on production environment.
File "/usr/local/lib/python3.9/site-packages/django/core/mail/message.py", line 298, in send
return self.get_connection(fail_silently).send_messages([self])
File "/usr/local/lib/python3.9/site-packages/django/core/mail/backends/smtp.py", line 124, in send_messages
new_conn_created = self.open()
File "/usr/local/lib/python3.9/site-packages/django/core/mail/backends/smtp.py", line 80, in open
self.connection = self.connection_class(
File "/usr/local/lib/python3.9/smtplib.py", line 255, in __init__
(code, msg) = self.connect(host, port)
File "/usr/local/lib/python3.9/smtplib.py", line 341, in connect
self.sock = self._get_socket(host, port, self.timeout)
File "/usr/local/lib/python3.9/smtplib.py", line 312, in _get_socket
return socket.create_connection((host, port), timeout,
File "/usr/local/lib/python3.9/socket.py", line 844, in create_connection
raise err
File "/usr/local/lib/python3.9/socket.py", line 832, in create_connection
sock.connect(sa)
OSError: [Errno 99] Address not available
My settings files has credentials as below:
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = 'smtp.gmail.com'
EMAIL_USE_TLS = True
EMAIL_PORT = 587
DEFAULT_FROM_EMAIL = '********'
EMAIL_HOST_USER = '*******'
EMAIL_HOST_PASSWORD = '******'
Tried with different credentials, but getting the same error. I tried to print the email credentials from django setting and it is correct.
I am using Python 3.7. I have a sockstunnel server running in docker mode, and today from the command-line I would like to have the client started and to talk to that tunnel server, but somehow it fails. here is my client code looks like:
import asyncio
...
def socks_tunnel_client(tunnel_host, tunnel_port, socks_host, ssl_ca_file, ssl_cert_file, ssl_key_file):
ssl_ctx_client = ssl.create_default_context(ssl.Purpose.SERVER_AUTH)
ssl_ctx_client.check_hostname = False
ssl_ctx_client.options |= (
ssl.OP_NO_TLSv1 | ssl.OP_NO_TLSv1_1 | ssl.OP_NO_COMPRESSION
)
ssl_ctx_client.set_ciphers("ECDHE-RSA-AES128-GCM-SHA256")
ssl_ctx_client.load_verify_locations(ssl_ca_file)
ssl_ctx_client.load_cert_chain(certfile=ssl_cert_file, keyfile=ssl_key_file)
loop = asyncio.get_event_loop()
# Each client connection will create a new protocol instance
coro_tunnel = loop.create_connection(
lambda: TunnelServer(is_server=False),
tunnel_host,
tunnel_port,
ssl=ssl_ctx_client,
)
loop.run_until_complete(coro_tunnel)
...
I have provided an ssl_ca_file file to make that client call. and when it is to step at line of "loop.run_until_complete(coro_tunnel)", it fails with such messages:
loop.run_until_complete(coro_tunnel)
File "/usr/lib/python3.7/asyncio/base_events.py", line 587, in run_until_complete
return future.result()
File "/usr/lib/python3.7/asyncio/base_events.py", line 989, in create_connection
ssl_handshake_timeout=ssl_handshake_timeout)
File "/usr/lib/python3.7/asyncio/base_events.py", line 1017, in _create_connection_transport
await waiter
File "/usr/lib/python3.7/asyncio/sslproto.py", line 530, in data_received
ssldata, appdata = self._sslpipe.feed_ssldata(data)
File "/usr/lib/python3.7/asyncio/sslproto.py", line 189, in feed_ssldata
self._sslobj.do_handshake()
File "/usr/lib/python3.7/ssl.py", line 774, in do_handshake
self._sslobj.do_handshake()
ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self signed certificate in certificate chain (_ssl.c:1091)
So my questions:
What does that mean, and how to solve that issue ?
"IF" the provided ssl_ca_file not good enough,(I was told to use this file, but I am not 100% sure), is there a way to by-pass this checking ? Someone mentioned to set "ssl_verify=False" to work around, but I could not figure out how to make this happen.
Thanks a lot for the help.
Jack
I am writing a small Python program that involves sending emails to players in a game. I'm currently using SMTPlib to do so, and for the first while it worked great, however now I get this error whenever I try to run it:
Traceback (most recent call last):
File "/Users/user/Desktop/test.py", line 17, in <module>
sendEmail()
File "/Users/user/Desktop/test.py", line 11, in sendEmail
with smtplib.SMTP_SSL("smtp.gmail.com", port, context=context) as server:
File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/smtplib.py", line 1034, in __init__
SMTP.__init__(self, host, port, local_hostname, timeout,
File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/smtplib.py", line 253, in __init__
(code, msg) = self.connect(host, port)
File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/smtplib.py", line 339, in connect
self.sock = self._get_socket(host, port, self.timeout)
File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/smtplib.py", line 1041, in _get_socket
new_socket = self.context.wrap_socket(new_socket,
File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/ssl.py", line 500, in wrap_socket
return self.sslsocket_class._create(
File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/ssl.py", line 1040, in _create
self.do_handshake()
File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/ssl.py", line 1309, in do_handshake
self._sslobj.do_handshake()
ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1122)
And the bare-bones code that throws this error:
import smtplib, ssl
def sendEmail():
port = 465 # For SSL
password = 'password'
senderEmail = 'senderEmail#email.com'
# Create a secure SSL context
context = ssl.create_default_context()
with smtplib.SMTP_SSL("smtp.gmail.com", port, context=context) as server:
server.login(senderEmail, password)
message = 'Hello world!'
server.sendmail(senderEmail, 'myEmail#email.com', message)
sendEmail()
I suspect that this error has to do with me using Python 3.9.0 instead of 3.7.6 as that is the only thing that has changed about my environment since the last time it was working, but I'm not certain about that*. What is causing this error, and what can I do to fix it?
*EDIT: I ran the same code on Python 3.7.6 in case that was the problem. Interestingly, it now gives a very similar error:
Traceback (most recent call last):
File "test.py", line 17, in <module>
sendEmail()
File "test.py", line 11, in sendEmail
with smtplib.SMTP_SSL("smtp.gmail.com", port, context=context) as server:
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/smtplib.py", line 1031, in __init__
source_address)
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/smtplib.py", line 251, in __init__
(code, msg) = self.connect(host, port)
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/smtplib.py", line 336, in connect
self.sock = self._get_socket(host, port, self.timeout)
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/smtplib.py", line 1039, in _get_socket
server_hostname=self._host)
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/ssl.py", line 423, in wrap_socket
session=session
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/ssl.py", line 870, in _create
self.do_handshake()
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/ssl.py", line 1139, in do_handshake
self._sslobj.do_handshake()
ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1076)
I am new to the ssl and stuff, I have generated the self signed certificates using openssl.
openssl req -newkey rsa:2048 -nodes -keyout key.pem -x509 -days 3650 -out certificate.pem
Where Server has the following Code.
if __name__ == "__main__":
context = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2)
context.load_cert_chain("/home/rootkit/ssl/certificate.pem",
"/home/rootkit/ssl/key.pem")
http_server = tornado.httpserver.HTTPServer(Application(), ssl_options=context)
#
# http_server = tornado.httpserver.HTTPServer(Application(), ssl_options={
# 'certfile': '/home/rootkit/ssl/certificate.pem',
# 'keyfile': '/home/rootkit/ssl/key.pem',
# })
http_server.listen(8888)
tornado.ioloop.IOLoop.current().start()
When I access the url from chrome it just give the exception because it is not signed by any authority so I proceed it as unsafe.
But if I see the traffic via wireshark it shows the encrypted traffic.
But when I tried to connect with the Tornado Client it throws the following error.
WARNING:tornado.general:SSL Error on 6 ('127.0.0.1', 8888): [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:645)
ERROR:tornado.application:Exception in callback functools.partial(<function wrap.<locals>.null_wrapper at 0xb72e514c>, <Task finished coro=<check_status() done, defined at /home/rootkit/PycharmProjects/websocketserver/file_upload/websocketclient.py:82> exception=SSLError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:645)')>)
Traceback (most recent call last):
File "/home/rootkit/.local/lib/python3.5/site-packages/tornado/ioloop.py", line 758, in _run_callback
ret = callback()
File "/home/rootkit/.local/lib/python3.5/site-packages/tornado/stack_context.py", line 300, in null_wrapper
return fn(*args, **kwargs)
File "/home/rootkit/.local/lib/python3.5/site-packages/tornado/ioloop.py", line 779, in _discard_future_result
future.result()
File "/usr/lib/python3.5/asyncio/futures.py", line 274, in result
raise self._exception
File "/usr/lib/python3.5/asyncio/tasks.py", line 241, in _step
result = coro.throw(exc)
File "/home/rootkit/PycharmProjects/websocketserver/file_upload/websocketclient.py", line 89, in check_status
param = await client.fetch(request)
File "/usr/lib/python3.5/asyncio/futures.py", line 361, in __iter__
yield self # This tells Task to wait for completion.
File "/usr/lib/python3.5/asyncio/tasks.py", line 296, in _wakeup
future.result()
File "/usr/lib/python3.5/asyncio/futures.py", line 274, in result
raise self._exception
File "/home/rootkit/.local/lib/python3.5/site-packages/tornado/simple_httpclient.py", line 272, in run
max_buffer_size=self.max_buffer_size)
File "/home/rootkit/.local/lib/python3.5/site-packages/tornado/gen.py", line 1133, in run
value = future.result()
File "/usr/lib/python3.5/asyncio/futures.py", line 274, in result
raise self._exception
File "/home/rootkit/.local/lib/python3.5/site-packages/tornado/gen.py", line 1141, in run
yielded = self.gen.throw(*exc_info)
File "/home/rootkit/.local/lib/python3.5/site-packages/tornado/tcpclient.py", line 242, in connect
server_hostname=host)
File "/home/rootkit/.local/lib/python3.5/site-packages/tornado/gen.py", line 1133, in run
value = future.result()
File "/usr/lib/python3.5/asyncio/futures.py", line 274, in result
raise self._exception
File "/home/rootkit/.local/lib/python3.5/site-packages/tornado/iostream.py", line 1501, in _do_ssl_handshake
self.socket.do_handshake()
File "/usr/lib/python3.5/ssl.py", line 988, in do_handshake
self._sslobj.do_handshake()
File "/usr/lib/python3.5/ssl.py", line 633, in do_handshake
self._sslobj.do_handshake()
ssl.SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:645)
Here is the Client code.
async def check_status():
url = "https://127.0.0.1:8888/"
request = httpclient.HTTPRequest(url=url,
method="GET",
client_key="/home/rootkit/client.key",
client_cert="/home/rootkit/ssl/client.pem")
client = httpclient.AsyncHTTPClient()
param = await client.fetch(request)
print(param)
I have generated the client certificates using the came command I used for the server.
What could be the possible issue.
What I am missing ?
I got the answer from the github repo that is,
The "client" certificate is a totally different thing: a way for the server to authenticate the client, so called "mutual authentication". It does nothing in this case because the server is not set up to check the client's certificate. It does not cause the client to skip validation of the server's certificate. To do that like you do for chrome, use validate_cert=False.
(standard disclaimer that you need to make sure that you don't accidentally leave validate_cert=False in when this code makes it into some real-world product or service)
So I just need to remove the client side validation of the certificate.
For "real production use" you probably want to generate a real trusted server certificate for your real dns domain, for example with "Let's Encrypt".
validate_cert=False will encrypt the traffic but not validate the certificate ?
So I changed my client to
async def check_status():
url = "https://127.0.0.1:8888/"
request = httpclient.HTTPRequest(url=url,
method="GET",
validate_cert=False)
client = httpclient.AsyncHTTPClient()
param = await client.fetch(request)
print(param.body)
I'm running into a strange issue with httplib2 and python3, I have a little script to connect to my test server, I try to disable SSL verification but it still spits out the following:
File "C:\Anaconda3\lib\site-packages\httplib2\__init__.py", line 987, in _conn_reque
conn.connect()
File "C:\Anaconda3\lib\http\client.py", line 1231, in connect
server_hostname=server_hostname)
File "C:\Anaconda3\lib\ssl.py", line 365, in wrap_socket
_context=self)
File "C:\Anaconda3\lib\ssl.py", line 583, in __init__
self.do_handshake()
File "C:\Anaconda3\lib\ssl.py", line 810, in do_handshake
self._sslobj.do_handshake()
ssl.SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:600)
The code I'm using to connect:
import httplib2
url = 'https://www.MyTestServer.com/Test'
h = httplib2.Http(".cache", disable_ssl_certificate_validation=True)
h.add_credentials('username', 'password')
resp, content = h.request(url, 'GET')