U
    lHJeO                     @   s  d dl Z d dlZd dlmZ d dlmZmZmZ d dlm	Z	m
Z
mZmZmZmZ d dlmZmZ d dlmZ d dlmZ d dlmZ d d	lmZ d d
lmZ d dlmZmZ d dlm Z m!Z!m"Z" e
# Z$e %e&e'Z(dddddgZ)ddgZ*ddddgZ+e)e* e)e* e)e)e+ dZ,dddgZ-dddddgZ.dddddgZ/d d!dd"d#ddgZ0e)e* e- e)e* e. e)e/ e)e+ e0 dZ1G d$d% d%ej2Z3G d&d' d'e3Z4G d(d) d)e3Z5G d*d+ d+e4Z6dS ),    N)groupby)ListOptionalTuple)aptevent_logger
exceptionsmessagessystemutil)NoCloudTypeReasonget_cloud_type)repo)IncompatibleService)ApplicationStatus)notices)Notice)ServicesOnceEnabledDataservices_once_enabled_file)MessagingOperationsMessagingOperationsDictStaticAffordance
strongswanstrongswan-hmacopenssh-clientopenssh-servershim-signedopenssh-client-hmacopenssh-server-hmacZ
libnettle8Zlibhogweed6Zlibgnutls30Zlibgmp10)ZxenialbionicfocalZjammyopenssllibssl1.0.0libssl1.0.0-hmac	libssl1.1libssl1.1-hmaclibgcrypt20libgcrypt20-hmacZgawkzupdate-notifier-commonzopenssl-fips-module-3Zlibssl3c                       s8  e Zd ZdZdZdZdZejj	Z
ddddd	dd	d
dddddddddddgZedd Zd2eee  eedd fddZd3eeddddZeeed  fd!d"Zeeed#f d$d%d&Zeee d$ fd'd(Zeeeej f d$ fd)d*Zdd$d+d,Zd4eed- fd.d/Zd5edd- fd0d1Z  ZS )6FIPSCommonEntitlementi  zubuntu-pro-fips.gpgz/proc/sys/crypto/fips_enabledTzfips-initramfsr$   r%   r"   r#   z
linux-fipsr   r   r   r   r!   r   r   r&   r'   zfips-initramfs-genericr   c                 C   s*   t  j}t  rt|g S t|g S )a  
        Dictionary of conditional packages to be installed when
        enabling FIPS services. For example, if we are enabling
        FIPS services in a machine that has openssh-client installed,
        we will perform two actions:

        1. Upgrade the package to the FIPS version
        2. Install the corresponding hmac version of that package
           when available.
        )r
   get_release_infoseriesis_container#FIPS_CONTAINER_CONDITIONAL_PACKAGESgetFIPS_CONDITIONAL_PACKAGES)selfr*    r0   </usr/lib/python3/dist-packages/uaclient/entitlements/fips.pyconditional_packages   s    
z*FIPSCommonEntitlement.conditional_packagesN)package_listcleanup_on_failureverbosereturnc              
      s   |rt tjj| jd | j}t j|dd g }t	
 }tt| jdd d}|D ]\}}	||krV||	7 }qV|D ]L}
zt j|
gddd W qt tjk
r   t tjj| j|
d Y qtX qtd	S )
a)  Install contract recommended packages for the entitlement.

        :param package_list: Optional package list to use instead of
            self.packages.
        :param cleanup_on_failure: Cleanup apt files if apt install fails.
        :param verbose: If true, print messages to stdout
        titleF)r3   r5   c                 S   s   |  ddS )Nz-hmac )replace)pkg_namer0   r0   r1   <lambda>       z8FIPSCommonEntitlement.install_packages.<locals>.<lambda>)key)r3   r4   r5   )servicepkgN)eventinfor	   ZINSTALLING_SERVICE_PACKAGESformatr8   packagessuperinstall_packagesr   get_installed_packages_namesr   sortedr2   r   ZUbuntuProErrorZFIPS_PACKAGE_NOT_AVAILABLE)r/   r3   r4   r5   Zmandatory_packagesZdesired_packagesinstalled_packagesZ
