+
    i                         R t ^ RIt^ RIt^ RIt^ RIt^ RIt^ RIHt ^ RIH	t	H
t
 ^ RIHt ]P                  ! ]4      tRt ! R R4      tR# )z0gpg.py - Collection of gpg key related functionsN)TemporaryDirectory)DictOptional)subp	GNUPGHOMEc                      a  ] tR t^t o R tR t]V 3R lR l4       tR tV 3R lR lt	V 3R lR	 lt
V 3R
 lR ltRV 3R lR lltRV 3R lR lltV 3R lR ltRV 3R lR lltV 3R lR ltRtV tR# )GPGc                @    R V n         / V n        \        4       V n        R# )FN)gpg_started_envr   temp_dirselfs   &//usr/lib/python3/dist-packages/cloudinit/gpg.py__init__GPG.__init__   s     	*,    c                    V # N r   s   &r   	__enter__GPG.__enter__   s    r   c                6   < V ^8  d   QhRS[ S[S[3,          /# )   return)r   str)format__classdict__s   "r   __annotate__GPG.__annotate__#   s      T#s(^ r   c                    V P                   '       d   V P                   # RV n        \        V P                  P                  /V n         V P                   # )zwhen 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   envGPG.env"   s?     999994==--.	yyr   c                &    V P                  4        R # r   )cleanup)r   exc_typ	exc_value	tracebacks   &&&&r   __exit__GPG.__exit__1   s    r   c                   < V ^8  d   QhRR/# r   r   Nr   )r   r   s   "r   r   r   4   s     $ $ $r   c                    V P                  4        V P                  '       dX   \        P                  P	                  V P                  P
                  4      '       d   V P                  P                  4        R# R# R# )z0cleanup the gpg temporary directory and kill gpgN)kill_gpgr   ospathisdirr"   r&   r   s   &r   r&   GPG.cleanup4   sG    ===RWW]]4==+=+=>>MM!!# ?=r   c                6   < V ^8  d   QhRS[ RS[S[ ,          /# r   keyr   r   r   )r   r   s   "r   r   r   :   s       # r   c                     \         P                   ! RRRV.RV P                  R7      P                  #   \         P                   d"   p\        P                  RY4        Rp?R# Rp?ii ; i)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   r6   errors   && r   export_armourGPG.export_armour:   se    	L99
J488 f	
 )) 	LII>KK	Ls   03 A)A$$A)c                &   < V ^8  d   QhRS[ RS[ /# r5   r   )r   r   s   "r   r   r   G   s      3 3 r   c                b    \         P                   ! RR.VRV P                  R7      P                  # )zvDearmor gpg key, dearmored key gets returned

note: man gpg(1) makes no mention of an --armour spelling, only --armor
r9   z	--dearmorF)datadecoder<   )r   r#   r>   )r   r6   s   &&r   dearmorGPG.dearmorG   s,    
 yyK s5TXX

&	r   c                &   < V ^8  d   QhRS[ RS[ /# )r   key_filer   rG   )r   r   s   "r   r   r   P   s      # c r   c                    . ROpV'       g   VP                  R4       VP                  V4       \        P                  ! W0P                  RR7      w  rEV'       d   \        P	                  RW4       V# )zList 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
z--with-colonsT)r<   r;   r=   )r9   z--no-optionsz--with-fingerprintz--no-default-keyringz--list-keysz	--keyring)appendr   r#   r@   warning)r   rN   human_outputcmdr>   stderrs   &&&   r   	list_keysGPG.list_keysP   sW    
 JJ'

