Ë
    x[hÛX  ã                   óŠ  — d dl Z d dlZd dlZd dlmZ d dlmZmZmZ d dl	m
Z
mZmZ  e j                  e«      ZdZdZdZd ee«      z   d	z   Z G d
„ d«      Z G d„ d«      Zd„ Zd„ Zd„ Zd„ Zd„ Zd„ Zefd„Zd%d„Z G d„ d«      Zdee   fd„Z dee   fd„Z!d„ Z"dede#fd„Z$d„ Z%efd„Z&d „ Z'efd!eeeef      fd"„Z(d#„ Z)d$„ Z*y)&é    N)Úsuppress)ÚListÚSequenceÚTuple)Ú	lifecycleÚsubpÚutilz/etc/ssh/sshd_config)Ú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.coméŽ   z§no-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                   ó"   — e Zd Z	 dd„Zd„ Zd„ Zy)ÚAuthKeyLineNc                 óJ   — || _         || _        || _        || _        || _        y ©N)Úbase64ÚcommentÚoptionsÚkeytypeÚsource)Úselfr   r   r   r   r   s         ú4/usr/lib/python3/dist-packages/cloudinit/ssh_util.pyÚ__init__zAuthKeyLine.__init__E   s'   € ð ˆŒØˆŒØˆŒØˆŒØˆ�ó    c                 ó6   — | j                   xr | j                  S r   )r   r   ©r   s    r   ÚvalidzAuthKeyLine.validN   s   € Ø�{‰{Ò+˜tŸ|™|Ð+r   c                 ó|  — g }| j                   r|j                  | j                   «       | j                  r|j                  | j                  «       | j                  r|j                  | j                  «       | j                  r|j                  | j                  «       |s| j
                  S dj                  |«      S ©Nú )r   Úappendr   r   r   r   Újoin)r   Útokss     r   Ú__str__zAuthKeyLine.__str__Q   s~   € ØˆØ�<Š<Ø�K‰K˜Ÿ™Ô%Ø�<Š<Ø�K‰K˜Ÿ™Ô%Ø�;Š;Ø�K‰K˜Ÿ™Ô$Ø�<Š<Ø�K‰K˜Ÿ™Ô%ÙØ—;‘;Ðà—8‘8˜D“>Ð!r   )NNNN)Ú__name__Ú
__module__Ú__qualname__r   r   r%   © r   r   r   r   D   s   „ àGKóò,ó"r   r   c                   ó   — e Zd ZdZd„ Zdd„Zy)ÚAuthKeyLineParserau  
    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                 ó$  — d}d}|t        |«      k  rc|s||   dvrZ||   }|dz   t        |«      k\  r|dz   }n>||dz      }|dk(  r|dk(  r|dz   }n|dk(  r| }|dz   }|t        |«      k  r|rŒR||   dvrŒZ|d| }||d j                  «       }||fS )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.
        Fr   )r!   ú	é   ú\r   N)ÚlenÚlstrip)r   ÚentÚquotedÚiÚcurcÚnextcr   Úremains           r   Ú_extract_optionsz"AuthKeyLineParser._extract_optionsu   sË   € ð ˆØˆØ”#�c“(Šl¡¨S°©V¸;Ñ-FØ�q‘6ˆDØ�1‰uœ˜C›Ò Ø˜‘E�ØØ˜˜A™‘JˆEØ�tŠ| ¨¢Ø˜‘E‘Ø˜’Ø#˜�Ø�A‘ˆAð ”#�c“(Šl¢¨S°©V¸;Ò-Fð �a˜�(ˆð �Q�R�—‘Ó!ˆØ˜Ð Ð r   Nc                 ó„  — |j                  d«      }|j                  d«      s|j                  «       dk(  rt        |«      S d„ }|j                  «       }	  ||«      \  }}}t        |||||¬«      S # t        $ rE | j                  |«      \  }	}
