
    Vh"                         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m	Z	m
Z
 ddlmZ  G d de	      Z e
e       G d d	             Z e
e       G d
 d             Z e
e       G d d             Zy)zF
Protocol agnostic implementations of SASL authentication mechanisms.
    N)md5)	Attribute	Interfaceimplementer)networkStringc                   (    e Zd Z ed      Zd Zd Zy)ISASLMechanismz#Common name for the SASL Mechanism.c                       y)z
        Get the initial client response, if defined for this mechanism.

        @return: initial client response string.
        @rtype: C{str}.
        N r       ^/home/dcms/DCMS/lib/python3.12/site-packages/twisted/words/protocols/jabber/sasl_mechanisms.pygetInitialResponsez!ISASLMechanism.getInitialResponse       r   c                      y)z
        Get the response to a server challenge.

        @param challenge: server challenge.
        @type challenge: C{str}.
        @return: client response.
        @rtype: C{str}.
        Nr   )	challenges    r   getResponsezISASLMechanism.getResponse!   r   r   N)__name__
__module____qualname__r   namer   r   r   r   r   r	   r	      s    >?Dr   r	   c                        e Zd ZdZdZd Zd Zy)	Anonymouszm
    Implements the ANONYMOUS SASL authentication mechanism.

    This mechanism is defined in RFC 2245.
    	ANONYMOUSc                      y Nr   selfs    r   r   zAnonymous.getInitialResponse6       r   c                      y r   r   r   r   s     r   r   zAnonymous.getResponse9       r   N)r   r   r   __doc__r   r   r   r   r   r   r   r   ,   s     Dr   r   c                   &    e Zd ZdZdZd Zd Zd Zy)Plainz
    Implements the PLAIN SASL authentication mechanism.

    The PLAIN SASL authentication mechanism is defined in RFC 2595.
    PLAINc                 F    |xs d| _         |xs d| _        |xs d| _        y)a  
        @param authzid: The authorization identity.
        @type authzid: L{unicode}

        @param authcid: The authentication identity.
        @type authcid: L{unicode}

        @param password: The plain-text password.
        @type password: L{unicode}
         N)authzidauthcidpassword)r   r(   r)   r*   s       r   __init__zPlain.__init__H   s%     }"}" Br   c                     | j                   j                  d      dz   | j                  j                  d      z   dz   | j                  j                  d      z   S )Nzutf-8    )r(   encoder)   r*   r   s    r   r   zPlain.getInitialResponseX   s[    LL(ll!!'*+  mm""7+	,	
r   c                      y r   r   r    s     r   r   zPlain.getResponsea   r!   r   N)r   r   r   r"   r   r+   r   r   r   r   r   r$   r$   >   s     D' 
r   r$   c                   D    e Zd ZdZdZd Zd Zd Zd Zd Z	d Z
d	 Zd
 Zy)	DigestMD5z
    Implements the DIGEST-MD5 SASL authentication mechanism.

    The DIGEST-MD5 SASL authentication mechanism is defined in RFC 2831.
    z
DIGEST-MD5c                 |    || _         || _        || _        | d| | _        || xj                  d| z  c_        yy)a  
        @param serv_type: An indication of what kind of server authentication
            is being attempted against.  For example, C{u"xmpp"}.
        @type serv_type: C{unicode}

        @param host: The authentication hostname.  Also known as the realm.
            This is used as a scope to help select the right credentials.
        @type host: C{unicode}

        @param serv_name: An additional identifier for the server.
        @type serv_name: C{unicode}

        @param username: The authentication username to use to respond to a
            challenge.
        @type username: C{unicode}

        @param password: The authentication password to use to respond to a
            challenge.
        @type password: C{unicode}
        /N)usernamer*   defaultRealm
digest_uri)r   	serv_typehost	serv_namer4   r*   s         r   r+   zDigestMD5.__init__p   sK    * !  &Kq/ OO9+.O !r   c                      y r   r   r   s    r   r   zDigestMD5.getInitialResponse   r   r   c                     | j                  |      }d|v ry|d   j                  d      }	 |d   }| j                  |||d         S # t        $ r | j                  j	                  |      }Y <w xY w)Ns   rspauthr      charsetascii   realm   nonce)_parsedecodeKeyErrorr5   r.   _genResponse)r   r   
directivescharsetrealms        r   r   zDigestMD5.getResponse   s    [[+
 #Z(//8	6x(E   %H1EFF  	6%%,,W5E	6s   A $A.-A.c                    |}i }d}d}|r|j                  d|      }||| j                         }|dz  }|||dz    dk(  r9|dz  }|j                  d|      }||| }	|j                  d|      dz   }|dk(  rHd}nE|j                  d|      }|dk(  r||d	 j                         }	d}n||| j                         }	|dz   }|	||<   |rd
D ]  }
|
|v s||
   j	                  d      ||
