a
    Dc``]                     @   s*  d dl Z d dlZd dlZd dlZd dlZd dlZd dlZd dlZd dl	Zd dl
Z
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 dZdd Zdd Zd8dd	ZG d
d deZdd Zdd ZG dd deZG dd deZG dd deZG dd deZG dd deZG dd deZG dd deeZ G dd deZ!G d d! d!e!eeeZ"G d"d# d#e!eeZ#G d$d% d%e!eeZ$G d&d' d'eZ%G d(d) d)eZ&G d*d+ d+e&Z'G d,d- d-e'Z(G d.d/ d/e&e!ee%eZ)G d0d1 d1e(e)Z*G d2d3 d3eZ+G d4d5 d5e+e'ee%eZ,G d6d7 d7e(e,Z-dS )9    N)_
   c              
   C   s   | j s
d S z$|  s,ttd tt W nb ttfyN   tt Y nD t	y } z,ttdt
|  td W Y d }~n
d }~0 0 d S )NZAbortingzConfirmation failed: %s   )confirmALCLogerrorr   sysexitBREAK_APT_EXIT_CODEKeyboardInterruptEOFError	Exceptionstr)configfrontendex r   -/usr/share/apt-listchanges/apt_listchanges.pyconfirm_or_exit1   s    r   c              
   C   s  t td| j|d  tjd}d|_tjj|_	tj
 }| jdkrbt| ||}d|d< d|d	< | r~| r~|ntj|||d
< | j|d< ||| ztjg d| dd W n@ ty } z&t td| j|d  W Y d }~n
d }~0 0 d S )Nz Mailing %(address)s: %(subject)s)addresssubjectzutf-8Z8bithtmlztext/html; charset=utf-8zContent-Typezauto-generatedzAuto-SubmittedZSubjectZTo)/usr/sbin/sendmailz-oiz-tT)inputZcheckz.Failed to send mail to %(address)s: %(errmsg)s)r   errmsg)r   infor   email_addressemailcharsetZCharsetZbody_encodingZQPZheader_encodingmessageZMessageZemail_formatr   convert_to_htmlisasciiisprintableheaderZHeaderZset_payload
subprocessrunZas_bytesr   warning)r   Zchangesr   r   r   r   r   r   r   mail_changes>   s4    





r'   c                 C   sJ   t jds&|r"ttd|  dS | jsF|rBttd|  dS dS )Nr   z9The mail frontend needs an installed 'sendmail', using %sFzDThe mail frontend needs an e-mail address to be configured, using %sT)ospathexistsr   r   r   r   )r   ZreplacementFrontendr   r   r   can_send_emailsY   s    

