
­­­­­­­­­­­­­­­­­­
<!DOCTYPE html>
<html>
3
;jb                 @   s  d dl Z d dlZd dlZ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mZmZmZmZmZmZmZ ddlmZmZmZ dZdOZdZd	Zd
ZddddZddedgfddedgfgZej dd Z!dd Z"dd Z#dd Z$G dd de%Z&dd Z'dPddZ(dd  Z)d!d" Z*d#d$ Z+dQd&d'Z,d(d) Z-e$d*d+ Z.e$d,d- Z/e$d.d/ Z0d0d1 Z1d2d3 Z2d4d5 Z3d6d7 Z4d8d9 Z5dRd:d;Z6e$e'ej7d<d= Z8d>d? Z9ej7ej:d@ej;e$e'e
j<ddfdAdBZ=e$dCdD Z>dEdF Z?dGdH Z@dSdIdJZAdKdL ZBdMdN ZCdS )T    N   )authcapabilitiesconfigconfig_handlers	constantserrorsfetch	log_utilsplatform_utilsprocess_utilsselinuxserver_infoupdate_utilsutils)	HTTPErrorjson_loads_nstrurlquotez!/usr/libexec/kcare/libcare-client/run/libcare/libcare.sock/var/run/libcare.sockz /var/cache/kcare/libcare_patchesz /var/cache/kcare/libcare_cvelistz&/etc/sysconfig/kcare/libcare.logrotatedb)mysqldmariadbdpostgresZubuntuz16.
libnss_dnsz7.c        	         s   t tj} t  y tj }|d j }|d }W n0 tk
r`   xtD ]\}}} |O  qFW Y n>X |d }x2tD ]*\}}}|d ks||krp|j	|rp| P qpW  fdd| D S )Nr   r   .c                s   g | ]}| kr|qS  r   ).0lib)blacklistedr   -/usr/libexec/kcare/python/kcarectl/libcare.py
<listcomp>R   s    z/_get_effective_libcare_libs.<locals>.<listcomp>)
listr   LIBCARE_LIBSsetr   
get_distrolower	ExceptionLIBCARE_LIBS_BLACKLIST
startswith)	libsZdistro_infodistroversion_Zbl_libsZversion_dottedZ	bl_distroZ
bl_versionr   )r   r    _get_effective_libcare_libs;   s    
r.   c               C   s   dddgt  dS )Nr   r   r   )r   r*   )r.   r   r   r   r    get_userspace_mapU   s    r/   c             G   s   t jjtjd| f| S )N	userspace)ospathjoinr   PATCH_CACHE)libnamepartsr   r   r    get_userspace_cache_path\   s    r7   c                s    fdd}|S )Nc                 sV   z
 | |S yt d W n6 tk
rN } ztjdj|dd W Y d d }~X nX X d S )N
clearcachez$Libcare cache clearing failed: '{0}'F)	print_msg)libcare_clientr'   r
   logerrorformat)argskwargserr)clblr   r    wrappera   s    
z$clear_libcare_cache.<locals>.wrapperr   )r@   rA   r   )r@   r    clear_libcare_cache`   s    
rB   c                   s0   e Zd Zd fdd	Zd	ddZdd Z  ZS )
UserspacePatchLevelNc                s   t | | j| |S )N)super__new__)clsr5   buildidlevelbaseurl)	__class__r   r    rE   o   s    zUserspacePatchLevel.__new__c             C   s   || _ || _|| _|| _d S )N)rH   r5   rG   rI   )selfr5   rG   rH   rI   r   r   r    __init__r   s    zUserspacePatchLevel.__init__c             G   s   t | j| jt| f| S )N)r7   r5   rG   str)rK   r6   r   r   r    
cache_pathx   s    zUserspacePatchLevel.cache_path)N)N)__name__
__module____qualname__rE   rL   rN   __classcell__r   r   )rJ   r    rC   n   s   
rC   c                s   dd  fdd}|S )Nc             S   s   d\}}z| dkrt  } i }g }x8t| D ],}|jdd||jd< |j|jdg  q*W tj|dd}djd	d
 |j D }djt|}W dtj	t
