M/eyddZddlZddlZddlmZddlmZddlZddl Z ddl Z ddl m Z ddl m Z ddl mZddl mZddl mZdd l mZdd l mZdd l mZddlZddlZddlZdd lmZdd lmZddlmZddlmZddlmZddlm Z ddlm!Z!ejDe#Z$dZ%GddZ&GddZ'y)zACME client API.N) parsedate_tz)Any)cast)List)Mapping)Optional)Set)Tuple)Union) HTTPAdapter)parse_header_links) challenges) crypto_util)errors)jws)messages-c teZdZdZdej ddddfdZdejdejfd Z d ejdejfd Z d7d ejd e ejdejfd Z d8d ejdedejfdZdedej"fdZdej&deej&ej,ffdZ d7dej"de ej0dej"fdZdej"dej0dej"fdZdej"dej"fdZ d8dej"dej0dedej"fdZ d8dej"dej0dedej"fdZdej>de ddfdZ!defdZ"d e#d!e#dej,fd"Z$d#ej,d$e%de&e%fd%Z'e(d&e%dddej fd'Z)e( d9d#ej,d(e e%d)e e%dejfd*Z*d ejd+ejdejfd,Z+d e#d!e#dej,fd-Z,d ejdejfd.Z-dej&dej&fd/Z. d9d#ej,d0e ej^d(e e%dej&fd1Z0d2ejbd#e2jfdejhfd3Z5e(d#ej,d4e dej0fd5Z6dej>de d&e%ddfd6Z7y):ClientV2zuACME client for a v2 API. :ivar messages.Directory directory: :ivar .ClientNetwork net: Client network. directorynet ClientNetworkreturnNc ||_||_y)zInitialize. :param .messages.Directory directory: Directory Resource :param .ClientNetwork net: Client network. N)rr)selfrrs -/usr/lib/python3/dist-packages/acme/client.py__init__zClientV2.__init__*s # new_accountc|j|jd|}|jdk(r0d|jvr"t j |jd|j |}||j_|S)zRegister. :param .NewRegistration new_account: :raises .ConflictError: in case the account already exists :returns: Registration Resource. :rtype: `.RegistrationResource` newAccountLocation) _postr status_codeheadersr ConflictError_regr_from_responseraccount)rrresponseregrs rrzClientV2.new_account3su::dnn\:KH   3 &:9I9I+I&&x'7'7 'CD D''1 rr+cp|j|d|j_|jjS)zQuery server about registration. :param messages.RegistrationResource regr: Existing Registration Resource. T)_get_v2_accountrr)rr+s rquery_registrationzClientV2.query_registrationFs- //d;xxrupdatec|j|}| |jn|}tjdit |}|j ||}||j _|S)aKUpdate registration. :param messages.RegistrationResource regr: Registration Resource. :param messages.Registration update: Updated body of the resource. If not provided, body will be taken from `regr`. :returns: Updated Registration Resource. :rtype: `.RegistrationResource` body)r-r3rUpdateRegistrationdict_send_recv_regrrr))rr+r0r3 updated_regrs rupdate_registrationzClientV2.update_registrationRsa##D)$n&**:T&\:++Dt+< 'r update_bodycvd|j_|jjd}|j |j d|}|j d}|j|r-tjj|jn |j|}||j_|S)NT)only_return_existingr!r#r3uri) rr)r3r0r$rr&r Registration from_jsonjson)rr+r:only_existing_regr* updated_urinew_regrs rr-zClientV2._get_v2_accounths II,,$,G::dnn\:r#)r3r>authorizationsrE)OpenSSLcryptoload_certificate_request FILETYPE_PEMr _pyopenssl_cert_or_req_all_names_pyopenssl_cert_or_req_san_ipappendr IdentifierIDENTIFIER_FQDN IDENTIFIER_IPNewOrderr$rOrderr@rArL_authzr_from_response _post_as_get OrderResourcer&get) rrEcsrdnsNamesipNamesrInameipsorderr*r3rLurls r new_orderzClientV2.new_ordertssnn55gnn6Q6QSZ[??D;;C@  D   x22x7O7O    C   x22x7M7M   !!k:::dnnZ8%@~~'' 8&& _C  ! !$"<"rYr3 identifier)rrer*updated_authzrs rpollz ClientV2.pollsH$$VZZ033 fkk,,fjj:x''rorderrdeadlinec|5tjjtjdz}|j||}|j ||S)adPoll authorizations and finalize the order. If no deadline is provided, this method will timeout after 90 seconds. :param messages.OrderResource orderr: order to finalize :param datetime.datetime deadline: when to stop polling and timeout :returns: finalized order :rtype: messages.OrderResource Zseconds)datetimenow timedeltapoll_authorizationsfinalize_order)rrjrks rpoll_and_finalizezClientV2.poll_and_finalizesS  ((,,.1C1CB1OOH))&(;""6844rcHg}|jjD]}tjj|ks%|j |j ||}|jj tjk7r|j|tjdtjj|krt|t|jjkrtjg}|D]c}|jj tjk7s+|jj D] }|j"|j|"e|rtj$||j'|S)zPoll Order Resource for status.rK)rL)r3rLrprqrYrZstatusrSTATUS_PENDINGrStimesleeplenr TimeoutError STATUS_VALIDrerrorValidationErrorr0)rrjrk responsesrcrefailedchalls rrszClientV2.poll_authorizationssU ;;-- C##'')H433D4E4Ec4JPS3T;;%%)@)@@$$V, 1 ##'')H4  y>C : :; ;%%' ' .F{{!!X%:%::#[[33.E{{. f-. . ((0 0}}I}66rctjjtjj|j}t j tj|}|j|jj|}|jt jj|j}|S)aStart the process of finalizing an order. :param messages.OrderResource orderr: order to finalize :param datetime.datetime deadline: when to stop polling and timeout :returns: updated order :rtype: messages.OrderResource )r]r2)rMrNrOrPrErCertificateRequestjoseComparableX509r$r3finalizer0rXr@rA)rrjr] wrapped_csrress rbegin_finalizationzClientV2.begin_finalizationsnn55 NN ' '911d6I6I#6NO jj--{;HNN$<$rrXr@rArxSTATUS_INVALIDrr IssuanceErrorErrorr~ certificater0text _get_linksr}) rrjrkrr*r3certificate_responsealt_chains_urlsrc alt_chainss rpoll_finalizationzClientV2.poll_finalizationsg##%0 JJqM((4H>>++HMMOterms_of_servicecd|jvr|jdd}tjtjj |j |j jd||S)Nzterms-of-servicercr#)r3r>r)rrRegistrationResourcer?r@rAr&r\)rr*r>rs rr(zClientV2._regr_from_responseLsk  /'~~.@A%H ,,&&00A  $$Z5-/ /rr3c|j|j|}|j||j|jS)N)r>r)r$r>r(r)rr+r3r*s rr7zClientV2._send_recv_regrXsB::dhh-'' $((!22(4 4rc|jdt|jd|jj|i|S)zWrapper around self.net.post that adds the newNonce URL. This is used to retry the request in case of a badNonce error. new_nonce_urlnewNonce) setdefaultgetattrrrpostrrrs rr$zClientV2._postfs9 /74>>:+NOtxx}}d-f--rcf|j|tjjdddS)zDeactivate registration. :param messages.RegistrationResource regr: The Registration Resource to be deactivated. :returns: The Registration resource that was deactivated. :rtype: `.RegistrationResource` deactivatedN)rxcontact)r9rr?r@r.s rdeactivate_registrationz ClientV2.deactivate_registrationos4''h.C.C.M.M$ 6/89 9rctjd}|j|j|}|j ||j j |jS)aDeactivate authorization. :param messages.AuthorizationResource authzr: The Authorization resource to be deactivated. :returns: The Authorization resource that was deactivated. :rtype: `.AuthorizationResource` r)rx)rUpdateAuthorizationr$r>rYr3rg)rrer3r*s rdeactivate_authorizationz!ClientV2.deactivate_authorization}sP++=A::fjj$/))( KK " "FJJ0 0rrgctjtjj|j |j j d|}|.|jj|k7rtj||S)Nr#r=) rAuthorizationResource Authorizationr@rAr&r\r3rgrUnexpectedUpdate)rr*rgr>res rrYzClientV2._authzr_from_responsess//''11(--/B  $$Z57  !fkk&<&< &J))&1 1 rchallbc|j|j|} |jdd}t j|t jj|j}|j|jk7rt j|j|S#t$rt j dwxYw)ahAnswer challenge. :param challb: Challenge Resource body. :type challb: `.ChallengeBody` :param response: Corresponding Challenge response :type response: `.challenges.ChallengeResponse` :returns: Challenge Resource with updated body. :rtype: `.ChallengeResource` :raises .UnexpectedUpdate: uprcz"up" Link header missing) authzr_urir3) r$r>rKeyErrorr ClientErrorrChallengeResource ChallengeBodyr@rAr)rrr*resprchallrs ranswer_challengezClientV2.answer_challenges zz&**h/ AD)%0J++!''11$))+>@ :: #))&**5 5  A$$%?@ @ As B,,C defaultc|jjdt|} t|}t j jt j|zS#t$rat |}|O t j|d|dnd}t j |dd|z cYS#ttf$rYnwxYw|}YwxYw)aCompute next `poll` time based on response ``Retry-After`` header. Handles integers and various datestring formats per https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.37 :param requests.Response response: Response from `poll`. :param int default: Default value (in seconds), used when ``Retry-After`` header is not present or invalid. :returns: Time point when next `poll` should be performed. :rtype: `datetime.datetime` z Retry-AfterNrrn) r&r\strint ValueErrorrrprr OverflowErrorrq)rr*r retry_afterrowhentz_secss rrzClientV2.retry_afters&&**=#g,G  +&G  $$&););G)LLL  ,D&00T"X=QbWXYG#,,d2Ah7'AA"M2G s5 A''C>6B74C7C CC  CCc|j|tj||}|jtj k7rt jdy)a.Revoke certificate. :param .ComparableX509 cert: `OpenSSL.crypto.X509` wrapped in `.ComparableX509` :param int rsn: Reason code for certificate revocation. :param str url: ACME URL to post to :raises .ClientError: If revocation is unsuccessful. )rreasonz0Successful revocation must return HTTP OK statusN)r$r Revocationr% http_clientOKrr)rrrrcr*s rrzClientV2._revokesY::c&11,0'*,-   ;>> 1$$BD D 2rr)F)NN)8__name__ __module__ __qualname____doc__rrrNewRegistrationrrr/rr?r9boolr-bytesr[rdrr requestsResponserirprursrrrtrrrrrrrZrrr classmethodrr(r7r$rrrTrYrrChallengeResponserrrrr4rrrr#sx ("4"4?tx'?'?HDaDa&  x'D'D  ( = =  GK(E(E$,X-B-B$C!)!>!>, H$A$A PT $99 !!8+A+A!F(899(668I8IIJ($CG5(>(>5$,X->->$?5KSKaKa5&7(*@*@7HL]L]7!)!7!772)?)? ( 6 6&(>$$,$5$5$48$ (55$B9>RX%;%;RxGXGXR15RBJBXBXR >4.. >S >T >=4= /#//9J9J/ L8#4#4 LS LTRUY L A A/ Ah>P>P A ASW>B /8+<+< /8C= /.6sm /!)!>!> / / 4H$A$A 4&33 48@8U8U 4.3.#.(2C2C. 9H,I,I 9%-%B%B 90)1)G)G0&.&D&D0$KO37h.?.?*283F3F*G#+C=DD//DcDDDrrc\eZdZdZdZdZdZdZ dejdde fd ejd e e jd ejd ed ededdfdZd$dZdej*dededefdZe d%dej2de edej2fdZdededededej2f dZdededej2fdZefdedededej2fdZdej2ddfdZded edefd!Z dededej2fd"Z!efdedej*dededej2f d#Z"y)&rzvWrapper around requests that signs POSTs for authentication. Also adds user agent, and handles Content-Type. zapplication/jsonzapplication/jose+jsonzapplication/problem+jsonz Replay-NonceNTz acme-pythonkeyr)alg verify_ssl user_agenttimeoutrc,||_||_||_||_t |_||_tj|_ ||_ t}|jjd||jjd|y)Nzhttp://zhttps://) rr)rrset_noncesrrSessionsession_default_timeoutr mount)rrr)rrrradapters rrzClientNetwork.__init__sw $!$ $'') '- 9g. :w/rcX |jjy#t$rYywxYwr)rclose Exceptionrs r__del__zClientNetwork.__del__s)  LL      s  ))objnoncercc |r |jdjnd}tjd||j||d}|j |j d|d<|j |d<tjj|fittttf|jdS) zWrap `JSONDeSerializable` object in JWS. .. todo:: Implement ``acmePath``. :param josepy.JSONDeSerializable obj: :param str url: The URL to which this object will be POSTed :param str nonce: :rtype: str )indentrzJWS payload: %s)rrrcr>kidr) json_dumpsencodeloggerdebugrr)rrJWSsignrrrr)rrrrcjobjrs r _wrap_in_jwszClientNetwork._wrap_in_jwss58s~~Q~'..0S '.88  << # LL/F5Mu ww||DDDc):F$CDOOWXOYYrr* content_typec|jjd}|r"|jddj} |j }|j dk(r/tj|jjdd|js\|E||jk7rtjd| tjj|tj$||%||j&k7rtjd |||j&k(r|tj$d ||S#t $rd}YwxYw#t j"$r}tj$||fd}~wwxYw) aCheck response content and its type. .. note:: Checking is not strict: wrong server response ``Content-Type`` HTTP header is ignored if response is an expected JSON object (c.f. Boulder #56). :param str content_type: Expected Content-Type response header. If JSON is expected and not present in server response, this function will raise an error. Otherwise, wrong Content-Type is ignored, but logged. :raises .messages.Error: If server response body carries HTTP Problem (https://datatracker.ietf.org/doc/html/rfc7807). :raises .ClientError: In case of other networking errors. Content-Type;rNir#zUNKNOWN-LOCATIONz/Ignoring wrong Content-Type (%r) for JSON Errorz: %++C0399;K ==?D   3 &&&x'7'7';';JHZ'[\ \{{#"="==LLI#%@"..22488 ((22K33H3H$H  +-s444((+Mk])[\\; D 00@ ,,h->??@s*E E EEF .FF methodrrc h|dk(rtjd||dntjd|||j|d<|jdi|djd|j|jd|j  |j j||g|i|}d |dvr t!j"|j$} nd|_|j(} tjd|j*dj-d|j.j1D| |S#tjj$rR} d }tj|t|}||j\} } } } td | | d | d }~wwxYw)aSend HTTP request. Makes sure that `verify_ssl` is respected. Logs request and response (with headers). For allowed parameters please see `requests.request`. :param str method: method for the new `requests.Request` object :param str url: URL for the new `requests.Request` object :raises requests.exceptions.RequestException: in case of any problems :returns: HTTP Response :rtype: `requests.Response` POSTzSending POST request to %s: %sdatazSending %s request to %s.verifyr&z User-AgentrzT.*host='(\S*)'.*Max retries exceeded with url\: (\/\w*).*(\[Errno \d+\])([A-Za-z ]*)Nz Requesting :Acceptzutf-8z!Received response: HTTP %d %s %s c3FK|]\}}dj||yw)z{0}: {1}N)format).0kvs r z.ClientNetwork._send_request..s+F$(Aq *00A6Fs!)r r rrrrrrequestr exceptionsRequestExceptionrematchrgroupsrbase64 b64encodecontentencodingrr%joinr&items)rrrcrrr*e err_regexmhostpath_err_noerr_msg debug_contents r _send_requestzClientNetwork._send_requestls" V  LL:vf~ / LL4fc B??x)R(y$$\4??C)T%:%:; C+t||++FCI$I&IH8 vi( (",,X-=-=>M !(H $MMM <))YYF,4,<,<,B,B,DFF"  $ S""33 C /pICF+Ay+,88: (D${4&ayAB B+ Cs!EF1A F,,F1c.|jdg|i|S)aSend HEAD request without checking the response. Note, that `_check_response` is not called, as it is expected that status code other than successfully 2xx will be returned, or messages2.Error will be raised by the server. HEAD)r@rs rheadzClientNetwork.heads!"t!!&:4:6::rc L|j|jd|fi||S)z$Send GET request and check response.GETr)rr@)rrcrrs rr\zClientNetwork.gets7## D  uc 4V 4<$Q Qrc|j|jvrx|j|j} tjjdj |}tjd||jj|ytj|#t j$r}tj||d}~wwxYw)NrzStoring nonce: %s)REPLAY_NONCE_HEADERr&rHeader_fieldsdecoderrrBadNoncer r radd MissingNonce)rr*r decoded_noncers r _add_noncezClientNetwork._add_nonces  # #x'7'7 7$$T%=%=>E 4 # 2 27 ; B B5 I  LL,e 4 LL  ] +%%h/ / ,, 4ooeU33 4s,B&&C9CCrc|js\tjd||j|}n"|j |j|d}|j ||jj S)NzRequesting fresh noncerF)rr r rCrrPpop)rrcrr*s r _get_noncezClientNetwork._get_noncesi|| LL1 2$99S> // -0HW[/\ OOH %||!!rc |j|i|S#tj$rB}|jdk(r-tj d||j|i|cYd}~Sd}~wwxYw)zPOST object wrapped in `.JWS` and check response. If the server responded with a badNonce error, the request will be retried once. badNoncez Retrying request after error: %sN) _post_oncerrcoder r )rrrrs rrzClientNetwork.postse "4??D3F3 3~~ zzZ' @%H&t777   s A)6A$A)#A$$A)c |jdd}|j||j|||}|jdd|i|jd|fd|i|}|j ||}|j ||S)Nrr&rr r!rF)rRrrSrr@rrP)rrcrrrrr!r*s rrVzClientNetwork._post_onces ?D9   dooc=&I3O)nl%CD%4%%fcGGG''|'L !r)rNr)#rrrrrJOSE_CONTENT_TYPErrHrRS256DEFAULT_NETWORK_TIMEOUTJWKrrr JWASignaturerrrrrJSONDeSerializablerrrrrrr@rCr\rPrSrrVr4rrrrs+/8( Z^*.**#0AX0DHH0x8U8U/V0''0BF0 0;>0]a0 Z 7 7ZZ#ZRUZ26:8x'8'88&.sm8?G?P?P88tECEcE#EEQYQbQbEN;#;;1B1B;1BQsQ#QQ&//Q 08#4#4 0 0 "c "# "# " #  1B1B  (9c(?(?!$DGLTL]L]rr)(rr2rp email.utilsr http.clientclientrloggingr/rztypingrrrrrr r r josepyrrMrrequests.adaptersr requests.utilsr acmerrrrr getLoggerrr r[rrr4rrris $! )-   8 $EDEDPFFr