|€|	}	  ||
«      \  }}}n# t        $ r t        |«      cY cY S w xY wY Œ]w xY w)Nz
ú#Ú c                 óê   — | j                  d d«      }t        |«      dk  rt        dt        |«      z  «      ‚|d   t        vrt        d|d   z  «      ‚t        |«      dk(  r|j	                  d«       |S )Né   zTo few fields: %sr   zInvalid keytype %sr;   )Úsplitr0   Ú	TypeErrorÚVALID_KEY_TYPESr"   )r2   r$   s     r   Úparse_ssh_keyz.AuthKeyLineParser.parse.<locals>.parse_ssh_key•   sp   € à—9‘9˜T 1Ó%ˆDÜ�4‹y˜1Š}ÜÐ 3´c¸$³iÑ ?Ó@Ð@Ø�A‰wœoÑ-ÜÐ 4°t¸A±wÑ >Ó?Ð?ô �4‹y˜AŠ~à—‘˜B”àˆKr   )r   r   r   r   )ÚrstripÚ
startswithÚstripr   r?   r8   )r   Úsrc_liner   ÚlinerA   r2   r   r   r   Úkeyoptsr7   s              r   ÚparsezAuthKeyLineParser.parse�   sß   € à�‰˜vÓ&ˆØ�?‰?˜3Ô 4§:¡:£<°2Ò#5Ü˜xÓ(Ð(ò	ð �j‰j‹lˆð
	-Ù)6°sÓ);Ñ&ˆW�f˜gô ØØØØØô
ð 	
øô ò 	-Ø $× 5Ñ 5°cÓ :ÑˆW�fØˆØ!�ð-Ù-:¸6Ó-BÑ*�˜&¡'øÜò -Ü" 8Ó,Ô,ð-úñ #*ð	-ús6   ÁA1 Á1!B?ÂB ÂB?Â B9Â4B?Â8B9Â9B?Â>B?r   )r&   r'   r(   Ú__doc__r8   rH   r)   r   r   r+   r+   a   s   „ ñò&!ô4(
r   r+   c                 ód  — g }t        «       }g }| D ]l  }	 t        j                  j                  |«      rJt	        j
                  |«      j                  «       }|D ]"  }|j                  |j                  |«      «       Œ$ Œn |S # t        t        f$ r t	        j                  t        d|«       Y Œ�w xY w)NzError reading lines from %s)r+   ÚosÚpathÚisfiler	   Úload_text_fileÚ
