U
    2ÜŸj•0  ã                	   @  sÔ  d Z ddlm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	 ddl
mZ ddlmZ ddlmZmZmZ ddlmZ dd	lmZmZmZmZ ejejkräzddlZejejf W n* eefk
râ   dejd
< eeƒ Y nX 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,d9d#d$d%d%d&œd'd(„Z-d#d)d*œd+d,„Z.d-d.„ Z/d/d0„ Z0d%d%d1œd2d3„Z1d:d4d#d$d)d5œd6d7„Z2e3d8k�rÐe%ƒ  dS );z2
Implementation module for the `ckeygen` command.
é    )ÚannotationsN)ÚCallable)Úwraps)Úreload)ÚAnyÚDictÚOptional)Úkeys)ÚfailureÚfilepathÚlogÚusageÚtermiosc                   s   ‡ fdd„}|S )Nc                   s    t ˆ ƒ‡ fdd„ƒ}|tˆ< |S )Nc                    s
   ˆ | |ŽS ©N© )ÚargsÚkwargs©Úkeygeneratorr   úA/tmp/pip-unpacked-wheel-4b529toj/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ddddgdddd	gd
dddgddddgddddgddddgddddgddddggZdddgdd d!gd"d#d$gd%dd&gd'd(d)g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ÚfzFilename of the key file.ÚtypeÚtzSpecify type of key to create.ÚcommentÚCzProvide new comment.ÚnewpassÚNzProvide new passphrase.ÚpassÚPzProvide old passphrase.ÚformatÚoúsha256-base64zFingerprint format of key file.úprivate-key-subtypez5OpenSSH 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-passphrasez"Create the key with no passphrase.ÚshowpubÚyz+Read private key file and print public key.ÚPEMÚv1)r!   r,   )Z
optActions)Ú__name__Ú
__module__Ú__qualname__ZsynopsisZlongdescZoptParametersZoptFlagsr   ZCompletionsZCompleteListÚlistr   r	   ZcompDatar   r   r   r   r   /   s4   






üøûþÿr   c               
   C  s  t ƒ } z|  tjdd … ¡ W nB tjk
r` } z"td| ƒ |  ¡  t d¡ W 5 d }~X Y nX t	 
¡  tt	_| d rÐ| d  ¡ tkr®td| d  ƒ t| d  ¡  | ƒ n t d| d d t ¡ ¡f ¡ nJ| d rât| ƒ n8| d rôt| ƒ n&| d	 �rt| ƒ n|  ¡  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/   r4   )r   ZparseOptionsÚsysÚargvr   Z
UsageErrorÚprintZopt_helpÚexitr   ZdiscardLogsÚhandleErrorZdeferrÚlowerr   Újoinr	   ÚprintFingerprintÚchangePassPhraseÚdisplayPublicKey)ÚoptionsÚur   r   r   ÚrunU   s4    ÿÿ



rI   c                 C  sP   | d dkrt jj| d< | S | d dkr8t jj| d< | S t  d| d › �¡‚d S )Nr)   zmd5-hexr+   z Unsupported fingerprint format: )r	   ZFingerprintFormatsZMD5_HEXZSHA256_BASE64ZBadFingerPrintFormat)rG   r   r   r   Úenumrepresentations   s    ÿrJ   c                   C  s   da t t ¡ ¡ ‚ d S )Né   )Z
exitStatusr   Úerrr
   ZFailurer   r   r   r   rA   €   s    rA   Ú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)rM   r   i   i  )Úkey_sizeZpublic_exponentÚbackend)	Úcryptography.hazmat.backendsrO   Ú)cryptography.hazmat.primitives.asymmetricrM   Úgenerate_private_keyÚintr	   ÚKeyÚ_saveKey)rG   rO   rM   ÚkeyPrimitiveÚkeyr   r   r   ÚgenerateRSAkey‡   s    
ý
rZ   Údsac                 C  sX   ddl m} ddlm} | d s(d| d< |jt| d ƒ|ƒ d�}t |¡}t|| ƒ d S )Nr   rN   )r[   r   i   )rP   rQ   )	rR   rO   rS   r[   rT   rU   r	   rV   rW   )rG   rO   r[   rX   rY   r   r   r   ÚgenerateDSAkey—   s    
þ
r\   Ú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   rN   )Úecr   é   s   ecdsa-sha2-nistpÚascii)ÚcurverQ   )rR   rO   rS   r^   ÚstrÚencoderT   r	   Z_curveTablerV   rW   )rG   rO   r^   ra   rX   rY   r   r   r   ÚgenerateECDSAkey¦   s     ÿ
rd   Úed25519c                 C  s"   t j ¡ }t  |¡}t|| ƒ d S r   )r	   ZEd25519PrivateKeyÚgeneraterV   rW   )rG   rX   rY   r   r   r   ÚgenerateEd25519key·   s    

rg   c                 C  s   | dkrdS 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'}).
    ÚEd25519r7   r6   Nr   r   r   r   r   Ú_defaultPrivateKeySubtype¾   s    ri   zDict[Any, Any]zOptional[Callable[[str], str]]rb   )rG   ÚinputCollectorÚkeyTypeNameÚreturnc                 C  s`   |dkrt }| d }|sXtj d|› �¡}t ¡ dkrHtj d|› �¡}|d| ƒpV|}t|ƒS )a  
    If C{options["filename"]} is None, prompt the user to enter a path
    or attempt to set it to .ssh/id_rsa
    @param options: command line options
    @param inputCollector: dependency injection for testing
    @param keyTypeName: key type or "rsa"
    Nr   z