|dd tj	t|dd X dS )z(KPT-1543 Save info about applied patches Nzlatest-versionpackagepatchescve)	cve_field
c             S   s   g | ]}d j |qS ) )r3   )r   recr   r   r    r!      s    zLrefresh_applied_patches_list.<locals>.save_current_state.<locals>.<listcomp>T)
ensure_dir)rS   rS   )_libcare_info_get_patches_infogetextendr   extract_unique_cvesr3   itemssortedatomic_writeLIBCARE_PATCHESLIBCARE_CVE_LIST)infoZversionsZcvesZpackagesZall_patchesrZ   Zcves_setr   r   r    save_current_state}   s    z8refresh_applied_patches_list.<locals>.save_current_statec                 s"   d }z | |}|S | X d S )Nr   )r=   r>   rf   )r@   rg   r   r    rA      s
    
z-refresh_applied_patches_list.<locals>.wrapperr   )r@   rA   r   )r@   rg   r    refresh_applied_patches_list|   s    rh   c          "   C   s  t jpd}t| } t|j }tjtj| d|| |d}|dtj	d| 7 }tj| d}|rlt
jjd||}i }|rd|i|d	< y tjtj|fd
di|}W n tjk
r   |rtjdj| |dd d S tjt||dd  Y nL tk
r4 }	 z.|	jdkr"|r"tjdj|dd W Y d d }	~	X nX tj|j ttj |j! }
|
jdg }t"j#|s|tj$dj| t%|||
d |
jd}t&|
d }t|||d}t
jj'| st
jj(|dkr:tj|
d }ytj)||t j*tj+|d W n< tk
r8 }	 z|	jd(kr&tj,d W Y d d }	~	X nX t|||}dd |d!|d"g}t-j.|ddd#\}}}|rtjd$j|||d%dt||d&}t
jj/| rt
jj0|rtj| t
j1||d'  t
j2|d' | |S ))Nmainuz	latest.v1z?info=updater*   tagsZStickyheaderscheck_licenseFz;No libcare patchset available for {0} at tag {1}, skipping.)r9   T)ignore_errorsi  z8Invalid sticky patch tag {0}: server rejected the value.zinvalid lib sticky patch)statusr   zkLatest LibCare patchset for {0} is incompatible with the current kernecare package version, please upgrade.rH   rI   zpatch.tar.gzr   Z	patch_url)check_signaturehash_checker    zKC+ licence is requiredtarZxfz-Cz--no-same-owner)catch_stdoutcatch_stderrz(Patches unpacking error: '{0}' '{1}' {2}zpatches unpacking errorlatestz.tmp)rs   rt   )3r   PREFIXr   stripr   get_patch_server_urlLIBNAME_MAPr^   r   Zencoded_server_lib_infor1   r2   r3   r	   wrap_with_cache_keyr   urlopen_authr   NotFoundr
   loginfor<   shutilrmtreer7   r   code
KcareErrorr   set_feature_flags_from_headersrm   r   nstrreadr   has_lc_capabilitiesCapabilitiesMismatchrC   rM   existsgetsize	fetch_urlUSE_SIGNATUREget_hash_checkerNoLibcareLicenseExceptionr   run_commandislinkisdirsymlinkrename)r5   build_idpatch_leveltagprefixurl	cache_dstZextra_kwargsresponseexmetarequired_capabilitiesrH   plevelZ
patch_pathdstcmdr   stdoutstderrZ	link_namer   r   r    fetch_userspace_patch   sr    
 
"

r   c             C   sL   |  t _| st  tj| rdndd | r0t  tjjd| r@dnd  d S )NFALSEYES)LIBCARE_DISABLEDzlibcare service is enableddisabled)	r   r   libcare_server_stopr   update_configlibcare_server_startr
   kcarelogrf   )r   r   r   r    set_libcare_status   s    r   c              C   s   t jstjjt jr^tjt jddg tjt jddg tjt jddg tjt jddg n6ytjdd	ddg} W n t	k
