Ë
    ojÀM  ã                   ó   — d Z ddlZddlZddl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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 ddlmZ ddlmZ ddl m!Z!  e«       Z"d„ Z#d„ Z$ G d„ d«      Z% ee«       G d„ de%«      «       Z& ee«       G d„ d«      «       Z'd„ Z( ee«       G d„ de%e!«      «       Z) G d„ d«      Z* G d„ d«      Z+y)zE
An implementation of the OpenSSH known_hosts database.

@since: 8.2
é    N)ÚErrorÚ
a2b_base64Ú
b2a_base64)Úclosing)Úsha1)Úimplementer)ÚHostKeyChangedÚInvalidEntryÚUserRejectedKey)ÚIKnownHostEntry)ÚBadKeyErrorÚFingerprintFormatsÚKey)Údefer)ÚLogger)ÚnativeString)ÚsecureRandom)ÚFancyEqMixinc                 ó4   — t        | «      j                  «       S )z½
    Encode a binary string as base64 with no trailing newline.

    @param s: The string to encode.
    @type s: L{bytes}

    @return: The base64-encoded string.
    @rtype: L{bytes}
    )r   Ústrip)Úss    úA/usr/lib/python3/dist-packages/twisted/conch/client/knownhosts.pyÚ
_b64encoder       s   € ô �a‹=×ÑÓ Ð ó    c                 ó&  — | j                  dd«      }t        |«      dk7  r
t        «       ‚|\  }}}|j                  dd«      }t        |«      dk(  r|\  }}|j                  d«      }n|d   }d}t	        j
                  t        |«      «      }||||fS )aµ  
    Extract common elements of base64 keys from an entry in a hosts file.

    @param string: A known hosts file entry (a single line).
    @type string: L{bytes}

    @return: a 4-tuple of hostname data (L{bytes}), ssh key type (L{bytes}), key
        (L{Key}), and comment (L{bytes} or L{None}).  The hostname data is
        simply the beginning of the line up to the first occurrence of
        whitespace.
    @rtype: L{tuple}
    Né   é   é   ó   
r   )ÚsplitÚlenr
   Úrstripr   Ú
fromStringr   )	ÚstringÚelementsÚ	hostnamesÚkeyTypeÚkeyAndCommentÚsplitkeyÚ	keyStringÚcommentÚkeys	            r   Ú_extractCommonr-   -   sš   € ð �|‰|˜D !Ó$€HÜ
ˆ8ƒ}˜ÒÜ‹nÐØ(0Ñ%€Iˆw˜Ø×"Ñ" 4¨Ó+€HÜ
ˆ8ƒ}˜ÒØ%Ñˆ	�7Ø—.‘. Ó'‰à˜Q‘Kˆ	ØˆÜ
�.‰.œ IÓ.Ó
/€CØ�g˜s GÐ+Ð+r   c                   ó   — e Zd ZdZd„ Zd„ Zy)Ú
_BaseEntryaª  
    Abstract base of both hashed and non-hashed entry objects, since they
    represent keys and key types the same way.

    @ivar keyType: The type of the key; either ssh-dss or ssh-rsa.
    @type keyType: L{bytes}

    @ivar publicKey: The server public key indicated by this line.
    @type publicKey: L{twisted.conch.ssh.keys.Key}

    @ivar comment: Trailing garbage after the key line.
    @type comment: L{bytes}
    c                 ó.   — || _         || _        || _        y ©N)r'   Ú	publicKeyr+   )Úselfr'   r2   r+   s       r   Ú__init__z_BaseEntry.__init__X   s   € ØˆŒØ"ˆŒØˆ�r   c                 ó    — | j                   |k(  S )a  
        Check to see if this entry matches a given key object.

        @param keyObject: A public key object to check.
        @type keyObject: L{Key}

        @return: C{True} if this entry's key matches C{keyObject}, C{False}
            otherwise.
        @rtype: L{bool}
        )r2   )r3   Ú	keyObjects     r   Ú
