a oeF@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 j5dkrddl6m7Z8nddl8Z8Gddde4j9Z:e;e;dd d!Ze;e?e?e?d$d%d&Z@e;e#jAdd'd(ZBe;e#jCdd)d*ZDe;e!jEdd+d,ZFe;e!jGdd-d.ZHe;e#jIdd/d0ZJdUe;e;eKe;d2d3d4ZLejMd5d6d7ZNdVeeejMd8d9d:ZOGd;d<d<ZPePd5d=d>ZQeePd8d?d@ZReeddAdBdCZSGdDdEdEejTZUGdFdGdGeUZVe jWe jWe;ddHdIdJZXegefe;ddKdLdMZYe;eedNefgedNeffdOdPdQZZe;e;dRdSdTZ[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@seZdZdZeedddZeeeeeddddZdeeee e eefdd d d Z e edd d Z deee ddddZddddZddddZeedddddZddddZedddZdS) DummyInstallerz(Dummy installer plugin for test purpose.returncCsgSNselfr!r!3C:\Program Files\Certbot\pkgs\certbot\tests\util.py get_all_names1szDummyInstaller.get_all_namesN)domain cert_pathkey_path chain_pathfullchain_pathrcCsdSr r!)r#r&r'r(r)r*r!r!r$ deploy_cert4szDummyInstaller.deploy_cert)r& enhancementoptionsrcCsdSr 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)Nr!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|jttjdg|R}|t |}t |S)zPath to a test vector.testdata) ratexitregistercloseimportlib_resourcesfiles __package__joinpath enter_contextZas_filer?)rBZ _file_manager vector_refpathr!r!r$ vector_pathSs  rNcGsRttjdg|R}|}z|ddWStyL|YS0dS)zLoad contents of a test vector.rCz  N) rGrHrIrJ read_bytesdecodereplaceencode ValueError)rBrLdatar!r!r$ load_vector\s  rV)filename loader_pem loader_derrcCs<tj|\}}|dkr |S|dkr0|StddS)Nz.pemz.derz1Loader could not be recognized based on extension)rrMsplitextlowerrT)rWrXrY_extr!r!r$ _guess_loaderis   r^cGs$t|dtjtj}t|t|S)zLoad certificate.)r^r FILETYPE_PEM FILETYPE_ASN1Zload_certificaterVrBloaderr!r!r$ load_certrsrdcGs$t|dtjtj}t|t|S)zLoad certificate request.r_)r^rr`raZload_certificate_requestrVrbr!r!r$load_csrysrecGstt|S)z(Load ComparableX509 certificate request.)joseComparableX509re)rBr!r!r$load_comparable_csrsrhc GsLt|dtjtj}|tjkr&tj}ntj}tt t |t |dt dS)zLoad RSA private key.r_N)passwordZbackend) r^rr`rarZload_pem_private_keyZload_der_private_keyrfComparableRSAKeyrrrVr)rBrcZ loader_fnr!r!r$load_rsa_private_keys rkcGs$t|dtjtj}t|t|S)zLoad pyOpenSSL private key.r_)r^rr`raZload_privatekeyrVrbr!r!r$load_pyopenssl_private_keysrlT) config_dirtestfileecrc sp|dtd }tjtj}tjtj|}tjtj|}|||fD]}tj|sPt |qPt d |rzdnd}t |D]$} ttj|| tj|| qtjD]0} ttj|d | tj|d | qtj||} tt |T} t| d(} | fd d | DWdn1sB0YWdn1sb0Y| S) aCreates 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}.pemwc3s|]}|dVqdS)ZMAGICDIRN)rR).0linermr!r$ szmake_lineage..)lenrrMjoinrZRENEWAL_CONFIGS_DIRZ ARCHIVE_DIRZLIVE_DIRexistsrmakedirsrNformatlistdirshutilcopyfilerZALL_FOURsymlinkopen writelines) rmrnroZ lineage_nameZconf_dir archive_dirZlive_dirZ directoryZsample_archivekindZ conf_pathsrcdstr!rsr$ make_lineages:     HrrcCsttjtjdtdS)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 MagicMockpatch_create_display_util_mockr!r!r!r$patch_display_utils r)stdoutrcCs*|r|nt}ttjtjdt|dS)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)ioStringIOrr rr%_create_display_util_mock_with_stdoutrr!r!r$patch_display_util_with_stdouts rc@seZdZdZddejjfeee de fe ddddZ ddd d Z e e ej d d d Zee dddZee ddddZdS) FreezableMockaMock 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.)frozenfunc return_valuercCs>|r tndh|_||_t|_|tjjkr4||_||_ dS)Nfreeze) set _frozen_set_funcr r_mocksentinelDEFAULTr_frozen)r#rrrr!r!r$__init__ s   zFreezableMock.__init__rcCs d|_dS)z)Freeze object preventing further changes.TN)rr"r!r!r$rszFreezableMock.freezeargskwargsrcOs*|jdur|j|i||j|i|Sr )rr)r#rrr!r!r$__call__s zFreezableMock.__call__)namercCs||dkr.zt||WSty*YdS0nJ|dvrHtt|d|S|dksZ||jvrft||Stt|d|SdS)NrFrZ side_effectrr)object__getattribute__AttributeErrorgetattrr)r#rr!r!r$rs   zFreezableMock.__getattribute__)rvaluercCsb|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 rr)rrrsetattrrr5r __setattr__)r#rrr!r!r$r*s    zFreezableMock.__setattr__)r;r<r=r>r rrr@r rrrrrrr?rrr!r!r!r$rs   rcCsXt}ddttjD}|D]$}|dkrtdtd}t|||q|td|dS)NcSs*g|]"}tttj|r|ds|qS__callabler display_obj FileDisplay startswithrqrr!r!r$ Fs z-_create_display_util_mock.. notificationTrrrr)rdirrr_assert_valid_callrr)display method_listmethod frozen_mockr!r!r$rCs rcstttddfdd ttddfdd }t}ddttjD}|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)rrrrr!r$ _write_msgRsz9_create_display_util_mock_with_stdout.._write_msgrcst|||i|dS)z< Mock function for display utility methods. N)r)rr)rr!r$ mock_methodXs z:_create_display_util_mock_with_stdout..mock_methodcSs*g|]"}tttj|r|ds|qSrrrr!r!r$ras z9_create_display_util_mock_with_stdout..rTrr)r?rrrrrrr)rrrrrrr!)rrr$rQsrrcOsN|r |dn|dg}|dd|dd|ddd}tj|i|dS)Nrrdefaultcli_flagforce_interactiveF)rrr)get display_utilZassert_valid_call)rrZ assert_argsZ assert_kwargsr!r!r$rps    rc@s,eZdZdZddddZddddZdS)TempDirTestCasezBBase test class which sets up and tears down a temporary directoryNrcCst|_dS)zExecute before testN)tempfileZmkdtemptempdirr"r!r!r$setUpszTempDirTestCase.setUpcCs*tgt_tt|jdS)zExecute after testN) loggingZshutdownZ getLoggerhandlersrZ_release_locksr{rmtreerr"r!r!r$tearDowns zTempDirTestCase.tearDown)r;r<r=r>rrr!r!r!r$r|srcs&eZdZdZddfdd ZZS)ConfigTestCasez2Test class which sets up a NamespaceConfig object.Nrcstttjfittj |_ |j id|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)NZcertonlyconfigZworkZlogsZauth_cert_pathZauth_chain_pathzhttps://example.com)superrrZNamespaceConfigr rcopydeepcopyrZ CLI_DEFAULTSrZset_argument_sources namespaceZverbrrMrvrrmZwork_dirZlogs_dirr'r*r)Zserverr" __class__r!r$rs   zConfigTestCase.setUp)r;r<r=r>r __classcell__r!r!rr$rsr)event_in event_outrMrcCsZtj|rt|}n t|}z(||jdds@JdW|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) rrMisdirrZlock_dirZLockFilerwaitrelease)rrrMZmy_lockr!r!r$ _handle_locks   r)callback path_to_lockrcCstttt}t}tjt|||fd}||jddsHJd|||j dd|j dkspJdS)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 rz*Timeout while waiting to acquire the lock.rN) reload_modulermultiprocessingEventZProcessrstartrrrvZexitcode)rrZ emit_eventZ receive_eventZprocessr!r!r$ lock_and_calls r.)reasonrcs(tdtftdtfdfdd }|S)zFDecorator to skip permanently a test on Windows. A reason is required..)functionrcsttjdk|S)zWrapped versionwin32)unittestZskipIfsysplatform)rrr!r$wrappersz skip_on_windows..wrapper)rr)rrr!rr$skip_on_windowss$r)rMrcCstjt|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) )rrMrvrZ gettempdir)rMr!r!r$ temp_joinsr)T)N)\r>rD contextlibrr importlibrrrrrrr{rrtypingrrrrr r r r rr Zcryptography.hazmat.backendsrZcryptography.hazmat.primitivesrZ-cryptography.hazmat.primitives.asymmetric.rsarZjosepyrfZOpenSSLrZcertbotrrZcertbot._internalrrrZcertbot._internal.displayrrZcertbot.compatrrZcertbot.displayrZcertbot.pluginsr version_infoZimportlib.resourcesZ resourcesrGZ Installerrr?rNbytesrVintr^ZX509rdZX509ReqrergrhrjrkZPKeyrlr@rrrrrrrrZTestCaserrrrrrrr!r!r!r$s                           $    - E *