U
    Jhh                     @   s  d dl 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mZmZmZmZ d dlZd dlmZmZmZmZ d d	lmZ d d
lmZ d dlmZmZmZmZmZ d dl m!Z! d dl"m#Z#m$Z$ d dl%m&Z&m'Z'm(Z( d dl)m*Z*m+Z+m,Z,m-Z-m.Z. dZ/G dd deZ0dd Z1edddd Z2edeej3 f dddZ4ej3ej5e6dddZ7edde6e6e8dd d!Z9e6ee6ef ej:e6d"d#d$Z;eej3 ee6eeej:e6f  f d%d&d'Z<e!ee6ef d(d)d*Z=eee6ef  dd+d,Z>ee6eeej:e6f  f ee6ef eee6ef  d-d.d/Z?e!ee6ef d(d0d1Z@dKee6eej3 f e6e8dd4d5d6ZAd7d8 ZBd9d: ZCe6e6e'e&eDeDe8d;d<d=ZEd>d? ZFe!d@dAdBZGdCdD ZHdEdF ZIdGdH ZJdIdJ ZKdS )L    )defaultdict)datetimetimezone)Enum)	lru_cache)choice)AnyDefaultDictDictListTupleN)
exceptions	livepatchmessagesutil)_reboot_required)_is_attached)PreserveAptCfgget_apt_cache_datetimeget_apt_pkg_cacheget_esm_apt_pkg_cacheget_pkg_candidate_version)UAConfig)ESMAppsEntitlementESMInfraEntitlement)ApplicabilityStatusApplicationStatusContractStatus)get_distro_infoget_kernel_infoget_release_infois_current_series_ltsis_supported)	esm-infraesm-appsc                   @   s$   e Zd ZdZdZdZdZdZdZdS )UpdateStatusz2Represents the availability of a security package.Zupgrade_availableZupgrade_available_not_preferredZpending_attachZpending_enableZupgrade_unavailableN)	__name__
__module____qualname____doc__	AVAILABLEAVAILABLE_NOT_PREFERRED
UNATTACHEDNOT_ENABLEDUNAVAILABLE r/   r/   :/usr/lib/python3/dist-packages/uaclient/security_status.pyr%   (   s   r%   c                 C   s   t t|  d S )N)printr   Zcreate_package_list_str)packagesr/   r/   r0   print_package_list1   s    r3   )maxsizec                  C   sR   t  j} dd| fddd| fddd| fd	dd
| fddd| fd	iS )NUbuntuz{}-securitystandard-securityZUbuntuESMAppsz{}-apps-securityr$   Z	UbuntuESMz{}-infra-securityr#   z{}-apps-updatesz{}-infra-updates)r    seriesformat)r7   r/   r/   r0   %get_origin_information_to_service_map5   s         r9   str)returnc               	   C   s`   t t} ttF}dd |jD }|| d< t|}|D ]}| t|| | q8W 5 Q R X | S )Nc                 S   s   g | ]}|j r|qS r/   )current_ver.0packager/   r/   r0   
<listcomp>G   s     z4get_installed_packages_by_origin.<locals>.<listcomp>all)	r   listr   r   r2   apt_pkgDepCache get_origin_for_installed_packageappend)resultcacheinstalled_packages	dep_cacher?   r/   r/   r0    get_installed_packages_by_originA   s    

rK   )r?   rJ   r;   c                 C   s   | j s
dS | j j}t|dkr@|| }|r6| j |kr:dS |j}|D ]B\}}t |j|jfd}|tkrr|  S |jdkrD|j	  S qDdS )a  
    Returns the origin for a package installed in the system.

    Technically speaking, packages don't have origins - their versions do.
    We check the available versions (installed, candidate) to determine the
    most reasonable origin for the package.
        unknownr5   third-party)
