+
    i/Z                        ^ RI t ^ RIt^ RIt^ RIHt ^ RIHtHtHt ^ RI	H
t
HtHt ] P                  ! ]4      tRtR$t^tR]! ]4      ,           R,           t ! R R	4      t ! R
 R4      tR tR tR tR tR tR t]3R ltR%R lt ! R R4      tR R lt R R lt!R t"R R lt#R t$]3R lt%R t&]3R  R! llt'R" t(R# t)R# )&    N)suppress)ListSequenceTuple)	lifecyclesubputilz/etc/ssh/sshd_configzno-port-forwarding,no-agent-forwarding,no-X11-forwarding,command="echo 'Please login as the user \"$USER\" rather than the user \"$DISABLE_USER\".';echo;sleep 10;exit "c                   6   a  ] tR t^Dt o RR ltR tR tRtV tR# )AuthKeyLineNc                B    W0n         W@n        WPn        W n        Wn        R # N)base64commentoptionskeytypesource)selfr   r   r   r   r   s   &&&&&&4/usr/lib/python3/dist-packages/cloudinit/ssh_util.py__init__AuthKeyLine.__init__E   s         c                B    V P                   ;'       d    V P                  # r   )r   r   r   s   &r   validAuthKeyLine.validN   s    {{++t||+r   c                   . pV P                   '       d   VP                  V P                   4       V P                  '       d   VP                  V P                  4       V P                  '       d   VP                  V P                  4       V P                  '       d   VP                  V P                  4       V'       g   V P
                  # R P                  V4      # ) )r   appendr   r   r   r   join)r   tokss   & r   __str__AuthKeyLine.__str__Q   s    <<<KK%<<<KK%;;;KK$<<<KK%;;88D>!r   )r   r   r   r   r   )NNNN)	__name__
__module____qualname____firstlineno__r   r   r"   __static_attributes____classdictcell____classdict__s   @r   r   r   D   s     ," "r   r   c                   4   a  ] tR t^at o RtR tRR ltRtV tR# )AuthKeyLineParsera9  
AUTHORIZED_KEYS FILE FORMAT
 AuthorizedKeysFile specifies the file containing public keys for public
 key authentication; if none is specified, the default is
 ~/.ssh/authorized_keys.  Each line of the file contains one key (empty
 (because of the size of the public key encoding) up to a limit of 8 kilo-
 bytes, which permits DSA keys up to 8 kilobits and RSA keys up to 16
 kilobits.  You don't want to type them in; instead, copy the
 identity.pub or the id_rsa.pub file and edit it.

 sshd enforces a minimum RSA key modulus size for protocol 1 and protocol
 2 keys of 768 bits.

 The options (if present) consist of comma-separated option specifica-
 tions.  No spaces are permitted, except within double quotes.  The fol-
 lowing option specifications are supported (note that option keywords are
 case-insensitive):
c                Z   Rp^ pV\        V4      8  d   V'       g   W,          R9  dj   W,          pV^,           \        V4      8  d   V^,           pM@W^,           ,          pVR8X  d   VR8X  d   V^,           pMVR8X  d   V'       * pV^,           pK  V^ V pWR P                  4       pWg3# )z
The options (if present) consist of comma-separated option specifica-
 tions.  No spaces are permitted, except within double quotes.
 Note that option keywords are case-insensitive.
F\r
   N)r   	)lenlstrip)r   entquotedicurcnextcr   remains   &&      r   _extract_options"AuthKeyLineParser._extract_optionsu   s     #c(lSV;-F6D1uC EAJEt|E#AAa( R!  r   Nc                   VP                  R 4      pVP                  R4      '       g   VP                  4       R8X  d   \        V4      # R pVP                  4       p V! V4      w  rgp\        TTTTTR7      #   \         dK    T P                  T4      w  rT'       g   T	p T! T
4      w  rgp LF  \         d    \        T4      u u # i ; ii ; i)z
# c                    V P                  R ^4      p\        V4      ^8  d   \        R\        V4      ,          4      hV^ ,          \        9  d   \        RV^ ,          ,          4      h\        V4      ^8X  d   VP	                  R4       V# )NzToo few fields: %szInvalid keytype %sr=   )splitr1   	TypeErrorVALID_KEY_TYPESr   )r3   r!   s   & r   parse_ssh_key.AuthKeyLineParser.parse.<locals>.parse_ssh_key   sp    99T1%D4y1} 4s4y @AAAwo- 4tAw >?? 4yA~BKr   )r   r   r   r   )rstrip
startswithstripr   r@   r9   )r   src_liner   linerB   r3   r   r   r   keyoptsr8   s   &&&        r   parseAuthKeyLineParser.parse   s    v&??34::<2#5x((	 jjl	-)6s);&Wg 
 	
  
	- $ 5 5c :W !--:6-B*' -"8,,-
	-s*   A8 8(C!B..C	CC		C r   )	r$   r%   r&   r'   __doc__r9   rJ   r(   r)   r*   s   @r   r-   r-   a   s     &!4*
 *
