ó õùPc @sºdZddlZddlZddlmZmZmZddlmZddlmZmZm Z ddlm Z m Z m Z m Z ddlmZmZmZddlmZmZmZmZmZmZmZmZmZdd lmZmZmZmZdd lmZ ddl!Z!ddl"Z"d efd „ƒYZ#dde%ee de&e&dd „ Z'd„Z(dZ)dZ*d„Z+d„Z,e dd„Z-d„Z.ddd„Z/dS(sThis module provides some more Pythonic support for SSL. Object types: SSLSocket -- subtype of socket.socket which does SSL over the socket Exceptions: SSLError -- exception raised for I/O errors Functions: cert_time_to_seconds -- convert time string used for certificate notBefore and notAfter functions to integer seconds past the Epoch (the time values returned from time.time()) fetch_server_certificate (HOST, PORT) -- fetch the certificate provided by the server running on HOST at port PORT. No validation of the certificate is performed. Integer constants: SSL_ERROR_ZERO_RETURN SSL_ERROR_WANT_READ SSL_ERROR_WANT_WRITE SSL_ERROR_WANT_X509_LOOKUP SSL_ERROR_SYSCALL SSL_ERROR_SSL SSL_ERROR_WANT_CONNECT SSL_ERROR_EOF SSL_ERROR_INVALID_ERROR_CODE The following group define certificate requirements that one side is allowing/requiring from the other side: CERT_NONE - no certificates from the other side are required (or will be looked at if provided) CERT_OPTIONAL - certificates are not required, but if provided will be validated, and if validation fails, the connection will also fail CERT_REQUIRED - certificates are required, and will be validated, and if validation fails, the connection will also fail The following constants identify various SSL protocol variants: PROTOCOL_SSLv2 PROTOCOL_SSLv3 PROTOCOL_SSLv23 PROTOCOL_TLSv1 iÿÿÿÿN(tOPENSSL_VERSION_NUMBERtOPENSSL_VERSION_INFOtOPENSSL_VERSION(tSSLError(t CERT_NONEt CERT_OPTIONALt CERT_REQUIRED(tPROTOCOL_SSLv2tPROTOCOL_SSLv3tPROTOCOL_SSLv23tPROTOCOL_TLSv1(t RAND_statustRAND_egdtRAND_add( tSSL_ERROR_ZERO_RETURNtSSL_ERROR_WANT_READtSSL_ERROR_WANT_WRITEtSSL_ERROR_WANT_X509_LOOKUPtSSL_ERROR_SYSCALLt SSL_ERROR_SSLtSSL_ERROR_WANT_CONNECTt SSL_ERROR_EOFtSSL_ERROR_INVALID_ERROR_CODE(tsockett _fileobjectt_delegate_methodsterror(t getnameinfot SSLSocketc Bs eZdZddeeedeedd„ Zdd„Z d„Z ed„Z d„Z dd„Z dd „Zdd „Zddd „Zddd „Zddd „Zddd„Zd„Zd„Zd„Zd„Zd„Zd„Zd„Zddd„ZRS(sµThis class implements a subtype of socket.socket that wraps the underlying OS socket in an SSL context when necessary, and provides read and write methods over that channel.c Cs<tj|d|jƒx3tD]+} yt|| ƒWqtk rGqXqW|rb| rb|}nytj|ƒWn4tk r©} | jtj kr‚nd|_ n>Xt j |j||||||| ƒ|_ |rç|jƒn||_||_||_||_||_| |_||_| |_d|_dS(Nt_socki(Rt__init__RRtdelattrtAttributeErrort getpeernamet socket_errorterrnotENOTCONNtNonet_sslobjt_ssltsslwrapt do_handshaketkeyfiletcertfilet cert_reqst ssl_versiontca_certstcipherstdo_handshake_on_connecttsuppress_ragged_eofst_makefile_refs( tselftsockR*R+t server_sideR,R-R.R0R1R/tattrte((s..\python\lib\ssl.pyRYs:                icCsQy|jj|ƒSWn6tk rL}|jdtkrF|jrFdS‚nXdS(sORead up to LEN bytes and return them. Return zero-length string on EOF.itN(R&treadRtargsRR1(R3tlentx((s..\python\lib\ssl.pyR9„s cCs|jj|ƒS(shWrite DATA to the underlying SSL channel. Returns number of bytes of DATA actually transmitted.(R&twrite(R3tdata((s..\python\lib\ssl.pyR=‘scCs|jj|ƒS(sáReturns a formatted version of the data in the certificate provided by the other end of the SSL channel. Return None if no certificate was provided, {} if a certificate was provided, but not validated.(R&tpeer_certificate(R3t binary_form((s..\python\lib\ssl.pyt getpeercert˜scCs|js dS|jjƒSdS(N(R&R%tcipher(R3((s..\python\lib\ssl.pyRB¡s icCs³|jrœ|dkr+td|jƒ‚nxtr˜y|jj|ƒ}WnDtk r}|jdtkrsdS|jdtkrŠdS‚q.X|Sq.Wn|j j ||ƒSdS(Nis3non-zero flags not allowed in calls to send() on %s( R&t ValueErrort __class__tTrueR=RR:RRRtsend(R3R>tflagstvR<((s..\python\lib\ssl.pyRF¨s     cCsX|jrtd|jƒ‚n5|dkr>|jj||ƒS|jj|||ƒSdS(Ns%sendto not allowed on instances of %s(R&RCRDR%Rtsendto(R3R>t flags_or_addrtaddr((s..\python\lib\ssl.pyRI½s   cCsˆ|jrq|dkr+td|jƒ‚nt|ƒ}d}x-||krl|j||ƒ}||7}q@W|Stj|||ƒSdS(Nis6non-zero flags not allowed in calls to sendall() on %s(R&RCRDR;RFRtsendall(R3R>RGtamounttcountRH((s..\python\lib\ssl.pyRLÆs   cCsO|jr8|dkr+td|jƒ‚n|j|ƒS|jj||ƒSdS(Nis3non-zero flags not allowed in calls to recv() on %s(R&RCRDR9Rtrecv(R3tbuflenRG((s..\python\lib\ssl.pyROÕs   cCs¤|r!|dkr!t|ƒ}n|dkr6d}n|jrŠ|dkratd|jƒ‚n|j|ƒ}t|ƒ}|||*|S|jj|||ƒSdS(Niis8non-zero flags not allowed in calls to recv_into() on %s(R%R;R&RCRDR9Rt recv_into(R3tbuffertnbytesRGt tmp_bufferRH((s..\python\lib\ssl.pyRQßs      cCs6|jrtd|jƒ‚n|jj||ƒSdS(Ns'recvfrom not allowed on instances of %s(R&RCRDRtrecvfrom(R3RPRG((s..\python\lib\ssl.pyRUðs cCs9|jrtd|jƒ‚n|jj|||ƒSdS(Ns,recvfrom_into not allowed on instances of %s(R&RCRDRt recvfrom_into(R3RRRSRG((s..\python\lib\ssl.pyRV÷s cCs|jr|jjƒSdSdS(Ni(R&tpending(R3((s..\python\lib\ssl.pyRWþs  cCs?|jr%|jjƒ}d|_|Stdt|ƒƒ‚dS(NsNo SSL wrapper around (R&tshutdownR%RCtstr(R3ts((s..\python\lib\ssl.pytunwraps   cCsd|_tj||ƒdS(N(R%R&RRX(R3thow((s..\python\lib\ssl.pyRX s cCs;|jdkr(d|_tj|ƒn|jd8_dS(Ni(R2R%R&Rtclose(R3((s..\python\lib\ssl.pyR]s cCs|jjƒdS(sPerform a TLS/SSL handshake.N(R&R)(R3((s..\python\lib\ssl.pyR)sc Cs~|jrtdƒ‚ntj||ƒtj|jt|j|j |j |j |j |j ƒ|_|jrz|jƒndS(sQConnects to remote ADDR, and then wraps the connection in an SSL channel.s/attempt to connect already-connected SSLSocket!N(R&RCRtconnectR'R(RtFalseR*R+R,R-R.R/R0R)(R3RK((s..\python\lib\ssl.pyR^s   cCsstj|ƒ\}}t|d|jd|jdtd|jd|jd|jd|j d|j d |j ƒ |fS( s¿Accepts a new connection from a remote client, and returns a tuple containing that new connection wrapped with a server-side SSL channel, and the address of the remote client.R*R+R5R,R-R.R/R0R1( RtacceptRR*R+RER,R-R.R/R0R1(R3tnewsockRK((s..\python\lib\ssl.pyR`-s         triÿÿÿÿcCs%|jd7_t|||dtƒS(sMake and return a file-like object that works with the SSL connection. Just use the code from the socket module.iR](R2RRE(R3tmodetbufsize((s..\python\lib\ssl.pytmakefile@sN(t__name__t __module__t__doc__R%R_RR RERR9R=RARBRFRIRLRORQRURVRWR[RXR]R)R^R`Re(((s..\python\lib\ssl.pyRSs2'            c Cs@t|d|d|d|d|d|d|d|d|d | ƒ S( NR*R+R5R,R-R.R0R1R/(R( R4R*R+R5R,R-R.R0R1R/((s..\python\lib\ssl.pyt wrap_socketMs   cCs%ddl}|j|j|dƒƒS(s¢Takes a date-time string in standard ASN1_print form ("MON DAY 24HOUR:MINUTE:SEC YEAR TIMEZONE") and return a Python time value in seconds past the epoch.iÿÿÿÿNs%b %d %H:%M:%S %Y GMT(ttimetmktimetstrptime(t cert_timeRj((s..\python\lib\ssl.pytcert_time_to_seconds]s s-----BEGIN CERTIFICATE-----s-----END CERTIFICATE-----cCscttdƒrBtj|ƒ}tdtj|dƒdtdStdtj|ƒtdSdS(s[Takes a certificate in binary DER format and returns the PEM version of it as a string.tstandard_b64encodes i@N(thasattrtbase64Rot PEM_HEADERttextwraptfillt PEM_FOOTERt encodestring(tder_cert_bytestf((s..\python\lib\ssl.pytDER_cert_to_PEM_certis$cCsw|jtƒs"tdtƒ‚n|jƒjtƒsJtdtƒ‚n|jƒttƒttƒ !}tj|ƒS(shTakes a certificate in ASCII PEM format and returns the DER-encoded version of it as a byte sequences(Invalid PEM encoding; must start with %ss&Invalid PEM encoding; must end with %s( t startswithRrRCtstriptendswithRuR;Rqt decodestring(tpem_cert_stringtd((s..\python\lib\ssl.pytPEM_cert_to_DER_certys   cCsx|\}}|dk r!t}nt}ttƒd|d|d|ƒ}|j|ƒ|jtƒ}|jƒt |ƒS(s÷Retrieve the certificate from the server at the specified address, and return it as a PEM-encoded string. If 'ca_certs' is specified, validate the server cert against it. If 'ssl_version' is specified, use it in the connection attempt.R-R,R.N( R%RRRiRR^RARER]Ry(RKR-R.thosttportR,RZtdercert((s..\python\lib\ssl.pytget_server_certificate‡s     cCsH|tkrdS|tkr dS|tkr0dS|tkr@dSdSdS(NtTLSv1tSSLv23tSSLv2tSSLv3s (R R RR(t protocol_code((s..\python\lib\ssl.pytget_protocol_namešs    cCslt|dƒr|j}ntj|d||ttdƒ}y|jƒWntk r]n X|j ƒ|S(sŒA replacement for the old socket.ssl function. Designed for compability with Python 2.5 and earlier. Will disappear in Python 3.0.RiN( RpRR'R(RR R%R!R"R)(R4R*R+tssl_sock((s..\python\lib\ssl.pytsslwrap_simple©s    (0RhRsR'RRRRRRRRRR R R R R RRRRRRRRRRRRRR"Rt _getnameinfoRqR#RR%R_RERiRnRrRuRyR€R„RŠRŒ(((s..\python\lib\ssl.pyt8s4  "@ "  ú