splitlinesr"   rH   ÚIOErrorÚOSErrorÚlogexcÚLOG)ÚfnamesÚlinesÚparserÚcontentsÚfnamerF   s         r   Úparse_authorized_keysrY   º   s©   € Ø€EÜÓ €FØ€HØò Cˆð	CÜ�w‰w�~‰~˜eÔ$Ü×+Ñ+¨EÓ2×=Ñ=Ó?�Ø!ò 8�DØ—O‘O F§L¡L°Ó$6Õ7ð8øð	Cð €Oøô œÐ!ò 	CÜ�K‰KœÐ:¸EÖBð	Cús   •A)BÂ*B/Â.B/c                 óè  — t        |D �cg c]  }|j                  «       sŒ|‘Œ c}«      }t        t        | «      «      D ]V  }| |   }|j                  «       sŒ|D ]4  }|j                  |j                  k(  sŒ|}||v sŒ$|j                  |«       Œ6 || |<   ŒX |D ]  }| j                  |«       Œ | D �cg c]  }t        |«      ‘Œ }}|j                  d«       dj                  |«      S c c}w c c}w )Nr;   ú
)	Úlistr   Úranger0   r   Úremover"   Ústrr#   )	Úold_entriesÚkeysÚkÚto_addr4   r2   ÚkeyÚbrU   s	            r   Úupdate_authorized_keysrf   Ê   sî   € Ü˜dÖ0˜ a§g¡g¥i’1Ò0Ó1€FÜ”3�{Ó#Ó$ò ˆØ˜!‰nˆØ�y‰yŒ{Øàò 	%ˆAØ�x‰x˜3Ÿ:™:Ó%à�à˜’;Ø—M‘M !Õ$ð	%ð ˆ�AŠðð ò  ˆØ×Ñ˜3Õð ð )Ö)˜ŒS��VÐ)€EÐ)ð 
‡L�L�ÔØ�9‰9�UÓÐùò1 1ùò( *s   ŠC* C*Â4C/c                 ó¼   — t        j                  | «      }|r|j                  st        d| z  «      ‚t        j
                  j                  |j                  d«      |fS )Nz"Unable to get SSH info for user %rz.ssh)ÚpwdÚgetpwnamÚpw_dirÚRuntimeErrorrK   rL   r#   )ÚusernameÚpw_ents     r   Úusers_ssh_inforn   æ   sH   € Ü�\‰\˜(Ó#€FÙ˜ŸšÜÐ?À8ÑLÓMÐMÜ�G‰G�L‰L˜Ÿ™¨Ó/°Ð8Ð8r   c                 ó  — d|fd|fdf}| sd} | j                  «       }g }|D ]`  }|D ]  \  }}|j                  ||«      }Œ |j                  d«      s t        j                  j                  ||«      }|j                  |«       Œb |S )Nú%hú%u)z%%ú%ú%h/.ssh/authorized_keysú/)r>   ÚreplacerC   rK   rL   r#   r"   )	ÚvalueÚhomedirrl   ÚmacrosÚpathsÚrenderedrL   ÚmacroÚfields	            r   Úrender_authorizedkeysfile_pathsr}   í   s–   € ð �Wˆo  hÐ/°Ð=€FÙØ)ˆØ�K‰K‹M€EØ€HØò ˆØ"ò 	.‰LˆE�5Ø—<‘<  uÓ-‰Dð	.à�‰˜sÔ#Ü—7‘7—<‘< ¨Ó.ˆDØ�‰˜Õðð €Or   c                 ó¸  — d}|rd}t        j                  |«      }|r$|| k7  r|dk7  rt        j                  d||| |«       yt        j                  |«      }|| k(  r|dz  }n9t        j
                  |«      }t        j                  | «      }	||	v r|dz  }n|dz  }||z  d	k(  rt        j                  d
||| «       y|r|dz  rt        j                  d||«       yy)aV  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éÀ  é8   é   r   zBPath %s in %s must be accessible by user %s, check its permissionsé   zRPath %s in %s must not give writepermission to group or world users. Ignoring key.T)r	   Ú	get_ownerrS   ÚdebugÚget_permissionsÚ	get_groupÚget_user_groups)
rl   Úcurrent_pathÚ	full_pathÚis_fileÚstrictmodesÚminimal_permissionsÚownerÚparent_permissionÚgroup_ownerÚuser_groupss
             r   Úcheck_permissionsr’     s  € ð  ÐÙà#Ðô �N‰N˜<Ó(€EÙ�u Ò(¨U°fª_Ü�	‰	ð@àØØØô	
ð ä×,Ñ,¨\Ó:Ðà�Òà˜uÑ$Ñä—n‘n \Ó2ˆÜ×*Ñ*¨8Ó4ˆà˜+Ñ%à 5Ñ(Ñð   5Ñ(ÐàÐ.Ñ.°!Ò3Ü�	‰	ð%àØØô	
ð ñ Ð)¨EÒ1Ü�	‰	ð@àØô		
ð àr   c                 óÄ  — t        | «      d   }t        d«      d   }	 |j                  d«      dd }d}t        j                  j	                  |j
                  «      }|D �]h  }|d|z   z  }t        j                  j                  |«      rt        j                  d|«        yt        j                  j                  |«      rt        j                  d|«        y|j                  |«      s||j
                  k(  rŒ›t        j                  j                  |«      sœt        j                  |«      5  d	}	|j                  }