pkg_groupsr;   Zpkg_listr@   	__class__r0   r1   rF      s@     
  
 z&FIPSCommonEntitlement.install_packagesF)	operationsilentr6   c                 C   s\   t  }t| |rX|s.ttjj|d |dkrDt	t
j n|dkrXt	t
j dS )zCheck if user should be alerted that a reboot must be performed.

        @param operation: The operation being executed.
        @param silent: Boolean set True to silence print/log of messages
        )rL   installzdisable operationN)r
   should_rebootrA   Zneeds_rebootrB   r	   ZENABLE_REBOOT_REQUIRED_TMPLrC   r   addr   FIPS_SYSTEM_REBOOT_REQUIREDFIPS_DISABLE_REBOOT_REQUIRED)r/   rL   rM   Zreboot_requiredr0   r0   r1   _check_for_reboot_msg   s"    
z+FIPSCommonEntitlement._check_for_reboot_msgr*   cloud_idr6   c                    s>   |dkr:t j| jjddrdS |dkr*dS tdt jkS dS )aV  Return False when FIPS is allowed on this cloud and series.

        On Xenial GCP there will be no cloud-optimized kernel so
        block default ubuntu-fips enable. This can be overridden in
        config with features.allow_xenial_fips_on_cloud.

        GCP doesn't yet have a cloud-optimized kernel or metapackage so
        block enable of fips if the contract does not specify ubuntu-gcp-fips.
        This also can be overridden in config with
        features.allow_default_fips_metapackage_on_gcp.

        :return: False when this cloud, series or config override allows FIPS.
        gcez.features.allow_default_fips_metapackage_on_gcp)ZconfigZpath_to_valueT)r   r    zubuntu-gcp-fips)r   Zis_config_value_truecfgboolrE   rD   r/   r*   rU   rJ   r0   r1   _allow_fips_on_cloud_instance   s    z3FIPSCommonEntitlement._allow_fips_on_cloud_instance.r6   c                    s^   dddd}t  \ } d kr"d t jtjj | d}| fddd	ffS )
Nzan AWSzan Azureza GCP)ZawsZazurerV   r9   )r*   Zcloudc                      s     S N)rZ   r0   rU   r/   r*   r0   r1   r<     r=   z:FIPSCommonEntitlement.static_affordances.<locals>.<lambda>T)	r   r
   r)   r*   r	   ZFIPS_BLOCK_ON_CLOUDrC   r8   r-   )r/   Zcloud_titles_Zblocked_messager0   r]   r1   static_affordances	  s    

 z(FIPSCommonEntitlement.static_affordancesc                    s   t  rg S t jS r\   )r
   r+   rE   rD   r/   rJ   r0   r1   rD     s    zFIPSCommonEntitlement.packagesc                    s   t   \}}t r2t s2ttj ||fS t	j
| jrtt| js\ttj t| j dkrttj ||fS ttj tjtjj| jdfS |tjkr||fS tjtjfS )N1)	file_name)rE   application_statusr
   r+   rO   r   remover   rQ   ospathexistsFIPS_PROC_FILEsetrD   Z	load_filestripZFIPS_MANUAL_DISABLE_URLrP   r   ZDISABLEDr	   ZFIPS_PROC_FILE_ERRORrC   ENABLEDFIPS_REBOOT_REQUIRED)r/   Zsuper_statusZ	super_msgrJ   r0   r1   rc   "  s:    
z(FIPSCommonEntitlement.application_statusc                 C   sP   t t }t | jt | j}||}|rLtt|t	j
j| jd dS )zRemove fips meta package to disable the service.

        FIPS meta-package will unset grub config options which will deactivate
        FIPS on any related packages.
        r7   N)ri   r   rG   rD   
differencer2   intersectionremove_packageslistr	   ZDISABLE_FAILED_TMPLrC   r8   )r/   rI   Zfips_metapackagero   r0   r0   r1   ro   L  s    

