2013-09-07 7 views
5

नोट: यह कोड उबंटू पर ठीक काम करता है लेकिन मैक पर नहीं और स्थानीय रूप से मैक/पायथन सेटिंग्स को बदलने की बजाय मैं कोड में परिवर्तन करने की कोशिश कर रहा हूं ताकि यह हर जगह काम करे ..पायथन हॉस्पिटलप्लिब SSL23_GET_SERVER_HELLO: अज्ञात प्रोटोकॉल

import ssl 
import httplib 
httplib.HTTPConnection(server, port, timeout) 

लेकिन यह फेंकता त्रुटि:

[Errno 1] _ssl.c:503: error:140770FC:SSL routines:SSL23_GET_SERVER_HELLO:unknown protocol

अब कोड का उपयोग नहीं कर रहा है urllib.request बजाय का उपयोग कर httplib

मैं तो यह डिफ़ॉल्ट प्रोटोकॉल, कुछ इस तरह के रूप में SSLv3 ले लेंगे कोड बदलना चाहते हैं:

ssl.SSLContext(ssl.PROTOCOL_SSLv3) 

मैं चारों ओर देखा और कुछ लिंक लेकिन कुछ भी काम कर रहा है मिल गया!

this link is for ubuntu

link for python urllib and cURL

python bug fix, but again for urllib

उत्तर

7

नोट:HTTPSConnection निर्माता अजगर 2.7.9 के बाद से तर्क, जो इस मामले में इस्तेमाल किया जाना चाहिए के रूप में एक SSL context पारित करने के लिए अनुमति देता है।

यह उत्तर उस परिवर्तन को पूर्ववत करता है और इसलिए केवल पाइथन के पुराने संस्करणों पर लागू होता है।


httplib.HTTPSConnection.connect सिर्फ एक https कनेक्शन initalize के लिए खोला सॉकेट पर ssl.wrap_socket कहता है, दुर्भाग्य से आप python2.7 में कोई पैरामीटर निर्दिष्ट नहीं कर सकते (python3 passing the SSLContext अनुमति देता है)।

आप प्रोटोकॉल संस्करण निर्दिष्ट करना चाहते हैं, तो आप बंदर पैच करने के लिए आवश्यकता होगी में से एक इन दो:

विधि 1: पैच httplib.HTTPSConnection.connect:

import httplib 
import socket 
import ssl 

def connect_patched(self): 
    "Connect to a host on a given (SSL) port." 

    sock = socket.create_connection((self.host, self.port), 
            self.timeout, self.source_address) 
    if self._tunnel_host: 
     self.sock = sock 
     self._tunnel() 
    self.sock = ssl.wrap_socket(sock, self.key_file, self.cert_file, 
           ssl_version=ssl.PROTOCOL_SSLv3) 

httplib.HTTPSConnection.connect = connect_patched 

इस के लिए प्रोटोकॉल संस्करण में परिवर्तन HTTPSConnection के साथ किए गए सभी कनेक्शन।

विधि 2: ssl.wrap_socket पैच:

import ssl 

wrap_socket_orig = ssl.wrap_socket 

def wrap_socket_patched(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 wrap_socket_orig(sock, keyfile, certfile, server_side, 
          cert_reqs, ssl_version, ca_certs, 
          do_handshake_on_connect, 
          suppress_ragged_eofs, ciphers) 

ssl.wrap_socket = wrap_socket_patched 

यह, सभी कोड wrap_socket का उपयोग करता है के लिए डिफ़ॉल्ट प्रोटोकॉल संस्करण बदलता है इसलिए भी अन्य पुस्तकालयों को प्रभावित करता है।

संपादित करें:

विधि 3: httplib वास्तव में ssl से केवल wrap_socket तक पहुँचता है क्योंकि, आप भी सिर्फ httplib.ssl एक वर्ग wrap_socket प्रदान करने के साथ बदल सकते थे।functools.partial का उपयोग करते हुए यह बहुत ही सुंदर इस लिखने के लिए बनाता है:

import httplib 
import ssl 
from functools import partial 

class fake_ssl: 
    wrap_socket = partial(ssl.wrap_socket, ssl_version=ssl.PROTOCOL_SSLv3) 

httplib.ssl = fake_ssl 
+1

मैं विधि 3 की कोशिश की और अब इसके फेंक "एसएसएल दिनचर्या: SSL3_GET_RECORD: गलत संस्करण संख्या" लेकिन अगर मैं द्वारा "openssl s_client -connect होस्ट सर्वर प्रोटोकॉल की जाँच करें: बंदरगाह | grep प्रोटोकॉल "यह रिटर्न" प्रोटोकॉल: एसएसएलवी 3 "! मैं अन्य विधियों और lyk कोशिश करेंगे .. – Peter

+1

अब सभी 3 विधियों को त्रुटि (सभी विधियों के लिए) "एसएसएल दिनचर्या: SSL3_GET_RECORD: गलत संस्करण संख्या" – Peter

+0

परिणाम समान होना चाहिए, इससे कोई फर्क नहीं पड़ता कि उपरोक्त तरीकों का कौन सा तरीका उपयोग। क्या आपने विभिन्न प्रोटोकॉल वर्सोइन की कोशिश की है? मुझे यकीन नहीं है कि आपको मिली त्रुटि को पुन: उत्पन्न कैसे करें। मुझे केवल एक ही त्रुटि मिलती है जब एक TLSv1 क्लाइंट का उपयोग कर किसी SSLv3 सर्वर से कनेक्ट हो रहा है ... – mata

संबंधित मुद्दे