|j                  }|j                  |j
                  «      rd
}	|j                  }
|j                  }t        j                   ||	d¬«       t        j"                  ||
|«       d d d «       t%        | ||d|«      }|r�Œi y t        j                  j                  |«      st        j                  j'                  |«      rt        j                  d|«       yt        j                  j                  |«      sDt        j(                  |ddd¬«       t        j"                  ||j                  |j                  «       t%        | ||d|«      }|sy	 y# 1 sw Y   ŒëxY w# t*        t,        f$ r-}t        j.                  t        t1        |«      «       Y d }~yd }~ww xY w)Nr.   r   rt   éÿÿÿÿr;   z-Invalid directory. Symlink exists in path: %sFz*Invalid directory. File exists in path: %séí  r€   T)ÚmodeÚexist_okz%s is not a file!é€  )r–   Úensure_dir_exists)rn   r>   rK   rL   Údirnamerj   ÚislinkrS   r…   rM   rC   Úexistsr	   ÚSeLinuxGuardÚpw_uidÚpw_gidÚmakedirsÚ	chownbyidr’   ÚisdirÚ
write_filerP   rQ   rR   r_   )rl   ÚfilenamerŒ   Ú
user_pwentÚ
root_pwentÚdirectoriesÚparent_folderÚhome_folderÚ	directoryr–   ÚuidÚgidÚpermissionsÚes                 r   Úcheck_create_pathr¯   G  sr  € Ü Ó)¨!Ñ,€JÜ Ó'¨Ñ*€JðGà—n‘n SÓ)¨!¨BÐ/ˆð ˆô —g‘g—o‘o j×&7Ñ&7Ó8ˆØ$ó *	ˆIØ˜S 9™_Ñ,ˆMô �w‰w�~‰~˜mÔ,Ü—	‘	ØCØ!ôñ ä�w‰w�~‰~˜mÔ,Ü—	‘	Ø@À-ôñ ð ×&Ñ& }Ô5Ø  J×$5Ñ$5Ò5àä—7‘7—>‘> -Ô0ô ×&Ñ& }Ó5ñ 	<Ø �DØ$×+Ñ+�CØ$×+Ñ+�CØ$×/Ñ/°
×0AÑ0AÔBØ$˜Ø(×/Ñ/˜Ø(×/Ñ/˜Ü—K‘K °DÀ4ÕHÜ—N‘N =°#°sÔ;÷	<ô ,Ø˜-¨°5¸+óˆKó ÙðU*	ôX �7‰7�>‰>˜(Ô#¤r§w¡w§}¡}°XÔ'>Ü�I‰IÐ)¨8Ô4Øô �w‰w�~‰~˜hÔ'ô �O‰O˜H b¨uÈÕMÜ�N‰N˜8 Z×%6Ñ%6¸
×8IÑ8IÔJä'Ø�h ¨$°ó
ˆñ Øð ð ÷K	<ð 	<ûôB ”WÐò Ü�‰”Cœ˜Q›Ô ÜûðúsR   žBJ# Â"6J# ÃAJ# Ä.A?JÆ-J# ÇJ# Ç
AJ# È A4J# ÊJ 	ÊJ# Ê#KÊ2#KËKc           
      óþ  — t        | «      \  }}t        j                  j                  |d«      }|}g }t	        j
                  |d¬«      5  	 t        |«      }|j                  dd«      }|j                  dd«      }	t        ||j                  | «      }d d d «       t        j!                  «       |«      D ]V  \  }
}t#        d
|
v d|
v |j%                  dj'                  |j                  «      «      g«      sŒAt)        | |	dk(  «      }|sŒT|} n ||k7  rt        j+                  d|«       |t-        |g«      fS # t        t        f$ r+ ||d<   t	        j                  t        d	t        |d   «       Y ŒÝw xY w# 1 sw Y   ŒâxY w)NÚauthorized_keysT©Ú	recursiveÚauthorizedkeysfilers   rŒ   Úyesr   zhFailed extracting 'AuthorizedKeysFile' in SSH config from %r, using 'AuthorizedKeysFile' file %r insteadrq   rp   z{}/zAAuthorizedKeysFile has an user-specific authorized_keys, using %s)rn   rK   rL   r#   r	   r�   Úparse_ssh_config_mapÚgetr}   rj   rP   rQ   rR   rS   ÚDEF_SSHD_CFGÚzipr>   ÚanyrC   Úformatr¯   r…   rY   )rl   Ússhd_cfg_fileÚssh_dirrm   Ú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ˆfÜ"$§'¡'§,¡,¨wÐ8IÓ"JÐØ:ÐØ€LÜ	×	Ñ	˜7¨dÔ	3ñ ð	Ü*¨=Ó9ˆGØŸ™Ø$Ð&?óˆIð "Ÿ+™+ m°UÓ;ˆKÜ:Ø˜6Ÿ=™=¨(óˆL÷ô0 "% Y§_¡_Ó%6¸Ó!Eò Ñˆ�+Üà˜Ð Ø˜Ð Ø×&Ñ& u§|¡|°F·M±MÓ'BÓCðõ
ô /Ø˜+ {°eÑ';óˆNò Ø+6Ð(Ùðð  Ð#>Ò>Ü�	‰	ðà$ô	
ð 	!ÜÐ7Ð8Ó9ðð øôG œÐ!ò 
	à9ˆL˜‰OÜ�K‰KÜðô Ø˜Q‘öð
	ú÷ð ús+   Á
E3ÁAD6Ä67E0Å-E3Å/E0Å0E3Å3E<c                 óz  — t        «       }g }| D ]-  }|j                  |j                  t        |«      |¬«      «       Œ/ t	        |«      \  }}t
        j                  j                  |«      }t        j                  |d¬«      5  t        ||«      }	t        j                  ||	d¬«       d d d «       y # 1 sw Y   y xY w)N)r   Tr²   ©Úpreserve_mode)r+   r"   rH   r_   rÆ   rK   rL   rš   r	   r�   rf   r£   )