r   d S X tj|  d S )
Nstopzlibcare.socketzlibcare.servicezreset-failedlibcareservice
/usr/sbin//sbin/)r   r   )
r   SKIP_SYSTEMCTL_CHECKr1   r2   r   	SYSTEMCTLr   r   find_cmdr'   )r   r   r   r    r      s    r   c              C   s   t jstjjt jrtjt jdddgddd\} }}| dkr@d S tjt jddg tjt jddg tjt jd	d
g tjt jd	dg tjt jddg n@t rd S ytj	ddd
dg}W n t
k
r   d S X tj| d S )Nz	is-activez--quietzlibcare.serviceT)rv   rw   r   r   zlibcare.socketzreset-failedr   startr   
/usr/sbin//sbin/)r   r   )r   r   r1   r2   r   r   r   r   libcare_server_startedr   r'   )r   r-   r   r   r   r    r     s&    r   Tc                s  dj dd t|pg D }ddg} s6|dd|g7 }yt| }W n6 tk
rx } ztjdj|d	d
W Y d d }~X nX g }x@|jdD ]2}|ry|jt	j
| W q tk
r   Y qX qW dd |D }x.|D ]&}t fdd|d j D |d< qW |S )N|c             s   s   | ]}d j tj|V  qdS )z({0})N)r<   reescape)r   procr   r   r    	<genexpr>$  s    z _libcare_info.<locals>.<genexpr>rf   z-jz-lz-rz/Gathering userspace libraries info error: '{0}'zuserspace libs info error)rp   rX   c             S   s$   g | ]}|j d |j d|dqS )commpid)r   r   r*   )pop)r   liner   r   r    r!   :  s    z!_libcare_info.<locals>.<listcomp>c             3   s(   | ] \}}d |ks  r||fV  qdS )patchlvlNr   )r   kv)patchedr   r    r   =  s    r*   )r3   rb   r:   r'   r   r   r<   splitappendjsonloads
ValueErrordictra   )r   limitZregexpr   linesr?   resultr   r   )r   r    r\      s&    &

&r\   c             C   s   t  }x<| D ]4}x.|d j D ]\}}|j|d |d f qW qW g }t }xb|D ]Z}xT|D ]L\}}	t||t|	d}
tjj|
r^t	|
d}|j
tj| W d Q R X q^W qTW |S )Nr*   rG   r   z	info.jsonr)r$   ra   addr/   r7   rM   r1   r2   isfileopenr   r   load)rf   rU   rZ   r-   datar   umapr   r   r   Zpatch_info_filenamefdr   r   r    r]   B  s    

"r]   c               C   s
   t t S )N)r]   r\   r   r   r   r    libcare_patch_info_basicR  s    r   c              C   s"   t  } | stjd tjd| iS )NzNo patched processes.r   )r   r
   r;   r   dumps)r   r   r   r    libcare_patch_infoW  s    
r   c              C   s"   t  } | stjd tjd| iS )NzNo patched processes.r   )r\   r
   r;   r   r   )r   r   r   r    libcare_info_  s    
r   c              C   s.   i } x$t  D ]}|jdd| |jd< qW | S )Nzlatest-versionrS   rT   )r   r^   )r   rZ   r   r   r    _libcare_versiong  s    r   c             C   s*   x$t  j D ]\}}| j|r|S qW dS )NrS   )r   ra   r)   )r5   rT   r,   r   r   r    libcare_versionn  s    
r   c             C   s   dj dd | D d S )N    c             s   s   | ]}t j|d  V  qdS )    N)r   bstr)r   pr   r   r    r   v  s    z(libcare_client_format.<locals>.<genexpr>r   )r3   )paramsr   r   r    libcare_client_formatu  s    r   c              C   s,   xt D ]} tjj| r| S qW tjdd S )NzLibcare socket is not found.)LIBCARE_SOCKETr1   r2   r   r   r   )Zlibcare_socketr   r   r    get_available_libcare_sockety  s    
r   c           
   G   s   t jrtjdtjtjtjd}|jd d}z||jt	  |jt j
 t| }tjdj| d |j| x|jd}|sP ||7 }qpW |jdd	}tjd