r   r-   c                    . p\        4       p. pV  Fx  p \        P                  P                  V4      '       dP   \        P
                  ! V4      P                  4       pV F#  pVP                  VP                  V4      4       K%  	  Kx  Kz  	  V#   \        \        3 d!    \        P                  ! \        R T4        K  i ; i)zError reading lines from %s)r-   ospathisfiler	   load_text_file
splitlinesr   rJ   IOErrorOSErrorlogexcLOG)fnameslinesparsercontentsfnamerH   s   &     r   parse_authorized_keysr]      s    E FH	Cww~~e$$++E2==?!DOOFLL$67 " %  O ! 	CKK:EB	Cs   A2B-C ?C c                 &   \        V Uu. uF  q"P                  4       '       g   K  VNK  	  up4      p\        \        V 4      4       Fh  pW,          pVP                  4       '       g   K#  V F;  pVP                  VP                  8X  g   K   TpW#9   g   K*  VP                  V4       K=  	  WPV&   Kj  	  V F  pV P                  V4       K  	  V  Uu. uF  p\        V4      NK  	  ppVP                  R 4       RP                  V4      # u upi u upi )r=   
)	listr   ranger1   r   remover   strr    )	old_entrieskeyskto_addr5   r3   keybrY   s	   &&       r   update_authorized_keysrj      s    d0dggi11d01F3{#$nyy{{Axx3::%;MM!$  A % 3  ))[SV[E) 
LL99U1 1( *s   D	D	Dc                     \         P                  ! V 4      pV'       d   VP                  '       g   \        R V ,          4      h\        P
                  P                  VP                  R4      V3# )z"Unable to get SSH info for user %rz.ssh)pwdgetpwnampw_dirRuntimeErrorrO   rP   r    )usernamepw_ents   & r   users_ssh_inforr      sJ    \\(#F?8LMMGGLL/88r   c                 (   R V3RV3R3pV '       g   Rp V P                  4       p. pV Ff  pV F  w  rxVP                  Wx4      pK  	  VP                  R4      '       g    \        P                  P                  W4      pVP                  V4       Kh  	  V# )%h%u%h/.ssh/authorized_keys/)z%%%)r?   replacerE   rO   rP   r    r   )	valuehomedirrp   macrospathsrenderedrP   macrofields	   &&&      r   render_authorizedkeysfile_pathsr      s     Woh/=F)KKMEH"LE<<-D #s##77<<.D  Or   c                .   RpV'       d   Rp\         P                  ! V4      pV'       d)   W`8w  d#   VR8w  d   \        P                  RVVV V4       R# \         P                  ! V4      pW`8X  d   VR,          pME\         P
                  ! V4      p\         P                  ! V 4      p	W9   d   V^8,          pM	V^,          pWu,          ^ 8X  d   \        P                  RVVV 4       R# V'       d)   V^,          '       d   \        P                  RVV4       R# R	# )
a>  Check if the file/folder in @current_path has the right permissions.

We need to check that:
1. If StrictMode is enabled, the owner is either root or the user
2. the user can access the file/folder, otherwise ssh won't use it
3. If StrictMode is enabled, no write permission is given to group
   and world users (022)
i  i  rootzXPath %s in %s must be own by user %s or by root, but instead is own by %s. Ignoring key.F  zBPath %s in %s must be accessible by user %s, check its permissionszRPath %s in %s must not give writepermission to group or world users. Ignoring key.T)r	   	get_ownerrW   debugget_permissions	get_groupget_user_groups)
rp   current_path	full_pathis_filestrictmodesminimal_permissionsownerparent_permissiongroup_owneruser_groupss
   &&&&&     r   check_permissionsr     s     # NN<(Eu(Uf_		@	
 ,,\:u$nn\2**84%5(  5(.!3		%	
  )E11		@		
 r   c           	         \        V 4      ^,          p\        R4      ^,          p VP                  R4      ^R pRp\        P                  P	                  VP
                  4      pV EF  pVRV,           ,          p\        P                  P                  V4      '       d   \        P                  RV4        R# \        P                  P                  V4      '       d   \        P                  RV4        R# VP                  V4      '       g   WcP
                  8X  d   K  \        P                  P                  V4      '       g   \        P                  ! V4      ;_uu_ 4        Rp	VP                  p
VP                  pVP                  VP
                  4      '       d   Rp	VP                  p
VP                  p\        P                   ! WiR	R
7       \        P"                  ! WjV4       RRR4       \%        WVRV4      pV'       d   EK   R# 	  \        P                  P                  V4      '       g&   \        P                  P'                  V4      '       d   \        P                  RV4       R# \        P                  P                  V4      '       gF   \        P(                  ! VRRR	R7       \        P"                  ! WP                  VP                  4       \%        WVR	V4      pV'       g   R#  R	#   + '       g   i     EL; i  \*        \,        3 d0   p\        P.                  ! \        \1        T4      4        Rp?R# Rp?ii ; i)   r   rw   r=   z-Invalid directory. Symlink exists in path: %sFz*Invalid directory. File exists in path: %s  r   T)modeexist_okNz%s is not a file!  )r   ensure_dir_exists)rr   r?   rO   rP   dirnamern   islinkrW   r   rQ   rE   existsr	   SeLinuxGuardpw_uidpw_gidmakedirs	chownbyidr   isdir
write_filerT   rU   rV   rc   )rp   filenamer   
user_pwent
root_pwentdirectoriesparent_folderhome_folder	directoryr   uidgidpermissionses   &&&           r   check_create_pathr   I  sz   )!,J'*JGnnS)!B/  ggooj&7&78$IS9_,M ww~~m,,		C! ww~~m,,		@-  &&}55 $5$5577>>-00 &&}55 D$++C$++C$//
0A0ABB$(//(//KK4HNN=s; 6 ,5+K ;U %X 77>>(##rww}}X'>'>II)84 ww~~h'' OOHbuMNN8%6%6
8I8IJ'$
   K 655B W CQ st   BL	 9$L	 L	 7L	 6L	 L	 #BK5(L	 	L	 &L	 3$L	 L	 0$L	 AL	 5L 	L	 	M	$MM	c           
      F   \        V 4      w  r#\        P                  P                  VR 4      pTp. p\        P
                  ! VRR7      ;_uu_ 4         \        V4      pVP                  RR4      pVP                  RR4      p	\        WP                  V 4      pRRR4       \        XP!                  4       V4       Fd  w  r\#        R	V
9   R
V
9   VP%                  RP'                  VP                  4      4      .4      '       g   KI  \)        WX	R8H  4      pV'       g   Kb  Tp M	  WT8w  d   \        P+                  RV4       V\-        V.4      3#   \        \        3 d0    YF^ &   \        P                  ! \        R\        T^ ,          4        Li ; i  + '       g   i     L; i)authorized_keysT	recursiveauthorizedkeysfilerv   r   yeszhFailed extracting 'AuthorizedKeysFile' in SSH config from %r, using 'AuthorizedKeysFile' file %r insteadNru   rt   z{}/zAAuthorizedKeysFile has an user-specific authorized_keys, using %s)rr   rO   rP   r    r	   r   parse_ssh_config_mapgetr   rn   rT   rU   rV   rW   DEF_SSHD_CFGzipr?   anyrE   formatr   r   r]   )rp   sshd_cfg_filessh_dirrq   default_authorizedkeys_fileuser_authorizedkeys_fileauth_key_fnsssh_cfg	key_pathsr   key_pathauth_key_fnpermissions_oks   &&           r   extract_authorized_keysr     s   &x0W"$'',,w8I"J:L			7d	3	3	*=9G$&?I "++mU;K:==(L 
40 "%Y__%6!E  &&u||FMM'BC
 
 /{e';N ~+6( "F  >		$	
 	!789 G ! 
	9OKK Q
	 
4	3s+   FAE=F
FFFF 	c                    \        4       p. pV  F.  pVP                  VP                  \        V4      VR 7      4       K0  	  \	        V4      w  rg\
        P                  P                  V4      p\        P                  ! VRR7      ;_uu_ 4        \        Wt4      p	\        P                  ! WiRR7       RRR4       R#   + '       g   i     R# ; i))r   Tr   preserve_modeN)r-   r   rJ   rc   r   rO   rP   r   r	   r   rj   r   )
re   rp   r   rZ   key_entriesrf   r   auth_key_entriesr   contents
   &&&       r   setup_user_keysr     s     FK6<<A<@A  '>h&G#[ggook*G			7d	3	3()9GDA 
4	3	3	3s   $B;;C	c                   @   a  ] tR tRt o RR lt]R 4       tR tRtV t	R# )SshdConfigLinei  Nc                *    Wn         W n        W0n        R # r   )rH   _keyrz   )r   rH   rf   vs   &&&&r   r   SshdConfigLine.__init__  s    		
r   c                V    V P                   f   R # V P                   P                  4       # r   )r   lowerr   s   &r   rh   SshdConfigLine.key  s     99yy  r   c                    V P                   f   \        V P                  4      # \        V P                   4      pV P                  '       d$   VR\        V P                  4      ,           ,          pV# )Nr   )r   rc   rH   rz   )r   r   s   & r   r"   SshdConfigLine.__str__  sL    99tyy>!DIIAzzzS3tzz?**Hr   )r   rH   rz   )NN)
r$   r%   r&   r'   r   propertyrh   r"   r(   r)   r*   s   @r   r   r     s(     
 ! ! r   r   c                :    V ^8  d   QhR\         \        ,          /#    returnr   r   )r   s   "r   __annotate__r     s     K KtN3 Kr   c                     \         P                  P                  V 4      '       g   . # \        \        P
                  ! V 4      P                  4       4      # r   )rO   rP   rQ   parse_ssh_config_linesr	   rR   rS   r\   s   &r   parse_ssh_configr     s9    77>>%  	!$"5"5e"<"G"G"IJJr   c                :    V ^8  d   QhR\         \        ,          /# r   r   )r   s   "r   r   r     s      T.%9 r   c                    . pV  F~  pVP                  4       pV'       d   VP                  R 4      '       d   VP                  \        V4      4       KN   VP	                  R^4      w  r4TP                  \        Y#T4      4       K  	  V#   \
         dB     TP	                  R^4      w  r4 LC  \
         d    \        P                  RT4         K  i ; ii ; i)r<   N=z;sshd_config: option "%s" has no key/value pair, skipping it)rF   rE   r   r   r?   
