U
    Jhr                     @   s&  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 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 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/m0Z0m1Z1m2Z2 d d
l3m4Z4 d dl3m5Z6 d dl7m8Z8 d dl7m5Z9 d dl:m;Z;m<Z< d dl=m>Z> d dl?m@Z@mAZAmBZB d dlCmDZD d dlEmFZF d dlGmHZHmIZImJZJ d dlKmLZL d dlMmNZN d dlOmPZP d dlQmRZRmSZSmTZT d dlUmVZV d dlWmXZX d dlYmZZZ d dl[m\Z\ G dd dZ]e)dddZ^e+d d!d"Z_e`eaeLd#d$d%Zbe`eaeaeLd&d'd(Zcdpee` e`ededee` e`d)d*d+ZeeLe`ead,d-d.Zfdd/d0d1ZgeLd2d3d4ZheLead5d6d7Ziee` e`d8d9d:ZjeLeaead;d<d=ZkeLead5d>d?ZleLe`ead@dAdBZme`eLeaeadCdDdEZndqee`e`dGdHdIZoe`dJdKdLZpe]e.dMdNdOZqe]e/dMdPdQZre]e-dMdRdSZse]e"dMdTdUZte]e#dMdVdWZue]e$dMdXdYZve]e(dMdZd[Zwe]e&dMd\d]Zxe]e%dMd^d_Zye)eaeLeeee f d`dadbZze>j{dcdddedf Z|eBdcej}ej~e|eFjdgeAe@dhejdie@djejdkdle@dmejdkdlgdngdoZdS )r    N)DictList
NamedTupleOptionalSetTupleUnion)apt
exceptionsmessagessystemutil)attach_with_tokenenable_entitlement_by_name)	_initiate)MagicAttachRevokeOptions_revoke)MagicAttachWaitOptions_wait)	FixStatusUnfixedPackagestatus_message)ESM_APPS_POCKETESM_INFRA_POCKETSTANDARD_UPDATES_POCKETFixPlanAptUpgradeStepFixPlanAttachStepFixPlanEnableStepFixPlanNoOpAlreadyFixedStepFixPlanNoOpLivepatchFixStepFixPlanNoOpStatusFixPlanNoOpStepFixPlanResultFixPlanStepFixPlanUSNResultFixPlanWarning"FixPlanWarningFailUpdatingESMCache&FixPlanWarningPackageCannotBeInstalled#FixPlanWarningSecurityIssueNotFixedNoOpAlreadyFixedDataNoOpLivepatchFixDataUSNAdditionalData)CVEFixPlanOptions)_plan)USNFixPlanOptions)ContractExpiryStatus_is_attached)cli_util)ProArgumentProArgumentGroup
ProCommand)action_detach)HelpCategory)CLOUD_TYPE_TO_TITLEPRO_CLOUD_URLSget_cloud_type)UAConfig)PRINT_WRAP_WIDTH)entitlement_factory)ApplicabilityStatusCanEnableFailureUserFacingStatus)notices)Notice)PRO_HOME_PAGE)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   sJ   d| _ g | _t | _tj| _|| _|| _|| _	|| _
d| _d| _d| _d S )Nr   TF)	pkg_indexunfixed_pkgssetinstalled_pkgsr   SYSTEM_NON_VULNERABLE
fix_statusrF   rH   rG   rI   should_print_pkg_header warn_package_cannot_be_installedfixed_by_livepatch)selfrF   rG   rH   rI    rT   2/usr/lib/python3/dist-packages/uaclient/cli/fix.py__init__R   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)rH   r   ZSECURITY_AFFECTED_PKGS	pluralizelenformatjoinsortedprinttextwrapfillr;   )rS   msgrT   rT   rU   print_fix_headere   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_listri   rJ   num_pkgspocket_source)rP   rb   _format_packages_messagerJ   r^   rH   get_pocket_description)rS   rh   ri   rj   rT   rT   rU   print_pkg_headerv   s    zFixContext.print_pkg_headerrY   unfixed_reasonc                 C   s"   |D ]}| j t||d qd S )N)pkgrr   )rK   appendr   )rS   rY   rr   rs   rT   rT   rU   add_unfixed_packages   s    
zFixContext.add_unfixed_packages)N)__name__
__module____qualname__strboolr   r:   rV   rf   r   rp   ru   rT   rT   rT   rU   rD   Q   s    rD   cvec                 C   s8   dj | j | jdd | j g}td| d S )N{issue}: {description}issuedescriptionz! - https://ubuntu.com/security/{}
)r_   rF   upperr   rb   r`   )r|   linesrT   rT   rU   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_planr_   rF   r   r   additional_data
isinstancer+   Zassociated_cvesrt   r   ZSECURITY_FOUND_CVESZurlsZSECURITY_CVE_PAGEZassociated_launchpad_bugsZSECURITY_FOUND_LAUNCHPAD_BUGSrb   r`   )r   Z
target_usnr   r   r|   Zlp_bugrT   rT   rU   print_usn_header   s*     