ra   rl   r   rV   Úkey_entriesrb   rÄ   Úauth_key_entriesr½   Úcontents
             r   Úsetup_user_keysrÍ   Ï  s©   € äÓ €FØ€KØò BˆØ×Ñ˜6Ÿ<™<¬¨A«¸˜<Ó@ÕAðBô '>¸hÓ&GÑ#€[Ð"Ü�g‰g�o‰o˜kÓ*€GÜ	×	Ñ	˜7¨dÔ	3ñ BÜ(Ð)9¸;ÓGˆÜ�‰˜ W¸DÕA÷B÷ Bñ Bús   Â%B1Â1B:c                   ó*   — e Zd Zdd„Zed„ «       Zd„ Zy)ÚSshdConfigLineNc                 ó.   — || _         || _        || _        y r   )rF   Ú_keyrv   )r   rF   rb   Úvs       r   r   zSshdConfigLine.__init__ß  s   € ØˆŒ	ØˆŒ	Øˆ�
r   c                 óP   — | j                   €y | j                   j                  «       S r   )rÑ   Úlowerr   s    r   rd   zSshdConfigLine.keyä  s    € à�9‰9ÐØà�y‰y�‰Ó Ð r   c                 óÀ   — | j                   €t        | j                  «      S t        | j                   «      }| j                  r|dt        | j                  «      z   z  }|S r    )rÑ   r_   rF   rv   )r   rÒ   s     r   r%   zSshdConfigLine.__str__ë  sJ   € Ø�9‰9ÐÜ�t—y‘y“>Ð!ä�D—I‘I“ˆAØ�zŠzØ�Sœ3˜tŸz™z›?Ñ*Ñ*�ØˆHr   )NN)r&   r'   r(   r   Úpropertyrd   r%   r)   r   r   rÏ   rÏ   Þ  s    „ óð
 ñ!ó ð!ór   rÏ   Úreturnc                 óœ   — t         j                  j                  | «      sg S t        t	        j
                  | «      j                  «       «      S r   )rK   rL   rM   Úparse_ssh_config_linesr	   rN   rO   ©rX   s    r   Úparse_ssh_configrÛ   õ  s6   € Ü�7‰7�>‰>˜%Ô Øˆ	Ü!¤$×"5Ñ"5°eÓ"<×"GÑ"GÓ"IÓJÐJr   c                 ó�  — g }| D ]r  }|j                  «       }|r|j                  d«      r|j                  t        |«      «       ŒA	 |j	                  d d«      \  }}|j                  t        |||«      «       Œt |S # t
        $ r@ 	 |j	                  dd«      \  }}n&# t
        $ r t        j                  d|«       Y Y Œ¹w xY wY Œhw xY w)Nr:   r.   ú=z;sshd_config: option "%s" has no key/value pair, skipping it)rD   rC   r"   rÏ   r>   Ú
ValueErrorrS   r…   )rU   ÚretrF   rd   Úvals        r   rÙ   rÙ   û  sÓ   € ð
 !#€CØò 3ˆØ�z‰z‹|ˆÙ�t—‘ sÔ+Ø�J‰J”~ dÓ+Ô,Øð	Ø—z‘z $¨Ó*‰HˆC�ð 	�
