# Path: pyxmpp/sasl/core.py
# class ClientAuthenticator:
#     """Base class for client authenticators.
# 
#     A client authenticator class is a client-side implementation of a SASL
#     mechanism. One `ClientAuthenticator` object may be used for one
#     client authentication process."""
# 
#     def __init__(self,password_manager):
#         """Initialize a `ClientAuthenticator` object.
# 
#         :Parameters:
#             - `password_manager`: a password manager providing authentication
#               credentials.
#         :Types:
#             - `password_manager`: `PasswordManager`"""
#         self.password_manager=password_manager
#         self.__logger=logging.getLogger("pyxmpp.sasl.ClientAuthenticator")
# 
#     def start(self,username,authzid):
#         """Start the authentication process.
# 
#         :Parameters:
#             - `username`: the username (authentication id).
#             - `authzid`: the authorization id requester.
#         :Types:
#             - `username`: `unicode`
#             - `authzid`: `unicode`
# 
#         :return: the initial response to send to the server or a failuer
#             indicator.
#         :returntype: `Response` or `Failure`"""
#         _unused, _unused = username, authzid
#         return Failure("Not implemented")
# 
#     def challenge(self,challenge):
#         """Process the server's challenge.
# 
#         :Parameters:
#             - `challenge`: the challenge.
#         :Types:
#             - `challenge`: `str`
# 
#         :return: the response or a failure indicator.
#         :returntype: `Response` or `Failure`"""
#         _unused = challenge
#         return Failure("Not implemented")
# 
#     def finish(self,data):
#         """Handle authentication succes information from the server.
# 
#         :Parameters:
#             - `data`: the optional additional data returned with the success.
#         :Types:
#             - `data`: `str`
# 
#         :return: success or failure indicator.
#         :returntype: `Success` or `Failure`"""
#         _unused = data
#         return Failure("Not implemented")
# 
# class Failure(Reply):
#     """The failure SASL message.
# 
#     :Ivariables:
#         - `reason`: the failure reason.
#     :Types:
#         - `reason`: unicode."""
#     def __init__(self,reason,encode=True):
#         """Initialize the `Failure` object.
# 
#         :Parameters:
#             - `reason`: the failure reason.
#         :Types:
#             - `reason`: unicode."""
#         Reply.__init__(self,"",encode)
#         self.reason=reason
#     def __repr__(self):
#         return "<sasl.Failure: %r>" % (self.reason,)
# 
# class Response(Reply):
#     """The response SASL message (clients's reply the the server's challenge)."""
#     def __init__(self,data="", encode=True):
#         """Initialize the `Response` object."""
#         Reply.__init__(self,data, encode)
#     def __repr__(self):
#         return "<sasl.Response: %r>" % (self.data,)
# 
# class Challenge(Reply):
#     """The challenge SASL message (server's challenge for the client)."""
#     def __init__(self,data):
#         """Initialize the `Challenge` object."""
#         Reply.__init__(self,data)
#     def __repr__(self):
#         return "<sasl.Challenge: %r>" % (self.data,)
# 
# class Success(Reply):
#     """The success SASL message (sent by the server on authentication success)."""
#     def __init__(self,username,realm=None,authzid=None,data=None):
#         """Initialize the `Success` object.
# 
#         :Parameters:
#             - `username`: authenticated username (authentication id).
#             - `realm`: authentication realm used.
#             - `authzid`: authorization id.
#             - `data`: the success data to be sent to the client.
#         :Types:
#             - `username`: `unicode`
#             - `realm`: `unicode`
#             - `authzid`: `unicode`
#             - `data`: `str`
#         """
#         Reply.__init__(self,data)
#         self.username=username
#         self.realm=realm
#         self.authzid=authzid
#     def __repr__(self):
#         return "<sasl.Success: authzid: %r data: %r>" % (self.authzid,self.data)


import base64
import logging
from pyxmpp.sasl.core import (ClientAuthenticator,Failure,Response,Challenge,Success)

class ExternalClientAuthenticator(ClientAuthenticator):
    """Provides client-side External SASL (TLS-Identify) authentication."""
    
    
    def __init__(self,password_manager):
        ClientAuthenticator.__init__(self, password_manager)
        self.password_manager = password_manager
        self.__logger = logging.getLogger("pyxmpp.sasl.external.ExternalClientAuthenticator")

    def start(self, username, authzid):
        self.username = username
        self.authzid = authzid
        # TODO: This isn't very XEP-0178'ish.
        # XEP-0178 says "=" should be sent when only one id-on-xmppAddr is 
        # in the cert, but we don't know that. Still, this conforms to the
        # standard and works.
        return Response(self.authzid, encode = True)
        #return Response("=", encode = False)

    def finish(self,data):
        """Handle authentication success information from the server.

        :Parameters:
            - `data`: the optional additional data returned with the success.
        :Types:
            - `data`: `str`

        :return: a success indicator.
        :returntype: `Success`"""

