'Handle one step of challenge/response authentication.
@param response: The text of a response. If None, this
function has been called as a result of an AUTH command with
no initial response. A response of \'*\' aborts authentication,
as per RFC 2554.'

def state_AUTH(self, response):

    if (self.portal is None):
        self.sendCode(454, 'Temporary    authentication    failure')
        self.mode = COMMAND
        return
    if (response is None):
        challenge = self.challenger.getChallenge()
        encoded = base64.b64encode(challenge)
        self.sendCode(334, encoded)
        return
    if (response == '*'):
        self.sendCode(501, 'Authentication    aborted')
        self.challenger = None
        self.mode = COMMAND
        return
    try:
        uncoded = base64.b64decode(response)
    except (TypeError, binascii.Error):
        self.sendCode(501, 'Syntax    error    in    parameters    or    arguments')
        self.challenger = None
        self.mode = COMMAND
        return
    self.challenger.setResponse(uncoded)
    if self.challenger.moreChallenges():
        challenge = self.challenger.getChallenge()
        coded = base64.b64encode(challenge)
        self.sendCode(334, coded)
        return
    self.mode = COMMAND
    result = self.portal.login(self.challenger, None, IMessageDeliveryFactory, IMessageDelivery)
    result.addCallback(self._cbAuthenticated)
    result.addCallback((lambda ign: self.sendCode(235, 'Authentication    successful.')))
    result.addErrback(self._ebAuthenticated)
