o
    f,                  
   @   s  U d Z ddlZddlZddlZddlZddlZddlmZmZm	Z	 ddl
mZmZmZmZ ddlmZ ddlmZ ddlmZ ddlmZmZ dd	lmZ d
egeg dZeed< eeZg dZdgZ e!dZ"dZ#dZ$g Z%ee& ed< i Z'i Z(eD ]2Z)e'*e) de#e) dfe) de#e)  ddfe) de#e)  ddfi e) de(e) d< q|dZ+de&ddfddZ,de&d ed!ed"e-ddf
d#d$Z.d%d& Z/d*d'ee	e&  fd(d)Z0dS )+zSSH: Configure SSH and SSH keys    N)ListOptionalSequence)	lifecyclessh_utilsubputil)Cloud)Config)
MetaSchema)ALL_DISTROSug_util)PER_INSTANCEcc_ssh)iddistros	frequencyactivate_by_schema_keysmeta)rsaecdsaed25519r   z4^(ecdsa-sk|ed25519-sk)_(private|public|certificate)$z/etc/ssh/ssh_host_%s_keyTHOST_KEY_PUBLISH_BLACKLIST_private  _public.pub  _certificatez	-cert.pubz;o=$(ssh-keygen -yf "%s") && echo "$o" root@localhost > "%s"keyfilereturnc                 C   sl   d}t  }|r|tddk rd}nd}td}|dkr%t| d| t| | t|  d| d	S )
a  
    For fedora 37, centos 9 stream and below:
     - sshd version is earlier than version 9.
     - 'ssh_keys' group is present and owns the private keys.
     - private keys have permission 0o640.
    For fedora 38, centos 10 stream and above:
     - ssh version is atleast version 9.
     - 'ssh_keys' group is absent. 'root' group owns the keys.
     - private keys have permission 0o600, same as upstream.
    Public keys in all cases have permission 0o644.
    r   	   r   i  r   ssh_keysr   N)	r   get_opensshd_upstream_versionr   Versionr   get_group_idoschownchmod)r   permissions_publicssh_versionpermissions_privategid r.   9/usr/lib/python3/dist-packages/cloudinit/config/cc_ssh.pyset_redhat_keyfile_perms@   s   
r0   namecfgcloudargsc           $      C   s  | ddr,tjdd}t|D ]}zt| W q ty+   tt	d| Y qw d|v rg }|d 
 D ]:\}}|tvrRt|rHd}	nd}	t	d	|	| q8t| d
 }
t| d }t|
|| d|v rr|dt|
f q8|rzt| t
 D ]c\}}||d v s||d vrq~t| d
 t| d
 }}ddt||f g}z'tjddd tj|dd W d    n1 sw   Y  t	d|| W q~ ty   tt	d| d|  Y q~w nt|dt}t s|ndd |D }t||}|r
t	dd| |D ]}t| }tj|rqt tj!| dd|ddd |g}tjdddl z*tj|dd!d"id#\}}t"|d$dsSt#j$%t&| |j'j(d%kr^t)| W n9 tj*y } z+t&|j+, }|j-dkr|, .d&rt	d'| ntt	d(|| W Y d }~nd }~ww W d    n	1 sw   Y  qd)|v rt|d) d*t/}t"|d) d+t0}nt/}t0}|rt1|d,}z|j23| W n ty   tt	d- Y nw zNt45||j'\}}t46|\}}t"|d.d} t7|d/tj8}!g }"t"|d0dr|9 pg }"nt	d1 d2|v r-|d2 }#|":|# t;|"|| |! W d S  tyG   tt	d3 Y d S w )4Nssh_deletekeysTz	/etc/ssh/zssh_host_*key*zFailed deleting key file %sr"   unsupportedunrecognizedz Skipping %s ssh_keys entry: "%s"r      r   HostCertificateshz-xcz/etc/ssh)	recursiveF)capturezGenerated a key for %s from %szFailed generating a key for z from ssh_genkeytypesc                 S   s   g | ]}|t vr|qS r.   )FIPS_UNSUPPORTED_KEY_NAMES).0namesr.   r.   r/   
<listcomp>   
    zhandle.<locals>.<listcomp>z5skipping keys that are not supported in fips mode: %s,z