r   )security_issuerG   rI   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optionsrI   r   unexpected-errorZ	named_msg)cve_planr,   Z	cves_datar   errorre   r
   AnonymousUbuntuProErrorr   NamedMessagecoder   rb   execute_fix_plan)r   rG   rI   r   r   ri   _rT   rT   rU   fix_cve   s     
 
 r   )r   rG   
no_relatedrI   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)rF   ).0ZusnrT   rT   rU   	<genexpr>   s     zfix_usn.<locals>.<genexpr>)Zrelated_usnsz- {})contextF- fix operationZ	operationTz
  - {}: {})#usn_planr.   Z	usns_datar   r   r   re   r
   r   r   r   r   r   rb   ZSECURITY_FIXING_REQUESTED_USNr_   r   r   rN   SYSTEM_NOT_AFFECTEDrelated_usns_planZSECURITY_RELATED_USNSr`   ZSECURITY_FIXING_RELATED_USNSrF   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_VULNERABLErr   rs   ZSECURITY_RELATED_USN_ERROR)r   rG   r   rI   r   r   Ztarget_usn_statusr   r   Zrelated_usn_statusZrelated_usn_planZfailure_on_related_usnri   rK   unfixed_pkgrT   rT   rU   fix_usn   s    
 
 

 r   )rk   ri   rJ   rl   rm   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{} {}:(rW   )rZ   r[   r\   z{}
{})rt   r_   rc   rd   r`   ra   r;   r   )	rk   ri   rJ   rl   rm   Z	msg_indexZsrc_pkgsZsrc_pkgZ
msg_headerrT   rT   rU   rn   /  s"     rn   )rI   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)rb   rC   r   r
   ZUbuntuProErrorre   )rI   r   errrT   rT   rU   _run_ua_attachK  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.)rF   Zcloud_specific_urlN)	r9   r8   keysrb   r   ZSECURITY_USE_PRO_TMPLr_   r7   get)Z
cloud_typer   rT   rT   rU   *_inform_ubuntu_pro_existence_if_applicableY  s    
r   rI   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   )rb   r   ZCLI_MAGIC_ATTACH_INITr   ZCLI_MAGIC_ATTACH_SIGN_INr_   r   r   r   r   r
   ZMagicAttachTokenErrorZCLI_MAGIC_ATTACH_FAILEDr   r   ZCLI_MAGIC_ATTACH_PROCESSINGr   Zcontract_token)rI   Zinitiate_respZwait_optionsZ	wait_respeZrevoke_optionsrT   rT   rU   _perform_magic_attache  s*    


r   )rI   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   rb   r   Z*SECURITY_UPDATE_NOT_INSTALLED_SUBSCRIPTIONr   prompt_choicesZSECURITY_FIX_ATTACH_PROMPTr   ZPROMPT_ENTER_TOKENinputr   )rI   choicer   rT   rT   rU   _prompt_for_attach  s    


r   )rK   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.
    rW   )rl   rY   rZ   r   )
