2013-07-06 13 views
6

Próbuję użyć Pythona 2.7 mechanize zalogować się do Mint.com z następującego kodu:Python ssl logowanie wiszące na Debianie

import mechanize 
br = mechanize.Browser() 
br.open("https://wwws.mint.com/login.event") 

to działa dobrze na OSX, ale wisi na Debianie. Problem wydaje się być związany z SSL; ślad błędu kończy

File "/usr/lib/python2.7/ssl.py", line 305, in do_handshake 
    self._sslobj.do_handshake() 

EDIT: problem nie zostanie rozwiązany przy użyciu urllib2 na Debianie. Jak zasugerowano w komentarzach, wydaje się, że problem jest w rzeczywistości związany z SSL. Dlaczego miałby to być problem z Debianem, a nie z OSX?

+0

Myślę, że nie ma to związku z samą mechanizacją, ma znaczenie dla python stdlib - patrz [ten problem] (http://bugs.python.org/issue1251). – alecxe

+0

@alecxe wielkie dzięki, że wydaje się mieć zastosowanie. Jednakże, zgodnie z tym wątkiem, ten problem powinien zostać załatany ... co oczywiście nie jest. Jakiś pomysł, co mogę zrobić, żeby sprawy zadziałały? Ponadto, jeśli ten błąd był przyczyną problemu, czy nie byłby to problem również w OSX, ponieważ oba są zarówno Pythonem 2.7.3? – rickcnagy

+0

Cóż, trudno powiedzieć. Kod działa dla mnie na Ubuntu 12.04 przy użyciu Pythona 2.7.3. – alecxe

Odpowiedz

1

Więc wszystko wygląda OK w Fedorze:

[[email protected] ~]$ python 
Python 2.7.5 (default, Aug 22 2013, 09:31:58) 
[GCC 4.8.1 20130603 (Red Hat 4.8.1-1)] on linux2 
Type "help", "copyright", "credits" or "license" for more information. 
>>> import mechanize 
>>> br = mechanize.Browser() 
>>> br.open("https://wwws.mint.com/login.event") 
<response_seek_wrapper at 0x29b6440 whose wrapped object = <closeable_response at 0x29b6320 whose fp = <socket._fileobject object at 0x298d150>>> 
>>> br.title() 
'Mint > Start Here' 
>>> 

co prowadzi mnie do zastanawiać SSL/biblioteki OpenSSL w użyciu. Wystarczy, aby przetestować go można uruchomić z wiersza poleceń:

$ openssl s_client -connect wwws.mint.com:443 

powinien pojawić się certyfikat SSL dla mięty wyświetlany wraz z weryfikacji pełnego łańcucha certyfikatów i ostatnim wierszu: "Sprawdź, czy kod powrotu: 0 (ok) "

Podczas gdy I wysoce wątpię, że jest to problem związany z SSL, sądzę, że warto go sprawdzić. Dodatkowo sprawdź wersję mechanizatora. Debian wyróżnia się stabilnymi wersjami kodu (nie nowymi wersjami). Wersja, którą zweryfikowałem z mechanizacją, to 0.2.5

1

Jest to przejaw niezgodności między najnowszymi wersjami OpenSSL a niektórymi serwerami WWW. Apple stara się jak najlepiej wyeliminować OpenSSL na OS X, więc stosują tylko łaty bezpieczeństwa (OpenSSL było trudne do obsługi w ramach systemu operacyjnego, nie wspominając o "drobnych" aktualizacjach wprowadzających takie problemy), podczas gdy Debian używa nowszy OpenSSL 1.0.1.

@ Sugestia Briana Redbearda, by sprawdzić z linią poleceń openssl jest dobra - zawiesiła się na wwws.mint.com, gdy tylko spróbowałem.

na ServerFault ostatecznie dostarczył odpowiedź. Łączony tam test SSLLab identyfikuje numer long handshake intolerance jako problem, który wpływa na OpenSSL 1.0.1 i późniejsze, i łączy się z OpenSSL bug z potencjalnymi obejściami.

Albo używając -no_tls1_2, jako jeden z deweloperów OpenSSL zaleca albo zmniejszenie szyfr listę z -cipher argumentu powoduje OpenSSL 1.0.1 z powodzeniem uścisk dłoni z wwws.mint.com (jak również inny serwer Starałem się skontaktować).

Dla moich celów - skrypt, który nie będzie dystrybuowany - I monkeypatched ssl.wrap_socket następująco:

import ssl 
old_wrap_socket = ssl.wrap_socket 
def wrap_socket(sock, keyfile=None, certfile=None, 
       server_side=False, cert_reqs=ssl.CERT_NONE, 
       ssl_version=ssl.PROTOCOL_SSLv3, ca_certs=None, 
       do_handshake_on_connect=True, 
       suppress_ragged_eofs=True, ciphers=None): 
    return old_wrap_socket(sock, keyfile, certfile, 
          server_side, cert_reqs, ssl_version, 
          ca_certs, do_handshake_on_connect, 
          suppress_ragged_eofs, ciphers) 
ssl.wrap_socket = wrap_socket 

import mechanize 

Domyślna wartość ssl_version jest ssl.PROTOCOL_SSLv23; zmieniając go na PROTOCOL_SSLv3 pomyślnie łączy.

Można ochronić tę poprawkę za pomocą testu, takiego jak ssl.OPENSSL_VERSION_INFO[:3] >= (1, 0, 1).

Powinno to zostać zgłoszone jako błąd Debiana OpenSSL, jeśli jeszcze go nie było.