U
    lHJeYq                     @   s  d dl Z d dlZd dlmZmZmZmZ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mZ d dlmZmZ d dlmZmZmZm Z m!Z!m"Z"m#Z#m$Z$m%Z%m&Z&m'Z'm(Z(m)Z)m*Z*m+Z+m,Z,m-Z-m.Z.m/Z/ d d	l0m1Z1 d d
l2m3Z3 d dl2m4Z5 d dl6m7Z7 d dl6m4Z8 d dl9m:Z: d dl;m<Z<m=Z= d dl>m?Z?m@Z@mAZA d dlBmCZC d dlDmEZEmFZF d dlGmHZH d dlImJZJ d dlKmLZLmMZMmNZN d dlOmPZP d dlQmRZR d dlSmTZT d dlUmVZV d dlWmXZX G dd dZYdd ZZdd Z[e'd d!d"Z\e)d#d$d%Z]e^e_eCd&d'd(Z`e^e_e_eCd)d*d+Zadfee^ e^ebebee^ e^d,d-d.ZceCe^e_d/d0d1Zddd2d3d4ZeeCd5d6d7ZfeCe_d8d9d:Zgee^ e^d;d<d=ZheCe_e_d>d?d@ZieCe_d8dAdBZjeCe^e_dCdDdEZke^eCe_e_dFdGdHZldgeVe^e^dJdKdLZme^dMdNdOZneYe+dPdQdRZoeYe,dPdSdTZpeYe dPdUdVZqeYe!dPdWdXZreYe"dPdYdZZseYe&dPd[d\ZteYe$dPd]d^ZueYe#dPd_d`Zve'e_eCeeVeejw f dadbdcZxddde ZydS )h    N)DictList
NamedTupleOptionalSetTupleUnion)apt
exceptionsmessagessecuritysystemutil)attach_with_tokenenable_entitlement_by_name)	_initiate)MagicAttachRevokeOptions_revoke)MagicAttachWaitOptions_wait)ESM_APPS_POCKETESM_INFRA_POCKETSTANDARD_UPDATES_POCKETFixPlanAptUpgradeStepFixPlanAttachStepFixPlanEnableStepFixPlanNoOpAlreadyFixedStepFixPlanNoOpLivepatchFixStepFixPlanNoOpStatusFixPlanNoOpStepFixPlanResultFixPlanStepFixPlanUSNResultFixPlanWarning&FixPlanWarningPackageCannotBeInstalled#FixPlanWarningSecurityIssueNotFixedNoOpAlreadyFixedDataNoOpLivepatchFixDataUSNAdditionalData)status_message)CVEFixPlanOptions)_plan)USNFixPlanOptions)_is_attached)NAME
USAGE_TMPL)CLOUD_TYPE_TO_TITLEPRO_CLOUD_URLSget_cloud_type)UAConfig)ContractExpiryStatusget_contract_expiry_status)PRINT_WRAP_WIDTH)entitlement_factory)ApplicabilityStatusCanEnableFailureUserFacingStatus)notices)Notice)PRO_HOME_PAGE)	FixStatus)colorize_commandsc                   @   s\   e Zd Zeeee edddZdd Zdee ee	e ddd	Z
ee ed
ddZdS )
FixContexttitledry_runaffected_pkgscfgc                 C   sD   d| _ g | _t | _tj| _|| _|| _|| _	|| _
d| _d| _d S )Nr   TF)	pkg_indexunfixed_pkgssetinstalled_pkgsr>   SYSTEM_NON_VULNERABLE
fix_statusrB   rD   rC   rE   should_print_pkg_header warn_package_cannot_be_installed)selfrB   rC   rD   rE    rO   2/usr/lib/python3/dist-packages/uaclient/cli/fix.py__init__J   s    zFixContext.__init__c                 C   sN   | j rJtjt| j jt| j dt| j d}tt	j
|tddd d S )N, )countpkgs    F)widthsubsequent_indentZreplace_whitespace)rD   r   ZSECURITY_AFFECTED_PKGS	pluralizelenformatjoinsortedprinttextwrapfillr6   )rN   msgrO   rO   rP   print_fix_header\   s    zFixContext.print_fix_headerNsource_pkgsstatuspocketc                 C   s4   | j r0tt||| jt| j|r&t|nd d d S )N)pkg_listrd   rF   num_pkgspocket_source)rL   r]   _format_packages_messagerF   rY   rD   get_pocket_description)rN   rc   rd   re   rO   rO   rP   print_pkg_headerm   s    
zFixContext.print_pkg_headerrT   unfixed_reasonc                 C   s$   |D ]}| j tj||d qd S )N)pkgrm   )rG   appendr   UnfixedPackage)rN   rT   rm   rn   rO   rO   rP   add_unfixed_packages   s    zFixContext.add_unfixed_packages)N)__name__
__module____qualname__strboolr   r3   rQ   ra   r   rk   rq   rO   rO   rO   rP   r@   I   s    r@   c                 C   s(   | j dtjd}|jtd t| d S )Nfixhelp)action)Z
add_parserr   ZCLI_ROOT_FIXZset_defaults
action_fix
fix_parser)Z
subparsersZ
parser_fixrO   rO   rP   set_fix_parser   s    r}   c                 C   s`   t jtdd| _d| _tj| _tj| j	_
| jdtjd | jddtjd | jd	dtjd | S )
z1Build or extend an arg parser for fix subcommand.z"fix <CVE-yyyy-nnnn+>|<USN-nnnn-d+>)nameZcommandrw   security_issuerx   z	--dry-run
store_true)rz   ry   z--no-related)r/   rZ   r.   Zusageprogr   ZCLI_FIX_DESCdescriptionZ	CLI_FLAGSZ
_optionalsrB   add_argumentZCLI_FIX_ISSUEZCLI_FIX_DRY_RUNZCLI_FIX_NO_RELATED)parserrO   rO   rP   r|      s&     
    r|   cvec                 C   s8   dj | j | jdd | j g}td| d S )N{issue}: {description}issuer   z! - https://ubuntu.com/security/{}
)rZ   rB   upperr   r]   r[   )r   linesrO   rO   rP   print_cve_header   s     r   )fix_planc                 C   s   | j }dj|j |jdg}|j}t|tr|jrj|	t
j |jD ] }|	dt
jjj|d qFn,|jr|	t
j |jD ]}|	d|  qtd| d S )Nr   r   z - {}r   z - r   )target_usn_planrZ   rB   r   r   additional_data
isinstancer(   Zassociated_cvesro   r   ZSECURITY_FOUND_CVESZurlsZSECURITY_CVE_PAGEZassociated_launchpad_bugsZSECURITY_FOUND_LAUNCHPAD_BUGSr]   r[   )r   Z
target_usnr   r   r   Zlp_bugrO   rO   rP   print_usn_header   s*     


r   )r   rC   rE   c                 C   sz   t t| gd|d}|jjd j}|rH|jrHtjt	|j
p<d|jdt|jjd  t  t|jjd ||\}}|S )N)cvesZoptionsrE   r   unexpected-errorZ	named_msg)cve_planr*   Z	cves_datar   errorr`   r
   AnonymousUbuntuProErrorr   NamedMessagecoder   r]   execute_fix_plan)r   rC   rE   r   r   rd   _rO   rO   rP   fix_cve   s     
 
 r   )r   rC   