z%FIPSCommonEntitlement.remove_packagesrM   r6   c                    s:   t  j|dr6ttj ttj ttj dS dS )NrM   TF)rE   _perform_enabler   rd   r   ZWRONG_FIPS_METAPACKAGE_ON_CLOUDrl   rR   )r/   rM   rJ   r0   r1   rs   ]  s    z%FIPSCommonEntitlement._perform_enablec                    s   ddg}t |tjjd|d}g }| D ]}|| jkr0|| q0|rvddg| }t |tjjd|d}t	 j
|d dS )zSetup apt config based on the resourceToken and directives.

        FIPS-specifically handle apt-mark unhold

        :raise UbuntuProError: on failure to setup any aspect of this apt
           configuration
        zapt-markZ	showholds )ZcommandZunholdrr   N)r   Zrun_apt_commandr	   ZEXECUTING_COMMAND_FAILEDrC   join
splitlinesfips_pro_package_holdsappendrE   setup_apt_config)r/   rM   cmdZholdsZunholdsZholdZ
unhold_cmdrJ   r0   r1   ry   h  s$    
z&FIPSCommonEntitlement.setup_apt_config)NTT)F)F)F) __name__
__module____qualname__Zrepo_pin_priorityrepo_key_filerh   Zapt_noninteractiver	   ZurlsZFIPS_HOME_PAGEZhelp_doc_urlrw   propertyr2   r   r   strrX   rF   rS   rZ   r   r   r_   rD   r   ZNamedMessagerc   ro   rs   ry   __classcell__r0   r0   rJ   r1   r(   h   sn   
   
4   *r(   c                       s   e Zd ZdZejZejZej	Z
dZejZeeedf dddZeeedf d fddZeedd	d
Zdeed fddZ  ZS )FIPSEntitlementfipsZ
UbuntuFIPS.r[   c                 C   s:   ddl m} ddlm} t|tjtttjt|tj	fS )Nr   )LivepatchEntitlementRealtimeKernelEntitlement)
Zuaclient.entitlements.livepatchr   uaclient.entitlements.realtimer   r   r	   ZLIVEPATCH_INVALIDATES_FIPSFIPSUpdatesEntitlementZFIPS_UPDATES_INVALIDATES_FIPSZREALTIME_FIPS_INCOMPATIBLE)r/   r   r   r0   r0   r1   incompatible_services  s       z%FIPSEntitlement.incompatible_servicesc                    s   t  j}t| j}tj}t| d |kt	 }|r>|j
nd |tjj| j|jdfdddftjj| j|jd fdddff S )Nr   F)r   fips_updatesc                      s    S r\   r0   r0   )is_fips_updates_enabledr0   r1   r<     r=   z4FIPSEntitlement.static_affordances.<locals>.<lambda>c                      s    S r\   r0   r0   )fips_updates_once_enabledr0   r1   r<     r=   )rE   r_   r   rW   r   rk   rX   rc   r   readr   r	   Z$FIPS_ERROR_WHEN_FIPS_UPDATES_ENABLEDrC   r8   Z)FIPS_ERROR_WHEN_FIPS_UPDATES_ONCE_ENABLED)r/   r_   r   Zenabled_statusZservices_once_enabled_objrJ   )r   r   r1   r_     s6    
 
 
z"FIPSEntitlement.static_affordancesc                 C   sr   d }t  r&tjj| jd}tjg}n| j}d }| jsVt	j
tjj| jd| jdfg}t	j
|| jdfg||dS Nr7   )msg
assume_yes)Z
pre_enablepost_enablepre_disable)r
   r+   r	    PROMPT_FIPS_CONTAINER_PRE_ENABLErC   r8   FIPS_RUN_APT_UPGRADEpre_enable_msgpurger   prompt_for_confirmationPROMPT_FIPS_PRE_DISABLEr   r/   r   Zpre_enable_promptr   r0   r0   r1   	messaging  s2    

