a G%@iŠ¢ã@s$ddlZddlZddlZddlZddlZddlZddlmZddlmZddl m Z ddl Z ddl m Z ddlmZddlmZddlmZdd lmZdd lmZdd lmZdd lmZdd lmZmZmZm Z ddl!m"Z"m#Z#ddl$m%Z%ddl&m'Z'm(Z(m)Z)m*Z*dd„Z+Gdd„deƒZ,dS)éN)ÚProcessPoolExecutor)Údatetime)Úgetpwuid)Ú __version__)Ú SoSComponent)Ú SoSIPParser)Ú SoSMacParser)ÚSoSHostnameParser)ÚSoSKeywordParser)ÚSoSUsernameParser)Ú SoSIPv6Parser)ÚSoSReportArchiveÚSoSReportDirectoryÚSoSCollectorArchiveÚSoSCollectorDirectory)ÚDataDirArchiveÚTarballArchive)ÚInsightsArchive)Úget_human_readableÚ import_moduleÚImporterHelperÚ is_executablecCs | |¡S©N)Úobfuscate_arc_files)ÚarcÚflist©rú8/usr/lib/python3.9/site-packages/sos/cleaner/__init__.pyr*srcsPeZdZdZdZdgggdgdddddgd d œ ZdK‡fd d „ ZdLd d„ZdMdd„ZdNdd„Z dOdd„Z e dd„ƒZ dd„Z dd„Ze dd„ƒZdd„Zdd „Zd!d"„Zd#d$„Zd%d&„Zd'd(„Zd)d*„Zd+d,„Zd-d.„ZdPd/d0„Zd1d2„Zd3d4„Zd5d6„Zd7d8„Zd9d:„Zd;d<„Zd=d>„Z d?d@„Z!dAdB„Z"dCdD„Z#dEdF„Z$dGdH„Z%dIdJ„Z&‡Z'S)QÚ SoSCleanera- This function is designed to obfuscate potentially sensitive information from an sos report archive in a consistent and reproducible manner. It may either be invoked during the creation of a report by using the --clean option in the report command, or may be used on an already existing archive by way of 'sos clean'. The target of obfuscation are items such as IP addresses, MAC addresses, hostnames, usernames, and also keywords provided by users via the --keywords and/or --keyword-file options. For every collection made in a report the collection is parsed for such items, and when items are found SoS will generate an obfuscated replacement for it, and in all places that item is found replace the text with the obfuscated replacement mapped to it. These mappings are saved locally so that future iterations will maintain the same consistent obfuscation pairing. In the case of IP addresses, support is for IPv4 and IPv6 - effort is made to keep network topology intact so that later analysis is as accurate and easily understandable as possible. If an IP address is encountered that we cannot determine the netmask for, a private IP address from 172.17.0.0/22 range is used instead. For IPv6, note that IPv4-mapped addresses, e.g. ::ffff:10.11.12.13, are NOT supported currently, and will remain unobfuscated. For hostnames, domains are obfuscated as whole units, leaving the TLD in place. For instance, 'example.com' may be obfuscated to 'obfuscateddomain0.com' and 'foo.example.com' may end up being 'obfuscateddomain1.com'. Users will be notified of a 'mapping' file that records all items and the obfuscated counterpart mapped to them for ease of reference later on. This file should be kept private. z6Obfuscate sensitive networking information in a reportÚautoéNú /etc/sos/cleaner/default_mappingFÚÚ obfuscate) Ú archive_typeÚdomainsÚdisable_parsersÚskip_cleaning_filesÚjobsÚkeywordsÚ keyword_fileÚmap_fileÚ no_updateÚkeep_binary_filesÚtargetÚ usernamesÚtreat_certificatesc sê|stƒ |||¡d|_nŠ|d|_|d|_|d|_|d|_|d|_d|_t|jdƒsl|jj |j_ d |j_ t   d ¡|_t   d ¡|_tjtj |jd ¡dd | ¡| ¡|_t d¡||_|j ¡|_|jj d ¡|_|jjrütj |jj¡nd}|j||jj g}t!|Žt"|Žt#|Žt$|Žt%|Žt&|Žg|_'|jj(D]v}|j'D]h} | j) *¡j+dddd} |  ,¡} | *¡ ,¡| krL| -d| ›¡|j .d|›d¡|j' /| ¡qLqBt0t1t2t3t4t5t6g|_7d|_8| -d|j›¡dS)NTÚoptionsÚtmpdirÚsys_tmpÚpolicyÚmanifestFr(rÚsosZsos_uiÚcleaner©Úexist_oké?z/etc/sos/cleanerÚparseré)ÚmaxsplitrzDisabling parser: zDisabling the 'zP' parser. Be aware that this may leave sensitive plain-text data in the archive.z#Cleaner initialized. From cmdline: )9ÚsuperÚ__init__Ú from_cmdlineÚoptsr2r3r4r5ÚhasattrÚthreadsr(r$ÚloggingZ getLoggerÚsoslogÚui_logÚosÚmakedirsÚpathÚjoinÚreview_parser_valuesÚ load_map_fileZcleaner_mappingÚumaskÚin_placeZget_preferred_hash_nameÚ hash_nameÚ componentsÚ add_sectionÚ cleaner_mdr+Údirnamer'r rr rr r Úparsersr&ÚnameÚlowerÚsplitÚstripÚlog_infoÚwarningÚremoverr rrrrrÚ archive_typesÚnested_archive) Úselfr;ÚargsZcmdlinerNZ hook_commonsÚ cleaner_dirZ parser_argsÚ_parserZ_loadedZ_tempZ _loaded_name©Ú __class__rrr?hst            ÿÿýú   ÿø  ÿzSoSCleaner.__init__cCsd|rd|›nd›d|›S)Nz[cleanerú:r"z] r©r^ÚmsgÚcallerrrrÚ _fmt_log_msg¶szSoSCleaner._fmt_log_msgcCs|j | ||¡¡dSr)rEÚdebugrhrerrrÚ log_debug¹szSoSCleaner.log_debugcCs|j | ||¡¡dSr)rEÚinforhrerrrrY¼szSoSCleaner.log_infocCs|j | ||¡¡dSr)rEÚerrorrhrerrrÚ log_error¿szSoSCleaner.log_errorcCs| d¡| |j¡dS)NzSoS Cleaner Detailed Help)Z set_titleÚadd_textÚ__doc__)ÚclsÚsectionrrrÚ display_helpÂs zSoSCleaner.display_helpc Csi}d}tj |jj¡r,td|jj›dƒ‚tj |jj¡s`|jj|krü| d|jj›d¡nœt|jjdddz}zt   |¡}WnZt j y | d ¡Yn>tyÜ}z&| d |jj›d |›¡WYd }~n d }~00Wd ƒn1sò0Y|S) z×Verifies that the map file exists and has usable content. If the provided map file does not exist, or it is empty, we will print a warning and continue on with cleaning building a fresh map r!zRequested map file z is a directoryzERROR: map file z6 does not exist, will not load any obfuscation matchesÚrúutf-8©ÚencodingzOERROR: Unable to parse map file, json is malformed. Will not load any mappings.zERROR: Could not load 'ú': N) rGrIÚisdirrAr+Ú ExceptionÚexistsrmÚopenÚjsonÚloadZJSONDecodeError)r^Z_confZ default_mapÚmfÚerrrrrrLÇs* ÿÿÿ<zSoSCleaner.load_map_filec Csš| d¡}|j dt›d¡|j |¡|jjs–z tdƒWnVtyf|j d¡| d¡Yn0t y”}z| d|¡WYd}~n d}~00dS) zWhen we are directly running `sos clean`, rather than hooking into SoSCleaner via report or collect, print a disclaimer banner a…This command will attempt to obfuscate information that is generally considered to be potentially sensitive. Such information includes IP addresses, MAC addresses, domain names, and any user-provided keywords. Note that this utility provides a best-effort approach to data obfuscation, but it does not guarantee that such obfuscation provides complete coverage of all such data in the archive, or that any obfuscation is provided to data that does not fit the description above. Users should review any resulting data and/or archives generated or processed by this utility for remaining sensitive content before being passed to a third party. z sos clean (version z) z- Press ENTER to continue, or CTRL-C to quit. z Exiting on user cancelé‚r<N) Z_fmt_msgrFrkrrAZbatchÚinputÚKeyboardInterruptÚ_exitry)r^rfÚerrrÚprint_disclaimerãs     zSoSCleaner.print_disclaimercCsd|_| dd¡}|jdddd|jdd gd ¢d d |jd dgdd|jddgddd|jdddgddd|jdddtdd|jddgdd d|jd!dd"d#d$|jd%d&d'd(d)|jd*d+d,d-d.d/|jd0d,d-d1d2d3|jd4d5gdd6d/|jd7d8gd9¢d:d;d<dS)=Nzsos clean|mask TARGET [options]zCleaner/Masking Optionsz7These options control how data obfuscation is performedr.ZTARGETz%The directory or archive to obfuscate)ÚmetavarÚhelpz--archive-typer)rÚreportZcollectZinsightszdata-dirÚtarballz8Specify what kind of archive the target was generated as)ÚdefaultÚchoicesr‡z --domainsÚextendz!List of domain names to obfuscate)ÚactionrŠr‡z--disable-parsersr&zCDisable specific parsers, so that those elements are not obfuscated)rrŠÚdestr‡z--skip-cleaning-filesz--skip-masking-filesr'zBList of files to skip/ignore during cleaning. Globs are supported.z-jz--jobsr z&Number of concurrent archives to clean)rŠÚtyper‡z --keywordsr)zList of keywords to obfuscatez--keyword-filer*z&Provide a file a keywords to obfuscate)rŠrŽr‡z --map-filer+r!z;Provide a previously generated mapping file for obfuscation)rŽrŠr‡z --no-updater,FÚ store_truezpóz3SoSCleaner.review_parser_values..N)rAr%ÚlenrWryr')r^Z_domrrrrKds  ÿÿzSoSCleaner.review_parser_valuesc Cs´|jj d¡|j_|jj d¡d d¡d|_|jr>| ¡g|_tj   |jj¡st|j   d|jj›¡|  d¡| ¡|js˜|j   d¡|  d¡g|_|jD]}|jdkr¤|j ¡q¤| ¡| ¡| ¡|jsü|jræd S|j  d ¡|  d¡|j  d t|jƒ›d ¡| ¡}| |¡}| |¡| ¡|jrZd d„|jDƒ}||fSd }t|jƒdkrx| ¡}n”|jd}|j}|  |j¡}|d ur| !| d¡d›d|j"›¡} t#tj  $|j%| ¡ddd} |  &|¡Wd ƒn1sú0Y| '¡tj  $|j%| !| d¡d¡¡}t( )||¡t *|¡} |j  d|›¡|j  d|›d¡|j  dt+| j,ƒ›¡|j  dt-| j.ƒj/›d¡|j  d¡| 0¡d S)a,SoSCleaner will begin by inspecting the TARGET option to determine if it is a directory, archive, or archive of archives. In the case of a directory, the default behavior will be to edit the data in place. For an archive will we unpack the archive, iterate over the contents, and then repack the archive. In the case of an archive of archives, such as one from SoSCollector, each archive will be unpacked, cleaned, and repacked and the final top-level archive will then be repacked as well. ú/éÿÿÿÿz.tarrz*Invalid target: no such file or directory r<z'No valid archives or directories found zHostname ParserNz#No reports obfuscated, aborting... z Successfully obfuscated z report(s) cSsg|] }|j‘qSr)Úfinal_archive_path)r¨Úarrrrª¨r«z&SoSCleaner.execute..r¤Úwrtruz2A mapping of obfuscated elements is available at z) The obfuscated archive is available at Ú z Size z Owner zcPlease send the obfuscated archive to your support representative and keep the mapping file private)1rAr.ÚrstriprWÚarc_namer@r…rrGrIrzrFrlrƒr£Úcompleted_reportsrTrUÚmappingZset_initial_countsÚpreload_all_archives_into_mapsÚgenerate_parser_item_regexesÚobfuscate_report_pathsrNrkr¬Úcompile_mapping_dictÚwrite_map_for_archiveÚwrite_map_for_configÚwrite_stats_to_manifestÚrebuild_nested_archiver¯Úget_new_checksumÚobfuscate_stringrOr{rJr3ÚwriteÚwrite_cleaner_logÚshutilÚmoveÚstatrÚst_sizerÚst_uidÚpw_nameZcleanup) r^r;Ú_mapÚmap_pathZ arc_pathsZ final_pathZarc_pathrÚchecksumZ chksum_nameÚcfZarcstatrrrÚexecutessŠ ÿ        ÿ       ÿÿ*þ  ÿ ÿ zSoSCleaner.executec Csì|jd}|j|d|jD]J}|j d¡d}| |j¡}|durd|›d|j›}|jj||dqt   |j j ¡D]X\}}}|D]H} t j  || ¡} |  |j j ¡d}| d¡}|jj| |dt  | ¡q„qv|jd d |j |jj¡S) zˆHandles repacking the nested tarball, now containing only obfuscated copies of the reports, log files, manifest, etc... z -obfuscated)rUr­r®Nz checksums/r¤©rŽT©r¢)r´Z setup_archiverµr¯rWr¿rOr¢Z add_stringrGÚwalkr]Úextracted_pathrIrJÚlstripÚadd_filer[rÂÚfinalizerAZcompression_type) r^r´r¢Zarc_destrËZdnameZdirnr™ÚfilesÚfilenameÚfnamerrrr¾Ôs"      z!SoSCleaner.rebuild_nested_archivecCs2i}|jD]"}i||j<||j | ¡¡q |S)aBuild a dict that contains each parser's map as a key, with the contents as that key's value. This will then be written to disk in the same directory as the obfuscated report so that sysadmins have a way to 'decode' the obfuscation locally )rTZ map_file_keyÚupdateZget_map_contents)r^rÉr;rrrrºìs   zSoSCleaner.compile_mapping_dictcCsFt|ddd$}| tj|dd¡Wdƒn1s80Y|S)zjWrite the mapping to a file on disk that is in the same location as the final archive(s). r±rtrur )ÚindentN)r{rÁr|Údumps)r^rÉrIr~rrrÚwrite_map_to_fileùs2zSoSCleaner.write_map_to_filec Cshz,tj |j| |j›d¡¡}| ||¡WStyb}z| d|›¡WYd}~dSd}~00dS)Nz -private_mapz"Could not write private map file: ) rGrIrJr3rÀr´rÛryrm)r^rÉrÊrrrrr»sþz SoSCleaner.write_map_for_archivec Cs|jjrŒ|jjsŒtj |jj¡}z6tj|dd| ||jj¡| d|jj›¡Wn4t yŠ}z|  d|›¡WYd}~n d}~00dS)z}Write the mapping to the config file so that subsequent runs are able to provide the same consistent mapping Tr8zWrote mapping to z&Could not update mapping config file: N) rAr+r,rGrIrSrHrÛrjryrm)r^rÉr`rrrrr¼ szSoSCleaner.write_map_for_configcCsŽtj |j|j›d¡}t|ddd6}|j d¡|j ¡D]}|  |¡q>Wdƒn1sb0Y|rŠ|  |¡|j j |dddS) z³When invoked via the command line, the logging from SoSCleaner will not be added to the archive(s) it processes, so we need to write it separately to disk z-obfuscation.logr±rtrurNzsos_logs/cleaner.logrÎ) rGrIrJr3r´r{Z sos_log_fileÚseekÚ readlinesrÁÚobfuscate_filer¢rÓ)r^r¢Zlog_nameZlogfileÚlinerrrrÂsÿ * zSoSCleaner.write_cleaner_logc Cs¢zhd}t|dƒF}t |j¡}| |¡}|s.q:| |¡q| ¡dWdƒWS1s\0YWn4tyœ}z| d|›¡WYd}~n d}~00dS)zvCalculate a new checksum for the obfuscated archive, as the previous checksum will no longer be valid iÚrbr²Nz!Could not generate new checksum: ) r{ÚhashlibÚnewrOÚreadrØZ hexdigestryrj)r^Ú archive_pathZ hash_sizeZ archive_fpZdigestZhashdatarrrrr¿,s    0&zSoSCleaner.get_new_checksumcCs(zødt|jƒ›d|jj›d}|j |¡|jjr>|j d¡|jjdkrft dƒsfd|j_|j d¡|jjdkr€|j d ¡n2|jjd krš|j d ¡n|jjdkr²|j d ¡|jD]"}|j d |j ›¡|  |¡q¸|j rö|  ¡|  |j ¡Wn*ty"|j d¡t d¡Yn0dS)zØPerform the obfuscation for each archive or sos directory discovered during setup. Each archive is handled in a separate thread, up to self.opts.jobs will be obfuscated concurrently. zFound z. total reports to obfuscate, processing up to z! concurrently within one archive zpWARNING: binary files that potentially contain sensitive information will NOT be removed from the final archive r#Zopensslr[zgWARNING: No `openssl` command available. Replacing `--treat-certificates` from `obfuscate` to `remove`.z‰WARNING: certificate files that potentially contain sensitive information will be CONVERTED to text and OBFUSCATED in the final archive. r‘zsWARNING: certificate files that potentially contain sensitive information will be KEPT in the final archive as is. zpWARNING: certificate files that potentially contain sensitive information will be REMOVED in the final archive. z Obfuscating zExiting on user cancelr€N)r¬rrAr(rFrkr-rZr0rräÚobfuscate_reportr]Ú_replace_obfuscated_archivesr‚rGrƒ)r^rfZ report_pathrrrr¹>sLÿÿ ÿ ÿÿ ÿ ÿ ÿ   z!SoSCleaner.obfuscate_report_pathscCsV|jD]J}t |j¡|jj}|j d¡d}tj  ||¡}t   |j|¡||_qdS)z±When we have a nested archive, we need to rebuild the original archive, which entails replacing the existing archives with their obfuscated counterparts r­r®N) rµrGr[rär]rÑr¯rWrIrJrÃrÄ)r^r¢rŽr‰Z dest_namerrrræts  z'SoSCleaner._replace_obfuscated_archivescCs|jD] }| ¡qdS)zéFor the parsers that use prebuilt lists of items, generate those regexes now since all the parsers should be preloaded by the archive(s) as well as being handed cmdline options and mapping file configuration. N)rTZgenerate_item_regexes)r^r;rrrr¸s z'SoSCleaner.generate_parser_item_regexesc Cs.|jD]}|j ¡ ¡d ¡}| ||¡D]}| |¡}|sBq.| d|›d|›d|j›¡|  ¡D]T}z|  |¡Wqht yº}z(| d|›d|›d|›¡WYd}~qhd}~00qhq.|  ||¡} | rþ| d|›d |j›¡| D]} |j  | ¡qì|j|D]} |j  | ¡qq| |j¡dS) a* For each archive we've determined we need to operate on, pass it to each prepper so that we can extract necessary files and/or items for direct regex replacement. Preppers define these methods per parser, so it is possible that a single prepper will read the same file for different parsers/mappings. This is preferable to the alternative of building up monolithic lists of file paths, as we'd still need to manipulate these on a per-archive basis. :param archive: The archive we are currently using to prepare our mappings with :type archive: ``SoSObfuscationArchive`` subclass :param prepper: The individual prepper we're using to source items :type prepper: ``SoSPrepper`` subclass rz Prepping z parser with file z from zFailed to prep z map from ú: Nz mapping with items from )rTrUrVrWrXZget_parser_file_listZget_file_contentrjr¡Ú splitlinesZ parse_lineryZget_items_for_mapr¶ÚaddZ regex_itemsZadd_regex_itemÚ set_parsers) r^r¢ÚprepperraZpnameZ_fileZcontentrßrZ map_itemsÚitemZritemrrrÚ_prepare_archive_with_prepper‰s4  ÿ ÿ  ÿz(SoSCleaner._prepare_archive_with_prepperccsZttjjƒ}g}| ¡D]}| td|›ƒ¡qt|dd„dD]}||jdVqBdS)a Discover all locally available preppers so that we can prepare the mappings with obfuscation matches in a controlled manner :returns: All preppers that can be leveraged locally :rtype: A generator of `SoSPrepper` items zsos.cleaner.preppers.cSs|jSr)Úpriority)ÚxrrrÚÁr«z)SoSCleaner.get_preppers..)Úkey)r1N) rr6r7ZpreppersZ get_modulesrŒrÚsortedrA)r^ÚhelperZprepsZ_preprërrrÚ get_preppersµs   zSoSCleaner.get_prepperscCsB| d¡| ¡D]}|jD]}| ||¡qq|j |j¡dS)aBefore doing the actual obfuscation, if we have multiple archives to obfuscate then we need to preload each of them into the mappings to ensure that node1 is obfuscated in node2 as well as node2 being obfuscated in node1's archive. z.Pre-loading all archives into obfuscation mapsN)rYrôrrírœrêrT)r^rër¢rrrr·Äs    z)SoSCleaner.preload_all_archives_into_mapsc sÚz’ˆj ˆj¡}t ¡}| d|¡ˆjs4ˆ ¡ˆ d¡t ˆ  ¡ƒ‰d}}}‡fdd„t ˆj j ƒDƒ}tˆj j ˆjd^}| t|‡‡fdd„t ˆj j ƒDƒ¡} | D]"\} } } || 7}|| 7}|| 7}q®Wdƒn1sæ0Yˆ ¡zˆ ˆ¡Wn<tyB} z"ˆjd | ›ˆjd WYd} ~ n d} ~ 00zˆ ˆ¡Wn<tyŽ} z"ˆjd | ›ˆjd WYd} ~ n d} ~ 00ˆjs0ˆ ¡}|r$ˆ d ¡z ˆ ˆ ˆj¡¡ˆ |¡WnRty"} z8ˆ d ˆj›d| ›¡ˆ d| ›¡WYd} ~ WdSd} ~ 00ˆj ˆ¡t ¡}| d|¡| d||¡| d|¡| d|¡d}|r‚d}||}ˆ d|›¡Wn@tyÔ} z&ˆj dˆj›d| ›¡WYd} ~ n d} ~ 00dS)zßIndividually handle each archive or directory we've discovered by running through each file therein. Positional arguments: :param archive str: Filepath to the directory or archive Ú start_timezBeginning obfuscation...rcsg|]}ˆ‘qSrr©r¨ÚirÏrrrªør«z/SoSCleaner.obfuscate_report..)Ú max_workersZ initializercsg|]}ˆ|dˆjj…‘qSr)rAr(rö)Ú file_listr^rrrªýr«Nz!Failed to obfuscate directories: ©rgzFailed to obfuscate symlinks: zRe-compressing...zArchive z failed to compress: zFailed to re-compress archive: Úend_timeZrun_timeZfiles_obfuscatedZtotal_substitutionsr"z! [removed %s unprocessable files]zObfuscation completedzException while processing rç) rRrQÚ archive_namerZnowÚ add_fieldZ is_extractedÚextractZ report_msgÚlistZ get_filesÚrangerAr(rZload_parser_entriesÚmaprÚobfuscate_directory_namesryrYÚobfuscate_symlinksrŸZget_compressionZrename_top_dirrÀÚcompressrjrµržrFrk)r^r¢Zarc_mdrõZfiles_obfuscated_countZtotal_sub_countZremoved_file_countZ archive_listÚexecutorZfuturesZfocZtscZrfcrÚmethodrûZrmsgr)r¢rùr^rråÐsŽ     þ  ÿÿ( ÿ ÿ  ÿÿÿ    ÿÿzSoSCleaner.obfuscate_reportcCs|j |g¡dSr)rœr)r^rÖrrrrÞ9szSoSCleaner.obfuscate_filec s|jd|jd| ¡D]ð}z®| |j¡d d¡‰‡fdd„|jDƒ}|sb| dˆ›d¡Wq|jd ˆ›|jdt  |¡}tj   |j|  ˆ¡¡}|  |¡}||ks²||krÈt  |¡t ||¡Wqty}z"| d |›d |›¡WYd }~qd }~00qd S) aÄIterate over symlinks in the archive and obfuscate their names. The content of the link target will have already been cleaned, and this second pass over just the names of the links is to ensure we avoid a possible race condition dependent on the order in which the link or the target get obfuscated. :param archive: The archive being obfuscated :type archive: ``SoSObfuscationArchive`` zObfuscating symlink namesrúr<r­cs(g|] }t‡fdd„|jDƒƒs|‘qS)c3s|]}| ˆ¡VqdSr)Úmatch)r¨Z_skip©Z_symrrÚ Or«z;SoSCleaner.obfuscate_symlinks...)ÚanyZ skip_patterns)r¨Z_prrrrªMsÿz1SoSCleaner.obfuscate_symlinks..z Skipping obfuscation of symlink z due to skip pattern matchzObfuscating symlink zError obfuscating symlink 'rwN)rYrüZ get_symlinksrWrÑrÒrTrjrGÚreadlinkrIrJrÀr[Úsymlinkry)r^r¢r Z_parsersÚ_targetZ _ob_sym_nameZ _ob_targetrrrrr<s2   ÿ ÿ ÿ  ÿ  zSoSCleaner.obfuscate_symlinkscCs¦| d|j›¡t| ¡ddD]~}t |¡D]n}tj ||¡}| |j ¡d}tj  |¡r0|  |¡}||kr0|  |¡}tj |j |  d¡|¡}t ||¡q0q"dS)z˜For all directories that exist within the archive, obfuscate the directory name if it contains sensitive strings found during execution z'Obfuscating directory names in archive T)Úreverser®r­N)rYrüròZget_directory_listrGÚlistdirrIrJrWrÑrxrÀr³rÒÚrename)r^r¢ÚdirpathÚ_nameZ_dirnameZ_arc_dirZ _ob_dirnameZ _ob_arc_dirrrrrjs"ÿ   ýz$SoSCleaner.obfuscate_directory_namesc CsT|jD]H}z| |¡}WqtyL}z| d|›¡WYd}~qd}~00q|S)NzError obfuscating string data: )rTZparse_string_for_keysryrY)r^Z string_datar;rrrrrÀs  (zSoSCleaner.obfuscate_stringcCsL|j d¡}|jD]4}| |j dd¡ ¡¡}| dt|jj   ¡ƒ¡qdS)zLWrite some cleaner-level, non-report-specific stats to the manifest rTú r™ÚentriesN) rRrQrTrUršrVrýr¬r¶ZdatasetÚkeys)r^Z parse_secr;Z_secrrrr½‰s  z"SoSCleaner.write_stats_to_manifest)NNNFN)N)N)N)N)F)(Ú__name__Ú __module__Ú __qualname__roZdescZ arg_defaultsr?rhrjrYrmÚ classmethodrrrLr…r–r—r£rKrÍr¾rºrÛr»r¼rÂr¿r¹rær¸rírôr·rårÞrrrÀr½Ú __classcell__rrrbrr.sh'óÿN      :"a   6 , i.r)-rár|rDrGrÃr¦Úconcurrent.futuresrrÚpwdrZsos.cleaner.preppersr6rZ sos.componentrZsos.cleaner.parsers.ip_parserrZsos.cleaner.parsers.mac_parserrZ#sos.cleaner.parsers.hostname_parserr Z"sos.cleaner.parsers.keyword_parserr Z#sos.cleaner.parsers.username_parserr Zsos.cleaner.parsers.ipv6_parserr Zsos.cleaner.archives.sosr rrrZsos.cleaner.archives.genericrrZsos.cleaner.archives.insightsrZ sos.utilitiesrrrrrrrrrrÚ s.