no_relatedrE   c                 C   s  t t| gd|d}|jjd jj}|rJ|jrJtjt	
|jp>d|jdt|jjd  tdt	jj| d  t|jjd j||\}}|tjtjfkr|S |jjd j}|r|r|S tdt	jjdd	d
 |D d  tdt	j  i }	|D ],}
td|
j t|
|||	|
j< t  qtt	j t|| t	jd d}|D ]}
|	|
j \}}t||
jt	jd |tjkrtdt	jjdd  d}|tjkrD|D ]"}|j rtd|j!|j  qd}qD|rtdt	j"j| d  |S )N)usnsr   r   r   r   r   )issue_idz
- c                 s   s   | ]}|j V  qd S N)rB   ).0ZusnrO   rO   rP   	<genexpr>  s     zfix_usn.<locals>.<genexpr>)Zrelated_usnsz- {})contextF- fix operationZ	operationTz
  - {}: {})#usn_planr,   Z	usns_datar   r   r   r`   r
   r   r   r   r   r   r]   ZSECURITY_FIXING_REQUESTED_USNrZ   r   r>   rJ   SYSTEM_NOT_AFFECTEDrelated_usns_planZSECURITY_RELATED_USNSr[   ZSECURITY_FIXING_RELATED_USNSrB   ZSECURITY_USN_SUMMARY_handle_fix_status_messageZFIX_ISSUE_CONTEXT_REQUESTEDZFIX_ISSUE_CONTEXT_RELATEDSYSTEM_VULNERABLE_UNTIL_REBOOTENABLE_REBOOT_REQUIRED_TMPLSYSTEM_STILL_VULNERABLErm   rn   ZSECURITY_RELATED_USN_ERROR)r   rC   r   rE   r   r   Ztarget_usn_statusr   r   Zrelated_usn_statusZrelated_usn_planZfailure_on_related_usnrd   rG   unfixed_pkgrO   rO   rP   fix_usn   s    
 
 

 r   )rf   rd   rF   rg   rh   returnc           	      C   s   | sdS g }g }| D ](}|d7 }| d|| | | qtjddd| d dt|tdd	}d
