o
    ¯b1-  ã                	   @   sv  d Z ddlZddlZddlZddlZddlmZ ddlmZ ddl	m
Z
 ddlmZmZmZmZ ejejkrWzddlZejejf W n eefyV   dejd< eeƒ Y nw eƒ Zdd	„ ZG d
d„ dejƒZdd„ Zdd„ Zdd„ Zedƒdd„ ƒZedƒdd„ ƒZ edƒdd„ ƒZ!edƒdd„ ƒZ"dd„ Z#d d!„ Z$d"d#„ Z%d$d%„ Z&d&e'd'e'fd(d)„Z(d*d+„ Z)e*d,kr¹eƒ  dS dS )-z2
Implementation module for the `ckeygen` command.
é    N)Úwraps)Úreload)Úkeys)ÚfailureÚfilepathÚlogÚusageÚtermiosc                    s   ‡ fdd„}|S )Nc                    s    t ˆ ƒ‡ fdd„ƒ}|tˆ< |S )Nc                     s   ˆ | i |¤ŽS )N© )ÚargsÚkwargs©Úkeygeneratorr
   ú?/usr/lib/python3/dist-packages/twisted/conch/scripts/ckeygen.pyÚwrapper"   s   z:_keyGenerator.<locals>.assignkeygenerator.<locals>.wrapper)r   ÚsupportedKeyTypes)r   r   ©ÚkeyTyper   r   Úassignkeygenerator!   s   z)_keyGenerator.<locals>.assignkeygeneratorr
   )r   r   r
   r   r   Ú_keyGenerator    s   r   c                	   @   s”   e Zd ZdZdZg d¢g d¢g d¢g d¢g d¢g d¢g d	¢g d
¢gZg d¢g d¢g d¢g d¢g d¢gZeje 	e
e ¡ ƒ¡e 	ddg¡dœd�ZdS )ÚGeneralOptionszUsage:    ckeygen [options]
 z8ckeygen manipulates public/private keys in various ways.)ÚbitsÚbNz$Number of bits in the key to create.)ÚfilenameÚfNzFilename of the key file.)ÚtypeÚtNzSpecify type of key to create.)ÚcommentÚCNzProvide new comment.)ÚnewpassÚNNzProvide new passphrase.)ÚpassÚPNzProvide old passphrase.)ÚformatÚoúsha256-base64zFingerprint format of key file.)úprivate-key-subtypeNNz5OpenSSH private key subtype to write ("PEM" or "v1").)ÚfingerprintÚlzShow fingerprint of key file.)Ú
changepassÚpz&Change passphrase of private key file.)ÚquietÚqzQuiet.)úno-passphraseNz"Create the key with no passphrase.)ÚshowpubÚyz+Read private key file and print public key.ÚPEMÚv1)r   r&   )Ú
optActionsN)Ú__name__Ú
__module__Ú__qualname__ÚsynopsisÚlongdescÚoptParametersÚoptFlagsr   ÚCompletionsÚCompleteListÚlistr   r   ÚcompDatar
   r
   r
   r   r   ,   s.    øûþ
ÿr   c               
   C   s(  t ƒ } z|  tjdd … ¡ W n" tjy1 } ztd| ƒ |  ¡  t d¡ W Y d }~nd }~ww t	 
¡  tt	_| d rk| d  ¡ tv rYtd| d  ƒ t| d  ¡  | ƒ d S t d| d d t ¡ ¡f ¡ d S | d rut| ƒ d S | d rt| ƒ d S | d	 r‰t| ƒ d S |  ¡  t d¡ d S )
Né   z	ERROR: %sr   z&Generating public/private %s key pair.z"Key type was %s, must be one of %sz, r'   r)   r.   )r   ÚparseOptionsÚsysÚargvr   Ú
UsageErrorÚprintÚopt_helpÚexitr   ÚdiscardLogsÚhandleErrorÚdeferrÚlowerr   Újoinr   ÚprintFingerprintÚchangePassPhraseÚdisplayPublicKey)ÚoptionsÚur
   r
   r   ÚrunR   s8   €ýÿÿrP   c                 C   sL   | d dkrt jj| d< | S | d dkrt jj| d< | S t  d | d ¡¡‚)Nr#   zmd5-hexr%   z"Unsupported fingerprint format: {})r   ÚFingerprintFormatsÚMD5_HEXÚSHA256_BASE64ÚBadFingerPrintFormatr#   )rN   r
   r
   r   Úenumrepresentationp   s   ÿrU   c                   C   s   da t t ¡ ¡ ‚ )Né   )Ú
