2010-03-02 11 views
8

के साथ पारस्परिक प्रमाणपत्र प्रमाणीकरण कैसे करें मैं अपने सर्वर से किसी अन्य वेब सेवा पर अनुरोध करने के लिए httplib2 का उपयोग कर रहा हूं। हम आपसी प्रमाण पत्र प्रमाणीकरण का उपयोग करना चाहते हैं। मैं देखता हूं कि आउटगोइंग कनेक्शन (h.set_certificate) के लिए प्रमाणपत्र का उपयोग कैसे करें, लेकिन मैं उत्तर सर्वर द्वारा उपयोग किए गए प्रमाणपत्र की जांच कैसे करूं?httplib2

This ticket यह इंगित करता है कि httplib2 स्वयं ऐसा नहीं करता है, और कहां देखना है इसके बारे में केवल अस्पष्ट सुझाव हैं।

क्या यह संभव है? क्या मुझे निचले स्तर पर हैक करना होगा?

उत्तर

5

यहाँ कोड मेरे सह कार्यकर्ता डेव सेंट जर्मेन समस्या को हल करने में लिखा था है:

import ssl 
import socket 
from httplib2 import has_timeout 
import httplib2 
import socks 


class CertificateValidationError(httplib2.HttpLib2Error): 
    pass 


def validating_sever_factory(ca_cert_file): 
    # we need to define a closure here because we don't control 
    # the arguments this class is instantiated with 
    class ValidatingHTTPSConnection(httplib2.HTTPSConnectionWithTimeout): 

     def connect(self): 
      # begin copypasta from HTTPSConnectionWithTimeout 
      "Connect to a host on a given (SSL) port." 

      if self.proxy_info and self.proxy_info.isgood(): 
       sock = socks.socksocket(socket.AF_INET, socket.SOCK_STREAM) 
       sock.setproxy(*self.proxy_info.astuple()) 
      else: 
       sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 

      if has_timeout(self.timeout): 
       sock.settimeout(self.timeout) 
      sock.connect((self.host, self.port)) 
      # end copypasta 


      try: 
       self.sock = ssl.wrap_socket(sock, 
          self.key_file, 
          self.cert_file, 
          cert_reqs=ssl.CERT_REQUIRED, 
          ca_certs=ca_cert_file 
          ) 
      except ssl.SSLError: 
       # we have to capture the exception here and raise later because 
       # httplib2 tries to ignore exceptions on connect 
       import sys 
       self._exc_info = sys.exc_info() 
       raise 
      else: 
       self._exc_info = None 

       # this might be redundant 
       server_cert = self.sock.getpeercert() 
       if not server_cert: 
        raise CertificateValidationError(repr(server_cert)) 

     def getresponse(self): 
      if not self._exc_info: 
       return httplib2.HTTPSConnectionWithTimeout.getresponse(self) 
      else: 
       raise self._exc_info[1], None, self._exc_info[2] 
    return ValidatingHTTPSConnection 


def do_request(url, 
     method='GET', 
     body=None, 
     headers=None, 
     keyfile=None, 
     certfile=None, 
     ca_certs=None, 
     proxy_info=None, 
     timeout=30): 
    """ 
    makes an http/https request, with optional client certificate and server 
    certificate verification. 
    returns response, content 
    """ 
    kwargs = {} 
    h = httplib2.Http(proxy_info=proxy_info, timeout=timeout) 
    is_ssl = url.startswith('https') 
    if is_ssl and ca_certs: 
     kwargs['connection_type'] = validating_sever_factory(ca_certs) 

    if is_ssl and keyfile and certfile: 
     h.add_certificate(keyfile, certfile, '') 
    return h.request(url, method=method, body=body, headers=headers, **kwargs) 
3

शायद चीजों को अपने प्रश्न के बाद से बदल गया है, मैं के रूप में httplib2 v0.7 के साथ आपसी प्रमाणीकरण करने के लिए, सक्षम हूँ नीचे:

import httplib2 

h=httplib2.Http(ca_certs='ca.crt') 
h.add_certificate(key='client_private_key.pem', cert='cert_client.pem', domain='') 
try: resp, cont = h.request('https://mytest.com/cgi-bin/test.cgi') 
except Exception as e: print e 

नोट domain='' तर्क, इस एक ही रास्ता मैं यह काम

+2

[इस लिंक] के अनुसार कर सकता है (http://nullege.com/codes/search/httplib2 है .Http.add_certificate), 'डोमेन' सिर्फ एक होस्टनाम और पोर्ट होना चाहिए। – arturo

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