|t||S )z;Format the packages and status to an user friendly message.    z{}/{}z{} {}:(rR   )rU   rV   rW   z{}
{})ro   rZ   r^   r_   r[   r\   r6   r)   )	rf   rd   rF   rg   rh   Z	msg_indexZsrc_pkgsZsrc_pkgZ
msg_headerrO   rO   rP   ri   ?  s"     ri   )rE   tokenr   c              
   C   sb   t tdd|gg zt| |dd W dS  tjk
r\ } zt |j W Y dS d}~X Y nX dS )ztAttach to an Ubuntu Pro subscription with a given token.

    :return: True if attach performed without errors.
    proZattachT)r   Zallow_enableFN)r]   r?   r   r
   ZUbuntuProErrorr`   )rE   r   errrO   rO   rP   _run_ua_attach[  s    
r   )r   c                  C   s:   t  \} }| t kr6ttjjt| t| d dS )z:Alert the user when running Pro on cloud with PRO support.)rB   Zcloud_specific_urlN)	r2   r1   keysr]   r   ZSECURITY_USE_PRO_TMPLrZ   r0   get)Z
cloud_typer   rO   rO   rP   *_inform_ubuntu_pro_existence_if_applicablei  s    
r   rE   c              
   C   s   t tj t| d}t dtjj|jd  t|jd}zt	|| d}W nJ t
jk
r } z*t tj t|jd}t|| d |W 5 d }~X Y nX t dtj  t| |jS )Nr   r   )	user_code)Zmagic_tokenr   )r]   r   ZCLI_MAGIC_ATTACH_INITr   ZCLI_MAGIC_ATTACH_SIGN_INrZ   r   r   r   r   r
   ZMagicAttachTokenErrorZCLI_MAGIC_ATTACH_FAILEDr   r   ZCLI_MAGIC_ATTACH_PROCESSINGr   Zcontract_token)rE   Zinitiate_respZwait_optionsZ	wait_respeZrevoke_optionsrO   rO   rP   _perform_magic_attachu  s*    


r   )rE   r   c                 C   sj   t   ttj tjtjdddgd}|dkr2dS |dkrBt| S |dkrfttj t	d}t
| |S dS )zZPrompt for attach to a subscription or token.

    :return: True if attach performed.
    sacZvalid_choicesF> T)r   r]   r   Z*SECURITY_UPDATE_NOT_INSTALLED_SUBSCRIPTIONr   prompt_choicesZSECURITY_FIX_ATTACH_PROMPTr   ZPROMPT_ENTER_TOKENinputr   )rE   choicer   rO   rO   rP   _prompt_for_attach  s    


r   )rG   r   c                 C   s4   t | }tjtj|j|dt| dt	ddS )zFormat the list of unfixed packages into an message.

    :returns: A string containing the message output for the unfixed
              packages.
    rR   )rg   rT   rU   r   )
rY   r^   r_   r   ZSECURITY_PKG_STILL_AFFECTEDrX   rZ   r[   r\   r6   )rG   Znum_pkgs_unfixedrO   rO   rP   _format_unfixed_packages_msg  s    r   )rE   rC   r   c                 C   s0   t | }|d tjkr,|r(ttj dS dS dS )zuCheck if the Ubuntu Pro subscription is expired.

    :returns: True if subscription is expired and not renewed.
    r   FT)r5   r4   ZEXPIREDr]   r   (SECURITY_DRY_RUN_UA_EXPIRED_SUBSCRIPTION)rE   rC   Zcontract_expiry_statusrO   rO   rP   _check_subscription_is_expired  s    
r   c                 C   s   ddl }ddlm} t  ttj tjtj	j
tdddgd}|dkrttj td}ttd	d
gg ||jddd|  t| |S dS )zdPrompt for attach a new subscription token to the user.

    :return: True if attach performed.
    r   N)cli)Zurlrr   r   r   r   detachTr   )
assume_yesrZ   F)argparseuaclientr   r   r]   r   Z%SECURITY_UPDATE_NOT_INSTALLED_EXPIREDr   r   ZSECURITY_FIX_RENEW_PROMPTrZ   r=   ZPROMPT_EXPIRED_ENTER_TOKENr   r?   Zaction_detachZ	Namespacer   )rE   r   r   r   r   rO   rO   rP   _prompt_for_new_token  s$    

 
r   )rE   servicer   c                 C   s   t tjj|d tjtjj|dddgd}|dkrt tdd|gg t| |dd\}}|s|d	k	rt	|t
r|jd	k	rt |jj |S d
S )zMPrompt for enable a pro service.

    :return: True if enable performed.
    r   r   r   r   r   enableT)rE   r~   r   NF)r]   r   ZSECURITY_SERVICE_DISABLEDrZ   r   r   ZSECURITY_FIX_ENABLE_PROMPTr?   r   r   r9   messager`   )rE   r   r   ZretreasonrO   rO   rP   _prompt_for_enable  s,      