~/.ssh/id_ÚWindowsz%HOMEPATH %\.ssh\id_z%Enter file in which the key is (%s): )ÚinputÚosÚpathÚ
expanduserÚplatformÚsystemrb   )rG   rj   rk   r   r   r   r   Ú_getKeyOrDefaultÐ   s    þrt   ÚNone)rG   rl   c                 C  s¨   t | ƒ}tj |d ¡r |d7 }t| ƒ} z8tj |¡}td| 	¡ | 
| d ¡tj |¡f ƒ W nB tjk
r€   t d¡ Y n$ tk
r¢   t |› d�¡ Y nX d S )Nú.pubz%s %s %sr)   zbad keyú, could not be opened, please specify a file.)rt   ro   rp   ÚexistsrJ   r	   rV   ÚfromFiler?   Úsizer-   ÚbasenameÚBadKeyErrorr=   r@   ÚFileNotFoundError)rG   r   rY   r   r   r   rD   ê   s$    
ýÿÿrD   c                 C  s@  t | ƒ}ztj |¡}W nð tjk
r²   |  d¡sBt d¡| d< ztjj|| d d�}W nR tjk
rz   t 	d¡ Y n4 tjk
r¬ } zt 	d|› �¡ W 5 d }~X Y nX Y nX tjk
rä } zt 	d|› �¡ W 5 d }~X Y n& t
k
�r   t 	|› d�¡ Y nX |  d¡�sLt d¡}t d	¡}||k�r8�qDtd
ƒ �q|| d< |  d¡d k�rlt| ¡ ƒ| d< z|jd| d | d d�}W n4 tk
�r¼ } zt 	d|› �¡ W 5 d }~X Y nX ztjj|| d d� W n< tjtjfk
�r } zt 	d|› �¡ W 5 d }~X Y nX t|dƒ�}| |¡ W 5 Q R X tdƒ d S )Nr'   zEnter old passphrase: ©Ú
passphrasez1Could not change passphrase: old passphrase errorzCould not change passphrase: rw   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.)rt   r	   rV   ry   ÚEncryptedKeyErrorÚgetÚgetpassr|   r=   r@   r}   r?   ri   r!   ÚtoStringÚ	ExceptionZ
fromStringÚopenÚwrite)rG   r   rY   ÚeÚp1Úp2Z
newkeydataÚfdr   r   r   rE   ÿ   sP    
& 


ý
""rE   c                 C  sž   t | ƒ}ztj |¡}W nd tk
r<   t |› d�¡ Y nB tjk
r|   |  d¡sdt	 	d¡| d< tjj|| d d�}Y nX | 
¡  d¡ d¡}t|ƒ d S )Nrw   r'   zEnter passphrase: r~   r‚   r`   )rt   r	   rV   ry   r}   r=   r@   r†   r‡   rˆ   Úpublicr‰   Údecoder?   )rG   r   rY   Z
displayKeyr   r   r   rF   2  s    
rF   )Úpromptrl   c                 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.
    )rn   )r“   r   r   r   Ú_inputSaveFile@  s    r”   zkeys.Key)rY   rG   rj   rl   c                 C  s¸  |dkrt }dddddœ}||  ¡  }|d }|sZt|||ƒ}td|› d	�ƒ}| ¡ pX|}tj |¡r”t|› d
�ƒ |dƒ}|d  	¡ dkr”t
 ¡  | d¡r¨d|d< n8|d sàt d¡}	t d¡}
|	|
krÎqØtdƒ q°|	|d< | d¡dkrþt|  ¡ ƒ|d< t ¡ › dt ¡ › �}t |¡}| | jd|d |d d�¡ | d¡ t |d ¡ |  ¡ jd|d�¡ t|ƒ}td|› �ƒ td|› d�ƒ td|d › d�ƒ t|  |d ¡ƒ dS ) zÀ
    Persist a SSH key on local filesystem.

    @param key: Key which is persisted on local filesystem.

    @param options:

    @param inputCollector: Dependency injection for testing.
    Nr]   re   rM   r[   )ZECrh   ZRSAZDSAr   z%Enter file in which to save the key (z): z already exists.zOverwrite (y/n)? r   r5   r3   ó    r'   z,Enter passphrase (empty for no passphrase): r€   r�   r,   ú@r‚   rƒ   i€�  rv   )r#   z&Your identification has been saved in z"Your public key has been saved in zThe key fingerprint in r)   z is:)rn   r!   rt   r”   Ústripro   rp   rx   r?   rB   r=   r@   r‡   rˆ   ri   ÚgetuserÚsocketÚgethostnamer   ZFilePathZ
setContentr‰   Úchmodr‘   rJ   r-   )rY   rG   rj   ZKeyTypeMappingrk   r   ZdefaultPathZnewPathZynrŽ   r�   r#   Úfpr   r   r   rW   I  sZ    
ÿ





ýÿ
ÿrW   Ú__main__)NrM   )N)4Ú__doc__Ú
__future__r   rˆ   ro   rr   r™   r=   Úcollections.abcr   Ú	functoolsr   Ú	importlibr   Útypingr   r   r   Ztwisted.conch.sshr	   Ztwisted.pythonr
   r   r   r   Úunix_getpassr   Ú	tcgetattrÚ	tcsetattrÚImportErrorÚAttributeErrorÚmodulesÚdictr   r   ÚOptionsr   rI   rJ   rA   rZ   r\   rd   rg   ri   rt   rD   rE   rF   r”   rW   r8   r   r   r   r   Ú<module>   sZ   
&



  ý3 ýF
