Ë
    x[hú  ã                   ó”   — d 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dlm	Z	m
Z
 ddlmZ  ej                  e«      ZdZ G d„ d«      Zy)	z0gpg.py - Collection of gpg key related functionsé    N)ÚTemporaryDirectory)ÚDictÚOptional)ÚsubpÚ	GNUPGHOMEc                   óÊ   — e Zd Zd„ Zd„ Zedeeef   fd„«       Zd„ Z	dd„Z
dedee   fd	„Zdedefd
„Zddedefd„Zddededdfd„Zdeddfd„Z	 ddededee   fd„Zdd„Zy)ÚGPGc                 ó>   — d| _         i | _        t        «       | _        y )NF)Úgpg_startedÚ_envr   Útemp_dir©Úselfs    ú//usr/lib/python3/dist-packages/cloudinit/gpg.pyÚ__init__zGPG.__init__   s   € Ø ˆÔØˆŒ	Ü*Ó,ˆ�ó    c                 ó   — | S ©N© r   s    r   Ú	__enter__zGPG.__enter__   s   € Øˆr   Úreturnc                 óš   — | j                   r| j                   S d| _        t        | j                  j                  i| _         | j                   S )a  when this env property gets invoked, set up our temporary
        directory, and also set gpg_started to tell the cleanup()
        method whether or not

        why put this here and not in __init__? pytest seems unhappy
        and it's not obvious how to work around it
        T)r   r   ÚHOMEr   Únamer   s    r   ÚenvzGPG.env"   s=   € ð �9Š9Ø—9‘9ÐØˆÔÜ˜4Ÿ=™=×-Ñ-Ð.ˆŒ	Ø�y‰yÐr   c                 ó$   — | j                  «        y r   )Úcleanup)r   Úexc_typÚ	exc_valueÚ	tracebacks       r   Ú__exit__zGPG.__exit__1   s   € Ø�‰�r   Nc                 óÚ   — | j                  «        | j                  rOt        j                  j	                  | j                  j
                  «      r| j                  j                  «        yyy)z0cleanup the gpg temporary directory and kill gpgN)Úkill_gpgr   ÚosÚpathÚisdirr   r   r   s    r   r   zGPG.cleanup4   sB   € à�‰ŒØ�=Š=œRŸW™WŸ]™]¨4¯=©=×+=Ñ+=Ô>Ø�M‰M×!Ñ!Õ#ð ?ˆ=r   Úkeyc                 óÒ   — 	 t        j                   ddd|gd| j                  ¬«      j                  S # t         j                  $ r!}t        j                  d||«       Y d}~yd}~ww xY w)z*Export gpg key, armoured key gets returnedÚgpgz--exportz--armourT©ÚcaptureÚ
