'Continue the process of logging in to the server.
This callback function runs after the server capabilities are received.
If the server provided a challenge in the greeting, proceed with an
APOP login.  Otherwise, if the server and the transport support
encrypted communication, try to switch to TLS and then complete
the login process with the L{_loginTLS} callback function.  Otherwise,
if insecure authentication is allowed, do a plaintext login.
Otherwise, fail with an L{InsecureAuthenticationDisallowed} error.
@type caps: L{dict} mapping L{bytes} to L{list} of L{bytes} and/or
L{bytes} to L{None}
@param caps: The server capabilities.
@type username: L{bytes}
@param username: The username with which to log in.
@type password: L{bytes}
@param password: The password with which to log in.
@rtype: L{Deferred <defer.Deferred>} which successfully fires with
L{bytes}
@return: A deferred which fires when the login process is complete.
On a successful login, it returns the server\'s response minus the
status indicator.'

def _login(self, caps, username, password):

    if (self.serverChallenge is not None):
        return self._apop(username, password, self.serverChallenge)
    tryTLS = ('STLS' in caps)
    tlsableTransport = (interfaces.ITLSTransport(self.transport, None) is not None)
    nontlsTransport = (interfaces.ISSLTransport(self.transport, None) is None)
    if ((not self.startedTLS) and tryTLS and tlsableTransport and nontlsTransport):
        d = self.startTLS()
        d.addCallback(self._loginTLS, username, password)
        return d
    elif (self.startedTLS or (not nontlsTransport) or self.allowInsecureLogin):
        return self._plaintext(username, password)
    else:
        return defer.fail(InsecureAuthenticationDisallowed())