r+   c                   @   s   e Zd ZdS )EUnknownFrontendN__name__
__module____qualname__r   r   r   r   r,   j   s   r,   c                    s   dt d d d fddtdt D  t d }dD ]n}z.t| |}|s\W  q t|d	  W   S  ty } z"t	t d
t
|  W Y d}~q>d}~0 0 q>tt d| j  | jS )z, Utility function used for testing purposes 
z$Available apt-listchanges frontends: c                    s    g | ]}d |d  | f qS )z	  %d. %s
r   r   ).0i	frontendsr   r   
<listcomp>p       z$_select_frontend.<locals>.<listcomp>r   z*Choose a frontend by entering its number: )r         r   	Error: %sNzUsing default frontend: %s)r   joinrangelen
ttyconfirmttyaskintr   r   r   r   r   r   )r   r6   promptr4   responser   r   r5   r   _select_frontendm   s     .rD   c                 C   s  t ttttttttd d d}ddg}| j	rBt
| tt| }n| j}|dkrTd S ||v r`n| jdkr~t| rxd}nd S n| jdkr|dkst| dsd}n|dkrt| d	sd	}|d
v rdtjvr|dr|dd  nd	}ttdd|i  |dkrxztd}|j||< W n^ tyv } zD| jrF| jrFd}d| _nd	}ttd||d  W Y d }~n
d }~0 0 || _||vrt|| | |S )N)textpagerdebconfmailsysloglogbrowserxterm-pagerxterm-browsergtknonerI   rJ   rO   r9   rH   r   rE   rF   )rN   rL   rM   ZDISPLAYzxterm-   z1$DISPLAY is not set, falling back to %(frontend)sr   rN   ZAptListChangesGtkFz|The gtk frontend needs a working python3-gi,
but it cannot be loaded. Falling back to %(frontend)s.
The error is: %(errmsg)s)r   r   )text_frd	pager_frddebconf_frdmail_frd
syslog_frdlog_frdbrowser_frdxterm_pager_frdxterm_browser_frdZselect_frontendrD   sortedlistkeysr   quietr+   r(   environ
startswithr   r   r   
__import__Zgtk_frdImportErrorZapt_modeZfrontend_from_envr   r,   )r   packages_countr6   Zfrontends_no_overridenamerN   r   r   r   r   make_frontend   sh    





rd   c                       s$   e Zd Z fddZdd Z  ZS )basec                    s   t    || _d S N)super__init__r   )selfr   args	__class__r   r   rh      s    
zbase.__init__c                 C   s   |S rf   r   ri   rE   r   r   r   _render   s    zbase._render)r.   r/   r0   rh   rn   __classcell__r   r   rk   r   re      s   re   c                       s$   e Zd Z fddZdd Z  ZS )titledc                    s   t  j|  d| _d S )Nzapt-listchanges output)rg   rh   titleri   rj   rk   r   r   rh      s    ztitled.__init__c                 C   s
   || _ d S rf   )rq   )ri   rq   r   r   r   	set_title   s    ztitled.set_title)r.   r/   r0   rh   rs   ro   r   r   rk   r   rp      s   rp   c                       sF   e Zd Z fddZdddZdd Zdd	 Zd
d Zdd Z  Z	S )r   c                    s   t  || || _d S rf   )rg   rh   rb   )ri   r   rb   rk   r   r   rh      s    zfrontend.__init__r   c                 C   s   d S rf   r   ri   diffr   r   r   update_progress   s    zfrontend.update_progressc                 C   s   d S rf   r   ri   r   r   r   progress_done   s    zfrontend.progress_donec                 C   s   d S rf   r   rm   r   r   r   display_output   s    zfrontend.display_outputc                 C   s   dS NFr   rw   r   r   r   needs_tty_stdin   s    zfrontend.needs_tty_stdinc                 C   s   dS NTr   rw   r   r   r   r      s    zfrontend.confirm)r   )
r.   r/   r0   rh   rv   rx   ry   r{   r   ro   r   r   rk   r   r      s   
r   c                   @   s   e Zd Zdd ZdS )rS   c           	      C   sH  dd l }dd l}dtjvs(tjd dkr,d S | |j|jd}|tjd  | }|  |j	||d}t
jdd}t| d |d	 |d
D ]*}| r|d| d
  q|d q|  |d|j |  |d |dd| j |dd| j |d |ddd |dd |  |  d S )Nr   ZDEBIAN_FRONTENDZpassthroughZDEBCONF_PIPE)readwriteapt-listchanges-tmp)prefixi  s   Template: apt-listchanges/info
Type: title
Description: NEWS

Template: apt-listchanges/title
Type: title
Description: ${title}

Template: apt-listchanges/news
Type: note
Description: ${packages_count} packages
r1   z  z .
Zx_loadtemplatefilezapt-listchanges/infozapt-listchanges/titlerq   zapt-listchanges/newsrb   seenZfalseZhigh)socketrG   r(   r^   ZAF_UNIXZSOCK_STREAMZconnectZmakefilecloseZDebconftempfileNamedTemporaryFilefchmodfilenor~   splitstripflushcommandrc   r   substrq   rb   Zsettitlefsetr   Zgo)	ri   rE   r   ZdcZsockZdcfdZdbtmpliner   r   r   ry      s6    


zdebconf_frd.display_outputNr.   r/   r0   ry   r   r   r   r   rS      s   rS   c                   @   s$   e Zd Zdd Zdd Zdd ZdS )r?   c                 C   s   t j r t j r t| S t }tdddd:}|	|
| |  ||  W  d    S 1 sv0    Y  d S )Nz/dev/ttyzrb+r   )	buffering)r   stdinisattystdoutr   rstripALChackssystem_encodingopenr~   to_bytesr   
from_bytesreadline)ri   rB   encZttyr   r   r   r@     s    zttyconfirm.ttyaskc                 C   s.   |  dtd }|dkp,tttj|S )Nzapt-listchanges: zDo you want to continue? [Y/n] r2   )r@   r   researchlocalenl_langinfoYESEXPR)ri   rC   r   r   r   r   )  s    zttyconfirm.confirmc                 C   s   | j jS rf   )r   r   rw   r   r   r   r{   -  s    zttyconfirm.needs_tty_stdinN)r.   r/   r0   r@   r   r{   r   r   r   r   r?     s   
r?   c                   @   s   e Zd ZdddZdd ZdS )simpleprogressr   c                 C   s6   | j jdkrd S t| ds2d| _ttdd  d S )Nr   message_printedReading changelogsz...)r   r]   hasattrr   r   r   r   rt   r   r   r   rv   1  s
    
zsimpleprogress.update_progressc                 C   s   d S rf   r   rw   r   r   r   rx   9  s    zsimpleprogress.progress_doneN)r   r.   r/   r0   rv   rx   r   r   r   r   r   0  s   
r   c                   @   s   e Zd ZdS )rT   Nr-   r   r   r   r   rT   <  s   rT   c                   @   s   e Zd Zdd ZdS )prepend_titlec                 C   s,   | j js|S | jd t| jd  d | S )Nr1   -z

)r   rp   rq   r>   rm   r   r   r   rn   @  s    zprepend_title._renderN)r.   r/   r0   rn   r   r   r   r   r   ?  s   r   c                   @   s   e Zd Zdd ZdS )rQ   c                 C   s    t jt | | d S rf   )r   r   r~   r   r   	as_stringrn   rm   r   r   r   ry   G  s    ztext_frd.display_outputNr   r   r   r   r   rQ   F  s   rQ   c                   @   s   e Zd Zdd ZdS )rU   c                 C   s<   dd l }|j|jd | t | | |  d S )Nr   )Zfacility)rI   ZopenlogZ
LOG_DAEMONr   r   r   rn   Zcloselog)ri   rE   rI   r   r   r   ry   K  s    zsyslog_frd.display_outputNr   r   r   r   r   rU   J  s   rU   c                   @   s   e Zd Zdd ZdS )rV   c                 C   s   t  | |}t| jjd}| jjrt	| jj| _
tj|  tj||  |  d}|j|d |jdkrttdt|jtd n
|| W d    n1 s0    Y  d S )Na)r   r   
preexec_fnenv)r   r   -Command %(cmd)s exited with status %(status)dcmdstatus)r   r   r   rn   r   r   rJ   filtershlexr   r   r$   Popenget_commandPIPEget_preexec_fnget_environZcommunicate
returncodeOSErrorr   r   rj   r   r~   )ri   rE   outputfprocessr   r   r   ry   S  s    
zlog_frd.display_outputNr   r   r   r   r   rV   R  s   rV   c                   @   s   e Zd ZdddZdd ZdS )fancyprogressr   c                 C   sp   |sd S t | dsd| _d| _|  j|7  _tdd| jd | j   }t|| _tj|d  tj	  d S )Nprogressr   r   z... %d%%d   )
r   r   line_lengthr   rb   r>   r   r   r~   r   )ri   ru   r   r   r   r   rv   d  s    

zfancyprogress.update_progressc                 C   sN   t | drJtjd| j d  tjtdd td d  tj  d S )Nr    r   r   z... ZDoner1   )r   r   r   r~   r   r   r   rw   r   r   r   rx   q  s    
 zfancyprogress.progress_doneN)r   r   r   r   r   r   r   c  s   
r   c                       sT   e Zd Z fddZdd Zdd Zdd Zd	d
 Zdd Zdd Z	dd Z
  ZS )
runcommandc                    s"   t  j|  d| _d| _d | _d S )NTr2   )rg   rh   waitsuffixr   rr   rk   r   r   rh   x  s    zruncommand.__init__c              	   C   s(  | j st dkrd S tjd| j|  d}z|| j	| 
| |  | |  t| j}td tj|  |jg |  |  d}|  }|dkrttdt|j|d tdd	D ]&}|t| jkr qtd
 qW | | n| | 0 | j s$td d S )Nr   r   )r   r   dirg?)r   r   r   r   r   r   g      ?) r   r(   forkr   r   r   
get_tmpdirr~   r   r   rn   r   fchown_tmpfiler   fstatst_atimetimesleepr$   r   r   rc   r   r   r   r   r   rj   r=   _close_temp_filer   r	   )ri   rE   r   Zatimer   r   r4   r   r   r   ry     s,    
$zruncommand.display_outputc                 C   s$   z|   W n ty   Y n0 d S rf   )r   FileNotFoundError)ri   r   r   r   r   r     s    zruncommand._close_temp_filec                 C   s   | j S rf   )r   rw   r   r   r   r     s    zruncommand.get_commandc                 C   s   d S rf   r   ri   r   r   r   r   r     s    zruncommand.fchown_tmpfilec                 C   s   d S rf   r   rw   r   r   r   r     s    zruncommand.get_tmpdirc                 C   s   d S rf   r   rw   r   r   r   r     s    zruncommand.get_preexec_fnc                 C   s   d S rf   r   rw   r   r   r   r     s    zruncommand.get_environ)r.   r/   r0   rh   ry   r   r   r   r   r   r   ro   r   r   rk   r   r   w  s   (r   c                       sL   e Zd Z fddZdd Zdd Zdd Zd	d
 Zdd Zdd Z	  Z
S )runcommand_drop_privsc                    sP   t  j|  |  | _|  | _| jjrL| jrLtt	d| jj
| jd  d S )Nz2Found user: %(user)s, temporary directory: %(dir)s)userr   )rg   rh   _find_user_pw_user_pw_find_tmpdir_tmpdirr   debugr   r   pw_namerr   rk   r   r   rh     s    


zruncommand_drop_privs.__init__c                 C   s    | j rt|| j j| j j d S rf   )r   r(   fchownpw_uidpw_gidr   r   r   r   r     s    z$runcommand_drop_privs.fchown_tmpfilec                 C   s   | j S rf   )r   rw   r   r   r   r     s    z runcommand_drop_privs.get_tmpdirc                    s    j s
d S  fdd}|S )Nc               
      s`   z t  jj t  jj W n: tyZ }  z"tt	dt