update_envú&Failed to export armoured key "%s": %sN)r   r   ÚstdoutÚProcessExecutionErrorÚLOGÚdebug©r   r'   Úerrors      r   Úexport_armourzGPG.export_armour:   sg   € ð	LÜ—9‘9Ø˜
 J°Ð4ØØŸ8™8ô÷ ‰fð	øô
 ×)Ñ)ò 	Lä�I‰IÐ>ÀÀU×KÐKØûð	Lús   ‚/2 ²A&ÁA!Á!A&c                 ó`   — t        j                   ddg|d| j                  ¬«      j                  S )z†Dearmor gpg key, dearmored key gets returned

        note: man gpg(1) makes no mention of an --armour spelling, only --armor
        r)   z	--dearmorF)ÚdataÚdecoder,   )r   r   r.   )r   r'   s     r   ÚdearmorzGPG.dearmorG   s,   € ô
 �y‰yØ�KÐ  s°5ÀTÇXÁXô
ç
‰&ð	r   Úkey_filec                 óÒ   — g d¢}|s|j                  d«       |j                  |«       t        j                  || j                  d¬«      \  }}|rt        j	                  d||«       |S )zòList keys from a keyring with fingerprints. Default to a
        stable machine parseable format.

        @param key_file: a string containing a filepath to a key
        @param human_output: return output intended for human parsing
        )r)   z--no-optionsz--with-fingerprintz--no-default-keyringz--list-keysz	--keyringz--with-colonsT)r,   r+   r-   )Úappendr   r   r0   Úwarning)r   r9   Úhuman_outputÚcmdr.   Ústderrs         r   Ú	list_keyszGPG.list_keysP   s]   € ò
ˆñ Ø�J‰J�Ô'à�
‰
�8ÔÜŸ™ 3°4·8±8ÀTÔJ‰ˆ�ÙÜ�K‰KØ8¸(ÀFôð ˆr   Ú	keyserverc                 óþ  — t         j                  d||«       d}d}t        |xs g «      }	 |dz  }	 t        j                  ddd|z  d	|gd| j                  ¬
«       t         j                  d|||«       y# t        j
                  $ r}|}Y d}~nd}~ww xY w	 t        |«      }t         j                  d|j                  |«       t        j                  |«       n$# t        $ r}t        d||||fz  «      |‚d}~ww xY wŒÓ)aÙ  Receive gpg key from the specified keyserver.

        Retries are done by default because keyservers can be unreliable.
        Additionally, there is no way to determine the difference between
        a non-existent key and a failure.  In both cases gpg (at least 2.2.4)
        exits with status 2 and stderr: "keyserver receive failed: No data"
        It is assumed that a key provided to cloud-init exists on the keyserver
        so re-trying makes better sense than failing.

        @param key: a string key fingerprint (as passed to gpg --recv-keys).
        @param keyserver: the keyserver to request keys from.
        @param retries: an iterable of sleep lengths for retries.
        Use None to indicate no retries.z&Importing key '%s' from keyserver '%s'r   NTé   r)   z--no-ttyz--keyserver=%sz--recv-keysr*   z/Imported key '%s' from keyserver '%s' on try %dz6Import failed with exit code %d, will try again in %ssz@Failed to import key '%s' from keyserver '%s' after %d tries: %s)r0   r1   Úiterr   r   r/   ÚnextÚ	exit_codeÚtimeÚsleepÚStopIterationÚ
ValueError)	r   r'   rA   ÚretriesÚtrynumr3   ÚsleepsÚeÚnaplens	            r   Úrecv_keyzGPG.recv_keyj   s  € ô 	�	‰	Ð:¸CÀÔKØˆØˆÜ�g’m Ó$ˆØØ�a‰KˆFðÜ—	‘	àØ"Ø(¨9Ñ4Ø%Øðð !Ø#Ÿx™xõ
ô —	‘	ØEØØØô	ð øÜ×-Ñ-ò Ø•ûðúðÜ˜f›�Ü—	‘	ØLØ—O‘OØôô
 —
‘
˜6Õ"øÜ ò Ü ð)Ø,/°¸FÀEÐ+JñKóð ðûðúð? s1   ²AA5 Á5BÂBÂBÂAC Ã	C;Ã#C6Ã6C;c                 óÂ   — 	 t        j                   dddd|gd| j                  ¬«       y# t         j                  $ r!}t        j	                  d||«       Y d}~yd}~ww xY w)	z0Delete the specified key from the local gpg ringr)   z--batchz--yesz--delete-keysTr*   zFailed delete key "%s": %sN)r   r   r/   r0   r<   r2   s      r   Ú
delete_keyzGPG.delete_key¡   sZ   € ð	BÜ�I‰IØ˜	 7¨O¸SÐAØØŸ8™8öøô
 ×)Ñ)ò 	BÜ�K‰KÐ4°c¸5×AÑAûð	Bús   ‚'* ªA½AÁAÚkeyidc                 ó  — | j                  |«      }|s9	 | j                  ||¬«       | j                  |«      }	 | j                  |«       |S |S # t        $ r t        j	                  d|«       ‚ w xY w# | j                  |«       w xY w)zget gpg keyid from keyserver)rA   zFailed to obtain gpg key %s)r4   rP   rJ   r0   Ú	exceptionrR   )r   rS   rA   Úarmours       r   Ú
getkeybyidzGPG.getkeybyid¬   s…   € ð ×#Ñ# EÓ*ˆÙð	'Ø—‘˜e¨y�Ô9Ø×+Ñ+¨EÓ2‘ð —‘ Ô&Øˆˆvˆøô ò Ü—‘Ð;¸UÔCØðûð —‘ Õ&ús   •$A Á!A0Á0A3 Á3Bc                 ód  — 	 | j                   syt        j                  d«      r/t        j                  g d¢d| j                  ¬«      j                  }yt        j                  g d¢dddg¬	«      j                  }t        j                  d
|«      }|D �cg c]  }|d   dk(  sŒt        |d   «      ‘Œ }}|rt        j                  d|«       |D ]&  }t        j                  |t        j                  «       Œ( yc c}w # t        j                  $ r }t        j                  d|«       Y d}~yd}~ww xY w)a  killing with gpgconf is best practice, but when it isn't available
        failover is possible

        GH: 4344 - stop gpg-agent/dirmgr daemons spawned by gpg
        key imports. Daemons spawned by cloud-config.service on systemd
        v253 report (running)
        NÚgpgconf)rY   z--killÚallTr*   )	Úpsz-ozppid,pidú-CÚkeyboxdr\   Údirmngrr\   z	gpg-agentr   rC   )r+   Úrcsz(?P<ppid>\d+)\s+(?P<pid>\d+)Ú1z&Killing gpg-agent and dirmngr pids: %sz"Failed to clean up gpg process: %s)r   r   Úwhichr   r.   ÚreÚfindallÚintr0   r1   r$   ÚkillÚsignalÚSIGKILLr/   r<   )r   Úgpg_process_outÚgpg_pidsÚpidÚroot_gpg_pidsÚgpg_pidrN   s          r   r#   zGPG.kill_gpg¾   s  € ð&	AØ×#Ò#ØÜ�z‰z˜)Ô$Ü"&§)¡)Ú0Ø Ø#Ÿx™xô#÷ ‘&ñ	  ô #'§)¡)ò
ð !Ø˜A˜ô#÷ ‘&ð  ô Ÿ:™:Ø3°_ó�ð ,4ö!Ø$'°s¸1±vÀ³}”C˜˜A™•Kð!�ð !ñ !Ü—I‘IØ@À-ôð  -ò 5�GÜ—G‘G˜G¤V§^¡^Õ4ñ5ùò!øô ×)Ñ)ò 	AÜ�K‰KÐ<¸a×@Ñ@ûð	Aús=   ‚C< �AC< ÁA C< ÂC7Â!C7Â1AC< Ã7C< Ã<D/ÄD*Ä*D/)r   N)F))rC   rC   )zkeyserver.ubuntu.com)Ú__name__Ú
__module__Ú__qualname__r   r   Úpropertyr   Ústrr   r!   r   r   r4   r8   r@   rP   rR   rW   r#   r   r   r   r	   r	      sÔ   „ ò-ò
ð ð�T˜#˜s˜(‘^ò ó ðòó$ð ð ¨°#©ó ð˜3ð  3ó ñ #ð ¸có ñ45˜Cð 5¨Cð 5ÀDó 5ðn	B˜cð 	B dó 	Bð ,BñØðØ%(ðà	�#‰óô$.Ar   r	   )Ú__doc__Úloggingr$   rb   rf   rG   Útempfiler   Útypingr   r   Ú	cloudinitr   Ú	getLoggerrm   r0   r   r	   r   r   r   ú<module>rx      sG   ðñ 7ã Û 	Û 	Û Û Ý 'ß !å à€g×Ñ˜Ó!€à€÷SAò SAr   