exitStatusr   Úerrr   ÚFailurer
   r
   r
   r   rG   }   s   rG   Úrsac                 C   sZ   ddl m} ddlm} | d sd| d< |jt| d ƒd|ƒ d�}t |¡}t|| ƒ d S )Nr   ©Údefault_backend)rZ   r   é   i  )Úkey_sizeÚpublic_exponentÚbackend)	Úcryptography.hazmat.backendsr\   Ú)cryptography.hazmat.primitives.asymmetricrZ   Úgenerate_private_keyÚintr   ÚKeyÚ_saveKey)rN   r\   rZ   ÚkeyPrimitiveÚkeyr
   r
   r   ÚgenerateRSAkey„   s   
ý
ri   Údsac                 C   sX   ddl m} ddlm} | d sd| d< |jt| d ƒ|ƒ d�}t |¡}t|| ƒ d S )Nr   r[   )rj   r   r]   )r^   r`   )	ra   r\   rb   rj   rc   rd   r   re   rf   )rN   r\   rj   rg   rh   r
   r
   r   ÚgenerateDSAkey”   s   
þ
rk   Úecdsac                 C   sl   ddl m} ddlm} | d sd| d< dt| d ƒ d¡ }|jtj| |ƒ d�}t 	|¡}t
|| ƒ d S )	Nr   r[   )Úecr   é   s   ecdsa-sha2-nistpÚascii)Úcurver`   )ra   r\   rb   rm   ÚstrÚencoderc   r   Ú_curveTablere   rf   )rN   r\   rm   rp   rg   rh   r
   r
   r   ÚgenerateECDSAkey£   s   ÿ
rt   Úed25519c                 C   s.   ddl m} |j ¡ }t |¡}t|| ƒ d S )Nr   )ru   )rb   ru   ÚEd25519PrivateKeyÚgenerater   re   rf   )rN   ru   rg   rh   r
   r
   r   ÚgenerateEd25519key´   s   

rx   c                 C   s   | dkrdS dS )a  
    Return a reasonable default private key subtype for a given key type.

    @type keyType: L{str}
    @param keyType: A key type, as returned by
        L{twisted.conch.ssh.keys.Key.type}.

    @rtype: L{str}
    @return: A private OpenSSH key subtype (C{'PEM'} or C{'v1'}).
    ÚEd25519r1   r0   r
   r   r
   r
   r   Ú_defaultPrivateKeySubtype½   s   rz   c                 C   s´   | d st j d¡}td| ƒ| d< t j | d d ¡r$| d  d7  < t| ƒ} z!tj | d ¡}t	d| 
¡ | | d ¡t j | d ¡f ƒ W d S  tjyY   t d¡ Y d S w )Nr   ú~/.ssh/id_rsaú%Enter file in which the key is (%s): ú.pubz%s %s %sr#   zbad key)ÚosÚpathÚ
expanduserÚinputÚexistsrU   r   re   ÚfromFilerC   Úsizer'   ÚbasenameÚBadKeyErrorr@   rE   )rN   r   rh   r
   r
   r   rK   Ï   s&   ýÿ