|   W Y d } ~ n
d } ~ 0 0 d S )Nr;   )r(   setgidr   r   setuidr   r   r   r   r   r   )r   rw   r   r   preexec  s
    z5runcommand_drop_privs.get_preexec_fn.<locals>.preexec)r   )ri   r   r   rw   r   r     s    z$runcommand_drop_privs.get_preexec_fnc                 C   s\   | j s
d S tj}| j j|d< | j j|d< dD ]}| j j||< q,| jrXdD ]}| j||< qH|S )NHOMEZSHELL)USERNAMEZUSERZLOGNAME)ZTMPDIRZTMPZTEMPDIRZTEMP)r   r(   r^   pw_dirZpw_shellr   r   )ri   Znewenvenvvarr   r   r   r     s    z!runcommand_drop_privs.get_environc                 C   s   t  dkrd S d }dD ]}|t jv rz0t j| }| sDt|nt|}W  qW q ty } z(tt	d|t
|d |W Y d }~qd }~0 0 q|r|jr|S tt	d d S )Nr   )ZAPT_LISTCHANGES_USERZ	SUDO_USERr   z9Error getting user from variable '%(envvar)s': %(errmsg)s)r   r   z1Cannot find suitable user to drop root privileges)r(   getuidr^   isdigitpwdgetpwnamgetpwuidr   RuntimeErrorr   r   r   r   r&   )ri   Zpwdatar   r   r   r   r   r   r     s&    