r   )r   rE   rC   r   c                 C   s   t || d}||}|r| \}}|tjkr2dS | \}}|tjkr|rhtdtj	j
|jd  dS t||jrxdS ttjj
|jd nttjj
|jd dS )zQ
    Verify if the Ubuntu Pro subscription has the required service enabled.
    )rE   r~   Tr   r   F)r7   Zuser_facing_statusr:   ZACTIVEapplicability_statusr8   Z
APPLICABLEr]   r   Z'SECURITY_DRY_RUN_UA_SERVICE_NOT_ENABLEDrZ   r~   r   SECURITY_UA_SERVICE_NOT_ENABLEDZ SECURITY_UA_SERVICE_NOT_ENTITLED)r   rE   rC   Zent_clsZentZ
ent_statusr   r   rO   rO   rP   )_handle_subscription_for_required_service  s<    

r   r   )rd   r   r   c                 C   s   | t jkr>|r tjj||d}ntjj|d}tt| n| t j	kr||r^tj
j||d}ntjj|d}tt| np| t jkr|rtjj||d}ntjj|d}tt| n2|rtjj||d}ntjj|d}tt| d S )N)r   r   r   )r>   rJ   r   Z%SECURITY_ISSUE_RESOLVED_ISSUE_CONTEXTrZ   ZSECURITY_ISSUE_RESOLVEDr]   r   Zhandle_unicode_charactersr   Z'SECURITY_ISSUE_UNAFFECTED_ISSUE_CONTEXTZSECURITY_ISSUE_UNAFFECTEDr   Z)SECURITY_ISSUE_NOT_RESOLVED_ISSUE_CONTEXTZSECURITY_ISSUE_NOT_RESOLVED)rd   r   r   r`   rO   rO   rP   r   .  s>    
 
 
  r   re   c                 C   s2   | t krtjS | tkrtjS | tkr*tjS | S d S r   )r   r   Z'SECURITY_UBUNTU_STANDARD_UPDATES_POCKETr   ZSECURITY_UA_INFRA_POCKETr   ZSECURITY_UA_APPS_POCKETr   rO   rO   rP   rj   S  s    rj   fix_contextstepc                 C   sh   | j |jjd|jjd d| _tjj|jj|jj	d}t
