o 6au@sdZddlZddlZddlZddlmZddlZddlmZ ddl Z ddl Z ddl Z ddl Z ddlmZddlmZddlmZddlmZddlmZdd lmZdd lmZdd lmZdd lmZdd lmZddlmZddlmZddlZddlZddlZddl Z ddl!m"Z"ddl#m$Z$ddl%m&Z&ddl'm(Z(ddl'm)Z)ddl'm*Z*ddl'm+Z+ddl,m-Z-e .e/Z0dZ1dZ2GdddZ3Gddde3Z4Gddde3Z5Gd d!d!Z6Gd"d#d#Z7Gd$d%d%Z8eee8e j9e/e j9e/<dS)&zACME client API.N) parsedate_tz) ModuleType)Any)Callable)cast)Dict)Iterable)List)Optional)Set)Text)Tuple)Union) HTTPAdapter)parse_header_links)SourceAddressAdapter) crypto_util)errors)jws)messages)VersionedLEACMEMixin-zapplication/pkix-certc @sdeZdZdZdejdddeddfdd Ze  d-d e j d e e d e e dej fd dZdej dejdej fddZdedede j fddZ d.dej de ejdej fddZdej dej fddZdejdejfddZ  d-d e j de ejd e e dejfd d!Zd"ejd e j dejfd#d$Zed e j d%edejfd&d'Zd(ejd)ed*e ddfd+d,Z dS)/ ClientBasezACME client base object. :ivar messages.Directory directory: :ivar .ClientNetwork net: Client network. :ivar int acme_version: ACME protocol version. 1 or 2. directorynet ClientNetwork acme_versionreturnNcCs||_||_||_dS)zInitialize. :param .messages.Directory directory: Directory Resource :param .ClientNetwork net: Client network. :param int acme_version: ACME protocol version. 1 or 2. Nrrr)selfrrrr -/usr/lib/python3/dist-packages/acme/client.py__init__8s zClientBase.__init__responseuriterms_of_servicecCs>d|jvr |jdd}tjtj||jd||dS)Nzterms-of-serviceurlLocation)bodyr$r%)linksrRegistrationResource Registration from_jsonjsonheadersget)clsr#r$r%r r r!_regr_from_responseDs  zClientBase._regr_from_responseregrr(cCs"||j|}|j||j|jdS)Nr$r%)_postr$r1r%)rr2r(r#r r r!_send_recv_regrPs zClientBase._send_recv_regrargskwargscOs@|d|jt|jdr|dt|jd|jj|i|S)zBWrapper around self.net.post that adds the acme_version. rnewNonce new_nonce_url) setdefaultrhasattrrgetattrrpostrr6r7r r r!r4^s zClientBase._postupdatecCs@|dur|jn|}tjdit|}|j||d}||j_|S)KUpdate 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` Nr(r )r(rUpdateRegistrationdictr5raccount)rr2r?r( updated_regrr r r!update_registrationgs  zClientBase.update_registrationcCs||tjdddS)zDeactivate registration. :param messages.RegistrationResource regr: The Registration Resource to be deactivated. :returns: The Registration resource that was deactivated. :rtype: `.RegistrationResource` deactivatedN)statuscontact)rFrr+r,rr2r r r!deactivate_registrationzs z"ClientBase.deactivate_registrationauthzrcCs.tjdd}||j|}|||jj|jS)aDeactivate authorization. :param messages.AuthorizationResource authzr: The Authorization resource to be deactivated. :returns: The Authorization resource that was deactivated. :rtype: `.AuthorizationResource` rG)rH)rUpdateAuthorizationr4r$_authzr_from_responser( identifier)rrLr(r#r r r!deactivate_authorizations  z#ClientBase.deactivate_authorizationrOcCsFtjtj||jd|d}|dur!|jj|kr!t ||S)Nr')r(r$) rAuthorizationResource Authorizationr,r-r.r/r(rOrUnexpectedUpdate)rr#rOr$rLr r r!rNs  z ClientBase._authzr_from_responsechallbcCsp||j|}z |jdd}Wn tytdwtj|tj | d}|j|jkr6t |j|S)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: upr&z"up" Link header missing) authzr_urir() r4r$r)KeyErrorr ClientErrorrChallengeResource ChallengeBodyr,r-rS)rrTr#rVchallrr r r!answer_challenges    zClientBase.answer_challengedefaultc Cs|jdt|}zt|}Wn<tyKt|}|durGzt|ddur+|dnd}tj|dd|WYSttfyFYnw|}Ynwtj tj|dS)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-AfterNrseconds) r.r/strint ValueErrorrdatetime timedelta OverflowErrornow)r0r#r] retry_afterrawhentz_secsr r r!ris   zClientBase.retry_aftercertrsnr&cCs0||tj||d}|jtjkrtddS)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. ) certificatereasonz0Successful revocation must return HTTP OK statusN)r4r Revocation status_code http_clientOKrrX)rrlrmr&r#r r r!_revokes  zClientBase._revoke)NNN)!__name__ __module__ __qualname____doc__r Directoryrcr" classmethodrequestsResponser rbr*r1r+r5rr4rFrKrQrP IdentifierrNrZrYr\rerijoseComparableX509rtr r r r!r1sd               rcseZdZdZejddfdejdejdej de de d d df fd d Z d9d e ej d ejfddZdejd ejfddZdejd ejfddZ d9dejde ed ejfddZd9dede ed ejfddZdejdeejd ejfddZd ejd eejejffd!d"Z $d:dejdeejd%ed&ed eejeejd'fff d(d)Z d*ed eejejffd+d,Z!d-ejd ejfd.d/Z"d-ejd ejfd0d1Z# $d;d-ejd2ed e$ejfd3d4Z%d5ejd6ed dfd7d8Z&Z'S)<ClientaFACME client for a v1 API. .. deprecated:: 1.18.0 Use :class:`ClientV2` instead. .. todo:: Clean up raised error types hierarchy, document, and handle (wrap) instances of `.DeserializationError` raised in `from_json()`. :ivar messages.Directory directory: :ivar key: `josepy.JWK` (private) :ivar alg: `josepy.JWASignature` :ivar bool verify_ssl: Verify SSL certificates? :ivar .ClientNetwork net: Client network. Useful for testing. If not supplied, it will be initialized using `key`, `alg` and `verify_ssl`. TNrkeyalg verify_sslrrrcsR||_|durt|||d}t|trtj||}t j ||dddS)zInitialize. :param directory: Directory Resource (`.messages.Directory`) or URI from which the resource will be downloaded. N)rrr) rr isinstancerbrrzr,r/r-superr")rrrrrr __class__r r!r" s    zClient.__init__new_regcCs@|durtn|}||j||}|jtjksJ||S)zRegister. :param .NewRegistration new_reg: :returns: Registration Resource. :rtype: `.RegistrationResource` N)rNewRegistrationr4rrqrrCREATEDr1)rrr#r r r!registers  zClient.registerr2cCs||tS)Query server about registration. :param messages.RegistrationResource regr: Existing Registration Resource. )r5rrBrJr r r!query_registration/szClient.query_registrationcCs||j|jj|jddS)aAgree to the terms-of-service. Agree to the terms-of-service in a Registration Resource. :param regr: Registration Resource. :type regr: `.RegistrationResource` :returns: Updated Registration Resource. :rtype: `.RegistrationResource` ) agreementrA)rFr?r(r%rJr r r! agree_to_tos9s zClient.agree_to_tosrOnew_authzr_uricCs`|dur td|jdrtdtj|d}||j j |}|j t j ks*J|||S)aGRequest challenges. :param .messages.Identifier identifier: Identifier to be challenged. :param str new_authzr_uri: Deprecated. Do not use. :returns: Authorization Resource. :rtype: `.AuthorizationResource` :raises errors.WildcardUnsupportedError: if a wildcard is requested Nz2request_challenges with new_authzr_uri deprecated.*zbRequesting an authorization for a wildcard name is forbidden by this version of the ACME protocol.)rO)loggerdebugvalue startswithrWildcardUnsupportedErrorrNewAuthorizationr4r new_authzrqrrrrN)rrOrrr#r r r!request_challengesIs    zClient.request_challengesdomaincCs|tjtj|d|S)a"Request challenges for domain names. This is simply a convenience function that wraps around `request_challenges`, but works with domain names instead of generic identifiers. See ``request_challenges`` for more documentation. :param str domain: Domain name to be challenged. :param str new_authzr_uri: Deprecated. Do not use. :returns: Authorization Resource. :rtype: `.AuthorizationResource` :raises errors.WildcardUnsupportedError: if a wildcard is requested typr)rrr~IDENTIFIER_FQDN)rrrr r r!request_domain_challengesds z Client.request_domain_challengescsrauthzrsc Cs|sJdtdtj|d}t}|j|jj||d|id}|j di d}z|j d}Wn t y=t d wtj|||ttjtjj|jd S) aRequest issuance. :param csr: CSR :type csr: `OpenSSL.crypto.X509Req` wrapped in `.ComparableX509` :param authzrs: `list` of `.AuthorizationResource` :returns: Issued certificate :rtype: `.messages.CertificateResource` zAuthorizations list is emptyzRequesting issuance...rAccept) content_typer.rUr&r'z"Location" Header missing)r$rcert_chain_urir()rrrCertificateRequestDER_CONTENT_TYPEr4rnew_certr)r/r.rWrrXCertificateResourcerrOpenSSLcryptoload_certificate FILETYPE_ASN1content)rrrreqrr#rr$r r r!request_issuanceys,       zClient.request_issuancerLcCs*|j|j}|||jj|j}||fSaPoll Authorization Resource for status. :param authzr: Authorization Resource :type authzr: `.AuthorizationResource` :returns: Updated Authorization Resource and HTTP response. :rtype: (`.AuthorizationResource`, `requests.Response`) )rr/r$rNr(rOrrLr#updated_authzrr r r!polls   z Client.poll mintime max_attempts.csN|dksJtt}t}ddt|D}t|dd|D|rt|\}} } tj } || krF|| j } t d| t | || \} }| | <|| d7<| jjtjtjfvr|| |krzt||j||d| | fn|| |s%|std d Drt|tfd d |D}||||fS) aPoll and request issuance. This function polls all provided Authorization Resource URIs until all challenges are valid, respecting ``Retry-After`` HTTP headers, and then calls `request_issuance`. :param .ComparableX509 csr: CSR (`OpenSSL.crypto.X509Req` wrapped in `.ComparableX509`) :param authzrs: `list` of `.AuthorizationResource` :param int mintime: Minimum time before next attempt, used if ``Retry-After`` is not present in the response. :param int max_attempts: Maximum number of attempts (per authorization) before `PollError` with non-empty ``waiting`` is raised. :returns: ``(cert, updated_authzrs)`` `tuple` where ``cert`` is the issued certificate (`.messages.CertificateResource`), and ``updated_authzrs`` is a `tuple` consisting of updated Authorization Resources (`.AuthorizationResource`) as present in the responses from server, and in the same order as the input ``authzrs``. :rtype: `tuple` :raises PollError: in case of timeout or if some authorization was marked by the CA as invalid rcSs g|] \}}tj||fqSr )rerh).0indexrLr r r! sz4Client.poll_and_request_issuance..cSsi|]}||qSr r rrLr r r! sz4Client.poll_and_request_issuance..zSleeping for %d secondsr)r]css|] }|jjtjkVqdSru)r(rHrSTATUS_INVALIDrr r r! sz3Client.poll_and_request_issuance..c3s|]}|VqdSrur rupdatedr r!rs) collections defaultdictrcset enumerateheapqheapifyheappoprerhrarrtimesleeprr(rHr STATUS_VALIDrheappushriaddanyvaluesr PollErrortupler)rrrrrattempts exhaustedwaitingrjrrLrhrarr#updated_authzrsr rr!poll_and_request_issuancesF           z Client.poll_and_request_issuancer$cCs8t}|jj|d|i|d}|ttjtjj|j fS)zReturns certificate from URI. :param str uri: URI of certificate :returns: tuple of the form (response, :class:`josepy.util.ComparableX509`) :rtype: tuple r)r.r) rrr/rrrrrrr)rr$rr#r r r! _get_certs   zClient._get_certcertrcCsL||j\}}d|jvrtd|jd|jkr t|j|j|dS)zCheck for new cert. :param certr: Certificate Resource :type certr: `.CertificateResource` :returns: Updated Certificate Resource. :rtype: `.CertificateResource` r'zLocation header missingrA)rr$r.rrXrStextr?)rrr#rlr r r! check_certs     zClient.check_certcCs ||S)zRefresh certificate. :param certr: Certificate Resource :type certr: `.CertificateResource` :returns: Updated Certificate Resource. :rtype: `.CertificateResource` )r)rrr r r!refresh"s zClient.refresh max_lengthcCszg}|j}|dur/t||kr/||\}}|jdid}|||dur/t||ks|dur;td||S)aFetch chain for certificate. :param .CertificateResource certr: Certificate Resource :param int max_length: Maximum allowed length of the chain. Note that each element in the certificate requires new ``HTTP GET`` request, and the length of the chain is controlled by the ACME CA. :raises errors.Error: if recursion exceeds `max_length` :returns: Certificate chain for the Certificate Resource. It is a list ordered so that the first element is a signer of the certificate from Certificate Resource. Will be empty if ``cert_chain_uri`` is ``None``. :rtype: `list` of `OpenSSL.crypto.X509` wrapped in `.ComparableX509` NrUr&z'Recursion limit reached. Didn't get {0}) rlenrr)r/appendrErrorformat)rrrchainr$r#rlr r r! fetch_chain1s zClient.fetch_chainrlrmcCs ||||jtttjdSRevoke certificate. :param .ComparableX509 cert: `OpenSSL.crypto.X509` wrapped in `.ComparableX509` :param int rsn: Reason code for certificate revocation. :raises .ClientError: If revocation is unsuccessful. N)rtrrrbrrprrlrmr r r!revokeOs z Client.revokeru)rr)r)(rvrwrxryrRS256rrzJWK JWASignatureboolr r"rr*rrrr~rbrQrrrrrrr r|r}rrcrrrrr rr __classcell__r r rr!rsz        '    N  rc seZdZdZdejddddffdd Zd ejdejfd d Z d ejdejfd dZ d2d ejde ej dejffdd Z d ejdejfddZdedejfddZdejdeejejffddZ d2dejde ejdejfddZdejdejdejfddZ d3dejdejd!edejfd"d#Zd$ejd%eddfd&d'Zdefd(d)Z d*e!d+e!dejfd,d-Z"d.ejd/e#de$e#fd0d1Z%Z&S)4ClientV2zuACME client for a v2 API. :ivar messages.Directory directory: :ivar .ClientNetwork net: Client network. rrrrNcstj||dddS)zInitialize. :param .messages.Directory directory: Directory Resource :param .ClientNetwork net: Client network. rN)rr")rrrrr r!r"dszClientV2.__init__ new_accountcCsL||jd|}|jdkrd|jvrt|jd||}||j_|S)zRegister. :param .NewRegistration new_account: :raises .ConflictError: in case the account already exists :returns: Registration Resource. :rtype: `.RegistrationResource` newAccountr') r4rrqr.r ConflictErrorr1rrD)rrr#r2r r r!rls   zClientV2.new_accountr2cCs6||j_||jd}|j||j|jd|j_|jjS)rNr3)rrDr4r$r1r%)rr2r#r r r!rs   zClientV2.query_registrationr?cs||}t||S)r@)_get_v2_accountrrF)rr2r?new_regrrr r!rFs zClientV2.update_registrationcCsJd|j_|jjdd}||jd|}|jd}|j|d}||j_|S)NT)only_return_existingrr'r$)rrDr(r?r4rr.)rr2only_existing_regr# updated_urirr r r!rs  zClientV2._get_v2_accountcsr_pemc Cstjtjj|}t|}t|}g}|D] }|tj tj |dq|D] }|tj tj |dq'tj |d}| |jd|} tj| } g} | jD]} | |j|| | dqQtj| | jd| |dS)zRequest a new Order object from the server. :param bytes csr_pem: A CSR in PEM format. :returns: The newly created order. :rtype: OrderResource r) identifiersnewOrderrr')r(r$authorizationsr)rrload_certificate_request FILETYPE_PEMr _pyopenssl_cert_or_req_all_names_pyopenssl_cert_or_req_san_iprrr~r IDENTIFIER_IPNewOrderr4rOrderr,r-rrN _post_as_get OrderResourcer.r/) rrrdnsNamesipNamesrnameipsorderr#r(rr&r r r! new_orders0        zClientV2.new_orderrLcCs(||j}|||jj|j}||fSr)rr$rNr(rOrr r r!rs  z ClientV2.pollorderrdeadlinecCs6|durtjtjdd}|||}|||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 NZr`)rerhrfpoll_authorizationsfinalize_order)rr r r r r!poll_and_finalizes  zClientV2.poll_and_finalizecCsg}|jjD],}tj|kr2|j|||d}|jjtjkr&| |n t dtj|ksqt |t |jjkrAt g}|D]}|jjtjkr_|jjD] }|jdur^| |qRqE|rgt ||j|dS)zPoll Order Resource for status.rrN)r)r(rrerhrNrrHrSTATUS_PENDINGrrrrr TimeoutErrorr challengeserrorValidationErrorr?)rr r  responsesr&rLfailedchallr r r!rs,        zClientV2.poll_authorizationsFfetch_alternative_chainsc stjtjj|j}tjt|d} |j j |t j |krstd|j}tj|}|jdur@t|j|jdurl|j}|j||jd}|rj|d} fdd| D} |j| d}|St j |ks"t) {Finalize an order and obtain a certificate. :param messages.OrderResource orderr: order to finalize :param datetime.datetime deadline: when to stop polling and timeout :param bool fetch_alternative_chains: whether to also fetch alternative certificate chains :returns: finalized order :rtype: messages.OrderResource rrN)r( fullchain_pem alternatecsg|]}|jqSr )rr)rr&rr r!r%sz+ClientV2.finalize_order..)alternative_fullchains_pem)rrrrrrrrrr4r(finalizererhrrrr$rr,r-rr IssuanceErrorrnr?r _get_linksr) rr r rr wrapped_csrr#r(certificate_responsealt_chains_urls alt_chainsr rr!r s*         zClientV2.finalize_orderrlrmcCs||||jddS)r revokeCertN)rtrrr r r!r*s zClientV2.revokecCst|jdo |jjjS)zGChecks if ACME server requires External Account Binding authentication.meta)r;rr(external_account_requiredrr r r!r)7sz"ClientV2.external_account_requiredr6r7cOs,|ddd|dd}|j|i|S)z Send GET request using the POST-as-GET protocol. :param args: :param kwargs: :return: Nrru)r4)rr6r7new_argsr r r!r;szClientV2._post_as_getr# relation_typecs.d|jvrgSt|jd}fdd|DS)z Retrieves all Link URIs of relation_type from the response. :param requests.Response response: The requests HTTP response. :param str relation_type: The relation type to filter by. Linkcs0g|]}d|vrd|vr|dkr|dqS)relr&r )rlr+r r!rPsz'ClientV2._get_links..)r.r)rr#r+r)r r/r!r"Es zClientV2._get_linksruF)'rvrwrxryrrzr"rr*rrr r+rFrbytesrr rQr r|r}rrerrrrrrrcrr)rrrbr r"rr r rr!r]sJ   #     ! $ rc @seZdZdZdddejdeddfdd Zd edefd d Z d#d e j de e egdfde jfddZdede jfddZ d$de jdejdede jfddZdejdeddfddZde jdefdd Zdefd!d"ZdS)%BackwardsCompatibleClientV2aACME client wrapper that tends towards V2-style calls, but supports V1 servers. .. deprecated:: 1.18.0 Use :class:`ClientV2` instead. .. note:: While this class handles the majority of the differences between versions of the ACME protocol, if you need to support an ACME server based on version 3 or older of the IETF ACME draft that uses combinations in authorizations (or lack thereof) to signal that the client needs to complete something other than any single challenge in the authorization to make it valid, the user of this class needs to understand and handle these differences themselves. This does not apply to either of Let's Encrypt's endpoints where successfully completing any challenge in an authorization will make it valid. :ivar int acme_version: 1 or 2, corresponding to the Let's Encrypt endpoint :ivar .ClientBase client: either Client or ClientV2 rrrserverrNcCsVtj||}|||_||jdkr"t|||d|_dSt ||d|_dS)Nr)rr)r) rrzr,r/r-_acme_version_from_directoryrrclientr)rrrr3rr r r!r"js   z$BackwardsCompatibleClientV2.__init__rcCs t|j|Sru)r<r5)rrr r r! __getattr__ss z'BackwardsCompatibleClientV2.__getattr__r2 check_tos_cbcsdtddffdd }|jdkr,tt|j}||}|jdur*||j||S|Stt|j}d|j j vrE||j j j|j dd }| |S) zCombined register and agree_tos for V1, new_account for V2 :param .NewRegistration regr: :param callable check_tos_cb: callback that raises an error if the check does not work tosrNcsdur |dSdSrur )r8r7r r! _assess_toss zDBackwardsCompatibleClientV2.new_account_and_tos.._assess_tosrr%T)terms_of_service_agreed) rbrrrr5rr%rrrr(r?r)rr2r7r: client_v1 client_v2r r9r!new_account_and_tosvs          z/BackwardsCompatibleClientV2.new_account_and_tosrcCsp|jdkr/tt|j}tjtjj|}t |}g}|D] }| | |qt j ||dStt|j|S)aRequest a new Order object from the server. If using ACMEv1, returns a dummy OrderResource with only the authorizations field filled in. :param bytes csr_pem: A CSR in PEM format. :returns: The newly created order. :rtype: OrderResource :raises errors.WildcardUnsupportedError: if a wildcard domain is requested but unsupported by the ACME version r)rr)rrrr5rrrrrrrrrrrr )rrr<rrrrr r r!r s   z%BackwardsCompatibleClientV2.new_orderFr r rc Cs|jdkrktt|j}|j}|ttj tj j ||j }d}t j |krFz||}Wntjy>tdYnwt j |ks(|durOtdtj tj j |jj}t|} |j|| dStt|j|||S)rrNzoFailed to fetch chain. You should not deploy the generated certificate, please rerun the command for a new one.)r)rrrr5rrrrrrrrrrerhrrrrrrdump_certificater(wrappeddecoderdump_pyopenssl_chainr?rr) rr r rr<rrrrl chain_strr r r!rs@    z*BackwardsCompatibleClientV2.finalize_orderrlrmcCs|j||dSr)r5rrr r r!rs z"BackwardsCompatibleClientV2.revokercCst|drdSdS)Nr8rr)r;)rrr r r!r4s z8BackwardsCompatibleClientV2._acme_version_from_directorycCs|jdkrdStt|jS)zChecks if the server requires an external account for ACMEv2 servers. Always return False for ACMEv1 servers, as it doesn't use External Account Binding.rF)rrrr5r)rr r r!r)s z5BackwardsCompatibleClientV2.external_account_requiredrur0)rvrwrxryrrrbr"rr6rrr rr*r>r1rr rerrrrcrrzr4r)r r r r!r2Ts(    * r2c@seZdZdZdZdZdZdZ dej dde dfd ej d e e jd ejd ed edede eeeeeffddfddZd2ddZdejdedededejf ddZe d3dejde edejfddZdeded ed!edejf d"d#Zd ed!edejfd$d%Z efdeded!edejfd&d'Z!dejddfd(d)Z"ded*edefd+d,Z#d ed!edejfd-d.Z$ed/fdedejdeded!edejf d0d1Z%dS)4rzvWrapper around requests that signs POSTs for authentication. Also adds user agent, and handles Content-Type. zapplication/jsonzapplication/jose+jsonzapplication/problem+jsonz Replay-NonceNTz acme-pythonrrDrr user_agenttimeoutsource_addressrc Csl||_||_||_||_t|_||_t|_ ||_ t }|dur&t |}|j d||j d|dS)Nzhttp://zhttps://)rrDrrr_noncesrDr|Sessionsession_default_timeoutrrmount) rrrDrrrDrErFadapterr r r!r"s zClientNetwork.__init__cCs&z|jWdStyYdSwru)rIclose Exceptionrr r r!__del__s  zClientNetwork.__del__objnoncer&rcCst|tr||_|r|jddnd}td||j|d}|dkr4||d<|jdur4|jd|d <|j |d <t j j |fi|jddS) aWrap `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: `josepy.JWS` r)indentzJWS payload: %s)rrQr&Nr$kidr) rrle_acme_version json_dumpsencoderrrrDrrJWSsign)rrPrQr&rjobjr7r r r! _wrap_in_jws"s    zClientNetwork._wrap_in_jwsr#rc Cs |jd}|r|dd}z|}Wn ty"d}Ynw|jdkr2t|jdd|j sd|dur_||j krDt d|zt j|tjy^}zt||fd}~wwt||durs||jkrst d |||jkr|durtd ||S) 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 (draft-ietf-appsawg-http-problem-00). :raises .ClientError: In case of other networking errors. Content-Type;rNir'zUNKNOWN-LOCATIONz/Ignoring wrong Content-Type (%r) for JSON Errorz.)rrrr:rDrJrIrequestr| exceptionsRequestExceptionrematchrbgroupsrdrr.r/rbase64 b64encoderencodingrrqjoinitems)rrfr&r6r7r#e err_regexmhostpath_err_noerr_msg debug_contentr r r! _send_request{sD     zClientNetwork._send_requestcOs|jdg|Ri|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)rr>r r r!headszClientNetwork.headcKs|j|jd|fi||dS)z$Send GET request and check response.GETr)rer)rr&rr7r r r!r/szClientNetwork.getc Cs||j|jvr9|j|j}z tjjd|}Wntjy*}zt ||d}~wwt d||j |dSt|)NrQzStoring nonce: %s)REPLAY_NONCE_HEADERr.rHeader_fieldsrArrbrBadNoncerrrGr MissingNonce)rr#rQ decoded_noncerr r r! _add_nonces     zClientNetwork._add_noncer9cCsL|js!td|dur||}n |j||dd}|||jS)NzRequesting fresh noncer)rGrrrrerpop)rr&r9r#r r r! _get_nonces    zClientNetwork._get_noncec Osbz |j|i|WStjy0}z|jdkr+td||j|i|WYd}~Sd}~ww)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_oncerrcoderr)rr6r7rr r r!r=s  zClientNetwork.postrc Ksh|dd}|||||||}|dd|i|jd|fd|i|}|j||d}|||S)Nr9r.r\rgrhr)rr[rr:rrer) rr&rPrrr7r9rhr#r r r!rs  zClientNetwork._post_once)rNru)&rvrwrxryrcJOSE_CONTENT_TYPErarrrDEFAULT_NETWORK_TIMEOUTrr rr*rrrbrcrr r"rOJSONDeSerializablerXr[r{r|r}rerrrr/rrr=rr r r r!rsr     ;K    rc@sneZdZdZdeddfddZdedefdd Zded eddfd d Z deddfd dZ de efddZ dS)_ClientDeprecationModulez Internal class delegating to a module, and displaying warnings when attributes related to deprecated attributes in the acme.client module. modulerNcCs||jd<dSN_module)__dict__)rrr r r!r"sz!_ClientDeprecationModule.__init__attrcCs*|dvrtjd|tddt|j|S)N)rr2zHThe {0} attribute in acme.client is deprecated and will be removed soon.r) stacklevel)warningswarnrDeprecationWarningr<rrrr r r!r6s  z$_ClientDeprecationModule.__getattr__rcCst|j||dSru)setattrr)rrrr r r! __setattr__sz$_ClientDeprecationModule.__setattr__cCst|j|dSru)delattrrrr r r! __delattr__z$_ClientDeprecationModule.__delattr__cCsdgt|jSr)dirrrr r r!__dir__ rz _ClientDeprecationModule.__dir__) rvrwrxryrr"rbrr6rrr rr r r r!r sr):ryrsrre email.utilsrr http.clientr5rrloggingrpsysrtypesrtypingrrrrrr r r r r rrjosepyrrr|requests.adaptersrrequests.utilsr!requests_toolbelt.adapters.sourceracmerrrr acme.mixinsr getLoggerrvrrrrrrr2rrmodulesr r r r!sh                       Fix