z#runcommand_drop_privs._find_user_pwc              	   C   s  | j s
d S t }tjtjB tjB }t| j jd zt	||rR|W t
d S |g}|dr|dd t| j j }t	||r|W t
d S || |dkrd}t	||r|W t
d S || ttd| j jt|d W t
d nt
d 0 d S )Nr   z/0z/tmpzJNone of the following directories is accessible by user %(user)s: %(dirs)s)r   dirs)r   r   Z
gettempdirr(   R_OKW_OKX_OKsetreuidr   accessr   endswithr   appendr   r   r   )ri   ZtmpdirflagsZchecked_tmpdirsr   r   r   r     s>    





z"runcommand_drop_privs._find_tmpdir)r.   r/   r0   rh   r   r   r   r   r   r   ro   r   r   rk   r   r     s   r   c                       s,   e Zd Z fddZdd Zdd Z  ZS )xtermc                    s4   t  j|  tj| _d| _t| j	dd| _
d S )NFr   zx-terminal-emulator)rg   rh   r(   P_NOWAITmoder   r   r   r   getr   rr   rk   r   r   rh     s    zxterm.__init__c                 C   s   | j d| jdg | j S )Nz-Tz-e)r   rq   r   rw   r   r   r   r     s    zxterm.get_commandc                 C   s   dS rz   r   rw   r   r   r   r{   !  s    zxterm.needs_tty_stdin)r.   r/   r0   rh   r   r{   ro   r   r   rk   r   r     s   r   c                       s,   e Zd Z fddZdd Zdd Z  ZS )rR   c                    s>   t  j|  |   t| jdd| _d| _t	
 | _d S )NrF   zsensible-pagerz.txt)rg   rh   _setup_less_variabler   r   r   r   r   r   r   r   r   rr   rk   r   r   rh   &  s
    zpager_frd.__init__c                 C   sr   dt d }tjdd}|s,|tjd< d S d|v s<d|v rD|d7 }d|v sTd	|v r\|d