matchesKeyz_BaseEntry.matchesKey]   s   € ð �~‰~ Ñ*Ð*r   N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r4   r7   © r   r   r/   r/   I   s   „ ñòó
+r   r/   c                   ó>   ‡ — e Zd ZdZˆ fd„Zed„ «       Zd„ Zd„ Zˆ xZ	S )Ú
PlainEntryzÖ
    A L{PlainEntry} is a representation of a plain-text entry in a known_hosts
    file.

    @ivar _hostnames: the list of all host-names associated with this entry.
    @type _hostnames: L{list} of L{bytes}
    c                 ó6   •— || _         t        ‰| �	  |||«       y r1   )Ú
_hostnamesÚsuperr4   )r3   r&   r'   r2   r+   Ú	__class__s        €r   r4   zPlainEntry.__init__u   s   ø€ Ø#ˆŒÜ‰Ñ˜ )¨WÕ5r   c                 óZ   — t        |«      \  }}}} | |j                  d«      |||«      }|S )a¶  
        Parse a plain-text entry in a known_hosts file, and return a
        corresponding L{PlainEntry}.

        @param string: a space-separated string formatted like "hostname
        key-type base64-key-data comment".

        @type string: L{bytes}

        @raise DecodeError: if the key is not valid encoded as valid base64.

        @raise InvalidEntry: if the entry does not have the right number of
        elements and is therefore invalid.

        @raise BadKeyError: if the key, once decoded from base64, is not
        actually an SSH key.

        @return: an IKnownHostEntry representing the hostname and key in the
        input line.

        @rtype: L{PlainEntry}
        ó   ,)r-   r    )Úclsr$   r&   r'   r,   r+   r3   s          r   r#   zPlainEntry.fromStringy   s5   € ô0 ,:¸&Ó+AÑ(ˆ	�7˜C Ù�9—?‘? 4Ó(¨'°3¸Ó@ˆØˆr   c                 ó`   — t        |t        «      r|j                  d«      }|| j                  v S )aT  
        Check to see if this entry matches a given hostname.

        @param hostname: A hostname or IP address literal to check against this
            entry.
        @type hostname: L{bytes}

        @return: C{True} if this entry is for the given hostname or IP address,
            C{False} otherwise.
        @rtype: L{bool}
        úutf-8)Ú
isinstanceÚstrÚencoder@   ©r3   Úhostnames     r   ÚmatchesHostzPlainEntry.matchesHost•   s+   € ô �h¤Ô$Ø—‘ wÓ/ˆHØ˜4Ÿ?™?Ð*Ð*r   c                 ó  — dj                  | j                  «      | j                  t        | j                  j                  «       «      g}| j                  �|j                  | j                  «       dj                  |«      S )a  
        Implement L{IKnownHostEntry.toString} by recording the comma-separated
        hostnames, key type, and base-64 encoded key.

        @return: The string representation of this entry, with unhashed hostname
            information.
        @rtype: L{bytes}
        rD   ó    )Újoinr@   r'   r   r2   Úblobr+   Úappend©r3   Úfieldss     r   ÚtoStringzPlainEntry.toString¥   sb   € ð �I‰I�d—o‘oÓ&Ø�L‰LÜ�t—~‘~×*Ñ*Ó,Ó-ð
ˆð
 �<‰<Ð#Ø�M‰M˜$Ÿ,™,Ô'Ø�y‰y˜Ó Ð r   )
r8   r9   r:   r;   r4   Úclassmethodr#   rM   rU   Ú__classcell__©rB   s   @r   r>   r>   k   s+   ø„ ñô6ð ñó ðò6+ö !r   r>   c                   ó(   — e Zd ZdZd„ Zd„ Zd„ Zd„ Zy)ÚUnparsedEntryzŒ
    L{UnparsedEntry} is an entry in a L{KnownHostsFile} which can't actually be
    parsed; therefore it matches no keys and no hosts.
    c                 ó   — || _         y)zv
        Create an unparsed entry from a line in a known_hosts file which cannot
        otherwise be parsed.
        N)Ú_string)r3   r$   s     r   r4   zUnparsedEntry.__init__¿   s   € ð
 ˆ�r   c                  ó   — y©z'
        Always returns False.
        Fr<   rK   s     r   rM   zUnparsedEntry.matchesHostÆ   ó   € ð r   c                  ó   — yr^   r<   )r3   r,   s     r   r7   zUnparsedEntry.matchesKeyÌ   r_   r   c                 ó8   — | j                   j                  d«      S )a  
        Returns the input line, without its newline if one was given.

        @return: The string representation of this entry, almost exactly as was
            used to initialize this entry but without a trailing newline.
        @rtype: L{bytes}
        r   )r\   r"   ©r3   s    r   rU   zUnparsedEntry.toStringÒ   s   € ð �|‰|×"Ñ" 5Ó)Ð)r   N)r8   r9   r:   r;   r4   rM   r7   rU   r<   r   r   rZ   rZ   ¸   s   „ ñò
òòó*r   rZ   c                 ó¼   — t        j                  | t        ¬«      }t        |t        «      r|j                  d«      }|j                  |«       |j                  «       S )zù
    Return the SHA-1 HMAC hash of the given key and string.

    @param key: The HMAC key.
    @type key: L{bytes}

    @param string: The string to be hashed.
    @type string: L{bytes}

    @return: The keyed hash value.
    @rtype: L{bytes}
    )Ú	digestmodrG   )ÚhmacÚHMACr   rH   rI   rJ   ÚupdateÚdigest)r,   r$   Úhashs      r   Ú_hmacedStringrj   Ý   sD   € ô �9‰9�S¤DÔ)€DÜ�&œ#ÔØ—‘˜wÓ'ˆØ‡K�K�ÔØ�;‰;‹=Ðr   c                   óF   ‡ — e Zd ZdZdZdZˆ fd„Zed„ «       Zd„ Z	d„ Z
ˆ xZS )ÚHashedEntrya�  
    A L{HashedEntry} is a representation of an entry in a known_hosts file
    where the hostname has been hashed and salted.

    @ivar _hostSalt: the salt to combine with a hostname for hashing.

    @ivar _hostHash: the hashed representation of the hostname.

    @cvar MAGIC: the 'hash magic' string used to identify a hashed line in a
    known_hosts file as opposed to a plaintext one.
    s   |1|)Ú	_hostSaltÚ	_hostHashr'   r2   r+   c                 óD   •— || _         || _        t        ‰| �  |||«       y r1   )rm   rn   rA   r4   )r3   ÚhostSaltÚhostHashr'   r2   r+   rB   s         €r   r4   zHashedEntry.__init__  s"   ø€ Ø!ˆŒØ!ˆŒÜ‰Ñ˜ )¨WÕ5r   c                 óê   — t        |«      \  }}}}|t        | j                  «      d j                  d«      }t        |«      dk7  r
t	        «       ‚|\  }} | t        |«      t        |«      |||«      }	|	S )a#  
        Load a hashed entry from a string representing a line in a known_hosts
        file.

        @param string: A complete single line from a I{known_hosts} file,
            formatted as defined by OpenSSH.
        @type string: L{bytes}

        @raise DecodeError: if the key, the hostname, or the is not valid
            encoded as valid base64

        @raise InvalidEntry: if the entry does not have the right number of
            elements and is therefore invalid, or the host/hash portion contains
            more items than just the host and hash.

        @raise BadKeyError: if the key, once decoded from base64, is not
            actually an SSH key.

        @return: The newly created L{HashedEntry} instance, initialized with the
            information from C{string}.
        Nó   |r   )r-   r!   ÚMAGICr    r
   r   )
rE   r$   Ústuffr'   r,   r+   ÚsaltAndHashrp   rq   r3   s
             r   r#   zHashedEntry.fromString  sw   € ô. (6°fÓ'=Ñ$ˆˆw˜˜WØœC §	¡	›NÐ,Ð-×3Ñ3°DÓ9ˆÜˆ{Ó˜qÒ Ü“.Ð Ø(Ñˆ�(Ù”:˜hÓ'¬°HÓ)=¸wÈÈWÓUˆØˆr   c                 ój   — t        j                  t        | j                  |«      | j                  «      S )a…  
        Implement L{IKnownHostEntry.matchesHost} to compare the hash of the
        input to the stored hash.

        @param hostname: A hostname or IP address literal to check against this
            entry.
        @type hostname: L{bytes}

        @return: C{True} if this entry is for the given hostname or IP address,
            C{False} otherwise.
        @rtype: L{bool}
        )re   Úcompare_digestrj   rm   rn   rK   s     r   rM   zHashedEntry.matchesHost'  s+   € ô ×"Ñ"Ü˜$Ÿ.™.¨(Ó3°T·^±^ó
ð 	
r   c                 óZ  — | j                   dj                  t        | j                  «      t        | j                  «      g«      z   | j
                  t        | j                  j                  «       «      g}| j                  �|j                  | j                  «       dj                  |«      S )zï
        Implement L{IKnownHostEntry.toString} by base64-encoding the salt, host
        hash, and key.

        @return: The string representation of this entry, with the hostname part
            hashed.
        @rtype: L{bytes}
        rs   rO   )
rt   rP   r   rm   rn   r'   r2   rQ   r+   rR   rS   s     r   rU   zHashedEntry.toString8  s‚   € ð �J‰JØ�i‰iœ D§N¡NÓ3´ZÀÇÁÓ5OÐPÓQñRà�L‰LÜ�t—~‘~×*Ñ*Ó,Ó-ð	
ˆð �<‰<Ð#Ø�M‰M˜$Ÿ,™,Ô'Ø�y‰y˜Ó Ð r   )r8   r9   r:   r;   rt   ÚcompareAttributesr4   rV   r#   rM   rU   rW   rX   s   @r   rl   rl   ñ   s8   ø„ ñ
ð €EàUÐô6ð
 ñó ðò<
ö"!r   rl   c                   óT   — e Zd ZdZd„ Zed„ «       Zd„ Zd„ Zd„ Z	d„ Z
d„ Zed	„ «       Zy
)ÚKnownHostsFileaz  
    A structured representation of an OpenSSH-format ~/.ssh/known_hosts file.

    @ivar _added: A list of L{IKnownHostEntry} providers which have been added
        to this instance in memory but not yet saved.

    @ivar _clobber: A flag indicating whether the current contents of the save
        path will be disregarded and potentially overwritten or not.  If
        C{True}, this will be done.  If C{False}, entries in the save path will
        be read and new entries will be saved by appending rather than
        overwriting.
    @type _clobber: L{bool}

    @ivar _savePath: See C{savePath} parameter of L{__init__}.
    c                 ó.   — g | _         || _        d| _        y)a$  
        Create a new, empty KnownHostsFile.

        Unless you want to erase the current contents of C{savePath}, you want
        to use L{KnownHostsFile.fromPath} instead.

        @param savePath: The L{FilePath} to which to save new entries.
        @type savePath: L{FilePath}
        TN)Ú_addedÚ	_savePathÚ_clobber)r3   ÚsavePaths     r   r4   zKnownHostsFile.__init__]  s   € ð ˆŒØ!ˆŒØˆ�r   c                 ó   — | j                   S )z<
        @see: C{savePath} parameter of L{__init__}
        )r   rb   s    r   r�   zKnownHostsFile.savePathk  s   € ð
 �~‰~Ðr   c              #   óÊ  K  — | j                   D ]  }|–— Œ | j                  ry	 | j                  j                  «       }|5  |D ]Q  }	 |j                  t        j                  «      rt        j                  |«      }nt        j                  |«      }|–— ŒS 	 ddd«       y# t        $ r Y yw xY w# t        t        t        f$ r t        |«      }Y Œ@w xY w# 1 sw Y   yxY w­w)aK  
        Iterate over the host entries in this file.

        @return: An iterable the elements of which provide L{IKnownHostEntry}.
            There is an element for each entry in the file as well as an element
            for each added but not yet saved entry.
        @rtype: iterable of L{IKnownHostEntry} providers
        N)r~   r€   r   ÚopenÚOSErrorÚ
startswithrl   rt   r#   r>   ÚDecodeErrorr
   r   rZ   )r3   ÚentryÚfpÚlines       r   ÚiterentrieszKnownHostsFile.iterentriesr  sã   è ø€ ð —[‘[ò 	ˆEØ‹Kð	ð �=Š=Øð	Ø—‘×$Ñ$Ó&ˆBð ñ 		Øò �ð0Ø—‘¤{×'8Ñ'8Ô9Ü +× 6Ñ 6°tÓ <™ä *× 5Ñ 5°dÓ ;˜ð “ñ÷		ð 		øô ò 	Ùð	ûô $¤\´;Ð?ò 0Ü)¨$Ó/’Eð0ú÷		ð 		üse   ‚#C#¦B# Á C#ÁCÁ	A
B2ÂCÂ	C#Â#	B/Â,C#Â.B/Â/C#Â2CÃCÃCÃCÃC ÃC#c                 óD  — t        | j                  «       t        | j                  «       «      D ]o  \  }}|j	                  |«      sŒ|j
                  |j                  «       k(  sŒ6|j                  |«      r y|dk  rd}d}n|dz   }| j                  }t        |||«      ‚ y)a  
        Check for an entry with matching hostname and key.

        @param hostname: A hostname or IP address literal to check for.
        @type hostname: L{bytes}

        @param key: The public key to check for.
        @type key: L{Key}

        @return: C{True} if the given hostname and key are present in this file,
            C{False} if they are not.
        @rtype: L{bool}

        @raise HostKeyChanged: if the host key found for the given hostname
            does not match the given key.
        Tr   Nr   F)
Ú	enumerater‹   r!   r~   rM   r'   ÚsshTyper7   r   r	   )r3   rL   r,   Úlineidxrˆ   rŠ   Úpaths          r   Ú
hasHostKeyzKnownHostsFile.hasHostKey‘  sœ   € ô" (¨×(8Ñ(8Ó(:¼SÀÇÁÓ=MÐ<MÓNò 	<‰NˆG�UØ× Ñ  Õ*¨u¯}©}ÀÇÁÃÓ/MØ×#Ñ# CÔ(Ùð  ’{Ø#˜Ø#™à&¨™{˜Ø#Ÿ~™~˜Ü(¨°°dÓ;Ð;ð	<ð r   c                 ó‚   ‡ ‡‡‡‡— t        j                  ‰ j                  ‰‰«      }ˆˆˆˆ ˆfd„}|j                  |«      S )a¹  
        Verify the given host key for the given IP and host, asking for
        confirmation from, and notifying, the given UI about changes to this
        file.

        @param ui: The user interface to request an IP address from.

        @param hostname: The hostname that the user requested to connect to.

        @param ip: The string representation of the IP address that is actually
        being connected to.

        @param key: The public key of the server.

        @return: a L{Deferred} that fires with True when the key has been
            verified, or fires with an errback when the key either cannot be
            verified or has changed.
        @rtype: L{Deferred}
        c           
      ó  •— | re‰j                  ‰‰«      sQ‰	j                  d‰j                  «       ›dt        ‰«      ›d�«       ‰j	                  ‰‰«       ‰j                  «        | S ˆˆˆˆfd„}‰j                  «       }|dk(  rd}dt        ‰«      ›dt        ‰«      ›d	|›d
‰j                  t        j                  ¬«      ›d�	}‰	j                  |j                  t        j                  «       «      «      }|j                  |«      S )NzWarning: Permanently added the z host key for IP address 'z' to the list of known hosts.c                 óˆ   •— | r6‰j                  ‰‰«       ‰j                  ‰‰«       ‰j                  «        | S t        «       ‚r1   )Ú
addHostKeyÚsaver   )ÚresponserL   Úipr,   r3   s    €€€€r   ÚpromptResponsezGKnownHostsFile.verifyHostKey.<locals>.gotHasKey.<locals>.promptResponseÕ  s9   ø€ ÙØŸ™¨°#Ô6ØŸ™¨¨CÔ0ØŸ	™	œØ'˜ä-Ó/Ð/r   ÚECÚECDSAzThe authenticity of host 'z (z)' can't be established.
z key fingerprint is SHA256:)Úformatz9.
Are you sure you want to continue connecting (yes/no)? )r‘   ÚwarnÚtyper   r•   r–   Úfingerprintr   ÚSHA256_BASE64ÚpromptrJ   ÚsysÚgetdefaultencodingÚaddCallback)
Úresultr™   Úkeytyper¡   ÚproceedrL   r˜   r,   r3   Úuis
        €€€€€r   Ú	gotHasKeyz/KnownHostsFile.verifyHostKey.<locals>.gotHasKeyÈ  sÛ   ø€ ÙØ—‘ r¨3Ô/Ø—G’Gð Ÿ8™8�:¤|°BÕ'7ð9ôð
 —O‘O B¨Ô,Ø—I‘I”KØ�÷0ð Ÿ(™(›*�à˜d’?Ø%�Gøô % XÕ.Ü$ RÕ(ÚØŸ™Ô/A×/OÑ/O˜ÕPð	ð ð Ÿ)™) F§M¡M´#×2HÑ2HÓ2JÓ$KÓL�Ø×*Ñ*¨>Ó:Ð:r   )r   Úexecuter‘   r¤   )r3   r¨   rL   r˜   r,   Úhhkr©   s   `````  r   ÚverifyHostKeyzKnownHostsFile.verifyHostKey²  s7   ü€ ô( �m‰m˜DŸO™O¨X°sÓ;ˆ÷(	;ð (	;ðT �‰˜yÓ)Ð)r   c                 ó¤   — t        d«      }|j                  «       }t        |t        ||«      ||d«      }| j                  j                  |«       |S )aï  
        Add a new L{HashedEntry} to the key database.

        Note that you still need to call L{KnownHostsFile.save} if you wish
        these changes to be persisted.

        @param hostname: A hostname or IP address literal to associate with the
            new entry.
        @type hostname: L{bytes}

        @param key: The public key to associate with the new entry.
        @type key: L{Key}

        @return: The L{HashedEntry} that was added.
        @rtype: L{HashedEntry}
        é   N)r   rŽ   rl   rj   r~   rR   )r3   rL   r,   Úsaltr'   rˆ   s         r   r•   zKnownHostsFile.addHostKeyô  sI   € ô" ˜BÓˆØ—+‘+“-ˆÜ˜D¤-°°hÓ"?ÀÈ#ÈtÓTˆØ�‰×Ñ˜5Ô!Øˆr   c           
      óØ  — | j                   j                  «       }|j                  «       s|j                  «        | j                  rd}nd}| j                   j                  |«      5 }| j                  rP|j                  dj                  | j                  D �cg c]  }|j                  «       ‘Œ c}«      dz   «       g | _        ddd«       d| _        yc c}w # 1 sw Y   d| _        yxY w)zM
        Save this L{KnownHostsFile} to the path it was loaded from.
        ÚwbÚabr   NF)