d|  | j|jjg|d d| _tj| _d S )Nreleasedrb   F)packageversionr   rl   T)rk   dataZrelated_source_packagesre   rL   r   ZFIX_CANNOT_INSTALL_PACKAGErZ   Zbinary_packageZbinary_package_versionr]   rq   Zsource_packagerM   r>   r   rK   )r   r   Zwarn_msgrO   rO   rP   )_execute_package_cannot_be_installed_step^  s"     r   c                 C   sR   | j |jj|jjd |  jt|jj7  _| j|jjt|jjd tj	| _
d S )N)rc   rd   rl   )rk   r   source_packagesrd   rF   rY   rq   r)   r>   r   rK   r   rO   rO   rP   &_execute_security_issue_not_fixed_stepw  s    
r   c              
   C   sv  | j |jjd|jjd |  jt|jj7  _|jjsR| jsFtt	j
 tj| _d S t s| jstt	j tj| _| j|jjt	jd d S ttdddgdddd	g t|jj g | jrtj| _d S z.t  tjd
ddd	g|jj ddid W n\ tk
rR } z<t|dt|}t| tj| _| j|jj|d W Y d S d }~X Y nX tj| _d| _| j|jj d S )Nr   rb   rl   r	   updatez&&installz--only-upgradez-yzapt-getZDEBIAN_FRONTENDZnoninteractive)cmdZoverride_env_varsr`   T)rk   r   r   re   rF   rY   Zbinary_packagesrM   r]   r   SECURITY_UPDATE_INSTALLEDr>   rJ   rK   r   Zwe_are_currently_rootrC   ZSECURITY_APT_NON_ROOTr   rq   r?   r\   r	   Zrun_apt_update_commandZrun_apt_command	Exceptiongetattrru   rL   rI   r   )r   r   r   r`   rO   rO   rP   _execute_apt_upgrade_step  sh    