zFIPSEntitlement.messagingFrq   c                    sT   t  \}}|d kr2|tjkr2td ttj t	 j
|drPttj dS dS )Nz>Could not determine cloud, defaulting to generic FIPS package.rr   TF)r   r   ZCLOUD_ID_ERRORLOGZwarningrA   rB   r	   Z.FIPS_COULD_NOT_DETERMINE_CLOUD_DEFAULT_PACKAGErE   rs   r   rd   r   ZFIPS_INSTALL_OUT_OF_DATE)r/   rM   Z
cloud_typeerrorrJ   r0   r1   rs     s    
zFIPSEntitlement._perform_enable)F)r{   r|   r}   namer	   Z
FIPS_TITLEr8   ZFIPS_DESCRIPTIONdescriptionZFIPS_HELP_TEXT	help_textoriginZPROMPT_FIPS_PRE_ENABLEr   r   r   r   r   r   r_   r   r   rX   rs   r   r0   r0   rJ   r1   r     s   !%r   c                       sl   e Zd ZdZejZdZejZ	ej
Zeeedf dddZeedddZdeed
 fddZ  ZS )r   zfips-updatesZUbuntuFIPSUpdates.r[   c                 C   s$   ddl m} tttjt|tjfS )Nr   r   )r   r   r   r   r	   FIPS_INVALIDATES_FIPS_UPDATESZ"REALTIME_FIPS_UPDATES_INCOMPATIBLE)r/   r   r0   r0   r1   r     s     z,FIPSUpdatesEntitlement.incompatible_servicesc                 C   sr   d }t  r&tjj| jd}tjg}ntj}d }| jsVt	j
tjj| jd| jdfg}t	j
|| jdfg||dS r   )r
   r+   r	   r   rC   r8   r   ZPROMPT_FIPS_UPDATES_PRE_ENABLEr   r   r   r   r   r   r0   r0   r1   r     s2    

z FIPSUpdatesEntitlement.messagingFrq   c                    sV   t  j|drR| jdpi }|| jdi | jjd|d tt	dd dS dS )Nrr   zservices-once-enabledT)r>   Zcontent)r   F)
rE   rs   rW   Z
read_cacheupdater   Zwrite_cacher   writer   )r/   rM   Zservices_once_enabledrJ   r0   r1   rs   1  s     z&FIPSUpdatesEntitlement._perform_enable)F)r{   r|   r}   r   r	   ZFIPS_UPDATES_TITLEr8   r   ZFIPS_UPDATES_DESCRIPTIONr   ZFIPS_UPDATES_HELP_TEXTr   r   r   r   r   r   r   rX   rs   r   r0   r0   rJ   r1   r     s   %r   c                       sd   e Zd ZdZejZejZej	Z
dZejZdZeeedf d fddZeeedd	d
Z  ZS )FIPSPreviewEntitlementzfips-previewZUbuntuFIPSPreviewzubuntu-pro-fips-preview.gpg.r[   c                    s   t  jtttjf S r\   )rE   r   r   r   r	   r   r`   rJ   r0   r1   r   L  s     z,FIPSPreviewEntitlement.incompatible_servicesrT   c                 C   s   dS )NTr0   rY   r0   r0   r1   rZ   T  s    z4FIPSPreviewEntitlement._allow_fips_on_cloud_instance)r{   r|   r}   r   r	   ZFIPS_PREVIEW_TITLEr8   ZFIPS_PREVIEW_DESCRIPTIONr   ZFIPS_PREVIEW_HELP_TEXTr   r   ZPROMPT_FIPS_PREVIEW_PRE_ENABLEr   r~   r   r   r   r   r   rX   rZ   r   r0   r0   rJ   r1   r   C  s    r   )7Zloggingre   	itertoolsr   typingr   r   r   Zuaclientr   r   r   r	   r
   r   Zuaclient.clouds.identityr   r   Zuaclient.entitlementsr   Zuaclient.entitlements.baser   Z(uaclient.entitlements.entitlement_statusr   Zuaclient.filesr   Zuaclient.files.noticesr   Zuaclient.files.state_filesr   r   Zuaclient.typesr   r   r   Zget_event_loggerrA   Z	getLoggerZreplace_top_level_logger_namer{   r   ZCONDITIONAL_PACKAGES_EVERYWHEREZ!CONDITIONAL_PACKAGES_OPENSSH_HMACZCONDITIONAL_PACKAGES_JAMMYr.   Z&UBUNTU_FIPS_METAPACKAGE_DEPENDS_XENIALZ&UBUNTU_FIPS_METAPACKAGE_DEPENDS_BIONICZ%UBUNTU_FIPS_METAPACKAGE_DEPENDS_FOCALZ%UBUNTU_FIPS_METAPACKAGE_DEPENDS_JAMMYr,   ZRepoEntitlementr(   r   r   r   r0   r0   r0   r1   <module>   s    
  rM