r<   	file_listlenZget_candidate_verr9   getoriginarchiveESM_SERVICESZ	component)r?   rJ   Zavailable_origins	candidaterS   _servicer/   r/   r0   rE   V   s$    

 
rE   )pkgversionr;   c                 C   s   t | dd}|r||kS dS )z;Returns True if the package version is a candidate version.F)Zcheck_esm_cache)r   )rY   rZ   Zcandidate_versionr/   r/   r0   _is_candidate_version{   s    r[   )service_nameua_inforZ   r;   c                 C   sl   | dks|d r@| |d kr@t |jj|j}|r8tjjS tjjS |d sPtjjS | |d krdtj	jS tj
jS )zDefines the update status for a package based on the service name.

    For ESM-[Infra|Apps] packages, first checks if Pro is attached. If this is
    the case, also check for availability of the service.
    )r6   standard-updatesattachedenabled_servicesentitled_services)r[   
parent_pkgnamever_strr%   r*   valuer+   r,   r-   r.   )r\   r]   rZ   Zis_candidater/   r/   r0   get_update_status   s$    

 
rf   )r2   r;   c              	   C   s,  t t}tt}| D ]}|jr|jD ]}||jkr*d}|jD ]<\}}t |j	|j
f}|rB|| ||jf d} qqB|jd d }	|s*d|	j
kr*|d ||	jf q*|j|kr||j }
|
jD ]N}||jkr|jD ]8\}}t |j	|j
f}|r|| ||jf  qqqqW 5 Q R X |S )zFilters a list of packages looking for available updates.

    All versions greater than the installed one are reported, based on where
    it is provided, including ESM pockets, excluding backports.
    FTr   Z	backportsr^   )r   rB   r   r   r<   version_listrP   r9   rR   rS   rT   rF   Zsiterc   )r2   rG   Z	esm_cacher?   rZ   Zcounted_as_securityrS   rW   rX   Zexpected_originZesm_packager/   r/   r0   filter_updates   sL    








rh   )cfgr;   c                 C   s   t | j}|g g d}|rt| }t| }| tjkrF|d d | d t	j
krf|d d | tjkr|d d | d t	j
kr|d d |S )z7Returns the Pro information based on the config object.)r_   r`   ra   ra   r$   r   r`   r#   )r   is_attachedr   r   Zcontract_statusr   ZENTITLEDrF   application_statusr   ENABLED)ri   rj   r]   Zinfra_entitlementZapps_entitlementr/   r/   r0   get_ua_info   s.    


rm   c                  C   s   zt  } W n tjk
r&   g  Y S X t j}| d k	r|d k	r|| jkr| j d k	r| j jdkr| j jd k	rt	| j jdkrdd | j jD S g S )NZappliedr   c                 S   s"   g | ]}|j pd |jpddqS )rL   Frc   Zpatchedrn   )r>   Zfixr/   r/   r0   r@     s   z,get_livepatch_fixed_cves.<locals>.<listcomp>)
r   statusr   ZProcessExecutionErrorr   Zproc_version_signature_versionZkernelstatefixesrQ   )Z	lp_statusZour_kernel_versionr/   r/   r0   get_livepatch_fixed_cves  s.    


	rr   )upgradable_versionsr]   r;   c                 C   sT   g }|   D ]B\}}|D ]4\}}t|||}||jj|j||||jd qq|S )N)r?   rZ   r\   ro   rS   Zdownload_size)itemsrf   rF   rb   rc   rd   size)rs   r]   updatesrX   rg   rZ   rS   ro   r/   r/   r0   create_updates_list  s    rw   c                 C   s  t | }d|i}t }|d }t||d< t|}g |d< t||}t|d |d< t|d |d< t|d	 |d
< t|d |d< t|d |d< t|d |d< t|d |d< t|d |d< t|d |d< t|d |d< t|d |d< t| j|d< d||dt idS )ag  Returns the status of security updates on a system.

    The returned dict has a 'packages' key with a list of all installed
    packages which can receive security updates, with or without ESM,
    reflecting the availability of the update based on the Pro status.

    There is also a summary with the Ubuntu Pro information and the package
    counts.
    ZuarA   Znum_installed_packagesr^   mainZnum_main_packages
restrictedZnum_restricted_packagesuniverseZnum_universe_packages
multiverseZnum_multiverse_packagesrO   Znum_third_party_packagesrN   Znum_unknown_packagesr#   Znum_esm_infra_packagesr$   Znum_esm_apps_packagesZnum_esm_infra_updatesZnum_esm_apps_updatesr6   Znum_standard_security_updatesreboot_requiredz0.1Z
fixed_cves)Z_schema_versionsummaryr2   r   )rm   rK   rQ   rh   rw   r   r|   rr   )ri   r]   r}   packages_by_originrI   rs   rv   r/   r/   r0   security_status_dict/  s:    

