܍~cP2ddlZddlZddlmZddlmZejeZdZ dZ dZ de e zdzZ Gd d ZGd d Zd ZdZdZdZdZdZe fdZddZGddZdZdZdZde defdZe fdZdZdS) N)log)utilz/etc/ssh/sshd_config)dsarsaecdsaed25519z(ecdsa-sha2-nistp256-cert-v01@openssh.comzecdsa-sha2-nistp256z(ecdsa-sha2-nistp384-cert-v01@openssh.comzecdsa-sha2-nistp384z(ecdsa-sha2-nistp521-cert-v01@openssh.comzecdsa-sha2-nistp521z+sk-ecdsa-sha2-nistp256-cert-v01@openssh.comz"sk-ecdsa-sha2-nistp256@openssh.comz#sk-ssh-ed25519-cert-v01@openssh.comzsk-ssh-ed25519@openssh.comzssh-dss-cert-v01@openssh.comzssh-dssz ssh-ed25519-cert-v01@openssh.comz ssh-ed25519zssh-rsa-cert-v01@openssh.comzssh-rsazssh-xmss-cert-v01@openssh.comzssh-xmss@openssh.comzno-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$eZdZ ddZdZdZdS) AuthKeyLineNcL||_||_||_||_||_dSN)base64commentoptionskeytypesource)selfrrrrrs 4/usr/lib/python3/dist-packages/cloudinit/ssh_util.py__init__zAuthKeyLine.__init__Fs+     c|jo|jSr)rrrs rvalidzAuthKeyLine.validOs{+t|+rcJg}|jr||j|jr||j|jr||j|jr||j|s|jSd|SN )rappendrrrrjoin)rtokss r__str__zAuthKeyLine.__str__Rs < & KK % % % < & KK % % % ; % KK $ $ $ < & KK % % % "; 88D>> !r)NNNN)__name__ __module__ __qualname__rrr!rrr r EsIGK,,, " " " " "rr c eZdZdZdZddZdS)AuthKeyLineParsera 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, id_dsa.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): cxd}d}|t|krz|s ||dvrn||}|dzt|kr|dz}nJ||dz}|dkr |dkr|dz}n |dkr| }|dz}|t|kr |d||dvn|d|}||d}||fS)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)lenlstrip)rentquotedicurcnextcrremains r_extract_optionsz"AuthKeyLineParser._extract_optionsvs  #c((lllSV;-F-Fq6D1uC  EAJEt|| E#AA#c((lllSV;-F-Fac(QRR!!  rNc|d}|ds|dkrt|Sd}|} ||\}}}n^#t$rQ||\} } || } || \}}}n!#t$rt|cYcYSwxYwYnwxYwt|||||S)Nz #c4|dd}t|dkrtdt|z|dtvrtd|dzt|dkr|d|S)NzTo few fields: %srzInvalid keytype %sr7)splitr, TypeErrorVALID_KEY_TYPESr)r.r s r parse_ssh_keyz.AuthKeyLineParser.parse..parse_ssh_keys99T1%%D4yy1}} 3c$ii ?@@@Awo-- 4tAw >???4yyA~~ BKr)rrrr)rstrip startswithstripr r;r4) rsrc_linerliner=r.rrrkeyoptsr3s rparsezAuthKeyLineParser.parses@v&& ??3   )4::<<2#5#5x(( (   jjll -)6s);); &Wfgg - - - $ 5 5c : : Wf! --:]6-B-B*&'' - - -"8,,,,,,, -#*'  -      s6*A::&C!B10C1C CCCCr)r"r#r$__doc__r4rDr%rrr'r'bsA&!!!4( ( ( ( ( ( rr'c~g}t}g}|D]} tj|rSt j|}|D]*}|||+v#ttf$rt j td|YwxYw|S)NzError reading lines from %s) r'ospathisfiler load_file splitlinesrrDIOErrorOSErrorlogexcLOG)fnameslinesparsercontentsfnamerBs rparse_authorized_keysrUs E  FHCC Cw~~e$$ 8u--88::!88DOOFLL$6$67777! C C C K:E B B B B B C OsA2B  ,B:9B:ctd|D}tdt|D]T}||}|s|D]-}|j|jkr|}||vr||.|||<U|D]}||d|D}|dd|S)Nc:g|]}||Sr%)r.0ks r z*update_authorized_keys..s%000aggii01000rrc,g|]}t|Sr%str)rYbs rr[z*update_authorized_keys..s ) ) )SVV ) ) )rr7 )listranger,rrremoverr) old_entrieskeysto_addr0r.rZkeyrQs rupdate_authorized_keysrhs 00d000 1 1F 1c+&& ' '  !nyy{{   % %Ax3:%%;;MM!$$$ A  3 * )[ ) ) )E LL 99U  rctj|}|r|jstd|ztj|jd|fS)Nz"Unable to get SSH info for user %rz.ssh)pwdgetpwnampw_dir RuntimeErrorrGrHr)usernamepw_ents rusers_ssh_inforpsU \( # #F NN?8LMMM GLL / / 88rc&d|fd|fdf}|sd}|}g}|D]j}|D]\}}|||}|ds tj||}||k|S)N%h%u)z%%%%h/.ssh/authorized_keys/)r:replacer?rGrHrr) valuehomedirrnmacrospathsrenderedrHmacrofields rrender_authorizedkeysfile_pathsrs Woh/ =F *) KKMMEH" . .LE5<<u--DDs## /7<<..D Orcd}|rd}tj|}|r,||kr&|dkr td||||dStj|}||kr|dz}n7tj|}tj|} || vr|dz}n|dz}||zd krtd |||dS|r'|d zd krtd ||dSd S)aVCheck 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) iirootzXPath %s in %s must be own by user %s or by root, but instead is own by %s. Ignoring key.F8rzBPath %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_ownerrOdebugget_permissions get_groupget_user_groups) rn current_path full_pathis_file strictmodesminimal_permissionsownerparent_permission group_owner user_groupss rcheck_permissionsrse $# N< ( (E u((Uf__  @        u,\:: u$n\22 *844 + % % 5 (   5 ( ..!33  %       u(50A55  @      u 4rct|d}tdd} |ddd}d}tj|j}|D]p}|d|zz }tj|rtd|dStj |rtd|dS| |s ||jkrtj |stj |5d } |j} |j} | |jrd } |j} |j} tj|| d tj|| | dddn #1swxYwYt%|||d|} | sdSrtj|stj|rtd |dStj |s8tj|ddd tj||j|jt%|||d |} | sdSnF#t*t,f$r2} tjtt1| Yd} ~ dSd} ~ wwxYwd S)Nr*rrvr7z-Invalid directory. Symlink exists in path: %sFz*Invalid directory. File exists in path: %srT)modeexist_okz%s is not a file!)rensure_dir_exists)rpr:rGrHdirnamerlislinkrOrrIr?existsr SeLinuxGuardpw_uidpw_gidmakedirs chownbyidrisdir write_filerLrMrNr^)rnfilenamer user_pwent root_pwent directories parent_folder home_folder directoryruidgid permissionses rcheck_create_pathrHsS))!,J''*JGnnS))!B$/  gooj&788 $* * I S9_ ,Mw~~m,,  C!uuw~~m,,  @-uu&&}55  J$5557>>-00 <&}55 < < D$+C$+C$// 0ABB0$(/(/K D4HHHHN=#s;;; < < < < < < < < < < < < < < <,-5+K uu  7>>( # # rw}}X'>'>  II)8 4 4 45w~~h'' K OHbu M M M M N8Z%6 8I J J J' h$    5  W  CQ   uuuuu 4sXB J-9;J-6AJ- A(F>2 J->G J-G J-!AJ->A,J--K0>'K++K0c dt|\}}tj|d}|}g}t j|d5 t |}|dd}|dd} t||j |}nC#ttf$r/||d<t j td t|dYnwxYwdddn #1swxYwYt||D]a\} } t#d | vd | v| d |j grt)|| | dk} | r| }nb||krtd ||t-|gfS)Nauthorized_keysT recursiveauthorizedkeysfileruryesrzhFailed extracting 'AuthorizedKeysFile' in SSH config from %r, using 'AuthorizedKeysFile' file %r insteadrsrrz{}/zAAuthorizedKeysFile has an user-specific authorized_keys, using %s)rprGrHrrrparse_ssh_config_mapgetrrlrLrMrNrO DEF_SSHD_CFGzipr:anyr?formatrrrU) rn sshd_cfg_filessh_dirrodefault_authorizedkeys_fileuser_authorizedkeys_file auth_key_fnsssh_cfg key_pathsrkey_path auth_key_fnpermissions_oks rextract_authorized_keysrsC&x00Wf"$',,w8I"J"J:L 7d 3 3 3 *=99G $&?I"++mU;;K:6=(LL!   9LO KQ       0"%Y__%6%6 !E!E  +   &&u||FM'B'BCC   /+{e';N +6(#>>>   $    !7899 s7 C0AB! C0!=C!C0 C!!C00C47C4ct}g}|D]9}||t||:t |\}}t j|}tj |d5t||} tj || dddddS#1swxYwYdS)N)rTr preserve_mode) r'rrDr^rrGrHrrrrhr) rernrrR key_entriesrZrauth_key_entriesrcontents rsetup_user_keysrs-  FK BB6<<A<@@AAAA'>h&G&G#["gook**G 7d 3 3 3BB()9;GG  WDAAAABBBBBBBBBBBBBBBBBBs(C  C C c2eZdZddZedZdZdS)SshdConfigLineNc0||_||_||_dSr)rB_keyrx)rrBrZvs rrzSshdConfigLine.__init__s   rcF|jdS|jSr)rlowerrs rrgzSshdConfigLine.keys! 9 4y   rc|jt|jSt|j}|jr|dt|jzz }|Sr)rr^rBrx)rrs rr!zSshdConfigLine.__str__sK 9 ty>> !DIAz +S3tz??**Hr)NN)r"r#r$rpropertyrgr!r%rrrrsR !!X! rrctj|sgStt j|Sr)rGrHrIparse_ssh_config_linesrrJrK)rTs rparse_ssh_configrsA 7>>%  !$."7"7"B"B"D"D E EErcg}|D]}|}|r|dr#|t|P |dd\}}nW#t $rJ |dd\}}n,#t $rt d|YYwxYwYnwxYw|t||||S)Nr6r*=z;sshd_config: option "%s" has no key/value pair, skipping it)r@r?rrr: ValueErrorrOr)rQretrBrgvals rrrs% C33zz|| ts++  JJ~d++ , , ,  zz$**HC    ::c1--SS    #   S  >$S112222 Js6A00 C;BC%B>:C=B>>CCcht|}|siSi}|D]}|js |j||j<|Sr)rrgrx)rTrQrrBs rrrsQ U # #E  C##x   DH JrrTreturnctj|sdSt|d5}|D])}|d|drddddS* dddn #1swxYwYdS)NFrzInclude z .d/*.confT)rGrHrIopenr?)rTfrBs r_includes_dconfr#s 7>>% u eS  Q  D:%:::;;    5sA,A,,A03A0ct|rtj|dst j|ddtj|dd}tj|st j|dt|}t||}|r7t j |dd|Ddzd t|d kS) zRead fname, and update if changes are necessary. @param updates: dictionary of desired values {Option: value} @return: boolean indicating if an update was done.z.dr)rz50-cloud-init.confr)rQupdatesr`c,g|]}t|Sr%r])rYrBs rr[z%update_ssh_config..>s333Ts4yy333rTrr) rrGrHrr ensure_dirrrI ensure_filerupdate_ssh_config_linesrr,)rrTrQchangeds rupdate_ssh_configr-s  u+w}}\\\** 6 OuLLLu 5 5 5 5 \\\+?@@w~~e$$ +  UE * * * U # #E%E7CCCG    II33U333 4 4t ;    w<<1 rc4t}g}td|D}t|dD]\}}|js |j|vr||j}||}|||j|krtd|||i| |td|||j|||_t|t|kr| D]m\}}||vr | || td||tdt|||n|S)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.c:g|]}||fSr%)rrXs rr[z+update_ssh_config_lines..Ns$;;;qQWWYYN;;;rr*)startz$line %d: option %s already set to %sz#line %d: option %s updated %s -> %sr7z line %d: option %s added with %s) setdictre enumeratergaddrxrOrrr,itemsr) rQrfoundrcasemapr0rBrgrxs rrrDs EEEG;;GLLNN;;;<rs( $$$$$$g!!& 2 c())*-00"""""""":V V V V V V V V r    8999*BBBJLLL^5A6666r B B B B.FFF 6   34&2.+++++r