7 }|d | tjd< d S )Nz	-P?e(%s)$zpress q to quitLESSr2   Ez--QUIT-Az -+EFz--quit-iz -+Fr   )r   r(   r^   r   )ri   rB   Zlessr   r   r   r   -  s    
zpager_frd._setup_less_variablec                 C   s   dS r|   r   rw   r   r   r   r{   >  s    zpager_frd.needs_tty_stdin)r.   r/   r0   rh   r   r{   ro   r   r   rk   r   rR   %  s   rR   c                   @   s   e Zd ZdS )rX   Nr-   r   r   r   r   rX   A  s   rX   c                   @   s   e Zd ZedejZedejZdZedejZ	edejZ
dZedZdZed	Zd
ZedZdd Zdd Zdd Zdd Zdd ZdS )r   z(?:lp:?\s+\#\d+(?:,\s*\#\d+)*)z(?P<linktext>#(?P<bugnum>\d+))z@<a href="https://launchpad.net/bugs/\g<bugnum>">\g<linktext></a>zE(?:closes:\s*(?:bug)?\#?\s?\d+(?:,\s*(?:bug)?\#?\s?\d+)*|(?<!">)#\d+)z(?P<linktext>#?(?P<bugnum>\d+))z=<a href="https://bugs.debian.org/\g<bugnum>">\g<linktext></a>z#\bC(VE|AN)-(19|20|21)\d\d-\d{4,7}\bzH<a href="https://cve.mitre.org/cgi-bin/cvename.cgi?name=\g<0>">\g<0></a>zs([a-zA-Z0-9_\+\-\.]+)@(([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)z <a href="mailto:\g<0>">\g<0></a>zf(ht|f)tps?\://[a-zA-Z0-9\-\.]+\.[a-zA-Z]{2,3}(:[a-zA-Z0-9]*)?/?([a-zA-Z0-9\-\._\?\,\'/\\\+&;%\$#\=~])*c                 C   s   |  | | |S rf   )rs   rn   )ri   rq   rE   r   r   r   r    U  s    
zhtml.convert_to_htmlc                 C   s   | dd dd ddS )N&z&amp;<z&lt;>z&gt;)replacerm   r   r   r   _html_encodeY  s    zhtml._html_encodec                    sd     |} j fdd|} j fdd|} j j|} j j|}|| d S )Nc                    s    j  j| dS Nr   )	lp_bug_resub
lp_bug_fmtgroupmrw   r   r   <lambda>^  r8   z#html._render_text.<locals>.<lambda>c                    s    j  j| dS r   )bug_rer  bug_fmtr  r  rw   r   r   r  _  r8   )	r   lp_bug_stanza_rer  bug_stanza_recve_recve_fmtemail_re	email_fmtr~   )ri   htmltextrE   r   rw   r   _render_text\  s    
zhtml._render_textc                 C   s   d}| j |D ]d}| ||||   | }| }|d dv r\|d d }|d8 }|d|| |f  q| |||d   d S )Nr   r   ).,;?'r   z<a href="%s">%s</a>)url_refinditerr  startendr  r~   r   )ri   r  r   ZprevposmatchZurlr   r   r   _render_lined  s    zhtml._render_linec                 C   s`   t  }|d || j |d |dD ]}| || |d q2|d | S )Nzs<html>
        <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
        <title>z6</title>
        </head>

        <body>
        <pre>r1   z</pre></body></html>)ioStringIOr~   rq   r   r  getvalue)ri   rE   r  r   r   r   r   rn   p  s    


zhtml._renderN)r.   r/   r0   r   compileIr
  r  r  r  r  r	  r  r  r  r  r  r    r   r  r  rn   r   r   r   r   r   D  s    


r   c                       s$   e Zd Z fddZdd Z  ZS )rW   c                    s6   t  j|  t| jdd| _d| _t	 | _
d S )NrK   zsensible-browserz.html)rg   rh   r   r   r   r   r   r   r   Zutf8_encodingr   rr   rk   r   r   rh     s    zbrowser_frd.__init__c                 C   s   dS r|   r   rw   r   r   r   r{     s    zbrowser_frd.needs_tty_stdin)r.   r/   r0   rh   r{   ro   r   r   rk   r   rW     s   rW   c                   @   s   e Zd ZdS )rY   Nr-   r   r   r   r   rY     s   rY   )N).r   r(   r   r   r$   r   Zemail.messager   Zemail.headerZemail.charsetr  r   r   r   r   r   r   r
   r   r'   r+   r   r,   rD   rd   objectre   rp   r   rS   r?   r   rT   r   rQ   rU   rV   r   r   r   r   rR   rX   r   rW   rY   r   r   r   r   <module>   sT   
P	)E[A