j|d |S |j  X d S )NzLibcare is disabled.r   
   r   zLibcare socket send: {cmd})r   i   zutf-8replacez!Libcare socket recieved: {result})r   )r   r   r   r   socketAF_UNIXSOCK_STREAM
settimeoutconnectr   LIBCARE_SOCKET_TIMEOUTr   r
   logdebugr<   sendallrecvdecodeclose)r   sockresr   r   r   r   r   r    r:     s(    



r:   c             C   s  |rzxp| D ]h}t d||}tjj|s(q
ytdd| W q
 tk
rp } ztjdj||ddW Y d d }~X q
X q
W d S x| D ]}ytdt | W n6 tk
r } ztjdj|d	dW Y d d }~X nX ytd W q tk
r } ztjd
j|ddW Y d d }~X qX qW d S )Nrl   rk   z	--storagez3Userspace patch applying error (storage={0}): '{1}'zuserspace patch apply error)rp   Zstoragez(Userspace storage switching error: '{0}'zuserspace storage switch errorz%Userspace patch applying error: '{0}')	r7   r1   r2   r   r:   r'   r   r   r<   )r   r   r   Zstorage_pathr?   r   r   r    libcare_patch_apply  s*    


&r   c              C   sH   yt d W n6 tk
rB }  ztjdj| ddW Y d d } ~ X nX d S )Nunloadz&Userspace patch unloading error: '{0}'zuserspace patch unload error)rp   )r:   r'   r   r   r<   )r?   r   r   r    libcare_unload  s    r   c              C   sD   yt d W n2 tk
r> }  ztjdj| W Y dd} ~ X nX dS )z;Reload libcare-server plugin without restarting the server.ZrepluginzUserspace replugin error: '{0}'N)r:   r'   r   r   r<   )r?   r   r   r    libcare_replugin  s    r   r   c             C   s  t   | tjkrtj rdS t }|dkr6t|j }g }x|D ]}|j|j	|g  q@W |srt
jdj| dS t||d\}}}}	|rtjd|st
jd dS tjtjjtjd t   yt||d W n> tjk
r }
 zt
jt|
 tjdW Y dd}
~
X nX t }t|}ttd	d
 |D s<dS t
jdj|	d t
jdj|d tdd
 |j D }tdd
 |	j D }|| }tdd
 |j D }t
jdjt ||d x,|j! D ] \}}t
jdj|t | qW |S )z0Patch userspace processes to the latest version.NzNo such userspace patches: {0})r   r   z8There were errors while patches downloading (unpacking).zNo patches were found.r0   )r   z)There were errors while patches applying.c             s   s   | ]}|d  V  qdS )r*   Nr   )r   itemr   r   r    r     s    z&do_userspace_update.<locals>.<genexpr>zPatched before: {before})beforezPatched after: {after})afterc             s   s   | ]}|D ]
}|V  q
qd S )Nr   )r   ra   r   r   r   r    r     s    c             s   s   | ]}|D ]
}|V  q
qd S )Nr   )r   ra   r   r   r   r    r     s    c             s   s   | ]}t |V  qd S )N)len)r   r   r   r   r    r     s    zThe patches have been successfully applied to {count} newly discovered processes. The overall amount of applied patches is {overall}.)countoverallz*Object `{0}` is patched for {1} processes.)"rotate_libcare_logsr   UPDATE_MODE_AUTOr   LIB_AUTO_UPDATEr/   r"   keysr_   r^   r
   r   r<   check_userspace_updatesr   r   r   restore_selinux_contextr1   r2   r3   r4   r   r;   rM   r\   _get_userspace_procsanyr   r$   valuessumr   ra   )moder   r   r   Zprocess_filterZuserspace_patchfailedsomething_foundr-   r   r   Z
data_afterr   Zuniq_procs_afterZuniq_procs_beforeZdiffr   r   r   r   r   r    do_userspace_update  sR    


r  c              C   s\   z.yt  \} }}}W n tjk
r*   dS X W d t  X | r@dS |rHdS tjddrXdS dS )N   r   z.libcarestatus)filename   r   )r  r   r   r   r   status_gap_passed)r  r-   libs_not_patchedr   r   r    get_userspace_update_status  s    
r  c             C   sd   i }xZ| D ]R}xL|d j  D ]<\}}|jdr||kr>g ||< || j|d |d f qW q
W |S )Nr*   r   r   r   )ra   r^   r   )rf   r   r   r5   rZ   r   r   r    r  .  s    

