2015-02-27 17 views
6

Sto utilizzando un proxy (dietro il firewall aziendale) per accedere a un dominio https. L'handshake SSL non sembra andare per il meglio:CertificateError: hostname non corrisponde a

CertificateError: hostname 'ats.finra.org:443' doesn't match 'ats.finra.org' 

sto usando Python 2.7.9 - Mechanize e ho ottenuto oltre tutte le schermate di login, la password, questioon sicurezza, ma si sta facendo appeso sulla certificazione.

Qualsiasi aiuto sarebbe sorprendente. Ho provato la chiave inglese trovata qui: Forcing Mechanize to use SSLv3

Tuttavia non funziona per il mio codice.

Se si desidera il file di codice, saremo lieti di inviarlo.

+0

Puoi quasi tutto il codice 'monkey-patch', forse questo può aiutarti http://stackoverflow.com/questions/28282797/feedparser-parse-ssl-certificate-verify-failed – cmidi

+1

Potrebbe essere interessante vedere il codice che stai usando Potrebbe essere semplicemente dare "host: port" dove invece è previsto solo il nome host, in modo che usi il nome sbagliato (cioè "host: port" invece di "host") per la verifica del nome host. Sono sicuro che non ha nulla a che fare con SSLv3. –

+0

Ciao @cmidi grazie per la risposta. Proverò quel codice lunedì. – pugmastaflex

risposta

3

Questo bug in ssl.math_hostname appare in v2.7.9 (non è in 2.7.5) e ha a che fare con lo stripping del nome host dal sintassi hostname: port. La seguente riscrittura di ssl.match_hostname corregge il bug. Mettete questo prima che il codice di mechanize:

import functools, re, urlparse 
import ssl 

old_match_hostname = ssl.match_hostname 

@functools.wraps(old_match_hostname) 
def match_hostname_bugfix_ssl_py_2_7_9(cert, hostname): 
    m = re.search(r':\d+$',hostname) # hostname:port 
    if m is not None: 
     o = urlparse.urlparse('https://' + hostname) 
     hostname = o.hostname 
    old_match_hostname(cert, hostname) 

ssl.match_hostname = match_hostname_bugfix_ssl_py_2_7_9 

Il seguente meccanizzare codice ora dovrebbe funzionare:

import mechanize 
import cookielib 

br = mechanize.Browser() 

# Cookie Jar 
cj = cookielib.LWPCookieJar() 
br.set_cookiejar(cj) 

# Browser options 
br.set_handle_equiv(True) 
br.set_handle_gzip(True) 
br.set_handle_redirect(True) 
br.set_handle_referer(True) 
br.set_handle_robots(False) 

# Follows refresh 0 but not hang on refresh > 0 
br.set_handle_refresh(mechanize._http.HTTPRefreshProcessor(), max_time=1) 

br.addheaders = [('User-Agent', 'Nutscrape 1.0')] 
# Use this proxy 
br.set_proxies({"http": "localhost:3128", "https": "localhost:3128"}) 
r = br.open('https://www.duckduckgo.com:443/') 
html = br.response().read() 
# Examine the html response from a browser 
f = open('foo.html','w') 
f.write(html) 
f.close() 
+3

L'errore è stato segnalato da qualche parte? Possiamo avere un link per favore? È stato risolto nelle versioni più recenti? – geckon

4

È possibile evitare questo errore scimmia patching ssl:

import ssl 
ssl.match_hostname = lambda cert, hostname: True 
0

Nel mio caso il il nome DNS del certificato era ::1 (per scopi di test locali) e la verifica del nome host non è riuscita con

ssl.CertificateError: hostname '::1' doesn't match '::1' 

per risolvere il problema in qualche modo scimmia correttamente ho patchato ssl.match_hostname con

import ssl                                                
ssl.match_hostname = lambda cert, hostname: hostname == cert['subjectAltName'][0][1] 

che in realtà controlla se la partita hostname.

Problemi correlati