r   c                 C   s   |j jdkrtnt}| j|j jd|d d| _t| jj	s| j
rPtdtj  qt| jstj| _| j|j jtjj|j jdd d S nXt| j| j
dr| j
rttj n6t| jstj| _| j|j jtjj|j jdd d S tj| _d S )	N	esm-infrar   rb   Fr   r   rl   )rE   rC   )r   Zrequired_servicer   r   rk   r   rL   r-   rE   Zis_attachedrC   r]   r   Z SECURITY_DRY_RUN_UA_NOT_ATTACHEDr   r>   r   rK   rq   ZSECURITY_UA_SERVICE_REQUIREDrZ   r   r   r   Z$SECURITY_UA_SERVICE_WITH_EXPIRED_SUBrJ   r   r   re   rO   rO   rP   _execute_attach_step  sL    

 
r   c                 C   s   |j jdkrtnt}| j|j jd|d d| _t|j j| j| j	st
tjj|j jd | j|j jtjj|j jdd tj| _d S tjS )Nr   r   rb   Fr   rl   )r   r   r   r   rk   r   rL   r   rE   rC   r]   r   r   rZ   rq   Z%SECURITY_UA_SERVICE_NOT_ENABLED_SHORTr>   r   rK   rJ   r   rO   rO   rP   _execute_enable_step  s:    
r   c                 C   s&   |j jtjjkr"ttj tj	| _
d S r   )r   rd   r   ZNOT_AFFECTEDvaluer]   r   ZSECURITY_NO_AFFECTED_PKGSr>   r   rK   r   rO   rO   rP   _execute_noop_not_affected_step  s    
r   c                 C   s*   t |jtr&ttjj| j|jjd d S )N)r   r   )	r   r   r'   r]   r   ZCVE_FIXED_BY_LIVEPATCHrZ   rB   Zpatch_versionr   rO   rO   rP   %_execute_noop_fixed_by_livepatch_step"  s    r   c                 C   sH   t |jtrD| j|jjd|jjd ttj |  j	t
|jj7  _	d S )Nr   rb   )r   r   r&   rk   r   re   r]   r   r   rF   rY   r   rO   rO   rP    _execute_noop_already_fixed_step.  s    
r   )r   rC   rE   r   c                 C   s  | j | j}t| j|| jpg |d}|  t|dd dD ]}t|trTt	|| t|t
rht|| t|trt|| |jtjkr qt|trt|| |jtjkr qt|trt|| |jtjkr qt|trt|| t|trt|| t|tr<t|| q<t  |jrPttttdd |jD  tj |_|jtjkrt!j"|j#drtj$|_t%j&j'dd	}t| t(j)t*j+dd	 t,|j| j |j|jfS )
NrA   c                 S   s   | j S r   )order)xrO   rO   rP   <lambda>K      z"execute_fix_plan.<locals>.<lambda>)keyc                 S   s   g | ]
}|j qS rO   )rn   )r   r   rO   rO   rP   
<listcomp>m  s   z$execute_fix_plan.<locals>.<listcomp>)rI   r   r   )-Zplanwarningsr@   rB   Zaffected_packagesra   r\   r   r$   r   r%   r   r   r   rK   r>   rJ   r   r   r   r   r   r   r   r   r   r   r]   rG   r   listrH   r   r   Zshould_rebootrI   r   r   r   rZ   r;   addr<   ZENABLE_REBOOT_REQUIREDr   )r   rC   rE   Z	full_planr   r   Z
reboot_msgrO   rO   rP   r   ;  s|    














r   c                K   sh   t tj| jstj| jd| jr.tt	j
 d| j krNt| j| j|}nt| j| j| j|}|jS )Nr   r   )rematchr   ZCVE_OR_USN_REGEXr   r
   ZInvalidSecurityIssueIdFormatrC   r]   r   ZSECURITY_DRY_RUN_WARNINGlowerr   r   r   Z	exit_code)argsrE   kwargsrd   rO   rO   rP   r{     s    
   r{   )N)r   )zr  r^   typingr   r   r   r   r   r   r   r   r	   r
   r   r   r   r   Zuaclient.actionsr   r   Z+uaclient.api.u.pro.attach.magic.initiate.v1r   Z)uaclient.api.u.pro.attach.magic.revoke.v1r   r   Z'uaclient.api.u.pro.attach.magic.wait.v1r   r   Zuaclient.api.u.pro.security.fixr   r   r   r   r   r   r   r   r   r   r    r!   r"   r#   r$   r%   r&   r'   r(   Z'uaclient.api.u.pro.security.fix._commonr)   Z+uaclient.api.u.pro.security.fix.cve.plan.v1r*   r+   r   Z+uaclient.api.u.pro.security.fix.usn.plan.v1r,   r   Z(uaclient.api.u.pro.status.is_attached.v1r-   Zuaclient.cli.constantsr.   r/   Zuaclient.clouds.identityr0   r1   r2   Zuaclient.configr3   Zuaclient.contractr4   r5   Zuaclient.defaultsr6   Zuaclient.entitlementsr7   Z(uaclient.entitlements.entitlement_statusr8   r9   r:   Zuaclient.filesr;   Zuaclient.files.noticesr<   Zuaclient.messages.urlsr=   Zuaclient.securityr>   Zuaclient.statusr?   r@   r}   r|   r   r   ru   rv   r   r   intri   r   r   r   r   r   r   r   r   r   r   rj   r   r   r   r   r   r   r   r   rp   r   r{   rO   rO   rO   rP   <module>   s   $
 T>   l   -   % ?0' 	    N