"r  c             C   sN   t  }xB| D ]:}x4|d j D ]$\}}|j||d |jddf qW qW |S )Nr*   rG   r   r   )r$   ra   r   r^   )rf   r   r   r5   rZ   r   r   r    _get_userspace_libs9  s
    
$r  c                s\   s$t  }g   fdd|j D  td d}t|}d }}d}xt|D ]}|\}	}
}y2t|	|
||d}|r||d kr|wNd}|dkrd}W qN tjk
r } zd}tj	t
| W Y d d }~X qN tjtjfk
r   Y qN tjk
r    Y qN tjk
r> } z,t|dd d	kr d}tjt
| W Y d d }~X qNX qNW tjd
d ||||fS )Nc                s   g | ]} j |qS r   )r_   )r   r*   )r   r   r    r!   E  s    z+check_userspace_updates.<locals>.<listcomp>F)r   r   T)r   r   rp   zinvalid lib sticky patchz.libcarestatus)r  )r/   r  r\   r  r  r   r   r   r
   logwarnrM   r   r   AlreadyTrialedExceptionr   getattrr;   r   touch_status_gap_file)r   r   r   Zdata_beforer   r  r  r  rZ   r5   r   r   r   er   r   )r   r    r  A  s>    
$r  c                 sf  d} d}t jddd}|ryt j|tgdd\} }}W n. tk
rd } zd} t|}W Y d d }~X nX | rtjd	j|dd
 ntj	ddd
 d t
jj sd S tjd }yt
j }tjd fdd|D }dd |D }|jdd d}	xD|D ]<\}}
|	t
jj|
7 }	|	|k rt
j|
 tjjd|
  qW W n$ tk
r`   tjddd
 Y nX d S )Nr   rS   Z	logrotateF)	raise_excT)rw   r   z5failed to run logrotate for libcare logs, stderr: {0})r9   zlogrotate utility wasn't foundz/var/log/libcare/i   r  z^\d+\.log.*c                s$   g | ]}j |rtjj |qS r   )matchr1   r2   r3   )r   fn)libcare_log_directory	pidlog_rer   r    r!     s    z'rotate_libcare_logs.<locals>.<listcomp>c             S   s   g | ]}t jj||fqS r   )r1   r2   getctime)r   fpr   r   r    r!     s    )reversez%Removed %s because of logs size limitz)Failed to cleanup libcare server logfilesi   )r   r   r   LIBCARE_LOGROTATE_CONFIGr'   rM   r
   r;   r<   r  r1   r2   r   r   !LIBCARE_PIDLOGS_MAX_TOTAL_SIZE_MBlistdirr   compilesortr   remover   rf   logexc)rcr   Zlogrotate_pathr-   r  Zmax_total_sizeZ	log_filesZpidlog_filesZpidlog_files_with_ctZ
total_sizefilepathr   )r  r  r    r   r  s<    




r   c              C   sJ   yt jdd
ddg} W n tk
r*   dS X t j| ddd\}}}|d	kS )zKAssume that whenever the service is not running, we did not patch anything.r   
/usr/sbin//sbin/r   rp   FT)rv   rw   r   )r+  r,  )r   r   r'   r   )r   r   r-   r   r   r    r     s    r   )r   r   )NN)TN)N)NN)Dr   r1   r   r   r   rS   r   r   r   r   r   r   r	   r
   r   r   r   r   r   r   py23r   r   r   ZLIBCARE_CLIENTr   rd   re   r"  r|   r$   r(   cachedr.   r/   r7   rB   intrC   rh   r   r   r   r   r\   r]   r   r   r   r   r   r   r   r:   r   log_all_parent_processesr   r   track_update_statusskip_if_no_selinux_moduleUPDATE_MODE_MANUALr  r  r  r  r  r   r   r   r   r   r    <module>   sh   @ 
L

"
$	H
1*