ó
    x[hÛX  ã                   óš  • S SK r S SKrS SKrS SKJr  S SKJrJrJr  S SK	J
r
JrJr  \ R                  " \5      rSrSrSrS\" \5      -   S	-   r " S
 S5      r " S S5      rS rS rS rS rS rS r\4S jrS%S jr " S S5      rS\\   4S jr S\\   4S jr!S r"S\S\#4S jr$S r%\4S jr&S  r'\4S!\\\\4      4S" jjr(S# r)S$ r*g)&é    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                   ó,   • \ rS rSr SS jrS rS rSrg)ÚAuthKeyLineéD   Nc                 ó@   • X0l         X@l        XPl        X l        Xl        g ©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                 ó@   • U R                   =(       a    U R                  $ r   )r   r   ©r   s    r   ÚvalidÚAuthKeyLine.validN   s   € Ø�{‰{×+˜tŸ|™|Ð+r   c                 ó®  • / nU R                   (       a  UR                  U R                   5        U R                  (       a  UR                  U R                  5        U R                  (       a  UR                  U R                  5        U R                  (       a  UR                  U R                  5        U(       d  U R
                  $ SR                  U5      $ ©NÚ )r   Úappendr   r   r   r   Újoin)r   Útokss     r   Ú__str__ÚAuthKeyLine.__str__Q   s~   € ØˆØ�<�<Ø�K‰K˜Ÿ™Ô%Ø�<�<Ø�K‰K˜Ÿ™Ô%Ø�;�;Ø�K‰K˜Ÿ™Ô$Ø�<�<Ø�K‰K˜Ÿ™Ô%ÞØ—;‘;Ðà—8‘8˜D“>Ð!r   )r   r   r   r   r   )NNNN)Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__r   r    r(   Ú__static_attributes__© r   r   r   r   D   s   † àGKôò,õ"r   r   c                   ó(   • \ rS rSrSrS rSS jrSrg)ÚAuthKeyLineParseréa   a9  
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                 óL  • SnSnU[        U5      :  ax  U(       d  X   S;  ai  X   nUS-   [        U5      :¼  a  US-   nOMXS-      nUS:X  a  US:X  a  US-   nOUS:X  a  U(       + nUS-   nU[        U5      :  a  U(       a  M_  X   S;  a  Mi  USU nXS R                  5       nXg4$ )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_optionsÚ"AuthKeyLineParser._extract_optionsu   sÁ   € ð ˆØˆØ”#�c“(‹l¦¨S©V¸;Ó-FØ‘6ˆDØ�1‰uœ˜C›Ó Ø˜‘E�ØØ˜A™‘JˆEØ�t‹| ¨£Ø˜‘E‘Ø˜“Ø#œ�Ø�A‘ˆAð ”#�c“(‹l§ ¨S©V¸;Õ-Fð �a˜�(ˆð �R�—‘Ó!ˆØÐ Ð r   Nc                 óˆ  • UR                  S5      nUR                  S5      (       d  UR                  5       S:X  a  [        U5      $ S nUR                  5       n U" U5      u  pgn[        UUUUUS9$ ! [         aD    U R                  U5      u  pšUc  U	n U" U
5      u  pgn N=! [         a    [        U5      s s $ f = ff = f)Nz
Ú#Ú c                 óò   • U R                  S S5      n[        U5      S:  a  [        S[        U5      -  5      eUS   [        ;  a  [        SUS   -  5      e[        U5      S:X  a  UR	                  S5        U$ )Né   zTo few fields: %sr   zInvalid keytype %srC   )Úsplitr7   Ú	TypeErrorÚVALID_KEY_TYPESr%   )r9   r'   s     r   Úparse_ssh_keyÚ.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   rG   r?   )r   Úsrc_liner   ÚlinerI   r9   r   r   r   Úkeyoptsr>   s              r   ÚparseÚAuthKeyLineParser.parse�   s×   € à�‰˜vÓ&ˆØ�?‰?˜3×Ñ 4§:¡:£<°2Ó#5Ü˜xÓ(Ð(ò	ð �j‰j‹lˆð
	-Ù)6°sÓ);Ñ&ˆW˜gô ØØØØØñ
ð 	
øô ó 	-Ø $× 5Ñ 5°cÓ :ÑˆWØ‰Ø!�ð-Ù-:¸6Ó-BÑ*�¢'øÜó -Ü" 8Ó,Ô,ð-úð	-ús*   ÁA3 Á3"CÂB#Â#B=Â8CÂ<B=Â=Cr/   r   )r*   r+   r,   r-   Ú__doc__r?   rQ   r.   r/   r   r   r1   r1   a   s   † ñò&!÷4(
r   r1   c                 ó‚  • / n[        5       n/ nU  Hw  n [        R                  R                  U5      (       aO  [        R
                  " U5      R                  5       nU H#  nUR                  UR                  U5      5        M%     Mw  My     U$ ! [        [        4 a     [        R                  " [        SU5         M¬  f = f)NzError reading lines from %s)r1   ÚosÚpathÚisfiler	   Úload_text_fileÚ
splitlinesr%   rQ   ÚIOErrorÚOSErrorÚlogexcÚLOG)ÚfnamesÚlinesÚparserÚcontentsÚfnamerO   s         r   Úparse_authorized_keysrc   º   s¤   € Ø€EÜÓ €FØ€HÛˆð	CÜ�w‰w�~‰~˜e×$Ñ$Ü×+Ò+¨EÓ2×=Ñ=Ó?�Û!�DØ—O‘O F§L¡L°Ó$6Ö7ó "ñ %ñ ð €Oøô œÐ!ó 	CÜ�KŠKœÐ:¸E×Bð	Cús   •A1BÂ,B>Â=B>c                 ó  • [        U Vs/ s H  o"R                  5       (       d  M  UPM     sn5      n[        [        U 5      5       Ha  nX   nUR                  5       (       d  M  U H9  nUR                  UR                  :X  d  M  UnX#;   d  M(  UR                  U5        M;     XPU'   Mc     U H  nU R                  U5        M     U  Vs/ s H  n[        U5      PM     nnUR                  S5        SR                  U5      $ s  snf s  snf )NrC   Ú
)	Úlistr    Úranger7   r   Úremover%   Ústrr&   )	Úold_entriesÚkeysÚkÚto_addr;   r9   ÚkeyÚbr_   s	            r   Úupdate_authorized_keysrp   Ê   sÞ   € Ü™dÓ0šd˜§g¡g§i—1™dÑ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   ŠD¦DÃ
Dc                 óÒ   • [         R                  " U 5      nU(       a  UR                  (       d  [        SU -  5      e[        R
                  R                  UR                  S5      U4$ )Nz"Unable to get SSH info for user %rz.ssh)ÚpwdÚgetpwnamÚpw_dirÚRuntimeErrorrU   rV   r&   )ÚusernameÚpw_ents     r   Úusers_ssh_inforx   æ   sH   € Ü�\Š\˜(Ó#€FÞ˜ŸŸÜÐ?À8ÑLÓMÐMÜ�G‰G�L‰L˜Ÿ™¨Ó/°Ð8Ð8r   c                 ó$  • SU4SU4S4nU (       d  Sn U R                  5       n/ nU He  nU H  u  pxUR                  Xx5      nM     UR                  S5      (       d  [        R                  R                  X5      nUR                  U5        Mg     U$ )Nú%hú%u)z%%Ú%ú%h/.ssh/authorized_keysÚ/)rF   ÚreplacerL   rU   rV   r&   r%   )	ÚvalueÚhomedirrv   ÚmacrosÚpathsÚrenderedrV   ÚmacroÚfields	            r   Úrender_authorizedkeysfile_pathsr‡   í   s‰   € ð �Wˆo  hÐ/°Ð=€FÞØ)ˆØ�K‰K‹M€EØ€HÛˆÛ"‰LˆEØ—<‘< Ó-ŠDñ #à�‰˜s×#Ñ#Ü—7‘7—<‘< Ó.ˆDØ�‰˜Öñ ð €Or   c                 óì  • SnU(       a  Sn[         R                  " U5      nU(       a%  X`:w  a   US:w  a  [        R                  SUUU U5        g[         R                  " U5      nX`:X  a  US-  nO<[         R
                  " U5      n[         R                  " U 5      n	X‰;   a  US-  nOUS-  nXu-  S	:X  a  [        R                  S
UUU 5        gU(       a"  US-  (       a  [        R                  SUU5        gg)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éÀ  é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_ownerr]   ÚdebugÚget_permissionsÚ	get_groupÚget_user_groups)
rv   Ú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                 ó2  • [        U 5      S   n[        S5      S   n UR                  S5      SS nSn[        R                  R	                  UR
                  5      nU GH…  nUSU-   -  n[        R                  R                  U5      (       a  [        R                  SU5          g[        R                  R                  U5      (       a  [        R                  SU5          gUR                  U5      (       d  XcR
                  :X  a  M«  [        R                  R                  U5      (       dŸ  [        R                  " U5         S	n	UR                  n
UR                  nUR                  UR
                  5      (       a  S
n	UR                  n
UR                  n[        R                   " XiSS9  [        R"                  " XjU5        S S S 5        [%        XUSU5      nU(       a  GM†    g   [        R                  R                  U5      (       d$  [        R                  R'                  U5      (       a  [        R                  SU5        g[        R                  R                  U5      (       dB  [        R(                  " USSSS9  [        R"                  " XR                  UR                  5        [%        XUSU5      nU(       d  g g! , (       d  f       GN= f! [*        [,        4 a.  n[        R.                  " [        [1        U5      5         S nAgS nAff = f)Nr5   r‰   r~   éÿÿÿÿrC   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)rx   rF   rU   rV   Údirnamert   Úislinkr]   r�   rW   rL   Úexistsr	   ÚSeLinuxGuardÚpw_uidÚpw_gidÚmakedirsÚ	chownbyidrœ   ÚisdirÚ
write_filerZ   r[   r\   ri   )rv   Úfilenamer–   Ú
user_pwentÚ
root_pwentÚdirectoriesÚparent_folderÚhome_folderÚ	directoryr    ÚuidÚgidÚpermissionsÚes                 r   Úcheck_create_pathr¹   G  st  € Ü Ó)¨!Ñ,€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Ñ5Ø ×$5Ñ$5Ó5áä—7‘7—>‘> -×0Ñ0ô ×&Ò& }Õ5Ø �DØ$×+Ñ+�CØ$×+Ñ+�CØ$×/Ñ/°
×0AÑ0A×BÑBØ$˜Ø(×/Ñ/˜Ø(×/Ñ/˜Ü—K’K À4ÒHÜ—N’N =°sÔ;÷ 6ô ,Ø¨°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×%6Ñ%6¸
×8IÑ8IÔJä'Ø ¨$°ó
ˆö Øð ð ÷K 6Ö5ûôB ”WÐó Ü�Š”Cœ˜Q›Ô ÜûðúsR   žBK Â';K Ã#A!K ÅBKÇK Ç%K Ç'A K ÉA;K Ë
K	ËK ËLË($LÌLc           
      ó  • [        U 5      u  p#[        R                  R                  US5      nUn/ n[        R
                  " USS9    [        U5      nUR                  SS5      nUR                  SS5      n	[        XƒR                  U 5      nS S S 5        [        WR!                  5       U5       Hb  u  p«[#        S
U
;   SU
;   UR%                  SR'                  UR                  5      5      /5      (       d  MH  [)        XW	S:H  5      nU(       d  M`  Un  O   XT:w  a  [        R+                  SU5        U[-        U/5      4$ ! [        [        4 a+    XFS'   [        R                  " [        S	[        US   5         Nëf = f! , (       d  f       Nõ= f)NÚauthorized_keysT©Ú	recursiveÚauthorizedkeysfiler}   r–   Úyesr   zhFailed extracting 'AuthorizedKeysFile' in SSH config from %r, using 'AuthorizedKeysFile' file %r insteadr{   rz   z{}/zAAuthorizedKeysFile has an user-specific authorized_keys, using %s)rx   rU   rV   r&   r	   r§   Úparse_ssh_config_mapÚgetr‡   rt   rZ   r[   r\   r]   ÚDEF_SSHD_CFGÚziprF   ÚanyrL   Úformatr¹   r�   rc   )rv   Ússhd_cfg_fileÚssh_dirrw   Ú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Ü"$§'¡'§,¡,¨wÐ8IÓ"JÐØ:ÐØ€LÜ	×	Ò	˜7¨dÓ	3ð	Ü*¨=Ó9ˆGØŸ™Ø$Ð&?óˆIð "Ÿ+™+ m°UÓ;ˆKÜ:ØŸ=™=¨(óˆL÷ 
4ô0 "% Y§_¡_Ó%6¸Ö!EÑˆÜà˜Ñ Ø˜Ñ Ø×&Ñ& u§|¡|°F·M±MÓ'BÓCð÷
ó 
ô /Ø {°eÑ';óˆN÷ ˆ~Ø+6Ð(Ùñ "Fð  Ó>Ü�	‰	ðà$ô	
ð 	!ÜÐ7Ð8Ó9ðð øôG œÐ!ó 
	à9˜‰OÜ�KŠKÜðô Ø˜Q‘öð
	ú÷ 
4Õ	3ús+   ÁE=Á	AD?Ä?8E:Å7E=Å9E:Å:E=Å=
Fc                 ót  • [        5       n/ nU  H+  nUR                  UR                  [        U5      US95        M-     [	        U5      u  pg[
        R                  R                  U5      n[        R                  " USS9   [        Xt5      n	[        R                  " XiSS9  S S S 5        g ! , (       d  f       g = f)N)r   Tr¼   ©Úpreserve_mode)r1   r%   rQ   ri   rÐ   rU   rV   r¤   r	   r§   rp   r­   )
rk   rv   r   r`   Úkey_entriesrl   rÎ   Úauth_key_entriesrÇ   Úcontents
             r   Úsetup_user_keysr×   Ï  sŽ   € äÓ €FØ€KÛˆØ×Ñ˜6Ÿ<™<¬¨A«¸˜<Ð@ÖAñ ô '>¸hÓ&GÑ#€[Ü�g‰g�o‰o˜kÓ*€GÜ	×	Ò	˜7¨dÓ	3Ü(Ð)9ÓGˆÜ�Š˜¸DÒA÷ 
4×	3Ö	3ús   Á?!B)Â)
B7c                   ó4   • \ rS rSrSS jr\S 5       rS rSrg)ÚSshdConfigLineiÞ  Nc                 ó(   • Xl         X l        X0l        g r   )rO   Ú_keyr€   )r   rO   rl   Úvs       r   r   ÚSshdConfigLine.__init__ß  s   € ØŒ	ØŒ	Ø�
r   c                 óR   • U R                   c  g U R                   R                  5       $ r   )rÛ   Úlowerr   s    r   rn   ÚSshdConfigLine.keyä  s    € à�9‰9ÑØà�y‰y�‰Ó Ð r   c                 óÌ   • U R                   c  [        U R                  5      $ [        U R                   5      nU R                  (       a  US[        U R                  5      -   -  nU$ r#   )rÛ   ri   rO   r€   )r   rÜ   s     r   r(   ÚSshdConfigLine.__str__ë  sJ   € Ø�9‰9ÑÜ�t—y‘y“>Ð!ä�D—I‘I“ˆAØ�z�zØ�Sœ3˜tŸz™z›?Ñ*Ñ*�ØˆHr   )rÛ   rO   r€   )NN)	r*   r+   r,   r-   r   Úpropertyrn   r(   r.   r/   r   r   rÙ   rÙ   Þ  s    † ôð
 ñ!ó ð!õr   rÙ   Úreturnc                 ó¨   • [         R                  R                  U 5      (       d  / $ [        [        R
                  " U 5      R                  5       5      $ r   )rU   rV   rW   Úparse_ssh_config_linesr	   rX   rY   ©rb   s    r   Úparse_ssh_configrè   õ  s9   € Ü�7‰7�>‰>˜%× Ñ Øˆ	Ü!¤$×"5Ò"5°eÓ"<×"GÑ"GÓ"IÓJÐJr   c                 ó¨  • / nU  H|  nUR                  5       nU(       a  UR                  S5      (       a  UR                  [        U5      5        ML   UR	                  S S5      u  p4UR                  [        X#U5      5        M~     U$ ! [
         a@     UR	                  SS5      u  p4 NB! [
         a    [        R                  SU5          MÇ  f = ff = f)NrB   r5   Ú=z;sshd_config: option "%s" has no key/value pair, skipping it)rM   rL   r%   rÙ   rF   Ú
ValueErrorr]   r�   )r_   ÚretrO   rn   Úvals        r   ræ   ræ   û  sÈ   € ð
 !#€CÛˆØ�z‰z‹|ˆÞ�t—‘ s×+Ñ+Ø�J‰J”~ dÓ+Ô,Ùð	Ø—z‘z $¨Ó*‰HˆCð 	�
‰
”> $¨SÓ1Ö2ñ# ð$ €Jøô ó 		ðØŸ:™: c¨1Ó-‘�‘SøÜó Ü—	‘	ð#àôó
 ðúð		ús*   ÁBÂ
CÂB(Â( CÃCÃCÃCc                 óš   • [        U 5      nU(       d  0 $ 0 nU H.  nUR                  (       d  M  UR                  X#R                  '   M0     U$ r   )rè   rn   r€   )rb   r_   rì   rO   s       r   rÀ   rÀ     sC   € Ü˜UÓ#€EÞØˆ	Ø
€CÛˆØ�x�xÙØŸ
™
ˆ�H‰H‹ñ ð €Jr   rb   c                 óÜ   • [         R                  R                  U 5      (       d  g[        R                  " U 5      R                  5        H  nUR                  SU  S35      (       d  M    g   g)NFzInclude z	.d/*.confT)rU   rV   rW   r	   rX   rY   rL   )rb   rO   s     r   Ú_includes_dconfrð   "  sV   € Ü�7‰7�>‰>˜%× Ñ ØÜ×#Ò# EÓ*×5Ñ5Ö7ˆØ�?‰?˜X e W¨IÐ6×7Ó7Ùñ 8ð r   c                 ó`  • [        U 5      (       a�  [        R                  R                  U  S35      (       d  [        R
                  " U  S3SS9  [        R                  R                  U  S3S5      n [        R                  R                  U 5      (       d  [        R                  " U S5        U $ )Nz.drŸ   )r    z50-cloud-init.confr¢   )	rð   rU   rV   r¬   r	   Ú
ensure_dirr&   rW   Úensure_filerç   s    r   Ú"_ensure_cloud_init_ssh_config_filerô   +  s}   € Ü�u×ÑÜ�w‰w�}‰} ˜w b˜\×*Ñ*Ü�OŠO˜u˜g R˜L¨uÒ5Ü—‘—‘ ˜w b˜\Ð+?Ó@ˆÜ�w‰w�~‰~˜e×$Ñ$ä×Ò˜U EÔ*Ø€Lr   c                 óø   • [        U5      n[        U5      n[        X S9nU(       aB  [        R                  " USR                  U Vs/ s H  n[        U5      PM     sn5      S-   SS9  [        U5      S:g  $ s  snf )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.)r_   Úupdatesre   TrÒ   r   )rô   rè   Úupdate_ssh_config_linesr	   r­   r&   ri   r7   )rö   rb   r_   ÚchangedrO   s        r   Úupdate_ssh_configrù   6  sq   € ô
 /¨uÓ5€EÜ˜UÓ#€EÜ%¨EÑC€GÞÜ�ŠØØ�I‰I©UÓ3ªU T”s˜4–y©UÑ3Ó4°tÑ;Øò	
ô
 ˆw‹<˜1ÑÐùò 4s   ÁA7c                 ó  • [        5       n/ n[        UR                  5        Vs/ s H  oDR                  5       U4PM     sn5      n[	        U SS9 H°  u  pgUR
                  (       d  M  UR
                  U;   d  M*  XWR
                     nX   n	UR                  U5        UR                  U	:X  a  [        R                  SXhU	5        Mv  UR                  U5        [        R                  SUUUR                  U	5        X—l        M²     [        U5      [        U5      :w  al  UR                  5        HX  u  p‰X‚;   a  M  UR                  U5        U R                  [        SX‰5      5        [        R                  S[        U 5      X‰5        MZ     U$ s  snf )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.r5   )Ústartz$line %d: option %s already set to %sz#line %d: option %s updated %s -> %srC   z line %d: option %s added with %s)ÚsetÚdictrk   rß   Ú	enumeratern   Úaddr€   r]   r�   r%   r7   ÚitemsrÙ   )
r_   rö   Úfoundrø   rl   Úcasemapr;   rO   rn   r€   s
             r   r÷   r÷   G  sB  € ô ‹E€EØ€Gô ¨G¯L©L¬NÓ;ªN q—W‘W“Y “N©NÑ;Ó<€Gä˜U¨!Ô,‰ˆØ�x�xÙØ�8‰8�wÕØŸ(™(Ñ#ˆCØ‘LˆEØ�I‰I�cŒNØ�z‰z˜UÓ"Ü—	‘	Ø:¸AÀEöð —‘˜sÔ#Ü—	‘	Ø9ØØØ—J‘JØôð #–
ñ) -ô, ˆ5ƒz”S˜“\Ó!Ø!Ÿ-™-ž/‰JˆCØ‹|ÙØ�N‰N˜3ÔØ�L‰Lœ¨¨CÓ7Ô8Ü�I‰IØ2´C¸³JÀöñ *ð €NùòC <s   ¤F
r_   c                 óŽ   • U (       d  g [        U5      nS U  5       n[        R                  " USR                  U5      S-   SSS9  g )Nc              3   ó4   #   • U  H  u  pU S U 3v •  M     g7f)r$   Nr/   )Ú.0rl   rÜ   s      r   Ú	<genexpr>Ú$append_ssh_config.<locals>.<genexpr>y  s   é € Ð,¢e™d˜a�!��A�a�S�z¢eùs   ‚re   ÚabT)ÚomoderÓ   )rô   r	   r­   r&   )r_   rb   rÖ   s      r   Úappend_ssh_configr
  u  sB   € ÞØÜ.¨uÓ5€EÙ,¡eÓ,€GÜ‡O‚OØØ�	‰	�'Ó˜TÑ!ØØó	r   c                  óB  • Sn [        [        R                  5         [        R                  " SS/SS/S9u  pSSS5        SnU R                  S	5       H8  nUR	                  U5      (       d  M  U[        U5      UR                  S
5       s  $    g! , (       d  f       N^= f)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.
rC   Ússhdz-Vr   r5   )ÚrcsNÚOpenSSH_re   Ú,)r   r   ÚProcessExecutionErrorrF   rL   r7   Úfind)ÚerrÚ_ÚprefixrO   s       r   Úget_opensshd_versionr  ‚  sƒ   € ð €CÜ	”$×,Ñ,Õ	-Ü—’˜F D˜>°°1¨vÑ6‰ˆ÷ 
.à€FØ—	‘	˜$–ˆØ�?‰?˜6×"Ó"Øœ˜F› d§i¡i°£nÐ5Ò5ñ  ð ÷ 
.Õ	-ús   œBÂ
Bc                  ój  • Sn [        5       nUc  [        R                  R                  U 5      $ SU;   a  USUR	                  S5       n OSU;   a  USUR	                  S5       n OUn  [        R                  R                  U 5      n U $ ! [
        [        4 a    [        R                  SU 5         gf = f)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ë   rG   r]   Ú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	 Â	&B2Â1B2r   )+ÚloggingrU   rr   Ú
contextlibr   Útypingr   r   r   Ú	cloudinitr   r   r	   Ú	getLoggerr*   r]   rÂ   rH   Ú_DISABLE_USER_SSH_EXITri   ÚDISABLE_USER_OPTSr   r1   rc   rp   rx   r‡   rœ   r¹   rÐ   r×   rÙ   rè   ræ   rÀ   Úboolrð   rô   rù   r÷   r
  r  r  r/   r   r   Ú<module>r&     s9  ðó Û 	Û 
Ý ß (Ñ (ç +Ñ +à×Ò˜Ó!€ð &€ð €ð, Ð ðñ Ð(Ó)ñ*ð -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   