‰
”> $¨¨SÓ1Õ2ð#3ð$ €Jøô ò 		ðØŸ:™: c¨1Ó-‘�‘SøÜò Ü—	‘	ð#àôò
 ðúñ ð		ús6   ÁA<Á<	CÂBÂCÂB?Â;CÂ>B?Â?CÃCc                 ó‚   — t        | «      }|si S i }|D ](  }|j                  sŒ|j                  ||j                  <   Œ* |S r   )rÛ   rd   rv   )rX   rU   rß   rF   s       r   r¶   r¶     sJ   € Ü˜UÓ#€EÙØˆ	Ø
€CØò #ˆØ�xŠxØØŸ
™
ˆˆD�H‰HŠð#ð €Jr   rX   c                 óÂ   — t         j                  j                  | «      syt        j                  | «      j                  «       D ]  }|j                  d| › d�«      sŒ y y)NFzInclude z	.d/*.confT)rK   rL   rM   r	   rN   rO   rC   )rX   rF   s     r   Ú_includes_dconfrã   "  sU   € Ü�7‰7�>‰>˜%Ô ØÜ×#Ñ# EÓ*×5Ñ5Ó7ò ˆØ�?‰?˜X e W¨IÐ6Õ7Ùðð r   c                 óD  — t        | «      r”t        j                  j                  | › d�«      st	        j
                  | › d�d¬«       t        j                  j                  | › d�d«      } t        j                  j                  | «      st	        j                  | d«       | S )Nz.dr•   )r–   z50-cloud-init.confr˜   )	rã   rK   rL   r¢   r	   Ú
ensure_dirr#   rM   Úensure_filerÚ   s    r   Ú"_ensure_cloud_init_ssh_config_filerç   +  st   € Ü�uÔÜ�w‰w�}‰} ˜w b˜\Ô*Ü�O‰O˜u˜g R˜L¨uÕ5Ü—‘—‘ ˜w b˜\Ð+?Ó@ˆÜ�w‰w�~‰~˜eÔ$ä×Ñ˜U EÔ*Ø€Lr   c                 óô   — t        |«      }t        |«      }t        || ¬«      }|rAt        j                  |dj                  |D �cg c]  }t        |«      ‘Œ c}«      dz   d¬«       t        |«      dk7  S c c}w )z©Read fname, and update if changes are necessary.

    @param updates: dictionary of desired values {Option: value}
    @return: boolean indicating if an update was done.)rU   Úupdatesr[   TrÈ   r   )rç   rÛ   Úupdate_ssh_config_linesr	   r£   r#   r_   r0   )ré   rX   rU   ÚchangedrF   s        r   Úupdate_ssh_configrì   6  so   € ô
 /¨uÓ5€EÜ˜UÓ#€EÜ%¨E¸7ÔC€GÙÜ�‰ØØ�I‰I¨UÖ3 T”s˜4•yÒ3Ó4°tÑ;Øõ	
ô
 ˆw‹<˜1ÑÐùò 4s   ÁA5c                 ó  — t        «       }g }t        |j                  «       D �cg c]  }|j                  «       |f‘Œ c}«      }t	        | d¬«      D ]©  \  }}|j
                  sŒ|j
                  |v sŒ"||j
                     }||   }	|j                  |«       |j                  |	k(  rt        j                  d|||	«       Œo|j                  |«       t        j                  d|||j                  |	«       |	|_        Œ« t        |«      t        |«      k7  rk|j                  «       D ]X  \  }}	||v rŒ|j                  |«       | j                  t        d||	«      «       t        j                  dt        | «      ||	«       ŒZ |S c c}w )zðUpdate 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.r.   )Ú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Údictra   rÔ   Ú	enumeraterd   Úaddrv   rS   r…   r"   r0   ÚitemsrÏ   )
rU   ré   Úfoundrë   rb   Úcasemapr4   rF   rd   rv   s
             r   rê   rê   G  s\  € ô ‹E€EØ€Gô ¨G¯L©L«NÖ; q�Q—W‘W“Y ’NÒ;Ó<€Gä˜U¨!Ô,ò #‰ˆˆ4Ø�xŠxØØ�8‰8�wÒØ˜$Ÿ(™(Ñ#ˆCØ˜C‘LˆEØ�I‰I�cŒNØ�z‰z˜UÒ"Ü—	‘	Ø:¸A¸sÀEõð —‘˜sÔ#Ü—	‘	Ø9ØØØ—J‘JØôð #�•