8388TJKK8( r   c                *   < V ^8  d   QhRS[ RS[ RR/# )r   r6   	keyserverr   NrG   )r   r   s   "r   r   r   j   s"     5 5C 5C 5D 5r   c                *   \         P                  RW4       ^ pRp\        T;'       g    . 4      p V^,          p \        P                  ! RRRV,          RV.RV P                  R7       \         P                  R	VVV4       R#   \        P
                   d   pTp Rp?MRp?ii ; i \        T4      p\         P                  R
TP                  T4       \        P                  ! T4       K    \         d   p\        RYYE3,          4      ThRp?ii ; i)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'NTr9   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)r@   rA   iterr   r#   r?   next	exit_codetimesleepStopIteration
ValueError)	r   r6   rX   retriestrynumrC   sleepsenaplens	   &&&&     r   recv_keyGPG.recv_keyj   s    			:CKgmm$aKF		"(94% !#xx
 		E	 -- f		LOO
 

6"   ),/F+JK s1   AB B%B  B%)AC- -D8DDc                $   < V ^8  d   QhRS[ RR/# )r   r6   r   NrG   )r   r   s   "r   r   r      s     	B 	Bc 	Bd 	Br   c                     \         P                   ! RRRRV.RV P                  R7       R#   \         P                   d"   p\        P	                  RY4        Rp?R# Rp?ii ; i)	z0Delete the specified key from the local gpg ringr9   z--batchz--yesz--delete-keysTr:   zFailed delete key "%s": %sN)r   r#   r?   r@   rQ   rB   s   && r   
delete_keyGPG.delete_key   sX    	BII	7OSA88
 )) 	BKK4cAA	Bs   (, A"AA"c                <   < V ^8  d   QhRS[ RS[ RS[S[ ,          /# )r   keyidrX   r   r7   )r   r   s   "r   r   r      s)      %(	#r   c                    V P                  V4      pV'       g9    V P                  WR7       V P                  V4      p T P                  T4       T# V#   \         d    \        P	                  RT4       h i ; i  T P                  T4       i ; i)zget gpg keyid from keyserver)rX   zFailed to obtain gpg key %s)rD   rf   r`   r@   	exceptionrj   )r   rm   rX   armours   &&& r   
getkeybyidGPG.getkeybyid   s     ##E*	'e9++E2 &v  ;UC &s   #A #A77A: :Bc                   < V ^8  d   QhRR/# r-   r   )r   r   s   "r   r   r      s     .A .A$ .Ar   c                    V P                   '       g   R# \        P                  ! R4      '       d2   \        P                  ! . R
ORV P                  R7      P                  pR# \        P                  ! . ROR^ ^.R7      P                  p\
        P                  ! RV4      pV Uu. uF$  q3^ ,          R8X  g   K  \        V^,          4      NK&  	  ppV'       d   \        P                  RV4       V F(  p\        P                  ! V\        P                  4       K*  	  R# u upi   \        P                   d"   p\        P                  R	T4        Rp?R# Rp?ii ; i)zkilling 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gpgconfTr:   )r;   rcsz(?P<ppid>\d+)\s+(?P<pid>\d+)1z&Killing gpg-agent and dirmngr pids: %sz"Failed to clean up gpg process: %s)ru   z--killall)	psz-ozppid,pid-Ckeyboxdrz   dirmngrrz   z	gpg-agent)r
   r   whichr#   r>   refindallintr@   rA   r0   killsignalSIGKILLr?   rQ   )r   gpg_process_outgpg_pidspidroot_gpg_pidsgpg_pidrd   s   &      r   r/   GPG.kill_gpg   s    &	A###zz)$$"&))0 #xx# &	   #'))
 !A# &   ::3_ ,4!+3C1v}KCAK8  ! !II@-  -GGGGV^^4  -! )) 	AKK<a@@	AsA   D$ D$ /D$ #AD$ %D9DAD$ D$ $E9EE)r   r
   r   N)F))   r   )zkeyserver.ubuntu.com)__name__
__module____qualname____firstlineno__r   r   propertyr#   r*   r&   rD   rK   rU   rf   rj   rq   r/   __static_attributes____classdictcell__)r   s   @r   r   r      s}     -
  $ $   45 5n	B 	B $.A .Ar   r   )__doc__loggingr0   r~   r   r]   tempfiler   typingr   r   	cloudinitr   	getLoggerr   r@   r!   r   r   r   r   <module>r      sE    7  	 	   ' ! !SA SAr   