# Path: pyxmpp/sasl/core.py
# class ClientAuthenticator:
#     """Base class for client authenticators.
# 
#     A client authenticator class is a client-side implementation of a SASL
#     mechanism. One `ClientAuthenticator` object may be used for one
#     client authentication process."""
# 
#     def __init__(self,password_manager):
#         """Initialize a `ClientAuthenticator` object.
# 
#         :Parameters:
#             - `password_manager`: a password manager providing authentication
#               credentials.
#         :Types:
#             - `password_manager`: `PasswordManager`"""
#         self.password_manager=password_manager
#         self.__logger=logging.getLogger("pyxmpp.sasl.ClientAuthenticator")
# 
#     def start(self,username,authzid):
#         """Start the authentication process.
# 
#         :Parameters:
#             - `username`: the username (authentication id).
#             - `authzid`: the authorization id requester.
#         :Types:
#             - `username`: `unicode`
#             - `authzid`: `unicode`
# 
#         :return: the initial response to send to the server or a failuer
#             indicator.
#         :returntype: `Response` or `Failure`"""
#         _unused, _unused = username, authzid
#         return Failure("Not implemented")
# 
#     def challenge(self,challenge):
#         """Process the server's challenge.
# 
#         :Parameters:
#             - `challenge`: the challenge.
#         :Types:
#             - `challenge`: `str`
# 
#         :return: the response or a failure indicator.
#         :returntype: `Response` or `Failure`"""
#         _unused = challenge
#         return Failure("Not implemented")
# 
#     def finish(self,data):
#         """Handle authentication succes information from the server.
# 
#         :Parameters:
#             - `data`: the optional additional data returned with the success.
#         :Types:
#             - `data`: `str`
# 
#         :return: success or failure indicator.
#         :returntype: `Success` or `Failure`"""
#         _unused = data
#         return Failure("Not implemented")
# 
# class Failure(Reply):
#     """The failure SASL message.
# 
#     :Ivariables:
#         - `reason`: the failure reason.
#     :Types:
#         - `reason`: unicode."""
#     def __init__(self,reason,encode=True):
#         """Initialize the `Failure` object.
# 
#         :Parameters:
#             - `reason`: the failure reason.
#         :Types:
#             - `reason`: unicode."""
#         Reply.__init__(self,"",encode)
#         self.reason=reason
#     def __repr__(self):
#         return "<sasl.Failure: %r>" % (self.reason,)
# 
# class Response(Reply):
#     """The response SASL message (clients's reply the the server's challenge)."""
#     def __init__(self,data="", encode=True):
#         """Initialize the `Response` object."""
#         Reply.__init__(self,data, encode)
#     def __repr__(self):
#         return "<sasl.Response: %r>" % (self.data,)
# 
# class Challenge(Reply):
#     """The challenge SASL message (server's challenge for the client)."""
#     def __init__(self,data):
#         """Initialize the `Challenge` object."""
#         Reply.__init__(self,data)
#     def __repr__(self):
#         return "<sasl.Challenge: %r>" % (self.data,)
# 
# class Success(Reply):
#     """The success SASL message (sent by the server on authentication success)."""
#     def __init__(self,username,realm=None,authzid=None,data=None):
#         """Initialize the `Success` object.
# 
#         :Parameters:
#             - `username`: authenticated username (authentication id).
#             - `realm`: authentication realm used.
#             - `authzid`: authorization id.
#             - `data`: the success data to be sent to the client.
#         :Types:
#             - `username`: `unicode`
#             - `realm`: `unicode`
#             - `authzid`: `unicode`
#             - `data`: `str`
#         """
#         Reply.__init__(self,data)
#         self.username=username
#         self.realm=realm
#         self.authzid=authzid
#     def __repr__(self):
#         return "<sasl.Success: authzid: %r data: %r>" % (self.authzid,self.data)


# Path: pyxmpp/sasl/external.py
import base64
import logging
from pyxmpp.sasl.core import (ClientAuthenticator,Failure,Response,Challenge,Success)


class ExternalClientAuthenticator(ClientAuthenticator):
    """Provides client-side External SASL (TLS-Identify) authentication."""
    
    
    def __init__(self,password_manager):
        ClientAuthenticator.__init__(self, password_manager)
        self.password_manager = password_manager
        self.__logger = logging.getLogger("pyxmpp.sasl.external.ExternalClientAuthenticator")

    def start(self, username, authzid):
        self.username = username
        self.authzid = authzid
        # TODO: This isn't very XEP-0178'ish.
        # XEP-0178 says "=" should be sent when only one id-on-xmppAddr is 
        # in the cert, but we don't know that. Still, this conforms to the
        # standard and works.
        return Response(self.authzid, encode = True)
        #return Response("=", encode = False)

    def finish(self,data):
        """Handle authentication success information from the server.

        :Parameters:
            - `data`: the optional additional data returned with the success.
        :Types:
            - `data`: `str`

        :return: a success indicator.
        :returntype: `Success`"""

        _unused = data