Force use of tls with requests

Hi !

I have used requests successfully for calling some rest resources. 
I have called these resources in our staging environment, and things has worked well. 
Now I've tried to call the resources in our test environment, but receives the error SSL3_GET_RECORD:decryption failed or bad record mac. 

I recon there is a problem with the ssl connection, and want to try forcing requests to use TLS v1. How can I achieve this? I have tried creating the class ForceTLSV1Adapter which is described here http://stackoverflow.com/questions/26733462/ssl-and-tls-in-python-requests, but I don't know how to tell requests to use this class. Could you please give me a hint?

Thanks in advance

Tor Erik


By the way, I've seen the advanced usage documentation (http://docs.python-requests.org/en/latest/user/advanced/), and tried to modify the Ssl3HttpAdapter to be a TLS Adapter. 
I use s = requests.Session() s.mount to mount the adapter. In the mount command, I have both tried the rest resource url and the root url (https://mydomain.com)


It's possible that the SSL version you need to try isn't TLSv1. Try SSLv3, for example.

> On 17 Dec 2014, at 10:01, tesande notifications@github.com wrote:
> 
> By the way, I've seen the advanced usage documentation (http://docs.python-requests.org/en/latest/user/advanced/), and tried to modify the Ssl3HttpAdapter to be a TLS Adapter. 
> I use s = requests.Session() s.mount to mount the adapter. In the mount command, I have both tried the rest resource url and the root url (https://mydomain.com)
> 
> —
> Reply to this email directly or view it on GitHub.


I have tried that as well. Same error message. To me it seems the adapter isn't used, since the error message indicates SSL3. 
How is it supposed to be plugged in? Am I correct about the request.Session() and mount() Should I mount all the addresses, or only the domain url?


The adapter is definitely being used if correctly plugged in. When you call `mount`, you pass two arguments: the first is a prefix to match, the second is an instance of your adapter. So long as your prefix matches your URL this should work fine: if it continues to fail, the problem is not that.

Again, try all the TLS constants available to you, all the way up to PROTOCOL_TLSv1_2 if your OpenSSL supports it. If that continues not to work, the problem is not the protocol we're using to do the negotiation.


I ran my two servers through ssllabs. One big difference is: 
There is no support for secure renegotiation. 

I guess this could be a reason. Is it a workaround, or do I have to make the ops guys update the server?


I have tried the following: Changed protocol for communication with one of the working servers to SSL2. Although my server doesn't support SSL 2 (Stated by ssllabs), the communication still works. I think that's weird. 

Here is my mounting code: 
urltorun = environment + "/" + url
s=requests.Session()
s.mount(urltorun,Ssl3HttpAdapter() )#Has changed the class implementation but not the class name
smoketeststorun = requests.get(urltorun)

Adapter: 
class Ssl3HttpAdapter(HTTPAdapter):

```
def init_poolmanager(self, connections, maxsize, block=False):
    print 'Yjoooooooooooooooooooooooooooninh'
    self.poolmanager = PoolManager(num_pools=connections,
                                   maxsize=maxsize,
                                   block=block,
                                   ssl_version=ssl.PROTOCOL_TLSv1)
```


That code appears to negotiate TLSv1, not SSLv2.


This is clearly _not_ a bug in requests. Further work on this _question_ should take place on the forum for questions about requests, [StackOverflow](https://stackoverflow.com/questions/tagged/python-requests).