ValueErrorrW   r   )rY   retrH   rh   vals   &    r   r   r     s    
 !#Czz|ts++JJ~d+,	zz$*HC 	

>$S12# $ J  		::c1-S 		#
 		s*   B		CB++!CCCCc                     \        V 4      pV'       g   / # / pV F/  pVP                  '       g   K  VP                  W#P                  &   K1  	  V# r   )r   rh   rz   )r\   rY   r   rH   s   &   r   r   r     sE    U#E	
Cxxx

HH  Jr   c                0    V ^8  d   QhR\         R\        /# )r   r\   r   )rc   bool)r   s   "r   r   r   $  s     
 
3 
4 
r   c                    \         P                  P                  V 4      '       g+   \         P                  P                  V  R 24      '       d   R# \         P                  P                  V 4      '       g   R# \        P
                  ! V 4      P                  4        F!  pVP                  RV  R24      '       g   K    R# 	  R# ).dTFzInclude z	.d/*.conf)rO   rP   r   rQ   r	   rR   rS   rE   )r\   rH   s   & r   _includes_dconfr   $  s     77>>%  RWW^^ugRL%A%A77>>%  ##E*557??XeWI677 8 r   c                 l   \        V 4      '       d   \        P                  P                  V  R 24      '       g   \        P
                  ! V  R 2RR7       \        P                  P                  V  R 2R4      p \        P                  P                  V 4      '       g   \        P                  ! V R4       V # )r   r   )r   z50-cloud-init.confr   )	r   rO   rP   r   r	   
