B =@Sa‰ã@sòddlZddlZddlZddlZddlmZddlmZmZddl Z ddl m Z ddl Z ddl mZddlZddlmZmZmZmZmZmZmZmZmZmZmZmZddlmZddlm Z m!Z!e  "e#¡Z$d Z%d Z&d Z'd Z(d ddgZ)dZ*dd„Z+dd„Z,Gdd„de-ƒZ.Gdd„de.ƒZ/Gdd„de.ƒZ0Gdd„de.ƒZ1Gdd„de1ƒZ2Gdd „d e1ƒZ3Gd!d"„d"e3ƒZ4Gd#d$„d$e1ƒZ5Gd%d&„d&e.ƒZ6Gd'd(„d(e6ƒZ7Gd)d*„d*e6ƒZ8e/e0e0e6e7e8e5d+œZ9erÚdd,l:m;Z;e9 |j}t|tjƒr$t | d¡¡}nt|tjƒr:t |¡}|S)Nzutf-8)ÚdataÚ isinstancer Ú binary_typer ÚloadsÚdecodeÚ string_types)Úrequestr$r!r!r"Ú_get_body_as_dictEs    r+c@seZdZdZdd„ZdS)Ú BaseSignerFcCs tdƒ‚dS)NÚadd_auth)ÚNotImplementedError)Úselfr*r!r!r"r-UszBaseSigner.add_authN)Ú__name__Ú __module__Ú __qualname__ÚREQUIRES_REGIONr-r!r!r!r"r,Rsr,c@s(eZdZdZdd„Zdd„Zdd„ZdS) Ú SigV2Authz+ Sign a request with Signature V2. cCs ||_dS)N)Ú credentials)r/r5r!r!r"Ú__init__^szSigV2Auth.__init__c Csþt d¡t|jƒ}|j}t|ƒdkr*d}d|j|j|f}tj |j j   d¡t d}g}xVt|ƒD]J}|dkrpqbt ||¡} | t|  d¡dd d t|   d¡d d ¡qbWd  |¡} || 7}t d |¡| |  d¡¡t | ¡¡ ¡ d¡} | | fS)Nz$Calculating signature using v2 auth.rú/z %s %s %s zutf-8)Ú digestmodÚ SignatureÚ)Úsafeú=z-_~ú&zString to sign: %s)ÚloggerÚdebugrrÚpathÚlenÚmethodÚnetlocÚhmacÚnewr5Ú secret_keyÚencoderÚsortedr Ú text_typeÚappendr ÚjoinÚupdateÚbase64Ú b64encodeÚdigestÚstripr() r/r*ÚparamsÚsplitr@Ústring_to_signZlhmacÚpairsÚkeyÚvalueÚqsZb64r!r!r"Úcalc_signatureas.     zSigV2Auth.calc_signaturecCs„|jdkrtƒ‚|jr|j}n|j}|jj|d<d|d<d|d<t tt ¡¡|d<|jj rh|jj |d<|  ||¡\}}||d<|S) NÚAWSAccessKeyIdÚ2ZSignatureVersionÚ HmacSHA256ZSignatureMethodZ TimestampZ SecurityTokenr9) r5rr$rQÚ access_keyÚtimeÚstrftimeÚISO8601ÚgmtimeÚtokenrX)r/r*rQrWÚ signaturer!r!r"r-}s   zSigV2Auth.add_authN)r0r1r2Ú__doc__r6rXr-r!r!r!r"r4Ysr4c@seZdZdd„Zdd„ZdS)Ú SigV3AuthcCs ||_dS)N)r5)r/r5r!r!r"r6—szSigV3Auth.__init__cCsÐ|jdkrtƒ‚d|jkr"|jd=tdd|jd<|jjrZd|jkrL|jd=|jj|jd<tj|jj d¡t d}|  |jd d¡¡t |  ¡ƒ  ¡}d|jjd| d¡f}d |jkrÂ|jd =||jd <dS) NÚDateT)ÚusegmtzX-Amz-Security-Tokenzutf-8)r8z6AWS3-HTTPS AWSAccessKeyId=%s,Algorithm=%s,Signature=%sr[zX-Amzn-Authorization)r5rÚheadersrrarDrErFrGrrLrrOrPr\r()r/r*Únew_hmacZencoded_signaturerbr!r!r"r-šs&    zSigV3Auth.add_authN)r0r1r2r6r-r!r!r!r"rd–srdc@s¾eZdZdZdZdd„Zd/dd„Zdd „Zd d „Zd d „Z dd„Z dd„Z dd„Z dd„Z dd„Zdd„Zdd„Zdd„Zdd„Zd d!„Zd"d#„Zd$d%„Zd&d'„Zd(d)„Zd*d+„Zd,d-„Zd.S)0Ú SigV4Authz+ Sign a request with Signature V4. TcCs||_||_||_dS)N)r5Ú _region_nameÚ _service_name)r/r5Ú service_nameÚ region_namer!r!r"r6¶szSigV4Auth.__init__FcCs:|rt || d¡t¡ ¡}nt || d¡t¡ ¡}|S)Nzutf-8)rDrErGrÚ hexdigestrO)r/rUÚmsgÚhexÚsigr!r!r"Ú_sign¾szSigV4Auth._signcCsPtƒ}x.|j ¡D] \}}| ¡}|tkr|||<qWd|krLt|jƒ|d<|S)zk Select the headers from the request that need to be included in the StringToSign. r )r rgÚitemsÚlowerÚSIGNED_HEADERS_BLACKLISTr#r)r/r*Z header_mapÚnamerVÚlnamer!r!r"Úheaders_to_signÅs zSigV4Auth.headers_to_signcCs&|jr| |j¡S| t|jƒ¡SdS)N)rQÚ_canonical_query_string_paramsÚ_canonical_query_string_urlrr)r/r*r!r!r"Úcanonical_query_stringÕs z SigV4Auth.canonical_query_stringcCsvg}x6|D].}t||ƒ}| t|ddt|ddf¡q Wg}x&t|ƒD]\}}| d||f¡qJWd |¡}|S)Nz-_.~)r;z%s=%sr=)ÚstrrJr rHrK)r/rQÚ key_val_pairsrUrVÚsorted_key_valsr{r!r!r"ryßs   z(SigV4Auth._canonical_query_string_paramsc Cs|d}|jrxg}x2|j d¡D]"}| d¡\}}}| ||f¡qWg}x&t|ƒD]\}}| d||f¡qPWd |¡}|S)Nr:r=r<z%s=%s)ÚqueryrRÚ partitionrJrHrK) r/Úpartsr{r}ÚpairrUÚ_rVr~r!r!r"rzîs z%SigV4Auth._canonical_query_string_urlcs\g}tt|ƒƒ}x@|D]8}d ‡fdd„| |¡Dƒ¡}| d|t|ƒf¡qWd |¡S)a  Return the headers that need to be included in the StringToSign in their canonical form by converting all header keys to lower case, sorting them in alphabetical order and then joining them into a string, separated by newlines. ú,c3s|]}ˆ |¡VqdS)N)Ú _header_value)Ú.0Úv)r/r!r"ú sz.SigV4Auth.canonical_headers..z%s:%sÚ )rHÚsetrKÚget_allrJr)r/rxrgZsorted_header_namesrUrVr!)r/r"Úcanonical_headersþs  zSigV4Auth.canonical_headerscCsd | ¡¡S)Nú )rKrR)r/rVr!r!r"r… szSigV4Auth._header_valuecCs$dd„t|ƒDƒ}t|ƒ}d |¡S)NcSsg|]}d| ¡ ¡‘qS)z%s)rtrP)r†Únr!r!r"ú sz,SigV4Auth.signed_headers..ú;)rŠrHrK)r/rxÚlr!r!r"Úsigned_headersszSigV4Auth.signed_headerscCsŠ| |¡stS|j}|rrt|dƒrr| ¡}t |jt¡}t ƒ}xt |dƒD]}|  |¡qJW|  ¡}|  |¡|S|r‚t |ƒ  ¡StSdS)NÚseekó)Ú_should_sha256_sign_payloadÚUNSIGNED_PAYLOADÚbodyÚhasattrÚtellÚ functoolsÚpartialÚreadÚPAYLOAD_BUFFERrÚiterrLrnr“ÚEMPTY_SHA256_HASH)r/r*Ú request_bodyÚpositionZread_chunksizeZchecksumÚchunkZ hex_checksumr!r!r"Úpayloads    zSigV4Auth.payloadcCs|j d¡sdS|j dd¡S)NrTÚpayload_signing_enabled)rÚ startswithÚcontextr)r/r*r!r!r"r•1s z%SigV4Auth._should_sha256_sign_payloadcCsš|j ¡g}| t|jƒj¡}| |¡| | |¡¡| |¡}| |  |¡d¡| |  |¡¡d|j kr||j d}n |  |¡}| |¡d  |¡S)Nr‰zX-Amz-Content-SHA256)rBÚupperÚ_normalize_url_pathrrr@rJr{rxrŒr’rgr£rK)r/r*Zcrr@rxZ body_checksumr!r!r"Úcanonical_request;s       zSigV4Auth.canonical_requestcCstt|ƒdd}|S)Nz/~)r;)r r)r/r@Znormalized_pathr!r!r"r¨JszSigV4Auth._normalize_url_pathcCsN|jjg}| |jddd…¡| |j¡| |j¡| d¡d |¡S)NÚ timestampréÚ aws4_requestr7)r5r\rJr¦rjrkrK)r/r*Úscoper!r!r"r­Ns     zSigV4Auth.scopecCsHg}| |jddd…¡| |j¡| |j¡| d¡d |¡S)Nrªrr«r¬r7)rJr¦rjrkrK)r/r*r­r!r!r"Úcredential_scopeVs    zSigV4Auth.credential_scopecCsHdg}| |jd¡| | |¡¡| t| d¡ƒ ¡¡d |¡S)z¬ Return the canonical StringToSign as well as a dict containing the original version of all headers that were included in the StringToSign. zAWS4-HMAC-SHA256rªzutf-8r‰)rJr¦r®rrGrnrK)r/r*r©Ústsr!r!r"rS^s zSigV4Auth.string_to_signcCsd|jj}| d| d¡|jddd…¡}| ||j¡}| ||j¡}| |d¡}|j||ddS) NZAWS4zutf-8rªrr«r¬T)rp)r5rFrrrGr¦rjrk)r/rSr*rUZk_dateZk_regionZ k_serviceZ k_signingr!r!r"rbjs zSigV4Auth.signaturecCs”|jdkrtƒ‚tj ¡}| t¡|jd<| |¡| |¡}t   d¡t   d|¡|  ||¡}t   d|¡|  ||¡}t   d|¡|  ||¡dS)Nrªz$Calculating signature using v4 auth.zCanonicalRequest: %szStringToSign: %sz Signature: %s)r5rÚdatetimeÚutcnowr^ÚSIGV4_TIMESTAMPr¦Ú_modify_request_before_signingr©r>r?rSrbÚ_inject_signature_to_request)r/r*Ú datetime_nowr©rSrbr!r!r"r-ss          zSigV4Auth.add_authcCsPd| |¡g}| |¡}| d| |¡¡| d|¡d |¡|jd<|S)NzAWS4-HMAC-SHA256 Credential=%szSignedHeaders=%sz Signature=%sz, Ú Authorization)r­rxrJr’rKrg)r/r*rbr‘rxr!r!r"r´…s  z&SigV4Auth._inject_signature_to_requestcCsrd|jkr|jd=| |¡|jjrDd|jkr6|jd=|jj|jd<|j dd¡snd|jkrd|jd=t|jd<dS)Nr¶zX-Amz-Security-Tokenr¤TzX-Amz-Content-SHA256)rgÚ_set_necessary_date_headersr5rar¦rr–)r/r*r!r!r"r³s    z(SigV4Auth._modify_request_before_signingcCs|d|jkrV|jd=tj |jdt¡}ttt |  ¡¡ƒƒ|jd<d|jkrx|jd=n"d|jkrh|jd=|jd|jd<dS)Nrerªz X-Amz-Date) rgr°Ústrptimer¦r²rÚintÚcalendarÚtimegmÚ timetuple)r/r*Zdatetime_timestampr!r!r"r·›s    z%SigV4Auth._set_necessary_date_headersN)F)r0r1r2rcr3r6rrrxr{ryrzrŒr…r’r£r•r©r¨r­r®rSrbr-r´r³r·r!r!r!r"ri°s.     rics0eZdZ‡fdd„Z‡fdd„Zdd„Z‡ZS)Ú S3SigV4Authcs6tt|ƒ |¡d|jkr"|jd=| |¡|jd<dS)NzX-Amz-Content-SHA256)Úsuperr½r³rgr£)r/r*)Ú __class__r!r"r³®s z*S3SigV4Auth._modify_request_before_signingcsx|j d¡}t|ddƒ}|dkr$i}| dd¡}|dk r<|S|j d¡rRd|jkrVdS|j dd¡rhdStt|ƒ |¡S) NÚ client_configÚs3r¤rz Content-MD5TZhas_streaming_inputF) r¦rÚgetattrrr¥rgr¾r½r•)r/r*rÀZ s3_configZ sign_payload)r¿r!r"r•µs     z'S3SigV4Auth._should_sha256_sign_payloadcCs|S)Nr!)r/r@r!r!r"r¨×szS3SigV4Auth._normalize_url_path)r0r1r2r³r•r¨Ú __classcell__r!r!)r¿r"r½­s  "r½cs4eZdZdZef‡fdd„ Zdd„Zdd„Z‡ZS)ÚSigV4QueryAuthicstt|ƒ |||¡||_dS)N)r¾rÄr6Ú_expires)r/r5rlrmÚexpires)r¿r!r"r6ßszSigV4QueryAuth.__init__c Csú|j d¡}d}||kr |jd=| | |¡¡}d| |¡|jd|j|dœ}|jjdk rf|jj|d<t |j ƒ}t dd„t |j d d  ¡Dƒƒ}d }|jr®| t|ƒ¡d |_|r¾t|ƒd }|t|ƒ} |} | d | d| d| | df} t| ƒ|_ dS)Nz content-typez0application/x-www-form-urlencoded; charset=utf-8zAWS4-HMAC-SHA256rª)zX-Amz-AlgorithmzX-Amz-Credentialz X-Amz-Datez X-Amz-ExpireszX-Amz-SignedHeaderszX-Amz-Security-TokencSsg|]\}}||df‘qS)rr!)r†Úkr‡r!r!r"rszASigV4QueryAuth._modify_request_before_signing..T)Úkeep_blank_valuesr:r=rééé)rgrr’rxr­r¦rÅr5rarrÚdictr rrsr$rLr+rr) r/r*Ú content_typeZblacklisted_content_typer’Z auth_paramsrÚ query_dictZoperation_paramsÚnew_query_stringÚpÚ new_url_partsr!r!r"r³ås6      z-SigV4QueryAuth._modify_request_before_signingcCs|jd|7_dS)Nz&X-Amz-Signature=%s)r)r/r*rbr!r!r"r´"sz+SigV4QueryAuth._inject_signature_to_request)r0r1r2ÚDEFAULT_EXPIRESr6r³r´rÃr!r!)r¿r"rÄÜs=rÄc@s eZdZdZdd„Zdd„ZdS)ÚS3SigV4QueryAuthaS3 SigV4 auth using query parameters. This signer will sign a request using query parameters and signature version 4, i.e a "presigned url" signer. Based off of: http://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-query-string-auth.html cCs|S)Nr!)r/r@r!r!r"r¨4sz$S3SigV4QueryAuth._normalize_url_pathcCstS)N)r–)r/r*r!r!r"r£8szS3SigV4QueryAuth.payloadN)r0r1r2rcr¨r£r!r!r!r"rÓ)s rÓc@seZdZdZdd„ZdS)ÚS3SigV4PostAuthz† Presigns a s3 post Implementation doc here: http://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-UsingHTTPPOST.html cCsPtj ¡}| t¡|jd<i}|j dd¡dk r:|jd}i}g}|j dd¡dk rv|jd}| dd¡dk rv|d}||d<d|d<| |¡|d<|jd|d<| ddi¡| d| |¡i¡| d|jdi¡|jj dk r|jj |d <| d |jj i¡t   t   |¡ d ¡¡ d ¡|d <| |d |¡|d <||jd<||jd<dS) Nrªzs3-presign-post-fieldszs3-presign-post-policyÚ conditionszAWS4-HMAC-SHA256zx-amz-algorithmzx-amz-credentialz x-amz-datezx-amz-security-tokenzutf-8Úpolicyzx-amz-signature)r°r±r^r²r¦rr­rJr5rarMrNr ÚdumpsrGr(rb)r/r*rµÚfieldsrÖrÕr!r!r"r-Gs4     zS3SigV4PostAuth.add_authN)r0r1r2rcr-r!r!r!r"rÔ@srÔc#@s¶eZdZddddddddd d d d d ddddddddddddddddd ddd d!d"g#Zd:d$d%„Zd&d'„Zd(d)„Zd*d+„Zd,d-„Zd;d.d/„Z dÚ HmacV1AuthZ accelerateZaclZcorsZdefaultObjectAclÚlocationÚloggingZ partNumberrÖZrequestPaymentZtorrentZ versioningZ versionIdÚversionsZwebsiteZuploadsZuploadIdzresponse-content-typezresponse-content-languagezresponse-expireszresponse-cache-controlzresponse-content-dispositionzresponse-content-encodingÚdeleteZ lifecycleZtaggingÚrestoreZ storageClassZ notificationZ replicationZ analyticsZmetricsZ inventoryÚselectz select-typeNcCs ||_dS)N)r5)r/r5rlrmr!r!r"r6}szHmacV1Auth.__init__cCs>tj|jj d¡td}| | d¡¡t| ¡ƒ  ¡  d¡S)Nzutf-8)r8) rDrEr5rFrGrrLrrOrPr()r/rSrhr!r!r"Ú sign_string€szHmacV1Auth.sign_stringcCs’dddg}g}d|kr|d=| ¡|d<x^|D]V}d}x>|D]6}| ¡}||dk r<||kr<| || ¡¡d}q.z%s:%sr‰)rtr¥rKr‹rHÚkeysrJ)r/rgrãÚcustom_headersrUråZsorted_header_keysr!r!r"Úcanonical_custom_headers—s      z#HmacV1Auth.canonical_custom_headerscCs(t|ƒdkr|S|dt|dƒfSdS)z( TODO: Do we need this? rÉrN)rAr)r/Únvr!r!r"Ú unquote_v¥s zHmacV1Auth.unquote_vcsŠ|dk r|}n|j}|jr†|j d¡}dd„|Dƒ}‡fdd„|Dƒ}t|ƒdkr†|jtdƒddd„|Dƒ}|d7}|d |¡7}|S) Nr=cSsg|]}| dd¡‘qS)r<rÉ)rR)r†Úar!r!r"r½sz1HmacV1Auth.canonical_resource..cs$g|]}|dˆjkrˆ |¡‘qS)r)Ú QSAOfInterestrë)r†rì)r/r!r"r¾sr)rUcSsg|]}d |¡‘qS)r<)rK)r†rìr!r!r"rÂsú?)r@rrRrAÚsortrrK)r/rRÚ auth_pathÚbufZqsar!)r/r"Úcanonical_resource®s   zHmacV1Auth.canonical_resourcecCsN| ¡d}|| |¡d7}| |¡}|r8||d7}||j||d7}|S)Nr‰)rð)r§rærérò)r/rBrRrgrÆrðÚcsrèr!r!r"Úcanonical_stringÇs   zHmacV1Auth.canonical_stringcCsB|jjr|d=|jj|d<|j||||d}t d|¡| |¡S)Nzx-amz-security-token)rðzStringToSign: %s)r5rarôr>r?rà)r/rBrRrgrÆrðrSr!r!r"Ú get_signatureÑs  zHmacV1Auth.get_signaturecCsX|jdkrt‚t d¡t|jƒ}t d|j¡|j|j||j|j d}|  ||¡dS)Nz(Calculating signature using hmacv1 auth.zHTTP request method: %s)rð) r5rr>r?rrrBrõrgrðÚ_inject_signature)r/r*rRrbr!r!r"r-Ýs     zHmacV1Auth.add_authcCs tddS)NT)rf)r)r/r!r!r"râèszHmacV1Auth._get_datecCs,d|jkr|jd=d|jj|f|jd<dS)Nr¶z AWS %s:%s)rgr5r\)r/r*rbr!r!r"röës zHmacV1Auth._inject_signature)NN)N)NN)NN)r0r1r2rír6ràrærérëròrôrõr-rârör!r!r!r"rÙns0      rÙc@s0eZdZdZdZefdd„Zdd„Zdd„Zd S) ÚHmacV1QueryAuthzÁ Generates a presigned request for s3. Spec from this document: http://docs.aws.amazon.com/AmazonS3/latest/dev/RESTAuthentication.html #RESTAuthenticationQueryStringAuth icCs||_||_dS)N)r5rÅ)r/r5rÆr!r!r"r6szHmacV1QueryAuth.__init__cCsttt ¡t|jƒƒƒS)N)r|r¹r]rÅ)r/r!r!r"râszHmacV1QueryAuth._get_datec Cs¾i}|jj|d<||d<xN|jD]D}| ¡}|dkrD|jd|d<q | d¡sV|dkr |j|||<q Wt|ƒ}t|jƒ}|dr’d|d|f}|d |d |d ||d f}t|ƒ|_dS) NrYr9reZExpireszx-amz-)z content-md5z content-typeéz%s&%srrÉrÊrË) r5r\rgrtr¥rrrr) r/r*rbrÎZ header_keyrårÏrÐrÑr!r!r"rö s   z!HmacV1QueryAuth._inject_signatureN)r0r1r2rcrÒr6rârör!r!r!r"r÷øs   r÷c@seZdZdZdd„ZdS)ÚHmacV1PostAuthz‘ Generates a presigned post for s3. Spec from this document: http://docs.aws.amazon.com/AmazonS3/latest/dev/UsingHTTPPOST.html cCsäi}|j dd¡dk r |jd}i}g}|j dd¡dk r\|jd}| dd¡dk r\|d}||d<|jj|d<|jjdk rš|jj|d<| d|jji¡t t  |¡  d¡¡  d¡|d<|  |d¡|d<||jd<||jd<dS) Nzs3-presign-post-fieldszs3-presign-post-policyrÕrYzx-amz-security-tokenzutf-8rÖrb) r¦rr5r\rarJrMrNr r×rGr(rà)r/r*rØrÖrÕr!r!r"r-2s&      zHmacV1PostAuth.add_authN)r0r1r2rcr-r!r!r!r"rù*srù)Zv2Zv3Zv3httpsrÁzs3-queryzs3-presign-postzs3v4-presign-post)ÚCRT_AUTH_TYPE_MAPS)Zv4zv4-queryZs3v4z s3v4-query)=rMrºr°ršÚ email.utilsrÚhashlibrrrDÚiorrÛÚoperatorrr]Zbotocore.compatrrr r r r r rrrrrZbotocore.exceptionsrZbotocore.utilsrrÚ getLoggerr0r>rŸrr_r²rur–r#r+Úobjectr,r4rdrir½rÄrÓrÔrÙr÷rùZAUTH_TYPE_MAPSZbotocore.crt.authrúrLr!r!r!r"Úsh   8   =~/M. 2'