ð)#ô, ˆ5ƒz”S˜“\Ò!Ø!Ÿ-™-›/ò 	‰JˆC�Ø�e‰|ØØ�N‰N˜3ÔØ�L‰Lœ¨¨C°Ó7Ô8Ü�I‰IØ2´C¸³JÀÀUõð	ð €NùòC <s   ¤FrU   c                 óˆ   — | sy t        |«      }d„ | D «       }t        j                  |dj                  |«      dz   dd¬«       y )Nc              3   ó0   K  — | ]  \  }}|› d |› �–— Œ y­w)r!   Nr)   )Ú.0rb   rÒ   s      r   ú	<genexpr>z$append_ssh_config.<locals>.<genexpr>y  s   è ø€ Ò,™d˜a �!��A�a�SŒzÑ,ùs   ‚r[   ÚabT)ÚomoderÉ   )rç   r	   r£   r#   )rU   rX   rÌ   s      r   Úappend_ssh_configrü   u  sB   € ÙØÜ.¨uÓ5€EÙ, eÔ,€GÜ‡O�OØØ�	‰	�'Ó˜TÑ!ØØö	r   c                  ó0  — d} t        t        j                  «      5  t        j                  ddgddg¬«      \  }} ddd«       d}| j                  d	«      D ]2  }|j	                  |«      sŒ|t        |«      |j                  d
«       c S  y# 1 sw Y   ŒRxY w)zàGet 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-Vr   r.   )ÚrcsNÚOpenSSH_r[   ú,)r   r   ÚProcessExecutionErrorr>   rC   r0   Úfind)ÚerrÚ_ÚprefixrF   s       r   Úget_opensshd_versionr  ‚  sŽ   € ð €CÜ	”$×,Ñ,Ó	-ñ 7Ü—‘˜F D˜>°°1¨vÔ6‰ˆˆ3÷7à€FØ—	‘	˜$“ò 6ˆØ�?‰?˜6Õ"Øœ˜F› d§i¡i°£nÐ5Ò5ð6ð ÷7ð 7ús   œBÂBc                  ó^  — d} t        «       }|€t        j                  j                  | «      S d|v r|d|j	                  d«       } nd|v r|d|j	                  d«       } n|} 	 t        j                  j                  | «      } | S # t
        t        f$ r t        j                  d| «       Y yw xY w)zäGet 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?   rS   Úwarning)Úupstream_versionÚfull_versions     r   Úget_opensshd_upstream_versionr  –  sÂ   € ð ÐÜ'Ó)€LØÐÜ× Ñ ×)Ñ)Ð*:Ó;Ð;Ø
ˆlÑØ'Ð(@¨,×*;Ñ*;¸CÓ*@ÐAÑØ	�Ñ	Ø'Ð(@¨,×*;Ñ*;¸CÓ*@ÐAÑà'ÐðJÜ$×,Ñ,×5Ñ5Ð6FÓGÐØÐøÜœ	Ð"ò JÜ�‰Ð6Ð8HÖIðJús   Á# B Â%B,Â+B,r   )+ÚloggingrK   rh   Ú
contextlibr   Útypingr   r   r   Ú	cloudinitr   r   r	   Ú	getLoggerr&   rS   r¸   r@   Ú_DISABLE_USER_SSH_EXITr_   ÚDISABLE_USER_OPTSr   r+   rY   rf   rn   r}   r’   r¯   rÆ   rÍ   rÏ   rÛ   rÙ   r¶   Úboolrã   rç   rì   rê   rü   r  r  r)   r   r   ú<module>r     s;  ðó Û 	Û 
Ý ß (Ñ (ç +Ñ +à€g×Ñ˜Ó!€ð &€ð €ð, Ð ðñ Ð(Ó)ñ*ð -0ñ0ð ÷"ñ "÷:V
ñ V
òrò ò89òò*BòJLð^ 5Aó 6órB÷ñ ð.K˜t NÑ3ó Kð T¨.Ñ%9ó ò6	ð˜3ð  4ó òð &2ó ò"+ð\ ?Kñ 
˜X e¨C°¨H¡oÑ6ó 
òó(Jr   