r^   rc   rd   r   ZSECURITY_PKG_STILL_AFFECTEDr]   r_   r`   ra   r;   )rK   Znum_pkgs_unfixedrT   rT   rU   _format_unfixed_packages_msg  s    r   )rI   rG   r   c                 C   s4   t | j}|r0|tjjkr0|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.
    FT)r0   Zcontract_statusr/   ZEXPIREDvaluerb   r   (SECURITY_DRY_RUN_UA_EXPIRED_SUBSCRIPTION)rI   rG   Zcontract_expiry_statusrT   rT   rU   _check_subscription_is_expired  s    


r   c                 C   s   ddl }t  ttj tjtjjt	dddgd}|dkr~ttj
 td}ttdd	gg t|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)Zurlrr   r   r   r   detachTZcli)Z
assume_yesr_   F)argparser   rb   r   Z%SECURITY_UPDATE_NOT_INSTALLED_EXPIREDr   r   ZSECURITY_FIX_RENEW_PROMPTr_   rB   ZPROMPT_EXPIRED_ENTER_TOKENr   rC   r5   Z	Namespacer   )rI   r   r   r   rT   rT   rU   _prompt_for_new_token  s    


r   )rI   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\}}|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   enablerI   nameNF)rb   r   ZSECURITY_SERVICE_DISABLEDr_   r   r   ZSECURITY_FIX_ENABLE_PROMPTrC   r   r   r>   messagere   )rI   r   r   ZretreasonrT   rT   rU   _prompt_for_enable  s$    
r   )r   rI   rG   r   c                 C   s   t || d}|r| \}}|tjkr*dS | \}}|tjkr|r`tdtj	j
|jd  dS t||jrpd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.
    r   Tr   r   F)r<   Zuser_facing_statusr?   ZACTIVEapplicability_statusr=   Z
APPLICABLErb   r   Z'SECURITY_DRY_RUN_UA_SERVICE_NOT_ENABLEDr_   r   r   ZSECURITY_UA_SERVICE_NOT_ENABLEDZ SECURITY_UA_SERVICE_NOT_ENTITLED)r   rI   rG   ZentZ
ent_statusr   r   rT   rT   rU   )_handle_subscription_for_required_service  s:    

r   r   )ri   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   rN   r   Z%SECURITY_ISSUE_RESOLVED_ISSUE_CONTEXTr_   ZSECURITY_ISSUE_RESOLVEDrb   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)ri   r   r   re   rT   rT   rU   r     s>    
 
 
  r   rj   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   rT   rT   rU   ro   ?  s    ro   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releasedrg   F)packageversionr   rq   T)rp   dataZrelated_source_packagesrj   rP   r   ZFIX_CANNOT_INSTALL_PACKAGEr_   Zbinary_packageZbinary_package_versionrb   ru   Zsource_packagerQ   r   r   rO   )r   r   Zwarn_msgrT   rT   rU   )_execute_package_cannot_be_installed_stepJ  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)rh   ri   rq   )rp   r   source_packagesri   rJ   r^   ru   r   r   r   rO   r   rT   rT   rU   &_execute_security_issue_not_fixed_stepc  s    
r   c                 C   s*   t  rttj ntdtj d  d S )Nr   )r   we_are_currently_rootrb   r   ZCLI_FIX_FAIL_UPDATING_ESM_CACHEZ(CLI_FIX_FAIL_UPDATING_ESM_CACHE_NON_ROOTr   rT   rT   rU   %_execute_fail_updating_esm_cache_steps  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   rg   rq   r	   updatez&&installz--only-upgradez-yzapt-getZDEBIAN_FRONTENDZnoninteractive)cmdZoverride_env_varsre   T)rp   r   r   rj   rJ   r^   Zbinary_packagesrQ   rb   r   SECURITY_UPDATE_INSTALLEDr   rN   rO   r   r   rG   ZSECURITY_APT_NON_ROOTr   ru   rC   ra   r	   Zrun_apt_update_commandZrun_apt_command	Exceptiongetattrry   rP   rM   r   )r   r   r   re   rT   rT   rU   _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   rg   Fr   r   rq   )rI   rG   )r   Zrequired_servicer   r   rp   r   rP   r0   rI   Zis_attachedrG   rb   r   Z SECURITY_DRY_RUN_UA_NOT_ATTACHEDr   r   r   rO   ru   ZSECURITY_UA_SERVICE_REQUIREDr_   r   r   r   Z$SECURITY_UA_SERVICE_WITH_EXPIRED_SUBrN   r   r   rj   rT   rT   rU   _execute_attach_step  sL    

 
r   c                 C   st   |j jdkrtnt}| j|j jd|d d| _t|j j| j| j	sn| j
|j jtjj|j jdd tj| _d S tjS )Nr   r   rg   Fr   rq   )r   r   r   r   rp   r   rP   r   rI   rG   ru   r   Z%SECURITY_UA_SERVICE_NOT_ENABLED_SHORTr_   r   r   rO   rN   r   rT   rT   rU   _execute_enable_step  s0    
r   c                 C   s&   |j jtjjkr"ttj tj	| _
d S r   )r   ri   r    ZNOT_AFFECTEDr   rb   r   ZSECURITY_NO_AFFECTED_PKGSr   r   rO   r   rT   rT   rU   _execute_noop_not_affected_step
  s    