ÿÿrK   c                 C   sT  | d st j d¡}td| ƒ| d< z
tj | d ¡}W nh tjyj   |  d¡s0t	 	d¡| d< ztjj| d | d d�}W n) tj
yM   t d¡ Y n tjyg } zt d|› �¡ W Y d }~nd }~ww Y n tj
y„ } zt d|› �¡ W Y d }~nd }~ww |  d	¡s£	 t	 	d¡}t	 	d¡}||kršntdƒ q‹|| d	< |  d¡d u r²t| ¡ ƒ| d< z|jd| d | d	 d�}W n tyÚ } zt d|› �¡ W Y d }~nd }~ww ztjj|| d	 d� W n tjtj
f�y } zt d|› �¡ W Y d }~nd }~ww t| d dƒ�}| |¡ W d   ƒ n	1 �sw   Y  tdƒ d S )Nr   r{   r|   r!   zEnter old passphrase: ©Ú
passphrasez1Could not change passphrase: old passphrase errorzCould not change passphrase: r   r>   z0Enter new passphrase (empty for no passphrase): úEnter same passphrase again: ú%Passphrases do not match.  Try again.r&   Úopenssh©Úsubtyperˆ   Úwbz;Your identification has been saved with the new passphrase.)r~   r   r€   r�   r   re   rƒ   ÚEncryptedKeyErrorÚgetÚgetpassr†   r@   rE   rC   rz   r   ÚtoStringÚ	ExceptionÚ
fromStringÚopenÚwrite)rN   r   rh   ÚeÚp1Úp2Ú
newkeydataÚfdr
   r
   r   rL   ä   sh   
€ÿ€€ÿ


û
ý€ÿ€ÿÿrL   c                 C   sž   | d st j d¡}td| ƒ| d< z
tj | d ¡}W n" tjy>   |  d¡s0t	 	d¡| d< tjj| d | d d�}Y nw | 
¡  d¡ d¡}t|ƒ d S )	Nr   r{   r|   r!   zEnter passphrase: r‡   r‹   ro   )r~   r   r€   r�   r   re   rƒ   r�   r�   r‘   Úpublicr’   ÚdecoderC   )rN   r   rh   Ú
displayKeyr
   r
   r   rM     s   
ýrM   ÚpromptÚreturnc                 C   s   t | ƒS )zv
    Ask the user where to save the key.

    This needs to be a separate function so the unit test can patch it.
    )r�   )rŸ   r
   r
   r   Ú_inputSaveFile%  s   r¡   c           
      C   sÊ  dddddœ}||   ¡  }|d s*tj d|› �¡}td|› d	�ƒ}| ¡ p'||d< tj |d ¡rKtd
 |d ¡ƒ t	dƒ}|d  
¡ dkrKt ¡  | d¡rUd|d< n|d sr	 t d¡}t d¡}||krintdƒ qZ||d< | d¡du r�t|   ¡ ƒ|d< t ¡ › dt ¡ › �}	t |d ¡ | jd|d |d d�¡ t |d d¡ t |d d ¡ |  ¡ jd|	d�¡ t|ƒ}td |d ¡ƒ td |d ¡ƒ td |d  ¡ƒ t|  |d  ¡ƒ dS )!zÈ
    Persist a SSH key on local filesystem.

    @param key: Key which is persisted on local filesystem.
    @type key: C{keys.Key} implementation.

    @param options:
    @type options: L{dict}
    rl   ru   rZ   rj   )ÚECry   ÚRSAÚDSAr   z
~/.ssh/id_z%Enter file in which to save the key (z): z{} already exists.zOverwrite (y/n)? r   r/   r-   ó    r!   r>   z,Enter passphrase (empty for no passphrase): r‰   rŠ   r&   Nú@r‹   rŒ   i€�  r}   )r   z(Your identification has been saved in {}z(Your public key has been saved in {}.pubzThe key fingerprint in {} is:r#   )r   r~   r   r€   r¡   Ústripr‚   rC   r#   r�   rI   r@   rE   r�   r‘   rz   ÚgetuserÚsocketÚgethostnamer   ÚFilePathÚ
setContentr’   Úchmodrœ   rU   r'   )
rh   rN   ÚKeyTypeMappingÚkeyTypeNameÚdefaultPathÚnewPathÚynr˜   r™   r   r
   r
   r   rf   .  sV   

ÿ



ûýÿÿrf   Ú__main__)+Ú__doc__r‘   r~   r©   r@   Ú	functoolsr   Úimpr   Útwisted.conch.sshr   Útwisted.pythonr   r   r   r   Úunix_getpassr	   Ú	tcgetattrÚ	tcsetattrÚImportErrorÚAttributeErrorÚmodulesÚdictr   r   ÚOptionsr   rP   rU   rG   ri   rk   rt   rx   rz   rK   rL   rM   rq   r¡   rf   r3   r
   r
   r
   r   Ú<module>   sP   
þ&



3	>
ÿ