TLS with timeouts (and several other difficulties)

I have an HTTP client in Python that should use TLS. I need not only to create encrypted connections, but also to extract information from a remote machine, such as a certificate issuer. I need to make a connection with many HTTP servers, it often behaves badly, so I absolutely need to have a timeout. When using connections other than TLS, mysocket.settimeout(5)it does what I want.

Among the many Python TLS modules:

python-gnutls does not allow settimeout () for sockets, because it uses non-blocking sockets:

gnutls.errors.OperationWouldBlock: Function was interrupted.

python-openssl has a similar problem:

OpenSSL.SSL.WantReadError

The standard library SSL module does not work with Python 2.5.

Other libraries, such as TLSlite , do not seem to allow access to certificate metadata.

The program is threaded, so I can not use signals. I need a detailed description control the HTTP dialog, so I can not use a standard library such as urllib2.

Background: This is a DNSwitness study project . Relevant SO threads: Python function timeout and How to limit the execution time of a function call in Python .

+3
source share
4 answers

, Twisted , . , , PyOpenSSL ( Twisted). , Twisted callback-based ( ).

, , , , -, .., (. ).

+1

, : PyOpenSSL, WantReadError. . :

#!/usr/bin/python

import OpenSSL
import socket
import struct

context = OpenSSL.SSL.Context(OpenSSL.SSL.TLSv1_METHOD)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.settimeout(5)
connection = OpenSSL.SSL.Connection(context,s)
connection.connect(("www.gmail.com",443))

# Put the socket in blocking mode
connection.setblocking(1)

# Set the timeout using the setsockopt
tv = struct.pack('ii', int(6), int(0))
connection.setsockopt(socket.SOL_SOCKET, socket.SO_RCVTIMEO, tv)

print "Connected to " , connection.getpeername()
print "Sate " , connection.state_string()

while True:
    try:
        connection.do_handshake()
        break
    except OpenSSL.SSL.WantReadError:
        print "Exception"
        pass
print "Sate " , connection.state_string()


print connection.send("koekoek\r\n")


while True:
    try:
        recvstr = connection.recv(1024)
        break
    except OpenSSL.SSL.WantReadError:
        print "Exception"
        pass

print recvstr 

SSL- gmail, , . , : * * - recv 6 .

, , , WantReadError , 6 . ( True, , ). -, , , connect().

, , , GNUTLS, - , , , True, : WantReadError, , , .

+1

. gnutls, :

  • Set settimeout () on a socket before connecting () on a bare socket wrapped by gnutls, so connect () is subject to a timeout as you would like.
  • Make sure you delete the timeout with the setting (None) or setblocking (1) BEFORE ASSIGNING GnuTLS ()
0
source

Source: https://habr.com/ru/post/1705208/


All Articles