ensure_dirr    rQ   ensure_filer   s   &r   "_ensure_cloud_init_ssh_config_filer   1  s}    uww}}wb\**OOugRLu5wb\+?@ww~~e$$UE*Lr   c                   \        V4      p\        V4      p\        W R7      pV'       dI   \        P                  ! TRP                  V Uu. uF  p\        V4      NK  	  up4      R,           RR7       \        V4      ^ 8g  # u upi )zRead fname, and update if changes are necessary.

@param updates: dictionary of desired values {Option: value}
@return: boolean indicating if an update was done.)rY   updatesr_   Tr   )r   r   update_ssh_config_linesr	   r   r    rc   r1   )r   r\   rY   changedrH   s   &&   r   update_ssh_configr   <  sq    
 /u5EU#E%ECGIIU3UTs4yU34t;	

 w<1 4s   Bc                <   \        4       p. p\        VP                  4        Uu. uF  qDP                  4       V3NK  	  up4      p\	        V ^R7       F  w  rgVP
                  '       g   K  VP
                  V9   g   K,  WWP
                  ,          pW,          p	VP                  V4       VP                  V	8X  d   \        P                  RWhV	4       K  VP                  V4       \        P                  RVVVP                  V	4       Wn        K  	  \        V4      \        V4      8w  dn   VP                  4        FY  w  rW9   d   K  VP                  V4       V P                  \        RW4      4       \        P                  R\        V 4      W4       K[  	  V# u upi )zUpdate the SSH config lines per updates.

@param lines: array of SshdConfigLine.  This array is updated in place.
@param updates: dictionary of desired values {Option: value}
@return: A list of keys in updates that were changed.)startz$line %d: option %s already set to %sz#line %d: option %s updated %s -> %sr=   z line %d: option %s added with %s)setdictre   r   	enumeraterh   addrz   rW   r   r   r1   itemsr   )
rY   r   foundr   rf   casemapr5   rH   rh   rz   s
   &&        r   r   r   M  sD    EEG GLLN;NqWWYNN;<GU!,xxx88w((#CLEIIcNzzU"		:AE s#		9JJ #
) -, 5zS\!!--/JC|NN3LLC78II2CJ * NC <s   Fc                \    V ^8  d   QhR\         \        \        \        3,          ,          /# )r   rY   )r   r   rc   )r   s   "r   r   r   {  s      
 
XeCHo6 
r   c                     V '       g   R # \        V4      pR V  4       p\        P                  ! VRP                  V4      R,           RRR7       R # )Nc              3   4   "   T F  w  rV R V 2x  K  	  R# 5i)r   NrL   ).0rf   r   s   &  r   	<genexpr>$append_ssh_config.<locals>.<genexpr>  s     ,eda!AaSzes   r_   abT)omoder   )r   r	   r   r    )rY   r\   r   s   && r   append_ssh_configr  {  sB    .u5E,e,GOO		'T!	r   c                 `   Rp \        \        P                  4      ;_uu_ 4        \        P                  ! RR.^ ^.R7      w  rRRR4       RpV P                  R4       F9  pVP	                  V4      '       g   K  V\        V4      VP                  R4       u # 	  R#   + '       g   i     Lb; i)	zGet the full version of the OpenSSH sshd daemon on the system.

On an ubuntu system, this would look something like:
1.2p1 Ubuntu-1ubuntu0.1

If we can't find `sshd` or parse the version number, return None.
r=   sshdz-V)rcsNOpenSSH_r_   ,)r   r   ProcessExecutionErrorr?   rE   r1   find)err_prefixrH   s       r   get_opensshd_versionr    s     C	$,,	-	-FD>1v6 
.F		$??6""Fdiin55    
.	-s   BB-	c                 t   Rp \        4       pVf    \        P                  P                  V 4      # RV9   d   VRVP	                  R4       p MRV9   d   VRVP	                  R4       p MTp  \        P                  P                  V 4      p V #   \
        \        3 d    \        P                  RT 4        R# i ; i)zGet the upstream version of the OpenSSH sshd daemon on the system.

This will NOT include the portable number, so if the Ubuntu version looks
like `1.2p1 Ubuntu-1ubuntu0.1`, then this function would return
`1.2`
z9.0Npr   z Could not parse sshd version: %s)	r  r   Versionfrom_strr  r   r@   rW   warning)upstream_versionfull_versions     r   get_opensshd_upstream_versionr    s     ')L  ))*:;;
l'(@,*;*;C*@A		'(@,*;*;C*@A'J$,,556FG	" J68HIJs   + B 'B76B7)rsaecdsaed25519z(ecdsa-sha2-nistp256-cert-v01@openssh.comzecdsa-sha2-nistp256z(ecdsa-sha2-nistp384-cert-v01@openssh.comzecdsa-sha2-nistp384z(ecdsa-sha2-nistp521-cert-v01@openssh.comzecdsa-sha2-nistp521z+sk-ecdsa-sha2-nistp256-cert-v01@openssh.comz"sk-ecdsa-sha2-nistp256@openssh.comz#sk-ssh-ed25519-cert-v01@openssh.comzsk-ssh-ed25519@openssh.comz ssh-ed25519-cert-v01@openssh.comzssh-ed25519zssh-rsa-cert-v01@openssh.comzssh-rsazssh-xmss-cert-v01@openssh.comzssh-xmss@openssh.comr   )*loggingrO   rl   
contextlibr   typingr   r   r   	cloudinitr   r   r	   	getLoggerr$   rW   r   rA   _DISABLE_USER_SSH_EXITrc   DISABLE_USER_OPTSr   r-   r]   rj   rr   r   r   r   r   r   r   r   r   r   r   r   r   r   r  r  r  rL   r   r   <module>r*     s     	 
  ( ( + +! & ,   ()* -00 " ":X
 X
v 89*BJL^ 5A 6rB .K6	
 &2 "+\ ?K 
(Jr   