r   ÚparentÚisdirÚmakedirsr€   r„   r~   ÚwriterP   rU   )r3   ÚpÚmodeÚhostsFileObjrˆ   s        r   r–   zKnownHostsFile.save  sº   € ð �N‰N×!Ñ!Ó#ˆØ�w‰wŒyØ�J‰JŒLà�=Š=Ø‰DàˆDà�^‰^× Ñ  Ó&ð 	!¨,Ø�{Š{Ø×"Ñ"Ø—J‘J¸d¿k¹kÖJ°U §¡Õ 0ÒJÓKÈeÑSôð !�”÷	!ð ˆ�ùò  K÷	!ð ˆ�ús   Á'1CÂCÂ/CÃCÃC)c                 ó$   —  | |«      }d|_         |S )aï  
        Create a new L{KnownHostsFile}, potentially reading existing known
        hosts information from the given file.

        @param path: A path object to use for both reading contents from and
            later saving to.  If no file exists at this path, it is not an
            error; a L{KnownHostsFile} with no entries is returned.
        @type path: L{FilePath}

        @return: A L{KnownHostsFile} initialized with entries from C{path}.
        @rtype: L{KnownHostsFile}
        F)r€   )rE   r�   Ú
knownHostss      r   ÚfromPathzKnownHostsFile.fromPath   s   € ñ ˜“Yˆ
Ø#ˆ
ÔØÐr   N)r8   r9   r:   r;   r4   Úpropertyr�   r‹   r‘   r¬   r•   r–   rV   r¼   r<   r   r   r|   r|   L  sP   „ ñò ð ñó ðòò>òB@*òDò.ð* ñó ñr   r|   c                   ó"   — e Zd ZdZd„ Zd„ Zd„ Zy)Ú	ConsoleUIz†
    A UI object that can ask true/false questions and post notifications on the
    console, to be used during key verification.
    c                 ó   — || _         y)aA  
        @param opener: A no-argument callable which should open a console
            binary-mode file-like object to be used for reading and writing.
            This initializes the C{opener} attribute.
        @type opener: callable taking no arguments and returning a read/write
            file-like object
        N)Úopener)r3   rÁ   s     r   r4   zConsoleUI.__init__9  s   € ð ˆ�r   c                 ó^   ‡ ‡— t        j                  d«      }ˆ ˆfd„}|j                  |«      S )a¿  
        Write the given text as a prompt to the console output, then read a
        result from the console input.

        @param text: Something to present to a user to solicit a yes or no
            response.
        @type text: L{bytes}

        @return: a L{Deferred} which fires with L{True} when the user answers
            'yes' and L{False} when the user answers 'no'.  It may errback if
            there were any I/O errors.
        Nc                 ó,  •— t        ‰j                  «       «      5 }|j                  ‰«       	 |j                  «       j	                  «       j                  «       }|dk(  r
	 d d d «       y|dk(  r
	 d d d «       y|j                  d«       Œ\# 1 sw Y   y xY w)NTs   yess   noFs   Please type 'yes' or 'no': )r   rÁ   r¶   Úreadliner   Úlower)ÚignoredÚfÚanswerr3   Útexts      €€r   ÚbodyzConsoleUI.prompt.<locals>.bodyR  s”   ø€ Ü˜Ÿ™›Ó'ð 	@¨1Ø—‘˜”ØØŸZ™Z›\×/Ñ/Ó1×7Ñ7Ó9�FØ Ò'Ø#÷	@ð 	@ð   5šØ$÷	@ð 	@ð Ÿ™Ð >Ô?ð ÷	@ð 	@ús   ›AB
Á)B
Á8B
Â
B)r   Úsucceedr¤   )r3   rÉ   ÚdrÊ   s   ``  r   r¡   zConsoleUI.promptC  s*   ù€ ô �M‰M˜$Óˆõ
	@ð �}‰}˜TÓ"Ð"r   c                 óÌ   — 	 t        | j                  «       «      5 }|j                  |«       ddd«       y# 1 sw Y   yxY w# t        $ r t        j                  d«       Y yw xY w)zÖ
        Notify the user (non-interactively) of the provided text, by writing it
        to the console.

        @param text: Some information the user is to be made aware of.
        @type text: L{bytes}
        NzFailed to write to console)r   rÁ   r¶   Ú	ExceptionÚlogÚfailure)r3   rÉ   rÇ   s      r   r�   zConsoleUI.warn`  sR   € ð	6Ü˜Ÿ™›Ó'ð ¨1Ø—‘˜”÷÷ ñ ûäò 	6Ü�K‰KÐ4Ö5ð	6ús(   ‚A ›6­A ¶?»A ¿A ÁA#Á"A#N)r8   r9   r:   r;   r4   r¡   r�   r<   r   r   r¿   r¿   3  s   „ ñò
ò#ó:6r   r¿   ),r;   re   r¢   Úbinasciir   r‡   r   r   Ú
contextlibr   Úhashlibr   Úzope.interfacer   Útwisted.conch.errorr	   r
   r   Útwisted.conch.interfacesr   Útwisted.conch.ssh.keysr   r   r   Útwisted.internetr   Útwisted.loggerr   Útwisted.python.compatr   Útwisted.python.randbytesr   Útwisted.python.utilr   rÏ   r   r-   r/   r>   rZ   rj   rl   r|   r¿   r<   r   r   ú<module>rÝ      sà   ðñ
ó Û 
ß AÑ AÝ Ý å &ç MÑ MÝ 4ß GÑ GÝ "Ý !Ý .Ý 1Ý ,áƒh€ò
!ò,÷8+ñ +ñD ˆ_ÓôI!�ó I!ó ðI!ñX ˆ_Ó÷!*ð !*ó ð!*òHñ( ˆ_ÓôW!�*˜ló W!ó ðW!÷tdñ d÷N96ò 96r   