a ‚oeöFã@s\dZddlZddlmZddlZddlmZddlZddl Z ddl Z ddl m Z ddl Z ddl Z ddlZddlmZddlmZddlmZdd lmZdd lmZdd lmZdd lmZdd lmZddlZddlmZddlmZddlmZddlmZddl 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/ddl.m0Z0ddl1m&Z2ddl3m4Z4e j5dk�r¦ddl6m7Z8nddl8Z8Gdd„de4j9ƒZ:e;e;dœd d!„Ze;e?e?e?d$œd%d&„Z@e;e#jAdœd'd(„ZBe;e#jCdœd)d*„ZDe;e!jEdœd+d,„ZFe;e!jGdœd-d.„ZHe;e#jIdœd/d0„ZJdUe;e;eKe;d2œd3d4„ZLejMd5œd6d7„ZNdVeeejMd8œd9d:„ZOGd;d<„d<ƒZPePd5œd=d>„ZQeePd8œd?d@„ZReeddAœdBdC„ZSGdDdE„dEejTƒZUGdFdG„dGeUƒZVe jWe jWe;ddHœdIdJ„ZXegefe;ddKœdLdM„ZYe;eedNefgedNeffdOœdPdQ„ZZe;e;dRœdSdT„Z[dS)WzTest utilities.éN)Ú ExitStack)Úreload)Ú synchronize)ÚAny)ÚCallable)Úcast)ÚIO)ÚIterable)ÚList)ÚOptional)ÚUnion)Úmock)Údefault_backend)Ú serialization)Ú RSAPrivateKey)Úcrypto)Ú configuration)Úutil)Ú constants)Úlock)Ústorage)Úobj)Ú filesystem)Úos)Úcommon)éé c@sÚeZdZdZeedœdd„Zeeeeeddœdd„Zdeeee e eefdd œd d „Z e edœd d „Z deee ddœdd„Zddœdd„Zddœdd„Zeedddœdd„ƒZddœdd„Zedœdd„ZdS) ÚDummyInstallerz(Dummy installer plugin for test purpose.©ÚreturncCsgS©N©©Úselfr!r!ú3C:\Program Files\Certbot\pkgs\certbot\tests\util.pyÚ get_all_names1szDummyInstaller.get_all_namesN)ÚdomainÚ cert_pathÚkey_pathÚ chain_pathÚfullchain_pathrcCsdSr r!)r#r&r'r(r)r*r!r!r$Ú deploy_cert4szDummyInstaller.deploy_cert)r&Ú enhancementÚoptionsrcCsdSr r!)r#r&r,r-r!r!r$Úenhance8szDummyInstaller.enhancecCsgSr r!r"r!r!r$Úsupported_enhancements<sz%DummyInstaller.supported_enhancementsF)ÚtitleÚ temporaryrcCsdSr r!)r#r0r1r!r!r$Úsave?szDummyInstaller.savecCsdSr r!r"r!r!r$Ú config_testBszDummyInstaller.config_testcCsdSr r!r"r!r!r$ÚrestartEszDummyInstaller.restart).N)ÚaddrcCsdSr r!)Úclsr5r!r!r$Úadd_parser_argumentsHsz#DummyInstaller.add_parser_argumentscCsdSr r!r"r!r!r$ÚprepareLszDummyInstaller.preparecCsdS)NÚr!r"r!r!r$Ú more_infoOszDummyInstaller.more_info)N)NF)Ú__name__Ú __module__Ú __qualname__Ú__doc__r Ústrr%r+r r r r.r/Úboolr2r3r4Ú classmethodrr7r8r:r!r!r!r$r/s"ÿ ÿÿ r)ÚnamesrcGsBtƒ}t |j¡t t¡jdg|¢RŽ}| t  |¡¡}t |ƒS)zPath to a test vector.Útestdata) rÚatexitÚregisterÚcloseÚimportlib_resourcesÚfilesÚ __package__ÚjoinpathÚ enter_contextZas_filer?)rBZ _file_managerÚ vector_refÚpathr!r!r$Ú vector_pathSs  rNcGsRt t¡jdg|¢RŽ}| ¡}z| ¡ dd¡ ¡WStyL|YS0dS)zLoad contents of a test vector.rCz Ú N) rGrHrIrJÚ read_bytesÚdecodeÚreplaceÚencodeÚ ValueError)rBrLÚdatar!r!r$Ú load_vector\s  rV)ÚfilenameÚ loader_pemÚ loader_derrcCs<tj |¡\}}| ¡dkr |S| ¡dkr0|Stdƒ‚dS)Nz.pemz.derz1Loader could not be recognized based on extension)rrMÚsplitextÚlowerrT)rWrXrYÚ_Úextr!r!r$Ú _guess_loaderis   r^cGs$t|dtjtjƒ}t |t|Ž¡S)zLoad certificate.éÿÿÿÿ)r^rÚ FILETYPE_PEMÚ FILETYPE_ASN1Zload_certificaterV©rBÚloaderr!r!r$Ú load_certrsÿrdcGs$t|dtjtjƒ}t |t|Ž¡S)zLoad certificate request.r_)r^rr`raZload_certificate_requestrVrbr!r!r$Úload_csrysÿrecGst t|Ž¡S)z(Load ComparableX509 certificate request.)ÚjoseÚComparableX509re)rBr!r!r$Úload_comparable_csr€srhc GsLt|dtjtjƒ}|tjkr&tj}ntj}t t t |t |Ždt ƒd�ƒ¡S)zLoad RSA private key.r_N)ÚpasswordZbackend) r^rr`rarZload_pem_private_keyZload_der_private_keyrfÚComparableRSAKeyrrrVr)rBrcZ loader_fnr!r!r$Úload_rsa_private_key…s ÿÿrkcGs$t|dtjtjƒ}t |t|Ž¡S)zLoad pyOpenSSL private key.r_)r^rr`raZload_privatekeyrVrbr!r!r$Úload_pyopenssl_private_key’sÿrlT)Ú config_dirÚtestfileÚecrc sp|dtdƒ …}tj ˆtj¡}tj ˆtj|¡}tj ˆtj|¡}|||fD]}tj |¡sPt   |¡qPt d  |rzdnd¡ƒ}t  |¡D]$} t tj || ¡tj || ¡¡qŒtjD]0} t tj |d  | ¡¡tj |d  | ¡¡¡q¸tj ˆ||¡} tt |ƒƒ�T} t| dƒ�(} |  ‡fd d „| Dƒ¡Wdƒn1�sB0YWdƒn1�sb0Y| S) a¶Creates a lineage defined by testfile. This creates the archive, live, and renewal directories if necessary and creates a simple lineage. :param str config_dir: path to the configuration directory :param str testfile: configuration file to base the lineage on :param bool ec: True if we generate the lineage with an ECDSA key :returns: path to the renewal conf file for the created lineage :rtype: str Nz.confzsample-archive{}z-ecr9z{0}1.pemz{0}.pemÚwc3s|]}| dˆ¡VqdS)ZMAGICDIRN)rR)Ú.0Úline©rmr!r$Ú Àszmake_lineage..)ÚlenrrMÚjoinrZRENEWAL_CONFIGS_DIRZ ARCHIVE_DIRZLIVE_DIRÚexistsrÚmakedirsrNÚformatÚlistdirÚshutilÚcopyfilerZALL_FOURÚsymlinkÚopenÚ writelines) rmrnroZ lineage_nameZconf_dirÚ archive_dirZlive_dirZ directoryZsample_archiveÚkindZ conf_pathÚsrcÚdstr!rsr$Ú make_lineage™s:ÿÿÿ   ÿ ÿ ÿHr„rcCsttjtjdtd�ƒS)aDPatch certbot.display.util to use a special mock display utility. The mock display utility works like a regular mock object, except it also also asserts that methods are called with valid arguments. The mock created by this patch mocks out Certbot internals. That is, the mock object will be called by the certbot.display.util functions and the mock returned by that call will be used as the display utility. This was done to simplify the transition from zope.component and mocking certbot.display.util functions directly in test code should be preferred over using this function in the future. See https://github.com/certbot/certbot/issues/8948 :returns: patch on the function used internally by certbot.display.util to get a display utility instance :rtype: mock.MagicMock ú)certbot._internal.display.obj.get_display)Z new_callable)rr Ú MagicMockÚpatchÚ_create_display_util_mockr!r!r!r$Úpatch_display_utilÆs ÿr‰)ÚstdoutrcCs*|r|nt ¡}ttjtjdt|ƒd�ƒS)aPatch certbot.display.util to use a special mock display utility. The mock display utility works like a regular mock object, except it also asserts that methods are called with valid arguments. The mock created by this patch mocks out Certbot internals. That is, the mock object will be called by the certbot.display.util functions and the mock returned by that call will be used as the display utility. This was done to simplify the transition from zope.component and mocking certbot.display.util functions directly in test code should be preferred over using this function in the future. See https://github.com/certbot/certbot/issues/8948 The `message` argument passed to the display utility methods is passed to stdout's write method. :param object stdout: object to write standard output to; it is expected to have a `write` method :returns: patch on the function used internally by certbot.display.util to get a display utility instance :rtype: mock.MagicMock r…)Únew)ÚioÚStringIOrr r†r‡Ú%_create_display_util_mock_with_stdout©rŠr!r!r$Úpatch_display_util_with_stdoutÞs ÿr�c@s€eZdZdZddejjfeee de fe ddœdd„Z ddœd d „Z e e ej d œd d „Zee dœdd„Zee ddœdd„ZdS)Ú FreezableMockaÄMock object with the ability to freeze attributes. This class works like a regular mock.MagicMock object, except attributes and behavior set before the object is frozen cannot be changed during tests. If a func argument is provided to the constructor, this function is called first when an instance of FreezableMock is called, followed by the usual behavior defined by MagicMock. The return value of func is ignored. FN.)ÚfrozenÚfuncÚ return_valuercCs>|r tƒndh|_||_t ¡|_|tjjkr4||_||_ dS)NÚfreeze) ÚsetÚ _frozen_setÚ_funcr r†Ú_mockÚsentinelÚDEFAULTr”Ú_frozen)r#r’r“r”r!r!r$Ú__init__ s   zFreezableMock.__init__rcCs d|_dS)z)Freeze object preventing further changes.TN)rœr"r!r!r$r•szFreezableMock.freeze©ÚargsÚkwargsrcOs*|jdur|j|i|¤Ž|j|i|¤ŽSr )r˜r™)r#rŸr r!r!r$Ú__call__s zFreezableMock.__call__)ÚnamercCs||dkr.zt ||¡WSty*YdS0nJ|dvrHtt |d¡|ƒS|dksZ||jvrft ||¡Stt |d¡|ƒSdS)NrœF©r”Z side_effectr™r—)ÚobjectÚ__getattribute__ÚAttributeErrorÚgetattrr—)r#r¢r!r!r$r¥s   zFreezableMock.__getattribute__)r¢ÚvaluercCsb|jr*||jvrtd|ƒ‚t|j||ƒS|dkr>|j |¡|dvrTt|j||ƒSt |||¡S)aÍ Before it is frozen, attributes are set on the FreezableMock instance and added to the _frozen_set. Attributes in the _frozen_set cannot be changed after the FreezableMock is frozen. In this case, they are set on the underlying _mock. In cases of return_value and side_effect, these attributes are always passed through to the instance's _mock and added to the _frozen_set before the object is frozen. zCannot change frozen attribute r—r£)rœr—r¦Úsetattrr™r5r¤Ú __setattr__)r#r¢r¨r!r!r$rª*s    zFreezableMock.__setattr__)r;r<r=r>r ršr›r@r rrr�r•r†r¡r?r¥rªr!r!r!r$r‘þs ÿÿ  r‘cCsXtƒ}dd„ttjƒDƒ}|D]$}|dkrtdtd�}t|||ƒq| ¡td|d�S)NcSs*g|]"}tttj|ƒƒr| d¡s|‘qS©Ú__©Úcallabler§Ú display_objÚ FileDisplayÚ startswith©rqr“r!r!r$Ú Fs þz-_create_display_util_mock..Ú notificationT©r’r“©r’r”)r‘Údirr¯r°Ú_assert_valid_callr©r•)ÚdisplayÚ method_listÚmethodÚ frozen_mockr!r!r$rˆCs rˆcs”tttddœ‡fdd„ ‰ttddœ‡fdd„ }tƒ}dd„ttjƒDƒ}|D]2}|d krftd ˆd �}n td |d �}t|||ƒqL| ¡td |d �S) N)ÚmessageÚ unused_argsÚ unused_kwargsrcs|rˆ |¡dS)z$Write to message to stdout. N)Úwrite)r½r¾r¿r�r!r$Ú _write_msgRsz9_create_display_util_mock_with_stdout.._write_msgržcst||ƒˆ|i|¤ŽdS)z< Mock function for display utility methods. N)r¸)rŸr )rÁr!r$Ú mock_methodXs z:_create_display_util_mock_with_stdout..mock_methodcSs*g|]"}tttj|ƒƒr| d¡s|‘qSr«r­r²r!r!r$r³as þz9_create_display_util_mock_with_stdout..r´Trµr¶)r?rr‘r·r¯r°r©r•)rŠrÂr¹rºr»r¼r!)rÁrŠr$rŽQsÿÿrŽržcOsN|r |dn|dg}| dd¡| dd¡| dd¡dœ}tj|i|¤ŽdS)Nrr½ÚdefaultÚcli_flagÚforce_interactiveF)rÃrÄrÅ)ÚgetÚ display_utilZassert_valid_call)rŸr Z assert_argsZ assert_kwargsr!r!r$r¸ps    ýr¸c@s,eZdZdZddœdd„Zddœdd„ZdS)ÚTempDirTestCasezBBase test class which sets up and tears down a temporary directoryNrcCst ¡|_dS)zExecute before testN)ÚtempfileZmkdtempÚtempdirr"r!r!r$ÚsetUpszTempDirTestCase.setUpcCs*t ¡gt ¡_t ¡t |j¡dS)zExecute after testN) ÚloggingZshutdownZ getLoggerÚhandlersrZ_release_locksr{ÚrmtreerÊr"r!r!r$ÚtearDownƒs zTempDirTestCase.tearDown)r;r<r=r>rËrÏr!r!r!r$rÈ|srÈcs&eZdZdZddœ‡fdd„ Z‡ZS)ÚConfigTestCasez2Test class which sets up a NamespaceConfig object.NrcsÀtƒ ¡t tjfit tj ¡¤Ž¡|_ |j   i¡d|j j _ tj |jd¡|j j _tj |jd¡|j j _tj |jd¡|j j _tj d|j j _tj d|j j _tj d|j j _d|j j _dS)NZcertonlyÚconfigZworkZlogsZauth_cert_pathZauth_chain_pathzhttps://example.com)ÚsuperrËrZNamespaceConfigr r†ÚcopyÚdeepcopyrZ CLI_DEFAULTSrÑZset_argument_sourcesÚ namespaceZverbrrMrvrÊrmZwork_dirZlogs_dirr'r*r)Zserverr"©Ú __class__r!r$rË”s þ  zConfigTestCase.setUp)r;r<r=r>rËÚ __classcell__r!r!rÖr$rÐ’srÐ)Úevent_inÚ event_outrMrcCsZtj |¡rt |¡}n t |¡}z(| ¡|jdd�s@Jdƒ‚W| ¡n | ¡0dS)a„ Acquire a file lock on given path, then wait to release it. This worker is coordinated using events to signal when the lock should be acquired and released. :param multiprocessing.Event event_in: event object to signal when to release the lock :param multiprocessing.Event event_out: event object to signal when the lock is acquired :param path: the path to lock é©Útimeoutz*Timeout while waiting to release the lock.N) rrMÚisdirrZlock_dirZLockFiler–ÚwaitÚrelease)rÙrÚrMZmy_lockr!r!r$Ú _handle_lock¥s   rá)ÚcallbackÚ path_to_lockrcCstttƒt ¡}t ¡}tjt|||fd�}| ¡|jdd�sHJdƒ‚|ƒ| ¡|j dd�|j dkspJ‚dS)zÜ Grab a lock on path_to_lock from a foreign process then execute the callback. :param callable callback: object to call after acquiring the lock :param str path_to_lock: path to file or directory to lock )ÚtargetrŸé rÜz*Timeout while waiting to acquire the lock.rN) Ú reload_modulerÚmultiprocessingÚEventZProcessráÚstartrßr–rvZexitcode)rârãZ emit_eventZ receive_eventZprocessr!r!r$Ú lock_and_call¸sÿ rê.)Úreasonrcs(tdtftdtfdœ‡fdd„ }|S)zFDecorator to skip permanently a test on Windows. A reason is required..)Úfunctionrcst tjdkˆ¡|ƒS)zWrapped versionÚwin32)ÚunittestZskipIfÚsysÚplatform)rì©rër!r$ÚwrapperÕsz skip_on_windows..wrapper)rr)rëròr!rñr$Úskip_on_windowsÓs$ró)rMrcCstj t ¡|¡S)z® Return the given path joined to the tempdir path for the current platform Eg.: 'cert' => /tmp/cert (Linux) or 'C:\Users\currentuser\AppData\Temp\cert' (Windows) )rrMrvrÉZ gettempdir)rMr!r!r$Ú temp_joinÛsrô)T)N)\r>rDÚ contextlibrrÓÚ importlibrrærŒrÌrçrr{rïrÉÚtypingrrrrr r r r rîr Zcryptography.hazmat.backendsrZcryptography.hazmat.primitivesrZ-cryptography.hazmat.primitives.asymmetric.rsarZjosepyrfZOpenSSLrZcertbotrrZcertbot._internalrrrZcertbot._internal.displayrr¯Zcertbot.compatrrZcertbot.displayrÇZcertbot.pluginsrÚ version_infoZimportlib.resourcesZ resourcesrGZ Installerrr?rNÚbytesrVÚintr^ZX509rdZX509ReqrergrhrjrkZPKeyrlr@r„r†r‰r�r‘rˆrŽr¸ZTestCaserÈrÐrèrárêrórôr!r!r!r$Ús€                           $    -ÿ ÿ E *