ssh-keygenz-tz-N z-fLANGC)r<   
update_envssh_quiet_keygenredhatzunknown keyz!ssh-keygen: unknown key type '%s'z(Failed generating key type %s to file %sssh_publish_hostkeys	blacklistenabled)rK   zPublishing host keys failed!disable_rootdisable_root_optsallow_public_ssh_keyszSSkipping import of publish SSH keys per config setting: allow_public_ssh_keys=Falsessh_authorized_keysz Applying SSH credentials failed!)<getr'   pathjoinglobr   del_file	ExceptionlogexcLOGitemsCONFIG_KEY_TO_FILEpattern_unsupported_config_keysmatchwarning
write_fileappendstrr   append_ssh_configPRIV_TO_PUBKEY_GEN_TPLSeLinuxGuardr   debugget_cfg_option_listGENERATE_KEY_NAMESfips_enabledset
differenceKEY_FILE_TPLexists
ensure_dirdirnameget_cfg_option_boolsysstdoutwritedecode_binarydistroosfamilyr0   ProcessExecutionErrorstderrlower	exit_code
startswithr   PUBLISH_HOST_KEYSget_public_host_keys
datasourcepublish_host_keysr   normalize_users_groupsextract_defaultget_cfg_option_strDISABLE_USER_OPTSget_public_ssh_keysextendapply_credentials)$r1   r2   r3   r4   key_pthfcert_configkeyvalreasontgt_fn	tgt_permsprivate_typepublic_typeprivate_filepublic_filecmdgenkeys	key_namesskipped_keyskeytyper   outerrehost_key_blacklistpublish_hostkeyshostkeysusers_groupsuser_user_configrM   rN   keyscfgkeysr.   r.   r/   handled   s  



	






r   c                 C   sV   t | } |rt| | |r|sd}|d|}|dd}nd}tj| d|d d S )NNONEz$USERz$DISABLE_USERrootrD   )options)ri   r   setup_user_keysreplace)r   r   rM   rN   
key_prefixr.   r.   r/   r     s   r   rK   c                    s   dt f g }g  | rfdd| D   fddtd D }|D ]}t|}| }|rBt|dkrB|t|dd  q$|S )	a  Read host keys from /etc/ssh/*.pub files and return them as a list.

    @param blacklist: List of key types to ignore. e.g. ['rsa']
    @returns: List of keys, each formatted as a two-element tuple.
        e.g. [('ssh-rsa', 'AAAAB3Nz...'), ('ssh-ed25519', 'AAAAC3Nx...')]
    z%s.pubc                    s   g | ]} |f qS r.   r.   )r?   key_type)public_key_file_tmplr.   r/   rA      s    
z(get_public_host_keys.<locals>.<listcomp>c                    s   g | ]}| vr|qS r.   r.   )r?   hostfile)blacklist_filesr.   r/   rA   $  rB   )*r8   N   )rk   rT   r   load_text_filesplitlenr_   tuple)rK   key_list	file_list	file_namefile_contentskey_datar.   )r   r   r/   r|     s"   



r|   )N)1__doc__rT   loggingr'   rerp   typingr   r   r   	cloudinitr   r   r   r   cloudinit.cloudr	   cloudinit.configr
   cloudinit.config.schemar   cloudinit.distrosr   r   cloudinit.settingsr   r   __annotations__	getLogger__name__rX   rg   r>   compiler[   rk   r{   r   r`   rZ   rb   kupdaterc   r0   listr   r   r|   r.   r.   r.   r/   <module>   sV   
$ 