Related
I would retrieve some information from an ABB G13 gateway that offer a RESTful JSON API. API is hosted by the gateway via https endpoint.
Basic authentication mechanism is used for authentication. However all traffic
goes through SSL layers.
On linux with command:
curl -s -k -X GET -u user:password https://host/meters/a_serial/power
All goes well!
I'm trying to write a script for windows in Python 2.7.10 with Requests 2.8.1 and with this code:
import requests
requests.get('https://host/meters/a_serial/power', auth=('user', 'password'))
I have this error:
Traceback (most recent call last):
File "C:/Users/mzilio/PycharmProjects/pwrgtw/test.py", line 20, in <module>
requests.get('https://host/meters/a_serial/power', auth=('user', 'password'))
File "C:\Python27\lib\site-packages\requests\api.py", line 69, in get
return request('get', url, params=params, **kwargs)
File "C:\Python27\lib\site-packages\requests\api.py", line 50, in request
response = session.request(method=method, url=url, **kwargs)
File "C:\Python27\lib\site-packages\requests\sessions.py", line 468, in request
resp = self.send(prep, **send_kwargs)
File "C:\Python27\lib\site-packages\requests\sessions.py", line 576, in send
r = adapter.send(request, **kwargs)
File "C:\Python27\lib\site-packages\requests\adapters.py", line 433, in send
raise SSLError(e, request=request)
requests.exceptions.SSLError: EOF occurred in violation of protocol (_ssl.c:590)
I've searched for a solution and I've tried to fix with this code:
import requests
from requests.adapters import HTTPAdapter
from requests.packages.urllib3.poolmanager import PoolManager
import ssl
class MyAdapter(HTTPAdapter):
def init_poolmanager(self, connections, maxsize, block=False):
self.poolmanager = PoolManager(num_pools=connections,
maxsize=maxsize,
block=block,
ssl_version=ssl.PROTOCOL_TLSv1)
s = requests.Session()
s.mount('https://', MyAdapter())
s.get('https://host/meters/a_serial/power')
But it doesn't work for me cause I get this error:
Traceback (most recent call last):
File "C:/Users/mzilio/PycharmProjects/pwrgtw/test.py", line 16, in <module>
s.get('https://host/meters/a_serial/power')
File "C:\Python27\lib\site-packages\requests\sessions.py", line 480, in get
return self.request('GET', url, **kwargs)
File "C:\Python27\lib\site-packages\requests\sessions.py", line 468, in request
resp = self.send(prep, **send_kwargs)
File "C:\Python27\lib\site-packages\requests\sessions.py", line 576, in send
r = adapter.send(request, **kwargs)
File "C:\Python27\lib\site-packages\requests\adapters.py", line 433, in send
raise SSLError(e, request=request)
requests.exceptions.SSLError: EOF occurred in violation of protocol (_ssl.c:590)
I'm stuck on this problem. Could someone help me? Thanks!
This thing worked for me, just make sure whether these modules are installed or not, if not then install them, following are:
pip install ndg-httpsclient
pip install pyopenssl
pip install pyasn1
It removed my SSLError: EOF occurred in violation of protocol (_ssl.c:590) error.
Hope it helps.
Step 1: Check that Python supports TLS 1.1
You may have a Python setup that only supports TLS 1.0 – not TLS 1.1 or above.
You can check it like this:
Python 3
from urllib.request import urlopen
urlopen('https://www.howsmyssl.com/a/check').read()
Python 2
from urllib2 import urlopen
urlopen('https://www.howsmyssl.com/a/check').read()
(If you get urllib.error.URLError: <urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:852)> you may have to disable certificate verification. NOTE: doing this will disable SSL protections against evildoers who would impersonate or intercept traffic to that website - see https://en.wikipedia.org/wiki/Man-in-the-middle_attack
)
import ssl
urlopen('https://www.howsmyssl.com/a/check', context=ssl._create_unverified_context()).read()
Check the output for the key tls_version. If it says TLS 1.0 and not TLS 1.1 or TLS 1.2 that could be the problem.
If you're using a virtualenv, be sure to run the command inside.
Step 2: Install Python with a newer version of OpenSSL
In order support TLS 1.1 or above, you may need to install a newer version of OpenSSL, and the install Python again afterwards. This should give you a Python that supports TLS 1.1.
The process depends on your operating system – here's a guide for OS X.
virtualenv users
For me, the Python outside of my virtualenv had TLS 1.2 support, so just I removed my old virtualenv, and created a new one with the same packages and then it worked. Easy peasy!
I found it was going through a proxy when it should have connected to the server directly.
I fixed this by doing
unset https_proxy
I had exactly the same error, turns out that I didn't have ndg-httpsclient installed, see my original issue raised in github.
If you are getting this error for intermediate requests, you can refer to the solution mentioned in https://github.com/requests/requests/issues/3391.
Basically, if you are making a lot of requests to a server and facing this issue with some of those requests you can use Session to just retry the requests.
Let me know if this works.
Close you proxy and try it again.
The only time I have seen errors of this nature have been times that I was using requests to screen scrape data and I was using a multiprocessing library. I would either try your code without the pool manager or split your app into two apps, one that doles out urls and another that consumes them.
The client-server pair here should give you some ideas. I was able to scale my client out horizontally when I used the hacky server code to load all urls into a Queue in memory just before app.run. Hope that helps.
ENV: Python 3.10, www.howsmyssl.com returns tls_version: TLS 1.3:
For poor guys like me who MUST make query thorough proxy, this cloud be blame on your incorrect HTTPS proxy setting (perhaps you aren't set it, but python somehow believes you've set it, don't know why exactly, maybe because you've set the http proxy), you need to set it "properly".
I'm using windows10, haven't set it before, after set it, python works normally, give it a try.
try to run:
pip install urllib3==1.25.11
It works for me anyway.
p={
'http':'http://my correct proxy here',
'https':'https://my correct proxy here'
}
self.response=requests.get(url=url,headers=self.headers,timeout=(6,15),proxies=p)
And then it raise the exception:
Traceback (most recent call last):
File "C:\Users\xyl13509876955\Desktop\Monitor\dicks.py", line 61, in send_request
self.response=requests.get(url=url,headers=self.headers,timeout=(6,15),proxies=p)
File "C:\Users\xyl13509876955\AppData\Local\Programs\Python\Python37\lib\site-packages\requests\api.py", line 76, in get
return request('get', url, params=params, **kwargs)
File "C:\Users\xyl13509876955\AppData\Local\Programs\Python\Python37\lib\site-packages\requests\api.py", line 61, in request
return session.request(method=method, url=url, **kwargs)
File "C:\Users\xyl13509876955\AppData\Local\Programs\Python\Python37\lib\site-packages\requests\sessions.py", line 542, in request
resp = self.send(prep, **send_kwargs)
File "C:\Users\xyl13509876955\AppData\Local\Programs\Python\Python37\lib\site-packages\requests\sessions.py", line 655, in send
r = adapter.send(request, **kwargs)
File "C:\Users\xyl13509876955\AppData\Local\Programs\Python\Python37\lib\site-packages\requests\adapters.py", line 449, in send
timeout=timeout
File "C:\Users\xyl13509876955\AppData\Local\Programs\Python\Python37\lib\site-packages\urllib3\connectionpool.py", line 696, in urlopen
self._prepare_proxy(conn)
File "C:\Users\xyl13509876955\AppData\Local\Programs\Python\Python37\lib\site-packages\urllib3\connectionpool.py", line 964, in _prepare_proxy
conn.connect()
File "C:\Users\xyl13509876955\AppData\Local\Programs\Python\Python37\lib\site-packages\urllib3\connection.py", line 359, in connect
conn = self._connect_tls_proxy(hostname, conn)
File "C:\Users\xyl13509876955\AppData\Local\Programs\Python\Python37\lib\site-packages\urllib3\connection.py", line 506, in _connect_tls_proxy
ssl_context=ssl_context,
File "C:\Users\xyl13509876955\AppData\Local\Programs\Python\Python37\lib\site-packages\urllib3\util\ssl_.py", line 432, in ssl_wrap_socket
ssl_sock = _ssl_wrap_socket_impl(sock, context, tls_in_tls)
File "C:\Users\xyl13509876955\AppData\Local\Programs\Python\Python37\lib\site-packages\urllib3\util\ssl_.py", line 474, in _ssl_wrap_socket_impl
return ssl_context.wrap_socket(sock)
File "C:\Users\xyl13509876955\AppData\Local\Programs\Python\Python37\lib\ssl.py", line 423, in wrap_socket
session=session
File "C:\Users\xyl13509876955\AppData\Local\Programs\Python\Python37\lib\ssl.py", line 827, in _create
raise ValueError("check_hostname requires server_hostname")
ValueError: check_hostname requires server_hostname
Please help me solve the problem and the best way is to show me the right code. I am very confused and frustrated for the problem!!
as a work around:
pip install urllib3==1.25.11
As I understand, in new urllib3 the main schema of proxy was changed... can read here.
This settings help for me (for urllib3=1.26.4).
An old
proxy={
'http':'8.88.888.8:8888',
'https':'8.88.888.8:8888'
}
The new
proxy={
'https': 'https://8.88.888.8:8888',
'http': 'http://8.88.888.8:8888',
}
UPDATED
I have met this issue again for requests 2.26.0, but in this time it works with an old schema...
proxy={
'http':'8.88.888.8:8888',
'https':'8.88.888.8:8888'
}
I have solved the problem. It is a bug with urllib3.
You can use pip install urllib3==1.25.8
Downgrading urllib3 has solved it for me too.
Though I had to reset the proxy env var:
https_proxy="http://127.0.0.1:<PROXY_PORT>" pip install urllib3==1.25.11
Without that, I was getting the following error and it couldn't downgrade urllib3 (see SSLError installing with pip).
WARNING: Retrying (Retry(total=4, connect=None, read=None, redirect=None, status=None)) after connection broken by 'SSLError(SSLError(1, '[SSL: WRONG_VERSION_NUMBER] wrong version number (_ssl.c:1091)'))': /simple/pip/
In my case, Charles' windows proxy function caused this error. After I close windows proxy, this error is gone.
Had the same problem on Ubuntu 18.04 using Python 3.6.9, searched through a lot of pages and finally fixed it via trial and error.
The fix is changing the environment variable https_proxy. Previously https_proxy is https://127.0.0.1:<PORT> and I removed the https header via:
export https_proxy=127.0.0.1:<PORT>
Then I can do python3 -m pip install --upgrade urllib3.
None of the answers did it for me. Here's a silly looking solution that fixed my problem:
If you, like me trying to install packages in a corporate environment, you probably have given a proxy to limit interactions with world wide web, so all you have to do is to export that proxy in http and https format.
something like this:
export http_proxy=http://x.x.x.x:8080
export https_proxy=http://x.x.x.x:8080
(my proxy didnt use the ssl, it didnt even matter.)
replace x with your proxy ip
Turn Your VPN/Proxy thing (which enables as System Proxy) maybe it fixed.
i was using QV2ray and i had this issue, when i disabled it, pip works fine.
Don't use VPN proxy service off it and try again
On Linux, the problem can be resolved by replacing https with http in the proxy settings environment variable export https_proxy=http://123.123.123.123:8888. Note, it is proxy settings for https, but an http address is used.
I ran into the same issue, the proxy config is enabled by accident. Just turning off the proxy worked for me.
I got this error when I was using a proxy. I disabled the proxy, the error was fixed.
As others mention, it has something to do with the connection to the server.
I solved it simply by closing Fiddler.
For those of you that can't disable their proxy, I found that downgrading pip was the only thing that worked.
The version that works for me is located here:
https://pypi.org/project/pip/20.2.4/
Download the whl and use
pip install pip-20.2.4-py2.py3-none-any.whl
at the location you downloaded it to.
I had the same problem using Python 3.10.7 (64-bit) on Windows 10.
Rolling back urllib3 to 1.25.11 didn't help.
Using python 3.19.13 (64-bit) instead resolved this error message no matter
which urllib3 is used.
I assume that this is caused by some compatibility issue with Python 3.10.x.
I set up a Mosquitto broker in a Raspberry Pi and created self-signed TLS server certificate with OpenSSL. Configuration works as I can connect successfully with Moquitto client from terminal, as well as from MQTTBox and MQTT.fx.
However when trying to connect with Python and Paho-MQTT following error
import paho.mqtt.client as mqtt
# SETTINGS & CONSTANTS
(...)
TLS_CA = "./tls/mqtt.crt"
# MQTT CALLBACKS
(...)
# INIT & CONNECT CLIENT
client = mqtt.Client(DEVICE_ID)
(...)
client.tls_set(TLS_CA)
client.username_pw_set(MQTT_USER, MQTT_PSWD)
client.connect(MQTT_HOST, MQTT_PORT, MQTT_KEEPALIVE)
I get the following error:
File "/usr/lib/python3.4/ssl.py", line 804, in do_handshake
self._sslobj.do_handshake()
ssl.SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:600)
I've tried many things:
1) Insert self-signed certificate into Raspbian ca-certificates
sudo mkdir /usr/local/share/ca-certificates/extra
sudo cp mqtt.crt /usr/local/share/ca-certificates/extra/mqtt.crt
sudo update-ca-certificates
2) Play with Paho's tls_set() options. I think ca_certs=mqtt.crt and tls_version=ssl.PROTOCOL_TLSv1 should be enough.
3) Use tls_insecure_set(True). I know this is not a valid solution, but I just wanted to try if something happen. Result is still CERTIFICATE_VERIFY_FAILED error
4) Use Python 2.7.9 and Python 3.4.2
I've actually run out of ideas
After long time trying and reading everywhere I realized the problem was caused by self-signed certificates. I generated new certificates with different Common Names for CA and broker and everything seems to work fine.
I'm using the REST API for a Cisco CMX device, and trying to write Python code which makes a GET request to the API for information. The code is as follows and is the same as that in the file except with the necessary information changed.
from http.client import HTTPSConnection
from base64 import b64encode
# Create HTTPS connection
c = HTTPSConnection("0.0.0.0")
# encode as Base64
# decode to ascii (python3 stores as byte string, need to pass as ascii
value for auth)
username_password = b64encode(b"admin:password").decode("ascii")
headers = {'Authorization': 'Basic {0}'.format(username_password)}
# connect and ask for resource
c.request('GET', '/api/config/v1/aaa/users', headers=headers)
# response
res = c.getresponse()
data = res.read()
However, I am continuously getting the following error:
Traceback (most recent call last):
File "/Users/finaris/PycharmProjects/test/test/test.py", line 14, in <module>
c.request('GET', '/api/config/v1/aaa/users', headers=headers)
File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/http/client.py", line 1106, in request
self._send_request(method, url, body, headers)
File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/http/client.py", line 1151, in _send_request
self.endheaders(body)
File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/http/client.py", line 1102, in endheaders
self._send_output(message_body)
File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/http/client.py", line 934, in _send_output
self.send(msg)
File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/http/client.py", line 877, in send
self.connect()
File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/http/client.py", line 1260, in connect
server_hostname=server_hostname)
File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/ssl.py", line 377, in wrap_socket
_context=self)
File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/ssl.py", line 752, in __init__
self.do_handshake()
File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/ssl.py", line 988, in do_handshake
self._sslobj.do_handshake()
File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/ssl.py", line 633, in do_handshake
self._sslobj.do_handshake()
ssl.SSLError: [SSL: TLSV1_ALERT_PROTOCOL_VERSION] tlsv1 alert protocol version (_ssl.c:645)
I also tried updating OpenSSL but that had no effect.
I had the same error and google brought me to this question, so here is what I did, hoping that it helps others in a similar situation.
This is applicable for OS X.
Check in the Terminal which version of OpenSSL I had:
$ python3 -c "import ssl; print(ssl.OPENSSL_VERSION)"
>> OpenSSL 0.9.8zh 14 Jan 2016
As my version of OpenSSL was too old, the accepted answer did not work.
So I had to update OpenSSL. To do this, I updated Python to the latest version (from version 3.5 to version 3.6) with Homebrew, following some of the steps suggested here:
$ brew update
$ brew install openssl
$ brew install python3
Then I was having problems with the PATH and the version of python being used, so I just created a new virtualenv making sure that the newest version of python was taken:
$ virtualenv webapp --python=python3.6
Issue solved.
The only thing you have to do is to install requests[security] in your virtualenv. You should not have to use Python 3 (it should work in Python 2.7). Moreover, if you are using a recent version of macOS, you don't have to use homebrew to separately install OpenSSL either.
$ virtualenv --python=/usr/bin/python tempenv # uses system python
$ . tempenv/bin/activate
$ pip install requests
$ python
>>> import ssl
>>> ssl.OPENSSL_VERSION
'OpenSSL 0.9.8zh 14 Jan 2016' # this is the built-in openssl
>>> import requests
>>> requests.get('https://api.github.com/users/octocat/orgs')
requests.exceptions.SSLError: HTTPSConnectionPool(host='api.github.com', port=443): Max retries exceeded with url: /users/octocat/orgs (Caused by SSLError(SSLError(1, u'[SSL: TLSV1_ALERT_PROTOCOL_VERSION] tlsv1 alert protocol version (_ssl.c:590)'),))
$ pip install 'requests[security]'
$ python # install requests[security] and try again
>>> import requests
>>> requests.get('https://api.github.com/users/octocat/orgs')
<Response [200]>
requests[security] allows requests to use the latest version of TLS when negotiating the connection. The built-in openssl on macOS supports TLS v1.2.
Before you install your own version of OpenSSL, ask this question: how is Google Chrome loading https://github.com?
I believe TLSV1_ALERT_PROTOCOL_VERSION is alerting you that the server doesn't want to talk TLS v1.0 to you. Try to specify TLS v1.2 only by sticking in these lines:
import ssl
from http.client import HTTPSConnection
context = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2)
# Create HTTPS connection
c = HTTPSConnection("0.0.0.0", context=context)
Note, you may need sufficiently new versions of Python (2.7.9+ perhaps?) and possibly OpenSSL (I have "OpenSSL 1.0.2k 26 Jan 2017" and the above seems to work, YMMV)
None of the accepted answers pointed me in the right direction, and this is still the question that comes up when searching the topic, so here's my (partially) successful saga.
Background: I run a Python script on a Beaglebone Black that polls the cryptocurrency exchange Poloniex using the python-poloniex library. It suddenly stopped working with the TLSV1_ALERT_PROTOCOL_VERSION error.
Turns out that OpenSSL was fine, and trying to force a v1.2 connection was a huge wild goose chase - the library will use the latest version as necessary. The weak link in the chain was actually Python, which only defined ssl.PROTOCOL_TLSv1_2, and therefore started supporting TLS v1.2, since version 3.4.
Meanwhile, the version of Debian on the Beaglebone considers Python 3.3 the latest. The workaround I used was to install Python 3.5 from source (3.4 might have eventually worked too, but after hours of trial and error I'm done):
sudo apt-get install build-essential checkinstall
sudo apt-get install libreadline-gplv2-dev libncursesw5-dev libssl-dev libsqlite3-dev tk-dev libgdbm-dev libc6-dev libbz2-dev
wget https://www.python.org/ftp/python/3.5.4/Python-3.5.4.tgz
sudo tar xzf Python-3.5.4.tgz
cd Python-3.5.4
./configure
sudo make altinstall
Maybe not all those packages are strictly necessary, but installing them all at once saves a bunch of retries. The altinstall prevents the install from clobbering existing python binaries, installing as python3.5 instead, though that does mean you have to re-install additional libraries. The ./configure took a good five or ten minutes. The make took a couple of hours.
Now this still didn't work until I finally ran
sudo -H pip3.5 install requests[security]
Which also installs pyOpenSSL, cryptography and idna. I suspect pyOpenSSL was the key, so maybe pip3.5 install -U pyopenssl would have been sufficient but I've spent far too long on this already to make sure.
So in summary, if you get TLSV1_ALERT_PROTOCOL_VERSION error in Python, it's probably because you can't support TLS v1.2. To add support, you need at least the following:
OpenSSL 1.0.1
Python 3.4
requests[security]
This has got me past TLSV1_ALERT_PROTOCOL_VERSION, and now I get to battle with SSL23_GET_SERVER_HELLO instead.
Turns out this is back to the original issue of Python selecting the wrong SSL version. This can be confirmed by using this trick to mount a requests session with ssl_version=ssl.PROTOCOL_TLSv1_2. Without it, SSLv23 is used and the SSL23_GET_SERVER_HELLO error appears. With it, the request succeeds.
The final battle was to force TLSv1_2 to be picked when the request is made deep within a third party library. Both this method and this method ought to have done the trick, but neither made any difference. My final solution is horrible, but effective. I edited /usr/local/lib/python3.5/site-packages/urllib3/util/ssl_.py and changed
def resolve_ssl_version(candidate):
"""
like resolve_cert_reqs
"""
if candidate is None:
return PROTOCOL_SSLv23
if isinstance(candidate, str):
res = getattr(ssl, candidate, None)
if res is None:
res = getattr(ssl, 'PROTOCOL_' + candidate)
return res
return candidate
to
def resolve_ssl_version(candidate):
"""
like resolve_cert_reqs
"""
if candidate is None:
return ssl.PROTOCOL_TLSv1_2
if isinstance(candidate, str):
res = getattr(ssl, candidate, None)
if res is None:
res = getattr(ssl, 'PROTOCOL_' + candidate)
return res
return candidate
and voila, my script can finally contact the server again.
As of July 2018, Pypi now requires that clients connecting to it use TLS 1.2. This is an issue if you're using the version of python shipped with MacOS (2.7.10) because it only supports TLS 1.0. You can change the version of ssl that python is using to fix the problem or upgrade to a newer version of python. Use homebrew to install the new version of python outside of the default library location.
brew install python#2
For Mac OS X
1) Update to Python 3.6.5 using the native app installer downloaded from the official Python language website https://www.python.org/downloads/
I've found that the installer is taking care of updating the links and symlinks for the new Python a lot better than homebrew.
2) Install a new certificate using "./Install Certificates.command" which is in the refreshed Python 3.6 directory
> cd "/Applications/Python 3.6/"
> sudo "./Install Certificates.command"
Another source of this problem: I found that in Debian 9, the Python httplib2 is hardcoded to insist on TLS v1.0. So any application that uses httplib2 to connect to a server that insists on better security fails with TLSV1_ALERT_PROTOCOL_VERSION.
I fixed it by changing
context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
to
context = ssl.SSLContext()
in /usr/lib/python3/dist-packages/httplib2/__init__.py .
Debian 10 doesn't have this problem.
I got this problem too.
In macos, here is the solution:
Step 1: brew restall python. now you got python3.7 instead of the old python
Step 2: build the new env base on python3.7. my path is /usr/local/Cellar/python/3.7.2/bin/python3.7
now, you'll not being disturbed by this problem.
I encountered this exact issue when I attempted gem install bundler, and I was confused by all the Python responses (since I was using Ruby). Here was my exact error:
ERROR: Could not find a valid gem 'bundler' (>= 0), here is why:
Unable to download data from https://rubygems.org/ - SSL_connect returned=1 errno=0 state=SSLv2/v3 read server hello A: tlsv1 alert protocol version (https://rubygems.org/latest_specs.4.8.gz)
My solution: I updated Ruby to the most recent version (2.6.5). Problem solved.
I ran into this issue using Flask with the flask_mqtt extension. The solution was to add this to the Python file:
app.config['MQTT_TLS_VERSION'] = ssl.PROTOCOL_TLSv1_2
I am setting up buildbot to use an iCloud email address as Status Target :
m = mail.MailNotifier(fromaddr="some_icloud_user#me.com",
sendToInterestedUsers=False,
extraRecipients=["some_other_icloud_users#me.com"],
useTls=True, relayhost="smtp.mail.me.com", smtpPort=587,
smtpUser="some_icloud_user#me.com", smtpPassword="some_icloud_password")
(the iCloud email setup instructions are here).
Seems like there's something wrong with the TLS/SSL handshake (from master/twistd.log) :
2014-06-09 00:43:34-0700 [ESMTPSender,client] SMTP Client retrying server. Retry: 1
2014-06-09 00:43:34-0700 [ESMTPSender,client] Unhandled Error
Traceback (most recent call last):
File "/Users/ionut/work/buildbot/sandbox/lib/python2.7/site-packages/Twisted-14.0.0-py2.7-macosx-10.9-intel.egg/twisted/internet/tcp.py", line 214, in doRead
return self._dataReceived(data)
File "/Users/ionut/work/buildbot/sandbox/lib/python2.7/site-packages/Twisted-14.0.0-py2.7-macosx-10.9-intel.egg/twisted/internet/tcp.py", line 220, in _dataReceived
rval = self.protocol.dataReceived(data)
File "/Users/ionut/work/buildbot/sandbox/lib/python2.7/site-packages/Twisted-14.0.0-py2.7-macosx-10.9-intel.egg/twisted/protocols/basic.py", line 571, in dataReceived
why = self.lineReceived(line)
File "/Users/ionut/work/buildbot/sandbox/lib/python2.7/site-packages/Twisted-14.0.0-py2.7-macosx-10.9-intel.egg/twisted/mail/smtp.py", line 1063, in lineReceived
why = self._okresponse(self.code,'\n'.join(self.resp))
--- <exception caught here> ---
File "/Users/ionut/work/buildbot/sandbox/lib/python2.7/site-packages/Twisted-14.0.0-py2.7-macosx-10.9-intel.egg/twisted/mail/smtp.py", line 1411, in esmtpState_starttls
self.transport.startTLS(self.context)
exceptions.AttributeError: 'Client' object has no attribute 'startTLS'
2014-06-09 00:43:34-0700 [ESMTPSender,client] Unhandled error in Deferred:
2014-06-09 00:43:34-0700 [ESMTPSender,client] Unhandled Error
Traceback (most recent call last):
Failure: twisted.mail.smtp.TLSError: 451 Could not complete the SSL/TLS handshake
<<< 250-NO-SOLICITING
<<< 250 SIZE 28311552
>>> STARTTLS
<<< 220 2.5.0 Go ahead with TLS negotiation.
Note : I am NOT able to send email from the command line via "mail" or "sendmail" - I didn't bother since I noticed buildbot has its own email client Python code.
Please help - thank you !
With all of the anti-spam measures in place these days, the strategy of sending mail directly to the recipient's mail server is unlikely to work very well. You would do better to either use your organization's SMTP server.
That aside, I suspect that the problem here is that you don't have pycrypto installed, or are using a Twisted reactor that doesn't support TLS.
Solved it : since buildbot uses virtualenv, I needed to install pyOpenSSL via easy_install - in the directory that contains the local python env (i.e., the "sandbox") I ran "easy_install pyopenssl" and the SSL handshake proceeded correctly, so buildbot can send emails now. Initially, I "installed" pyOpenSSL by linking to the SSL directory from inside the system Python framework. Looks like the buildbot install script doesn't install pyOpenSSL, weird. Thank you !