
    hO                       S r SSKJr  SSKrSSKrSSKJrJrJ	r	  SSK
Jr  SSKJr  SSKJrJrJrJr  SSKJr  SS	KJrJrJr  SS
KJr  SSKJrJrJr  SSKJ r   SSK!J"r"  SSK#J$r$  SSK%J&r&  SSK'J(r(  SSK)J*r*  SSK+J,r,  \$" 5       r-S"S jr.S#S jr/ " S S5      r0\" \5       " S S\05      5       r1\" \5       " S S5      5       r2S$S jr3\" \5       " S S\0\,5      5       r4 " S S5      r5 " S  S!5      r6g)%zE
An implementation of the OpenSSH known_hosts database.

@since: 8.2
    )annotationsN)Error
a2b_base64
b2a_base64)closing)sha1)IOCallableIterableLiteral)implementer)HostKeyChangedInvalidEntryUserRejectedKey)IKnownHostEntry)BadKeyErrorFingerprintFormatsKey)defer)Deferred)Logger)nativeString)FilePath)secureRandom)FancyEqMixinc                4    [        U 5      R                  5       $ )z
Encode a binary string as base64 with no trailing newline.

@param s: The string to encode.

@return: The base64-encoded string.
)r   strip)ss    f/root/1688_scrapy/alibaba-scraper/venv/lib/python3.13/site-packages/twisted/conch/client/knownhosts.py
_b64encoder    $   s     a=      c                $   U R                  SS5      n[        U5      S:w  a
  [        5       eUu  p#nUR                  SS5      n[        U5      S:X  a  Uu  pgUR                  S5      nOUS   nSn[        R
                  " [        U5      5      nX#X4$ )ai  
Extract common elements of base64 keys from an entry in a hosts file.

@param string: A known hosts file entry (a single line).

@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.
N            
r   )splitlenr   rstripr   
fromStringr   )	stringelements	hostnameskeyTypekeyAndCommentsplitkey	keyStringcommentkeys	            r   _extractCommonr4   /   s     ||D!$H
8}n(0%I""4+H
8}%	..'QK	
..I.
/Cs++r!   c                  ,    \ rS rSrSrSS jrSS jrSrg)	
_BaseEntryI   a  
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} or C{None}
c                (    Xl         X l        X0l        g N)r.   	publicKeyr2   )selfr.   r:   r2   s       r   __init___BaseEntry.__init__X   s    "r!   c                $    U R                   U:H  nU$ )z
Check to see if this entry matches a given key object.

@param keyObject: A public key object to check.

@return: C{True} if this entry's key matches C{keyObject}, C{False}
    otherwise.
)r:   )r;   	keyObjectresults      r   
matchesKey_BaseEntry.matchesKey]   s     9,r!   )r2   r.   r:   N)r.   bytesr:   r   r2   bytes | NonereturnNone)r?   r   rE   bool)__name__
__module____qualname____firstlineno____doc__r<   rA   __static_attributes__ r!   r   r6   r6   I   s    

r!   r6   c                  h   ^  \ rS rSrSr        SU 4S jjr\S	S j5       rS
S jrSS jr	Sr
U =r$ )
PlainEntryj   z
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.
c                2   > Xl         [        TU ]	  X#U5        g r9   )
_hostnamessuperr<   )r;   r-   r.   r:   r2   	__class__s        r   r<   PlainEntry.__init__s   s     (1W5r!   c                T    [        U5      u  p#pEU " UR                  S5      X4U5      nU$ )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".

@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}
   ,)r4   r'   )clsr+   r-   r.   r3   r2   r;   s          r   r*   PlainEntry.fromString}   s/    , ,:&+A(	C9??4('@r!   c                j    [        U[        5      (       a  UR                  S5      nXR                  ;   $ )z
Check to see if this entry matches a given hostname.

@param hostname: A hostname or IP address literal to check against this
    entry.

@return: C{True} if this entry is for the given hostname or IP address,
    C{False} otherwise.
utf-8)
isinstancestrencoderS   r;   hostnames     r   matchesHostPlainEntry.matchesHost   s,     h$$w/H??**r!   c                   SR                  U R                  5      U R                  [        U R                  R                  5       5      /nU R                  b  UR                  U R                  5        SR                  U5      $ )z
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.
rX       )joinrS   r.   r    r:   blobr2   appendr;   fieldss     r   toStringPlainEntry.toString   sb     IIdoo&LLt~~**,-

 <<#MM$,,'yy  r!   )rS   )r-   zlist[bytes]r.   rC   r:   r   r2   rD   )r+   rC   rE   rP   )ra   bytes | strrE   rG   rE   rC   )rH   rI   rJ   rK   rL   r<   classmethodr*   rb   rk   rM   __classcell__rU   s   @r   rP   rP   j   sV    66 6 	6
 6  2+! !r!   rP   c                  P    \ rS rSr% SrSrS\S'   SS jrSS jrSS jr	SS	 jr