<     |S )z
        Parses the server challenge.

        Splits the challenge into a dictionary of directives with values.

        @return: challenge directives and their values.
        @rtype: C{dict} of C{str} to C{str}.
        r   T   =      "   ,FN)   qop   cipher)indexlstripfindrstripsplit)r   r   s	paramDictcurremainingParamsmiddler   endvalueparams              r   r@   zDigestMD5._parse   s:    	
 WWT3'FS='')DaKF&1*%-!ggdF+&ffT3'!+!8&+OffT6*"9fgJ--/E&+OfSM002EAg#IdO/ 2 ) 	@E	!#,U#3#9#9$#?	% 	@ r   c                     g }|j                         D ]+  \  }}|dv r	|dz   |z   }n|dz   |z   }|j                  |       - dj                  |      S )af  
        Create message string from directives.

        @param directives: dictionary of directives (names to their values).
                           For certain directives, extra quotes are added, as
                           needed.
        @type directives: C{dict} of C{str} to C{str}
        @return: message string.
        @rtype: C{str}.
        )   usernamer>      cnoncer?   
   digest-uris   authzidrN   rH   rK   )itemsappendjoin)r   rD   directive_listr   rZ   	directives         r   _unparsezDigestMD5._unparse   so     %++- 	-KD%   !4K%/	 4K%/	!!),	-  yy((r   c                     d d }fd}	 |dz   |z   dz   |z         dz   |z   dz   |z   }
d|z   } | |	 | |
            |dz   |z   dz   |z   dz   dz   dz    | |            z               }|S )z
        Calculates response with given encoded parameters.

        @return: The I{response} field of a response to a Digest-MD5 challenge
            of the given parameters.
        @rtype: L{bytes}
        c                 4    t        |       j                         S r   )r   digest)rT   s    r   Hz'DigestMD5._calculateResponse.<locals>.H   s    q6==?"r   c                 ,    t        j                  |       S r   )binasciib2a_hex)ns    r   HEXz)DigestMD5._calculateResponse.<locals>.HEX   s    ##A&&r   c                       | dz   |z         S )N   :r   )krT   ri   s     r   KDz(DigestMD5._calculateResponse.<locals>.KD   s    QX\?"r   rp   s   AUTHENTICATE:   authr   )r   cnoncencnoncer4   r*   rF   urirn   rr   a1a2responseri   s                @r   _calculateResponsezDigestMD5._calculateResponse   s    	#	'	# x$&-89D@5H4ORXX#AbE
r!D(61D87BTICPQRTPUJV
 r   c                    	 | j                   j                  |      }| j                  j                  |      }| j                  j                  |      }t        dd      }| j                         }d}	| j                  |||||||      }
||||||	||
|j                  d      d	}| j                  |      S # t        $ r  w xY w)z
        Generate response-value.

        Creates a response to a challenge according to section 2.1.2.1 of
        RFC 2831 using the C{charset}, C{realm} and C{nonce} directives
        from the challenge.
        rI   08xrs   r=   )	r]   r>   r?   r^   s   ncrM   r_   s   responser<   )	r4   r.   r*   r6   UnicodeErrorr   
_gen_noncer{   re   )r   rE   rF   rv   r4   r*   r6   ru   rt   qoprz   rD   s               r   rC   zDigestMD5._genResponse	  s    	}}++G4H}}++G4H//8J
 aW&" **Bx5*

 "%!w/


 }}Z((3  		s   AB5 5C c                     dt        j                          t        j                         t        j                         fz  }t	        |      }t        |      j                         j                  d      S )Nz%f:%f:%dr=   )randomtimeosgetpidr   r   	hexdigestr.   )r   nonceString
nonceBytess      r   r   zDigestMD5._gen_nonce0  sM     FMMOTYY["))+#NN";/
:((*11'::r   N)r   r   r   r"   r   r+   r   r   r@   re   r{   rC   r   r   r   r   r1   r1   f   s9     D/:G"*X)>:%)N;r   r1   )r"   rk   r   r   r   hashlibr   zope.interfacer   r   r   twisted.python.compatr   r	   r   r$   r1   r   r   r   <module>r      s   
  	    < < /Y , ^  " ^$ $ $N ^L; L; L;r   