r   rA   F)package_lists
show_itemsalways_showr;   c           	      C   sL  t | d }ttjj|d dt t|d  }|dkrzt | d t | d  t | d  }ttj|j||d	d
 |dkrt | d t | d  t | d  }|s|rttj|j||dd
 |dkrt | d }|s|rttj|j||d |dkr@t | d }|s&|r@ttj	|j||d td d S )NrA   )count rM   )rA   r#   rx   ry   r#   Main/Restricted)offsetr   
repository)rA   r$   rz   r{   r$   Universe/Multiverse)rA   rO   rO   )r   r   )rA   rN   rN   rL   )
rQ   r1   r   ZSS_SUMMARY_TOTALr8   r:   ZSS_SUMMARY_ARCHIVE	pluralizeZSS_SUMMARY_THIRD_PARTYZSS_SUMMARY_UNAVAILABLE)	r   r   r   Ztotal_packagesr   Zpackages_mrZpackages_umZpackages_thirdpartyZpackages_unknownr/   r/   r0   _print_package_summarya  sn    







 
	r   c                  C   sH   t  j} t| j}dt|jt|j}tt	j
j|d td d S )Nz{}/{}daterL   )r    r7   r   eolr8   r:   Zmonthyearr1   r   ZSS_INTERIM_SUPPORT)r7   eol_dater   r/   r/   r0   _print_interim_release_support  s
    
r   c                  C   sB   t  j} t| r4t| j}ttjjt	|j
d n
ttj d S )Nr   )r    r7   r"   r   r   r1   r   ZSS_LTS_SUPPORTr8   r:   r   ZSS_NO_SECURITY_COVERAGE)r7   r   r/   r/   r0   _print_lts_support  s
    
r   rX   r   service_statusservice_applicabilityinstalled_updatesavailable_updatesrj   c           
      C   s   t  j}t|j}|tjkr6tjj|| t	|j
d}	ntjj| |t	|j
d}	|rn|	dtj|j|d 7 }	|r|	dtj|j|d 7 }	t|	 |r|tjkr|tjkrtd ttjj| d td d S )N)r   rX   r   )rX   r   r   r   )rv   rL   rX   )r    r7   r   Zeol_esmr   rl   r   ZSS_SERVICE_ENABLEDr8   r:   r   ZSS_SERVICE_ADVERTISEZSS_SERVICE_ENABLED_COUNTSr   ZSS_SERVICE_ADVERTISE_COUNTSr1   DISABLEDr   Z
APPLICABLEZSS_SERVICE_COMMAND)
rX   r   r   r   r   r   rj   r7   Zeol_date_esmmessager/   r/   r0   _print_service_support  sF    	





r   c                  C   sb   t  } | d kr$ttj td d S ttj}||  }|jdkr^ttj	j
|jd td d S )NrL   r   )days)r   r1   r   ZSS_UPDATE_UNKNOWNr   nowr   Zutcr   ZSS_UPDATE_DAYSr8   )Zlast_apt_updater   Ztime_since_updater/   r/   r0   _print_apt_update_call  s    

r   )ri   c              	   C   s  t | }t| }| d }| d }| d }| d }t j}t }t| d }	t }
t	|
d |
d  |
d  d }t	|
d |
d  |
d  d }t
|
 ttj td	 t  |st|rt  ttj d S |tjkrt  |	rttj n
ttj td	 tdd
||t|
d t||	d |
d sT|
d sT|
d rvtdd||t|
d t||	d |	sttj d S )Nr   r_   rx   ry   r#   rz   r{   r$   rL   r   r   r   )r   r   rk   applicability_statusr    r7   r!   rm   rK   rh   r   r1   r   ZSS_HELP_CALLr   r"   r   SS_NO_INTERIM_PRO_SUPPORTr   r   r   ZSS_IS_ATTACHEDZSS_IS_NOT_ATTACHEDr   rQ   ZSS_LEARN_MORE)ri   esm_infra_entesm_apps_entesm_infra_statusesm_infra_applicabilityesm_apps_statusesm_apps_applicabilityr7   is_ltsrj   r~   Z"security_upgradable_versions_infraZ!security_upgradable_versions_appsr/   r/   r0   security_status  s    






r   c                  C   sx   t  } | d }dd |D }t| ddd |rjttj td ttj t| ttjjt	|d n
ttj
 d S )NrO   c                 S   s   g | ]
}|j qS r/   rc   r=   r/   r/   r0   r@   A  s     z-list_third_party_packages.<locals>.<listcomp>Tr   r   rL   r?   )rK   r   r1   r   ZSS_THIRD_PARTYSS_PACKAGES_HEADERr3   SS_SHOW_HINTr8   r   ZSS_NO_THIRD_PARTY)r~   Zthird_party_packagespackage_namesr/   r/   r0   list_third_party_packages>  s      