S
rg)UnparsedEntry   z
L{UnparsedEntry} is an entry in a L{KnownHostsFile} which can't actually be
parsed; therefore it matches no keys and no hosts.
NrF   r.   c                    Xl         g)z^
Create an unparsed entry from a line in a known_hosts file which cannot
otherwise be parsed.
N_string)r;   r+   s     r   r<   UnparsedEntry.__init__   s	    
 r!   c                    gz
Always returns False.
FrN   r`   s     r   rb   UnparsedEntry.matchesHost        r!   c                    grz   rN   )r;   r3   s     r   rA   UnparsedEntry.matchesKey   r|   r!   c                8    U R                   R                  S5      $ )z
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&   )rw   r)   r;   s    r   rk   UnparsedEntry.toString   s     ||""5))r!   rv   )r+   rC   rE   rF   ra   rC   rE   rG   )r3   r   rE   rG   rn   )rH   rI   rJ   rK   rL   r.   __annotations__r<   rb   rA   rk   rM   rN   r!   r   rs   rs      s'    
 GT*r!   rs   c                    [         R                  " U [        S9n[        U[        5      (       a  UR                  S5      nUR                  U5        UR                  5       $ )z
Return the SHA-1 HMAC hash of the given key and string.

@param key: The HMAC key.

@param string: The string to be hashed.

@return: The keyed hash value.
)	digestmodr\   )hmacHMACr   r]   r^   r_   updatedigest)r3   r+   hashs      r   _hmacedStringr      sG     99SD)D&#w'KK;;=r!   c                  x   ^  \ rS rSrSrSrSr            S
U 4S jjr\SS j5       r	SS jr
SS jrS	rU =r$ )HashedEntry   aq  
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.   r:   r2   c                >   > Xl         X l        [        TU ]  X4U5        g r9   )r   r   rT   r<   )r;   hostSalthostHashr.   r:   r2   rU   s         r   r<   HashedEntry.__init__  s     "!W5r!   c                    [        U5      u  p#pEU[        U R                  5      S R                  S5      n[        U5      S:w  a
  [	        5       eUu  pxU " [        U5      [        U5      X4U5      n	U	$ )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.

@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#   )r4   r(   MAGICr'   r   r   )
rY   r+   stuffr.   r3   r2   saltAndHashr   r   r;   s
             r   r*   HashedEntry.fromString  so    , (6f'=$C		N,-33D9{q . (:h'H)=wWUr!   c                l    [         R                  " [        U R                  U5      U R                  5      $ )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}
)r   compare_digestr   r   r   r`   s     r   rb   HashedEntry.matchesHost+  s+     ""$..(3T^^
 	
r!   c                \   U R                   SR                  [        U R                  5      [        U R                  5      /5      -   U R
                  [        U R                  R                  5       5      /nU R                  b  UR                  U R                  5        SR                  U5      $ )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}
r   re   )
r   rf   r    r   r   r.   r:   rg   r2   rh   ri   s     r   rk   HashedEntry.toString<  s     JJiiDNN3Z5OPQRLLt~~**,-	
 <<#MM$,,'yy  r!   )r   r   )r   rC   r   rC   r.   rC   r:   r   r2   rD   rE   rF   )r+   rC   rE   r   r   rn   )rH   rI   rJ   rK   rL   r   compareAttributesr<   ro   r*   rb   rk   rM   rp   rq   s   @r   r   r      sw    
 EU
6
6 
6 	
6
 
6 
6 

6  :
"! !r!   r   c                      \ rS rSrSrSS jr\SS j5       rSS jrSS jr	          SS jr
SS jrSS	 jr\SS
 j5       rSrg)KnownHostsFileiP  aN  
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                ,    / U l         Xl        SU l        g)z
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)r;   savePaths     r   r<   KnownHostsFile.__init__a  s     .0!r!   c                    U R                   $ )z,
@see: C{savePath} parameter of L{__init__}
)r   r   s    r   r   KnownHostsFile.savePatho  s    
 ~~r!   c              #    #    U R                    H  nUv   M	     U R                  (       a  g U R                  R                  5       nU   U HX  n UR                  [        R                  5      (       a  [        R                  U5      nO[        R                  U5      n Uv   MZ     SSS5        g! [         a     gf = f! [        [        [        4 a    [        U5      n NCf = f! , (       d  f       g= f7f)a  
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
startswithr   r   r*   rP   DecodeErrorr   r   rs   )r;   entryfplines       r   iterentriesKnownHostsFile.iterentriesv  s      [[EK ! ==	$$&B 0{'8'899 + 6 6t < * 5 5d ;   R  		 $\;? 0)$/E0 Rsp   *C8B1 C8	C'9C	C'
C	C'(	C81
B>;C8=B>>C8 C$!C'#C$$C''
C51C8c                ^   [        U R                  5       [        U R                  5      * 5       H{  u  p4UR                  UR                  5       :X  d  M%  UR                  U5      (       d  M=  UR                  U5      (       a    gUS:  a  SnSnOUS-   nU R                  n[        XFU5      e   g)an  
Check for an entry with matching hostname and key.

@param hostname: A hostname or IP address literal to check for.

@param key: The public key to check for.

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

@raise HostKeyChanged: if the host key found for the given hostname
    does not match the given key.
Tr   Nr%   F)
	enumerater   r(   r   r.   sshTyperb   rA   r   r   )r;   ra   r3   lineidxr   r   paths          r   
hasHostKeyKnownHostsFile.hasHostKey  s     ((8(8(:S=M<MNNG}}-%2C2CH2M2M##C(( {##&{#~~(d;; O r!   c                   ^ ^^^^ [         R                  " T R                  TT5      nSUUUU U4S jjnUR                  U5      $ )aQ  
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                `  > U (       a  T	R                  TT5      (       dg  STR                  5        STR                  5        S3nT
R                  UR	                  S5      5        T	R                  TT5        T	R                  5         U $ SUUUU	4S jjnTR                  5       nUS:X  a  SnS[        T5      < S	[        T5      < S
U< STR                  [        R                  S9< S3	nT
R                  UR	                  [        R                  " 5       5      5      nUR                  U5      $ )NzWarning: Permanently added the z host key for IP address 'z' to the list of known hosts.
r\   c                   > U (       a6  TR                  TT5        TR                  TT5        TR                  5         U $ [        5       er9   )
addHostKeysaver   )responsera   ipr3   r;   s    r   promptResponseGKnownHostsFile.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   rG   rE   rG   )r   typedecodewarnr_   r   r   r   fingerprintr   SHA256_BASE64promptsysgetdefaultencodingaddCallback)r@   
addMessager   keytyper   proceedra   r   r3   r;   uis         r   	gotHasKey/KnownHostsFile.verifyHostKey.<locals>.gotHasKey  s   r3//9#((* F,,.IIK= 9$$ 
 GGJ--g67OOB,IIK0 0  #xxzd?%G %X.$R(/A/O/OP	  ))FMM#2H2H2J$KL**>::r!   )r@   rG   rE   zbool | Deferred[bool])r   executer   r   )r;   r   ra   r   r3   hhkr   s   `````  r   verifyHostKeyKnownHostsFile.verifyHostKey  s7    , mmDOOXs;)	; )	;V y))r!   c                    [        S5      nUR                  5       n[        U[        X15      XBS5      nU R                  R                  U5        U$ )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   r   r   r   rh   )r;   ra   r3   saltr.   r   s         r   r   KnownHostsFile.addHostKey  sE    " B++-D-"?tT5!r!   c           
        U R                   R                  5       nUR                  5       (       d  UR                  5         U R                  (       a  SOSnU R                   R                  U5       nU R                  (       aR  UR                  SR                  U R                   Vs/ s H  oDR                  5       PM     sn5      S-   5        / U l        SSS5        SU l        gs  snf ! , (       d  f       N= f)z=
Save this L{KnownHostsFile} to the path it was loaded from.
war&   NF)
r   parentisdirmakedirsr   r   r   writerf   rk   )r;   pmodehostsFileObjr   s        r   r   KnownHostsFile.save  s     NN!!#wwyyJJL)-#C^^  &,{{""JJdkkJkU 0kJKeS ! '   K '&s   06C)&C$?C)$C))
C7c                $    U " U5      nSUl         U$ )au  
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.

@return: A L{KnownHostsFile} initialized with entries from C{path}.
F)r   )rY   r   
knownHostss      r   fromPathKnownHostsFile.fromPath   s     Y
#
r!   )r   r   r   N)r   FilePath[str]rE   rF   )rE   r   )rE   zIterable[IKnownHostEntry])ra   rC   r3   r   rE   rG   )
r   	ConsoleUIra   rC   r   rC   r3   r   rE   Deferred[bool])ra   rC   r3   r   rE   r   )rE   rF   )r   r   rE   r   )rH   rI   rJ   rK   rL   r<   propertyr   r   r   r   r   r   ro   r   rM   rN   r!   r   r   r   P  s|       ><C*C*',C*27C*>AC*	C*J."  r!   r   c                  6    \ rS rSrSrSS jrS	S jrS
S jrSrg)r   i1  zz
A UI object that can ask true/false questions and post notifications on the
console, to be used during key verification.
c                    Xl         g)a  
@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)r;   r   s     r   r<   ConsoleUI.__init__7  s	     r!   c                b   ^ ^ [         R                  " S5      nU U4S jnUR                  U5      $ )aw  
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R                  5       5       nUR                  T5         UR                  5       R	                  5       R                  5       nUS:X  a
   S S S 5        gUS;   a
   S S S 5        gUR                  S5        M_  ! , (       d  f       g = f)NTs   yes>   r!      noFs   Please type 'yes' or 'no': )r   r   r   readliner   lower)ignoredfanswerr;   texts      r   bodyConsoleUI.prompt.<locals>.bodyP  s    '1ZZ\//1779F'# ('  </$ ('  >?  ('s   AB*B:B