r   c                 C   s0   t |jtr,ttjj| j|jjd d| _	d S )N)r   r   T)
r   r   r*   rb   r   ZCVE_FIXED_BY_LIVEPATCHr_   rF   Zpatch_versionrR   r   rT   rT   rU   %_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   rg   )r   r   r)   rp   r   rj   rb   r   r   rJ   r^   r   rT   rT   rU    _execute_noop_already_fixed_step  s    
r   )r   rG   rI   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r|t|| t|trt|| |jtjkr q0t|trt|| |jtjkr q0t|trt|| |jtjkr q0t|trt|| t|trt|| t|tr<t|| q<t  |jrft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	 |j.st/|j| j |j|jfS )
NrE   c                 S   s   | j S r   )order)xrT   rT   rU   <lambda><      z"execute_fix_plan.<locals>.<lambda>)keyc                 S   s   g | ]
}|j qS rT   )rs   )r   r   rT   rT   rU   
<listcomp>`  s   z$execute_fix_plan.<locals>.<listcomp>)rM   r   r   )0ZplanwarningsrD   rF   Zaffected_packagesrf   ra   r   r'   r   r(   r   r&   r   r   r   rO   r   rN   r   r   r   r   r!   r   r   r   r   r   rb   rK   r   listrL   r   r   Zshould_rebootrM   r   r   r   r_   r@   addrA   ZENABLE_REBOOT_REQUIREDrR   r   )r   rG   rI   Z	full_planr   r   Z
reboot_msgrT   rT   rU   r   ,  s    















r   Zfix)r   c                K   sJ   | j rttj d| j kr0t| j| j |}nt| j| j | j|}|j	S )Nr|   )
rG   rb   r   ZSECURITY_DRY_RUN_WARNINGr   lowerr   r   r   Z	exit_code)argsrI   kwargsri   rT   rT   rU   
action_fix~  s    
   r   Tr   )helpz	--dry-run
store_true)r   actionz--no-related)Z	arguments)r   r   r   Zhelp_categoryZpreserve_descriptionZargument_groups)N)r   )rc   typingr   r   r   r   r   r   r   Zuaclientr	   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.fix._commonr   r   r   Z/uaclient.api.u.pro.security.fix._common.plan.v1r   r   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.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/   r0   Zuaclient.clir1   Zuaclient.cli.commandsr2   r3   r4   Zuaclient.cli.detachr5   Zuaclient.cli.parserr6   Zuaclient.clouds.identityr7   r8   r9   Zuaclient.configr:   Zuaclient.defaultsr;   Zuaclient.entitlementsr<   Z(uaclient.entitlements.entitlement_statusr=   r>   r?   Zuaclient.filesr@   Zuaclient.files.noticesrA   Zuaclient.messages.urlsrB   Zuaclient.statusrC   rD   r   r   ry   rz   r   r   intrn   r   r   r   r   r   r   r   r   r   r   ro   r   r   r   r   r   r   r   r   r   r   Z assert_vulnerability_issue_validr   ZCLI_ROOT_FIXZCLI_FIX_DESCZSECURITYZCLI_FIX_ISSUEZCLI_FIX_DRY_RUNZCLI_FIX_NO_RELATEDZfix_commandrT   rT   rT   rU   <module>   s   $
X?   l   ,   %  
?0" 	    R