r   c                  C   sx   t  } | d }dd |D }t| ddd |rjttj td ttj t| ttjjt	|d n
ttj
 d S )NrN   c                 S   s   g | ]
}|j qS r/   r   r=   r/   r/   r0   r@   U  s     z-list_unavailable_packages.<locals>.<listcomp>Tr   rL   r   )rK   r   r1   r   ZSS_UNAVAILABLEr   r3   r   r8   r   ZSS_NO_UNAVAILABLE)r~   Zunknown_packagesr   r/   r/   r0   list_unavailable_packagesR  s      

r   c              	      s  t  }|d }|d |d  }|| }t }t|d }|D ]\}}||j q<t j}	t }
t| }t	| }|
 d }| d }tdd |D tdd |D  t fdd|D }t|dd	d
 |
st|	rt  ttj d S |tjkrt  td tdd||t|t|dd ttjjdd td t|	s rnttjjdd t  rttjjdd t  p}|r|rtjjdd}ntjjdd}t| t| |rttjjt |d d S )Nr#   rx   ry   r   c                 S   s   g | ]
}|j qS r/   r   r=   r/   r/   r0   r@     s     z+list_esm_infra_packages.<locals>.<listcomp>c                 S   s   g | ]
}|j qS r/   r   r=   r/   r/   r0   r@     s     c                    s&   g | ]}|j kr|j  kr|j qS r/   r   r=   Zavailable_package_namesZinstalled_package_namesr/   r0   r@     s   

Tr   rL   r   Fr   r   r   )!rK   setrh   addrb   r    r7   r!   r   r   rk   r   sortedr   r"   r   r1   r   r   r   r   r   r   rQ   SS_SERVICE_HELPr8   SS_UPDATES_AVAILABLEr3   SS_UPDATES_INSTALLEDSS_FURTHER_OTHER_PACKAGESSS_OTHER_PACKAGESr   r   )ri   r~   Zinfra_packagesZmr_packagesZall_infra_packagesZinfra_updatessecurity_upgradable_versionsupdaterW   r7   r   r   r   r   r   remaining_package_names	hint_listmsgr/   r   r0   list_esm_infra_packagesg  s    	  
	

r   c              	      s  t  }|d }|d |d  }|| }t }t|d }|D ]\}}||j q<t }	t| }
|
 d }|
 d }t	dd |D t	dd |D  t	 fdd|D }t
|dd	d
 |	sttj d S tdd||t|t|dd ttjjdd td |r r2ttjjdd t  rRttjjdd t  pZ}|r|rxtjjdd}ntjjdd}t| t| |rttjjt|d d S )Nr$   rz   r{   r   c                 S   s   g | ]
}|j qS r/   r   r=   r/   r/   r0   r@     s     z*list_esm_apps_packages.<locals>.<listcomp>c                 S   s   g | ]
}|j qS r/   r   r=   r/   r/   r0   r@     s     c                    s&   g | ]}|j kr|j  kr|j qS r/   r   r=   r   r/   r0   r@     s   

Tr   r   Fr   r   rL   r   )rK   r   rh   r   rb   r!   r   rk   r   r   r   r1   r   r   r   rQ   r   r8   r   r3   r   r   r   r   r   )ri   r~   Zapps_packagesZum_packagesZall_apps_packagesZapps_updatesr   r   rW   r   r   r   r   r   r   r   r/   r   r0   list_esm_apps_packages  s~    	  
	
r   )rA   F)Lcollectionsr   r   r   enumr   	functoolsr   Zrandomr   typingr   r	   r
   r   r   rC   Zuaclientr   r   r   r   Z5uaclient.api.u.pro.security.status.reboot_required.v1r   Z(uaclient.api.u.pro.status.is_attached.v1r   Zuaclient.aptr   r   r   r   r   Zuaclient.configr   Zuaclient.entitlementsr   r   Z(uaclient.entitlements.entitlement_statusr   r   r   Zuaclient.systemr   r   r    r!   r"   rU   r%   r3   r9   ZPackagerK   rD   r:   rE   boolr[   ZVersionrf   rh   rm   rr   rw   r   r   r   r   intr   r   r   r   r   r   r   r/   r/   r/   r0   <module>   s   	
 %	
@!
4  ?
2MY