B)r   succeedr   )r;   r   dr   s   ``  r   r   ConsoleUI.promptA  s*     MM$
	@ }}T""r!   c                     [        U R                  5       5       nUR                  U5        SSS5        g! , (       d  f       g= f! [         a    [        R                  S5         gf = f)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.
NzFailed to write to console)r   r   r   	Exceptionlogfailure)r;   r   r   s      r   r   ConsoleUI.warn^  sI    	6'1 ('' 	6KK45	6s+   A 6A 
A A A A)(A)r   N)r   zCallable[[], IO[bytes]]rE   rF   )r   rC   rE   r   )r   rC   rE   rF   )	rH   rI   rJ   rK   rL   r<   r   r   rM   rN   r!   r   r   r   1  s    
#:6r!   r   )r   rC   rE   rC   )r+   rC   rE   z&tuple[bytes, bytes, Key, bytes | None])r3   rC   r+   rm   rE   rC   )7rL   
__future__r   r   r   binasciir   r   r   r   
contextlibr   hashlibr   typingr	   r
   r   r   zope.interfacer   twisted.conch.errorr   r   r   twisted.conch.interfacesr   twisted.conch.ssh.keysr   r   r   twisted.internetr   twisted.internet.deferr   twisted.loggerr   twisted.python.compatr   twisted.python.filepathr   twisted.python.randbytesr   twisted.python.utilr   r  r    r4   r6   rP   rs   r   r   r   r   rN   r!   r   <module>r     s   
 #  
 A A   2 2 & M M 4 G G " + ! . , 1 ,h!,4 B _I! I! I!X _#* #* #*L" _]!*l ]! ]!@^ ^B86 86r!   