Exemplo n.º 1
0
    def auth(self, mechanism, authobject, *, initial_response_ok=True):
        """Authentication command - requires response processing.

        'mechanism' specifies which authentication mechanism is to
        be used - the valid values are those listed in the 'auth'
        element of 'esmtp_features'.

        'authobject' must be a callable object taking a single argument:

                data = authobject(challenge)

        It will be called to process the server's challenge response; the
        challenge argument it is passed will be a bytes.  It should return
        bytes data that will be base64 encoded and sent to the server.

        Keyword arguments:
            - initial_response_ok: Allow sending the RFC 4954 initial-response
              to the AUTH command, if the authentication methods supports it.
        """
        mechanism = mechanism.upper()
        initial_response = authobject() if initial_response_ok else None
        if initial_response is not None:
            response = encode_base64(initial_response.encode('ascii'), eol='')
            code, resp = self.docmd('AUTH', mechanism + ' ' + response)
        else:
            code, resp = self.docmd('AUTH', mechanism)
        if code == 334:
            challenge = base64.decodebytes(resp)
            response = encode_base64(authobject(challenge).encode('ascii'),
                eol='')
            code, resp = self.docmd(response)
        if code in (235, 503):
            return code, resp
        raise SMTPAuthenticationError(code, resp)
Exemplo n.º 2
0
 def auth(self, mechanism, authobject, *, initial_response_ok=True):
     """Authentication command - requires response processing.
     'mechanism' specifies which authentication mechanism is to
     be used - the valid values are those listed in the 'auth'
     element of 'esmtp_features'.
     'authobject' must be a callable object taking a single argument:
             data = authobject(challenge)
     It will be called to process the server's challenge response; the
     challenge argument it is passed will be a bytes.  It should return
     an ASCII string that will be base64 encoded and sent to the server.
     Keyword arguments:
         - initial_response_ok: Allow sending the RFC 4954 initial-response
           to the AUTH command, if the authentication methods supports it.
     """
     # RFC 4954 allows auth methods to provide an initial response.  Not all
     # methods support it.  By definition, if they return something other
     # than None when challenge is None, then they do.  See issue #15014.
     mechanism = mechanism.upper()
     initial_response = (authobject() if initial_response_ok else None)
     if initial_response is not None:
         response = encode_base64(initial_response.encode('ascii'), eol='')
         (code, resp) = self.docmd("AUTH", mechanism + " " + response)
     else:
         (code, resp) = self.docmd("AUTH", mechanism)
     # If server responds with a challenge, send the response.
     if code == 334:
         challenge = base64.decodebytes(resp)
         response = encode_base64(authobject(challenge).encode('ascii'),
                                  eol='')
         (code, resp) = self.docmd(response)
     if code in (235, 503):
         return (code, resp)
     raise SMTPAuthenticationError(code, resp)
Exemplo n.º 3
0
  def sendMail( self, password ):
    with SMTP( common['mailserver'], 587 ) as smtp:
      smtp.set_debuglevel(1)
      smtp.ehlo()
      smtp.starttls()
      smtp.ehlo()

      if not (hex(sys.hexversion) == '0x30500f0'):
        smtp.login( self.getShortAddressList()[0], password )
      else:
        # Application side workaround for http://bugs.python.org/issue25446
        # smtp.login using AUTH LOGIN mechanism is broken in released Python 3.5.0
        #
        # prefer AUTH LOGIN over other mechanism if available
        if not "LOGIN" in smtp.esmtp_features["auth"].split():
          # best effort approach: allow any other mechanism
          smtp.login( self.getShortAddressList()[0], password )
        else:
          (code, resp) = smtp.docmd("AUTH", "LOGIN " +
            encode_base64(self.getShortAddressList()[0].encode('ascii'), eol=''))
          if not code == 334:
            raise SMTPException("Authentication not possible with this login.")
          (code, resp) = smtp.docmd(encode_base64(password.encode('ascii'), eol=''))
          # 235 : 'Authentication successful'
          # 503 : 'Error: already authenticated'
          if not code in (235, 503):
            raise SMTPException("Authentication unsuccessful.")

      smtp.sendmail( self.message[self.FROM],
        self.header[self.TO] + self.header[self.CC], self.message.as_string() )
Exemplo n.º 4
0
    def login(self, user, password):
        def encode_cram_md5(challenge, user, password):
            challenge = base64.b64decode(challenge)
            response = user + " " + hmac.HMAC(password.encode('ascii'),
                                              challenge, 'md5').hexdigest()
            return encode_base64(response.encode('ascii'), eol='')

        def encode_plain(user, password):
            s = "\0%s\0%s" % (user, password)
            return encode_base64(s.encode('ascii'), eol='')

        AUTH_PLAIN = "PLAIN"
        AUTH_CRAM_MD5 = "CRAM-MD5"
        AUTH_LOGIN = "******"

        yield from self.ehlo_or_helo_if_needed()

        if not self.supports("auth"):
            raise SMTPException("SMTP AUTH extension not supported by server.")

        # Authentication methods the server claims to support
        advertised_authlist = self.esmtp_extensions["auth"]

        # List of authentication methods we support: from preferred to
        # less preferred methods. Except for the purpose of testing the weaker
        # ones, we prefer stronger methods like CRAM-MD5:
        preferred_auths = [AUTH_CRAM_MD5, AUTH_PLAIN, AUTH_LOGIN]

        # We try the authentication methods the server advertises, but only the
        # ones *we* support. And in our preferred order.
        authlist = [auth for auth in preferred_auths if auth in advertised_authlist]
        if not authlist:
            raise SMTPException("No suitable authentication method found.")

        # Some servers advertise authentication methods they don't really
        # support, so if authentication fails, we continue until we've tried
        # all methods.
        for authmethod in authlist:
            if authmethod == AUTH_CRAM_MD5:
                (code, resp) = yield from self.execute_command("AUTH", AUTH_CRAM_MD5)
                if code == 334:
                    (code, resp) = yield from self.execute_command(encode_cram_md5(resp, user, password))
            elif authmethod == AUTH_PLAIN:
                (code, resp) = yield from self.execute_command("AUTH",
                    AUTH_PLAIN + " " + encode_plain(user, password))
            elif authmethod == AUTH_LOGIN:
                (code, resp) = yield from self.execute_command("AUTH",
                    "%s %s" % (AUTH_LOGIN, encode_base64(user.encode('ascii'), eol='')))
                if code == 334:
                    (code, resp) = yield from self.execute_command(encode_base64(password.encode('ascii'), eol=''))

            # 235 == 'Authentication successful'
            # 503 == 'Error: already authenticated'
            if code in (235, 503):
                return (code, resp)

        # We could not login sucessfully. Return result of last attempt.
        raise SMTPAuthenticationError(code, resp)
Exemplo n.º 5
0
    def login(self, user, password):
        def encode_cram_md5(challenge, user, password):
            challenge = base64.decodestring(challenge)
            response = user + " " + hmac.HMAC(password, challenge).hexdigest()
            return encode_base64(response)

        def encode_plain(user, password):    
            s = "\0%s\0%s" % (user, password)    
            return encode_base64(s.encode('ascii'), eol='')
            
        AUTH_PLAIN = "PLAIN"
        AUTH_CRAM_MD5 = "CRAM-MD5"
        AUTH_LOGIN = "******"

        self.ehlo_or_helo_if_needed()

        if not self.has_extn("auth"):
            raise SMTPException("SMTP AUTH extension not supported by server.")

        authlist = self.esmtp_features["auth"].split()
        preferred_auths = [AUTH_CRAM_MD5, AUTH_PLAIN, AUTH_LOGIN]

        authmethod = None

        for method in preferred_auths:
            if method in authlist:
                authmethod = method
                break
                
        if authmethod == AUTH_LOGIN:
            (code, resp) = self.docmd("AUTH",
                "%s %s" % (AUTH_LOGIN, encode_base64(user)))

            if code != 334:
                raise SMTPAuthenticationError(code, resp)

            (code, resp) = self.docmd(encode_base64(password))     
                  
        elif authmethod == AUTH_PLAIN:
            temp_encode_plain = str(encode_plain(user, password))
            temp_encode_plain = temp_encode_plain.replace("\n","")
            (code, resp) = self.docmd("AUTH",
                AUTH_PLAIN + " " + temp_encode_plain)

        elif authmethod == AUTH_CRAM_MD5:
            (code, resp) = self.docmd("AUTH", AUTH_CRAM_MD5)

            if code == 503:
                return (code, resp)

            (code, resp) = self.docmd(encode_cram_md5(resp, user, password)) 
                
        elif authmethod is None:
            raise SMTPException("No suitable authentication method found.")

        if code not in (235, 503):
            raise SMTPAuthenticationError(code, resp)
        return (code, resp)
Exemplo n.º 6
0
    def login(self, user, password):
        def encode_cram_md5(challenge, user, password):
            challenge = encode_base64.decodestring(challenge)
            response = user + " " + smtplib.hmac.HMAC(password,
                                                      challenge).hexdigest()
            return encode_base64(response)

        def encode_plain(user, password):
            s = "\0%s\0%s" % (user, password)
            return encode_base64(s.encode('ascii'), eol='')

        AUTH_PLAIN = "PLAIN"
        AUTH_CRAM_MD5 = "CRAM-MD5"
        AUTH_LOGIN = "******"

        self.ehlo_or_helo_if_needed()

        if not self.has_extn("auth"):
            raise smtplib.SMTPException(
                "SMTP AUTH extension not supported by server.")

        authlist = self.esmtp_features["auth"].split()
        preferred_auths = [AUTH_CRAM_MD5, AUTH_PLAIN, AUTH_LOGIN]

        authmethod = None
        for method in preferred_auths:
            if method in authlist:
                authmethod = method
                break

        if authmethod == AUTH_LOGIN:
            (code,
             resp) = self.docmd("AUTH",
                                "%s %s" % (AUTH_LOGIN, encode_base64(user)))
            if code != 334:
                raise smtplib.SMTPAuthenticationError(code, resp)
            (code, resp) = self.docmd(encode_base64(password))
        elif authmethod == AUTH_PLAIN:
            temp_encode_plain = str(encode_plain(user, password))
            temp_encode_plain = temp_encode_plain.replace("\n", "")
            (code, resp) = self.docmd("AUTH",
                                      AUTH_PLAIN + " " + temp_encode_plain)
        elif authmethod == AUTH_CRAM_MD5:
            (code, resp) = self.docmd("AUTH", AUTH_CRAM_MD5)
            if code == 503:
                return (code, resp)
            (code, resp) = self.docmd(encode_cram_md5(resp, user, password))
        elif authmethod is None:
            raise smtplib.SMTPException(
                "No suitable authentication method found.")
        if code not in (235, 503):
            raise smtplib.SMTPAuthenticationError(code, resp)
        return (code, resp)
Exemplo n.º 7
0
    def login(self, username, password):
        def encode_cram_md5(challenge, username, password):
            challenge = base64.decodebytes(challenge)
            response = username + " " + hmac.HMAC(password.encode("ascii"), challenge, "md5").hexdigest()
            return encode_base64(response.encode("ascii"), eol="")

        def encode_plain(user, password):
            return encode_base64(("\0%s\0%s" % (user, password)).encode("ascii"), eol="")

        AUTH_PLAIN = "PLAIN"
        AUTH_CRAM_MD5 = "CRAM-MD5"
        AUTH_LOGIN = "******"

        yield self.ehlo_or_helo_if_needed()
        if not self.has_extn("auth"):
            raise smtplib.SMTPException("SMTP Auth extension not supported by server ")

        advertised_authlist = self.esmtp_features["auth"].split()

        preferred_auths = [AUTH_CRAM_MD5, AUTH_PLAIN, AUTH_LOGIN]

        authlist = [auth for auth in preferred_auths if auth in advertised_authlist]
        if not authlist:
            raise smtplib.SMTPException("No suitable authentication method found.")

        # Some servers advertise authentication methods they don't really
        # support, so if authentication fails, we continue until we've tried
        # all methods.
        for authmethod in authlist:
            if authmethod == AUTH_CRAM_MD5:
                (code, resp) = yield self.docmd(b"AUTH", AUTH_CRAM_MD5)
                if code == 334:
                    (code, resp) = yield self.docmd(encode_cram_md5(resp, username, password).encode("ascii"))
            elif authmethod == AUTH_PLAIN:
                (code, resp) = yield self.docmd(
                    b"AUTH", (AUTH_PLAIN + " " + encode_plain(username, password)).encode("ascii")
                )
            elif authmethod == AUTH_LOGIN:
                (code, resp) = yield self.docmd(
                    b"AUTH", ("%s %s" % (AUTH_LOGIN, encode_base64(username.encode("ascii"), eol=""))).encode("ascii")
                )
                if code == 334:
                    (code, resp) = yield self.docmd(encode_base64(password.encode("ascii"), eol="").encode("ascii"))

            # 235 == 'Authentication successful'
            # 503 == 'Error: already authenticated'
            if code in (235, 503):
                return (code, resp)

        # We could not login sucessfully. Return result of last attempt.
        raise smtplib.SMTPAuthenticationError(code, resp)
Exemplo n.º 8
0
    def login(self, user, password):
        def encode_cram_md5(challenge, user, password):
            challenge = base64.decodestring(challenge)
            response = user + " " + hmac.HMAC(password, challenge).hexdigest()
            return encode_base64(response, eol="")

        def encode_plain(user, password):
            return encode_base64("\0%s\0%s" % (user, password), eol="")

        AUTH_PLAIN = "PLAIN"
        AUTH_CRAM_MD5 = "CRAM-MD5"
        AUTH_LOGIN = "******"

        self.ehlo_or_helo_if_needed()

        if not self.has_extn("auth"):
            raise SMTPException("SMTP AUTH extension not supported by server.")
        authlist = self.esmtp_features["auth"].split()
        preferred_auths = [AUTH_CRAM_MD5, AUTH_PLAIN, AUTH_LOGIN]

        # Determine the authentication method we'll use
        authmethod = None
        for method in preferred_auths:
            if method in authlist:
                authmethod = method
                break

        if authmethod == AUTH_CRAM_MD5:
            (code, resp) = self.docmd("AUTH", AUTH_CRAM_MD5)
            if code == 503:
                # 503 == 'Error: already authenticated'
                return (code, resp)
            (code, resp) = self.docmd(encode_cram_md5(resp, user, password))
        elif authmethod == AUTH_PLAIN:
            (code, resp) = self.docmd(
                "AUTH", AUTH_PLAIN + " " + encode_plain(user, password))
        elif authmethod == AUTH_LOGIN:
            (code, resp) = self.docmd(
                "AUTH", "%s %s" % (AUTH_LOGIN, encode_base64(user, eol="")))
            if code != 334:
                raise SMTPAuthenticationError(code, resp)
            (code, resp) = self.docmd(encode_base64(password, eol=""))
        elif authmethod is None:
            raise SMTPException("No suitable authentication method found.")
        if code not in (235, 503):
            # 235 == 'Authentication successful'
            # 503 == 'Error: already authenticated'
            raise SMTPAuthenticationError(code, resp)
        return (code, resp)
Exemplo n.º 9
0
    def login(self, username, password):
        def encode_cram_md5(challenge, username, password): 
            challenge = base64.decodebytes(challenge)
            response = username + " " + hmac.HMAC(password.encode('ascii'), challenge, 'md5').hexdigest()
            return encode_base64(response.encode('ascii'), eol="")

        def encode_plain(user, password): 
            return encode_base64(("\0%s\0%s" % (user, password)).encode('ascii'), eol="")

        AUTH_PLAIN = "PLAIN"
        AUTH_CRAM_MD5 = "CRAM-MD5"
        AUTH_LOGIN = "******"

        yield self.ehlo_or_helo_if_needed()
        if not self.has_extn('auth'):
            raise smtplib.SMTPException("SMTP Auth extension not supported by server ")

        advertised_authlist = self.esmtp_features["auth"].split()

        preferred_auths = [AUTH_CRAM_MD5, AUTH_PLAIN, AUTH_LOGIN]

        authlist = [auth for auth in preferred_auths if auth in advertised_authlist]
        if not authlist:
            raise smtplib.SMTPException("No suitable authentication method found.")

        # Some servers advertise authentication methods they don't really
        # support, so if authentication fails, we continue until we've tried
        # all methods.
        for authmethod in authlist:
            if authmethod == AUTH_CRAM_MD5:
                (code, resp) = yield self.docmd(b'AUTH', AUTH_CRAM_MD5)
                if code == 334:
                    (code, resp) =yield self.docmd(encode_cram_md5(resp, username, password).encode('ascii'))
            elif authmethod == AUTH_PLAIN:
                (code, resp) =yield self.docmd(b'AUTH',
                 (AUTH_PLAIN + " " + encode_plain(username, password)).encode('ascii'))
            elif authmethod == AUTH_LOGIN:
                (code, resp) = yield self.docmd(b'AUTH',
                ("%s %s" % (AUTH_LOGIN, encode_base64(username.encode('ascii'), eol=''))).encode('ascii'))
                if code == 334:
                    (code, resp) = yield self.docmd(encode_base64(password.encode('ascii'), eol='').encode('ascii'))

            # 235 == 'Authentication successful'
            # 503 == 'Error: already authenticated'
            if code in (235, 503):
                raise gen.Return((code, resp))

        # We could not login sucessfully. Return result of last attempt.
        raise smtplib.SMTPAuthenticationError(code, resp)
Exemplo n.º 10
0
	def login (self, phase = 1, resp = None):		
		def encode_cram_md5(challenge, user, password):
			challenge = base64.decodebytes(challenge)
			response = user + " " + hmac.HMAC(password.encode('ascii'),
											challenge, 'md5').hexdigest()
			return encode_base64(response.encode('ascii'), eol='')
	
		def encode_plain(user, password):
			s = "\0%s\0%s" % (user, password)
			return encode_base64(s.encode('ascii'), eol='')
		
		try:
			advertised_authlist = self.esmtp_features["auth"].split()		
		except KeyError:
			advertised_authlist = []	
		user, password = self.composer.get_LOGIN ()
		
		AUTH_PLAIN = "PLAIN"
		AUTH_CRAM_MD5 = "CRAM-MD5"
		AUTH_LOGIN = "******"

		preferred_auths = [AUTH_CRAM_MD5, AUTH_PLAIN, AUTH_LOGIN]		
		authlist = [auth for auth in preferred_auths if auth in advertised_authlist]
		if not authlist:
			self.__code, self.__resp = 900, "No Suitable Authentication Method"			
			self.__stat = 9
			self.push ("rset")
			return
		
		if AUTH_PLAIN in authlist:
			self.push ("AUTH %s %s" % (AUTH_PLAIN, encode_plain (user, password)))
			self.__stat = 3
			
		elif AUTH_LOGIN in authlist:
			if phase == 1:
				self.push ("AUTH %s %s" % (AUTH_LOGIN, encode_base64(user.encode('ascii'), eol='')))
				self.__stat = 2.5
			else:
				self.push (encode_base64(password.encode('ascii'), eol=''))	
				self.__stat = 3
			
		else:
			if phase == 1:
				self.push ("AUTH %s" % (AUTH_CRAM_MD5,))
				self.__stat = 2.5
			else:	
				self.push (encode_cram_md5 (resp, user, password))
				self.__stat = 3
Exemplo n.º 11
0
        def encode_digest_md5(challenge, user, password):
            challenge = base64.decodestring(challenge)
            c = digest_md5_decode_challenge(challenge)

            realm = c["realm"]
            nonce = c["nonce"]
            qop = c["qop"]
            cnonce = generate_cnonce()
            if "realm" in c:
                digest_uri = "smtp/%s" % realm
                realmPair = ',realm="%s"' % realm
            else:
                digest_uri = "smtp/localhost"
                realmPair = ""

            credential = md5("%s:%s:%s" % (user, realm, password))
            # XXX: not support authorization ID
            a1 = "%s:%s:%s" % (credential, nonce, cnonce)
            if qop == "auth":
                a2 = "AUTHENTICATE:%s" % digest_uri
            else:
                # XXX: most servers and clients don't implement auth-int/auth-conf,
                # they use dummy MD5 digest for body.
                a2 = "AUTHENTICATE:%s:00000000000000000000000000000000" % digest_uri

            a1 = hexlify(md5(a1))
            a2 = hexlify(md5(a2))
            response = hexlify(
                md5("%s:%s:00000001:%s:%s:%s" % (a1, nonce, cnonce, qop, a2)))
            response = (
                'username="******"%s,nonce="%s",cnonce="%s",'
                'nc=00000001,qop=%s,digest-uri="%s",response=%s' %
                (user, realmPair, nonce, cnonce, qop, digest_uri, response))
            return encode_base64(response, eol="")
Exemplo n.º 12
0
        def encode_digest_md5(challenge, user, password):
            challenge = base64.decodestring(challenge)
            c = digest_md5_decode_challenge(challenge)

            realm = c["realm"]
            nonce = c["nonce"]
            qop = c["qop"]
            cnonce = generate_cnonce()
            if "realm" in c:
                digest_uri = "smtp/%s" % realm
                realmPair = ',realm="%s"' % realm
            else:
                digest_uri = "smtp/localhost"
                realmPair = ""

            credential = md5("%s:%s:%s" % (user, realm, password))
            # XXX: not support authorization ID
            a1 = "%s:%s:%s" % (credential, nonce, cnonce)
            if qop == "auth":
                a2 = "AUTHENTICATE:%s" % digest_uri
            else:
                # XXX: most servers and clients don't implement auth-int/auth-conf,
                # they use dummy MD5 digest for body.
                a2 = "AUTHENTICATE:%s:00000000000000000000000000000000" % digest_uri

            a1 = hexlify(md5(a1))
            a2 = hexlify(md5(a2))
            response = hexlify(md5("%s:%s:00000001:%s:%s:%s" %
                (a1, nonce, cnonce, qop, a2)))
            response = ( 'username="******"%s,nonce="%s",cnonce="%s",'
                'nc=00000001,qop=%s,digest-uri="%s",response=%s' %
                (user, realmPair, nonce, cnonce, qop, digest_uri, response))
            return encode_base64(response, eol="")
Exemplo n.º 13
0
 def auth_login(self, challenge):
     """ Authobject to use with LOGIN authentication. Requires self.user and
     self.password to be set."""
     (code, resp) = self.docmd(encode_base64(self.user.encode("ascii"), eol=""))
     if code == 334:
         return self.password
     raise SMTPAuthenticationError(code, resp)
Exemplo n.º 14
0
    def auth(self, mechanism, authobject):
        """Authentication command - requires response processing.

        'mechanism' specifies which authentication mechanism is to
        be used - the valid values are those listed in the 'auth'
        element of 'esmtp_features'.

        'authobject' must be a callable object taking a single argument:

                data = authobject(challenge)

        It will be called to process the server's challenge response; the
        challenge argument it is passed will be a bytes.  It should return
        bytes data that will be base64 encoded and sent to the server.
        """

        mechanism = mechanism.upper()
        (code, resp) = self.docmd("AUTH", mechanism)
        # Server replies with 334 (challenge) or 535 (not supported)
        if code == 334:
            challenge = base64.decodebytes(resp)
            response = encode_base64(
                authobject(challenge).encode('ascii'), eol='')
            (code, resp) = self.docmd(response)
            if code in (235, 503):
                return (code, resp)
        raise SMTPAuthenticationError(code, resp)
    def login(self, user, password):
        def encode_cram_md5(challenge, user, password):
            challenge = base64.decodestring(challenge)
            response = user + ' ' + hmac.HMAC(password, challenge).hexdigest()
            return encode_base64(response, eol='')

        def encode_plain(user, password):
            return encode_base64('\x00%s\x00%s' % (user, password), eol='')

        AUTH_PLAIN = 'PLAIN'
        AUTH_CRAM_MD5 = 'CRAM-MD5'
        AUTH_LOGIN = '******'
        self.ehlo_or_helo_if_needed()
        if not self.has_extn('auth'):
            raise SMTPException('SMTP AUTH extension not supported by server.')
        authlist = self.esmtp_features['auth'].split()
        preferred_auths = [AUTH_CRAM_MD5, AUTH_PLAIN, AUTH_LOGIN]
        authmethod = None
        for method in preferred_auths:
            if method in authlist:
                authmethod = method
                break

        if authmethod == AUTH_CRAM_MD5:
            code, resp = self.docmd('AUTH', AUTH_CRAM_MD5)
            if code == 503:
                return (code, resp)
            code, resp = self.docmd(encode_cram_md5(resp, user, password))
        else:
            if authmethod == AUTH_PLAIN:
                code, resp = self.docmd(
                    'AUTH', AUTH_PLAIN + ' ' + encode_plain(user, password))
            else:
                if authmethod == AUTH_LOGIN:
                    code, resp = self.docmd(
                        'AUTH',
                        '%s %s' % (AUTH_LOGIN, encode_base64(user, eol='')))
                    if code != 334:
                        raise SMTPAuthenticationError(code, resp)
                    code, resp = self.docmd(encode_base64(password, eol=''))
                else:
                    if authmethod is None:
                        raise SMTPException(
                            'No suitable authentication method found.')
        if code not in (235, 503):
            raise SMTPAuthenticationError(code, resp)
        return (code, resp)
Exemplo n.º 16
0
 def auth_login(self, challenge):
     """ Authobject to use with LOGIN authentication. Requires self.user and
     self.password to be set."""
     (code, resp) = self.docmd(
         encode_base64(self.user.encode('ascii'), eol=''))
     if code == 334:
         return self.password
     raise SMTPAuthenticationError(code, resp)
Exemplo n.º 17
0
 def encode_cram_md5(challenge, user, password):
     challenge = base64.decodestring(challenge)
     if isinstance(
             password, unicode_type
     ):  # Added by Kovid, see http://bugs.python.org/issue5285
         password = password.encode('utf-8')
     response = user + " " + hmac.HMAC(password, challenge).hexdigest()
     return encode_base64(response, eol="")
Exemplo n.º 18
0
def auth_cram_md5(user, password):
    res = send("AUTH CRAM-MD5")
    if res[0] != "5":
        challenge = res[4:]
        challenge = base64.decodestring(challenge)
        response = user + " " + hmac.HMAC(password, challenge).hexdigest()
        if send(encode_base64(response, eol=""))[0] == '2':
            return True
    return False
Exemplo n.º 19
0
    def login(self): #log in on the SMTP server
        self.putcmd('auth login')
        (code, msg) = self.getreply()
        if code != 334:
            raise SMTPResponseException(code, msg)

        self.putcmd(encode_base64(self.username, eol=''))
        (code, msg) = self.getreply()
        if code != 334:
            raise SMTPResponseException(code, msg)
        
        self.putcmd(encode_base64(self.password, eol=''))
        (code, msg) = self.getreply()
        if code not in (235, 503):
            # 235 == 'Authentication successful'
            # 503 == 'Error: already authenticated'
            raise SMTPResponseException(code, msg)
        return (code, msg)
Exemplo n.º 20
0
    def login(self):  #log in on the SMTP server
        self.putcmd('auth login')
        (code, msg) = self.getreply()
        if code != 334:
            raise SMTPResponseException(code, msg)

        self.putcmd(encode_base64(self.username, eol=''))
        (code, msg) = self.getreply()
        if code != 334:
            raise SMTPResponseException(code, msg)

        self.putcmd(encode_base64(self.password, eol=''))
        (code, msg) = self.getreply()
        if code not in (235, 503):
            # 235 == 'Authentication successful'
            # 503 == 'Error: already authenticated'
            raise SMTPResponseException(code, msg)
        return (code, msg)
Exemplo n.º 21
0
 def auth(self, mechanism, authobject, *, initial_response_ok=True):
     """Authentication command - requires response processing."""
     mechanism = mechanism.upper()
     initial_response = (authobject() if initial_response_ok else None)
     if initial_response is not None:
         response = encode_base64(initial_response.encode('ascii'), eol='')
         (code, resp) = self.docmd('AUTH', mechanism + ' ' + response)
     else:
         (code, resp) = self.docmd('AUTH', mechanism)
     # If server responds with a challenge, send the response.
     if code == 334:
         challenge = base64.decodebytes(resp)
         response = encode_base64(
             authobject(challenge).encode('ascii'), eol='')
         (code, resp) = self.docmd(response)
     if code in (235, 503):
         return code, resp
     raise SMTPAuthenticationError(code, resp)
Exemplo n.º 22
0
    def login(self, user, password):
        def encode_cram_md5(challenge, user, password):
            challenge = base64.decodebytes(challenge)
            response = user + ' ' + hmac.HMAC(password.encode('ascii'),
                                              challenge).hexdigest()
            return encode_base64(response.encode('ascii'), eol='')

        def encode_plain(user, password):
            s = '\x00%s\x00%s' % (user, password)
            return encode_base64(s.encode('ascii'), eol='')

        AUTH_PLAIN = 'PLAIN'
        AUTH_CRAM_MD5 = 'CRAM-MD5'
        AUTH_LOGIN = '******'
        self.ehlo_or_helo_if_needed()
        if not self.has_extn('auth'):
            raise SMTPException('SMTP AUTH extension not supported by server.')
        advertised_authlist = self.esmtp_features['auth'].split()
        preferred_auths = [AUTH_CRAM_MD5, AUTH_PLAIN, AUTH_LOGIN]
        authlist = [
            auth for auth in preferred_auths if auth in advertised_authlist
        ]
        if not authlist:
            raise SMTPException('No suitable authentication method found.')
        for authmethod in authlist:
            if authmethod == AUTH_CRAM_MD5:
                (code, resp) = self.docmd('AUTH', AUTH_CRAM_MD5)
                if code == 334:
                    (code,
                     resp) = self.docmd(encode_cram_md5(resp, user, password))
            elif authmethod == AUTH_PLAIN:
                (code, resp) = self.docmd(
                    'AUTH', AUTH_PLAIN + ' ' + encode_plain(user, password))
            elif authmethod == AUTH_LOGIN:
                (code, resp) = self.docmd(
                    'AUTH', '%s %s' %
                    (AUTH_LOGIN, encode_base64(user.encode('ascii'), eol='')))
                if code == 334:
                    (code, resp) = self.docmd(
                        encode_base64(password.encode('ascii'), eol=''))
            while code in (235, 503):
                return (code, resp)
        raise SMTPAuthenticationError(code, resp)
Exemplo n.º 23
0
 def smtp_AUTH(self, arg):
     user = self.__server.auth.get('user')
     password = self.__server.auth.get('password')
     s = encode_base64("\0%s\0%s" % (user, password), eol="")
     if arg == 'PLAIN {}'.format(s):
         self.push('235 Authentication successful')
     else:
         self.push(
             '535 SMTP Authentication unsuccessful/'
             'Bad username or password')
Exemplo n.º 24
0
    def login(self, user, password):

        def encode_cram_md5(challenge, user, password):
            challenge = base64.decodestring(challenge)
            response = user + ' ' + hmac.HMAC(password, challenge).hexdigest()
            return encode_base64(response, eol='')

        def encode_plain(user, password):
            return encode_base64('\x00%s\x00%s' % (user, password), eol='')

        AUTH_PLAIN = 'PLAIN'
        AUTH_CRAM_MD5 = 'CRAM-MD5'
        AUTH_LOGIN = '******'
        self.ehlo_or_helo_if_needed()
        if not self.has_extn('auth'):
            raise SMTPException('SMTP AUTH extension not supported by server.')
        authlist = self.esmtp_features['auth'].split()
        preferred_auths = [AUTH_CRAM_MD5, AUTH_PLAIN, AUTH_LOGIN]
        authmethod = None
        for method in preferred_auths:
            if method in authlist:
                authmethod = method
                break

        if authmethod == AUTH_CRAM_MD5:
            code, resp = self.docmd('AUTH', AUTH_CRAM_MD5)
            if code == 503:
                return (code, resp)
            code, resp = self.docmd(encode_cram_md5(resp, user, password))
        elif authmethod == AUTH_PLAIN:
            code, resp = self.docmd('AUTH', AUTH_PLAIN + ' ' + encode_plain(user, password))
        elif authmethod == AUTH_LOGIN:
            code, resp = self.docmd('AUTH', '%s %s' % (AUTH_LOGIN, encode_base64(user, eol='')))
            if code != 334:
                raise SMTPAuthenticationError(code, resp)
            code, resp = self.docmd(encode_base64(password, eol=''))
        elif authmethod is None:
            raise SMTPException('No suitable authentication method found.')
        if code not in (235, 503):
            raise SMTPAuthenticationError(code, resp)
        return (code, resp)
Exemplo n.º 25
0
def smtp_login():
    global file_smtp, sock_smtp_ssl, username, password
    #userstr = username_verify.get()
    # userstr = "*****@*****.**"
    #username = userstr
    print("username")
    print(username)
    user64 = encode_base64(username.encode('ascii'), eol='')
    #passstr = password_verify.get()
    # passstr = "<your-password>"
    #password = passstr
    print(password)
    pass64 = encode_base64(password.encode('ascii'), eol='')
    auths = '%s %s%s' % ("AUTH", "LOGIN" + " " + user64, CRLF)
    rcode, rstatus = send_command_smtp(sock_smtp_ssl, auths)

    passs = '%s%s' % (pass64, CRLF)
    rcode, rstatus = send_command_smtp(sock_smtp_ssl, passs)
    print(rcode)

    return int(rcode)
Exemplo n.º 26
0
    def auth(self, mechanism, authobject, *, initial_response_ok=True):
        """Authentication command - requires response processing.

        'mechanism' specifies which authentication mechanism is to
        be used - the valid values are those listed in the 'auth'
        element of 'esmtp_features'.

        'authobject' must be a callable object taking a single argument:

                data = authobject(challenge)

        It will be called to process the server's challenge response; the
        challenge argument it is passed will be a bytes.  It should return
        an ASCII string that will be base64 encoded and sent to the server.

        Keyword arguments:
            - initial_response_ok: Allow sending the RFC 4954 initial-response
              to the AUTH command, if the authentication methods supports it.
        """
        # RFC 4954 allows auth methods to provide an initial response.  Not all
        # methods support it.  By definition, if they return something other
        # than None when challenge is None, then they do.  See issue #15014.
        mechanism = mechanism.upper()
        initial_response = (authobject() if initial_response_ok else None)
        if initial_response is not None:
            response = encode_base64(initial_response.encode('ascii'), eol='')
            (code, resp) = self.docmd("AUTH", mechanism + " " + response)
        else:
            (code, resp) = self.docmd("AUTH", mechanism)
        # If server responds with a challenge, send the response.
        if code == 334:
            challenge = base64.decodebytes(resp)
            response = encode_base64(
                authobject(challenge).encode('ascii'), eol='')
            (code, resp) = self.docmd(response)
        if code in (235, 503):
            return (code, resp)
        raise SMTPAuthenticationError(code, resp)
Exemplo n.º 27
0
    def login(self, user, password):

        def encode_cram_md5(challenge, user, password):
            challenge = base64.decodebytes(challenge)
            response = user + ' ' + hmac.HMAC(password.encode('ascii'), challenge).hexdigest()
            return encode_base64(response.encode('ascii'), eol='')

        def encode_plain(user, password):
            s = '\x00%s\x00%s' % (user, password)
            return encode_base64(s.encode('ascii'), eol='')

        AUTH_PLAIN = 'PLAIN'
        AUTH_CRAM_MD5 = 'CRAM-MD5'
        AUTH_LOGIN = '******'
        self.ehlo_or_helo_if_needed()
        if not self.has_extn('auth'):
            raise SMTPException('SMTP AUTH extension not supported by server.')
        advertised_authlist = self.esmtp_features['auth'].split()
        preferred_auths = [AUTH_CRAM_MD5, AUTH_PLAIN, AUTH_LOGIN]
        authlist = [auth for auth in preferred_auths if auth in advertised_authlist]
        if not authlist:
            raise SMTPException('No suitable authentication method found.')
        for authmethod in authlist:
            if authmethod == AUTH_CRAM_MD5:
                (code, resp) = self.docmd('AUTH', AUTH_CRAM_MD5)
                if code == 334:
                    (code, resp) = self.docmd(encode_cram_md5(resp, user, password))
            elif authmethod == AUTH_PLAIN:
                (code, resp) = self.docmd('AUTH', AUTH_PLAIN + ' ' + encode_plain(user, password))
            elif authmethod == AUTH_LOGIN:
                (code, resp) = self.docmd('AUTH', '%s %s' % (AUTH_LOGIN, encode_base64(user.encode('ascii'), eol='')))
                if code == 334:
                    (code, resp) = self.docmd(encode_base64(password.encode('ascii'), eol=''))
            while code in (235, 503):
                return (code, resp)
        raise SMTPAuthenticationError(code, resp)
Exemplo n.º 28
0
    def send_mail(self, eml_path):
        self.__smtp_connection()
        smtp_hdr = []
        smtp_hdr.append("ehlo %s\r\n" % (self.ehlo))
        if self.uid != None and self.pwd != None and get_param(
            ("--auth", "-a")) == "True":
            auth_key = b""
            auth_key += '\x00'
            auth_key += self.uid.encode('ascii')
            auth_key += '\x00'
            auth_key += self.pwd.encode('ascii')
            smtp_hdr.append("AUTH PLAIN %s\r\n" %
                            (encode_base64(auth_key, eol='')))

        for hdr_it in smtp_hdr:
            sys.stdout.write("%sC%s > %s" % (C_GREEN, C_END, hdr_it))
            self.sock.send(hdr_it.encode())
            sleep(0.05)

        smtp_hdr = []
        smtp_hdr.append("quit\r\n")

        if type(eml_path) != list:
            eml_path = [
                eml_path,
            ]

        for item in eml_path:
            if os.path.exists(item) == False:
                continue
            self.__send_mail_from_log(item)

        for hdr_it in smtp_hdr:
            sys.stdout.write("%sC%s > %s" % (C_GREEN, C_END, hdr_it))
            sleep(0.05)
            self.sock.send(hdr_it.encode())

        for i in range(2500):
            if self.asw_command[-1] == "221":
                break
            sleep(0.001)

        self.__smtp_disconnection()
Exemplo n.º 29
0
def login_auth(user, password):
    login = encode_base64(user, eol="")         #aXNzYWhhckBpbmJveC5ydQ==
    password = encode_base64(password, eol="")  #Mjh6UjVRMXRK
    if request("AUTH LOGIN")[0] == '3' and request(login)[0] == '3' and request(password)[0] == '2':
        return True
    return False
Exemplo n.º 30
0
        self.assertEqual(self.serv.last_message.decode(), expected)
        self.assertIn("BODY=8BITMIME", self.serv.last_mail_options)
        self.assertIn("SMTPUTF8", self.serv.last_mail_options)
        self.assertEqual(self.serv.last_rcpt_options, [])

    def test_send_message_error_on_non_ascii_addrs_if_no_smtputf8(self):
        msg = EmailMessage()
        msg["From"] = "Páolo <fő[email protected]>"
        msg["To"] = "Dinsdale"
        msg["Subject"] = "Nudge nudge, wink, wink \u1F609"
        smtp = smtplib.SMTP(HOST, self.port, local_hostname="localhost", timeout=3)
        self.addCleanup(smtp.close)
        self.assertRaises(smtplib.SMTPNotSupportedError, smtp.send_message(msg))


EXPECTED_RESPONSE = encode_base64(b"\0psu\0doesnotexist", eol="")


class SimSMTPAUTHInitialResponseChannel(SimSMTPChannel):
    def smtp_AUTH(self, arg):
        # RFC 4954's AUTH command allows for an optional initial-response.
        # Not all AUTH methods support this; some require a challenge.  AUTH
        # PLAIN does those, so test that here.  See issue #15014.
        args = arg.split()
        if args[0].lower() == "plain":
            if len(args) == 2:
                # AUTH PLAIN <initial-response> with the response base 64
                # encoded.  Hard code the expected response for the test.
                if args[1] == EXPECTED_RESPONSE:
                    self.push("235 Ok")
                    return
Exemplo n.º 31
0
    def login(self, user, password):
        def encode_cram_md5(challenge, user, password):
            challenge = base64.b64decode(challenge)
            response = user + " " + hmac.HMAC(password.encode('ascii'),
                                              challenge, 'md5').hexdigest()
            return encode_base64(response.encode('ascii'), eol='')

        def encode_plain(user, password):
            s = "\0%s\0%s" % (user, password)
            return encode_base64(s.encode('ascii'), eol='')

        AUTH_PLAIN = "PLAIN"
        AUTH_CRAM_MD5 = "CRAM-MD5"
        AUTH_LOGIN = "******"

        yield from self.ehlo_or_helo_if_needed()

        if not self.supports("auth"):
            raise SMTPException("SMTP AUTH extension not supported by server.")

        # Authentication methods the server claims to support
        advertised_authlist = self.esmtp_extensions["auth"]

        # List of authentication methods we support: from preferred to
        # less preferred methods. Except for the purpose of testing the weaker
        # ones, we prefer stronger methods like CRAM-MD5:
        preferred_auths = [AUTH_CRAM_MD5, AUTH_PLAIN, AUTH_LOGIN]

        # We try the authentication methods the server advertises, but only the
        # ones *we* support. And in our preferred order.
        authlist = [
            auth for auth in preferred_auths if auth in advertised_authlist
        ]
        if not authlist:
            raise SMTPException("No suitable authentication method found.")

        # Some servers advertise authentication methods they don't really
        # support, so if authentication fails, we continue until we've tried
        # all methods.
        for authmethod in authlist:
            if authmethod == AUTH_CRAM_MD5:
                (code, resp) = yield from self.execute_command(
                    "AUTH", AUTH_CRAM_MD5)
                if code == 334:
                    (code, resp) = yield from self.execute_command(
                        encode_cram_md5(resp, user, password))
            elif authmethod == AUTH_PLAIN:
                (code, resp) = yield from self.execute_command(
                    "AUTH", AUTH_PLAIN + " " + encode_plain(user, password))
            elif authmethod == AUTH_LOGIN:
                (code, resp) = yield from self.execute_command(
                    "AUTH", "%s %s" %
                    (AUTH_LOGIN, encode_base64(user.encode('ascii'), eol='')))
                if code == 334:
                    (code, resp) = yield from self.execute_command(
                        encode_base64(password.encode('ascii'), eol=''))

            # 235 == 'Authentication successful'
            # 503 == 'Error: already authenticated'
            if code in (235, 503):
                return (code, resp)

        # We could not login sucessfully. Return result of last attempt.
        raise SMTPAuthenticationError(code, resp)
Exemplo n.º 32
0
 def encode_cram_md5(challenge, user, password):
     challenge = base64.decodestring(challenge)
     response = user + " " + hmac.HMAC(password, challenge).hexdigest()
     return encode_base64(response, eol="")
Exemplo n.º 33
0
        self.assertIn('SMTPUTF8', self.serv.last_mail_options)
        self.assertEqual(self.serv.last_rcpt_options, [])

    def test_send_message_error_on_non_ascii_addrs_if_no_smtputf8(self):
        msg = EmailMessage()
        msg['From'] = "Páolo <fő[email protected]>"
        msg['To'] = 'Dinsdale'
        msg['Subject'] = 'Nudge nudge, wink, wink \u1F609'
        smtp = smtplib.SMTP(
            HOST, self.port, local_hostname='localhost', timeout=3)
        self.addCleanup(smtp.close)
        self.assertRaises(smtplib.SMTPNotSupportedError,
                          smtp.send_message(msg))


EXPECTED_RESPONSE = encode_base64(b'\0psu\0doesnotexist', eol='')

class SimSMTPAUTHInitialResponseChannel(SimSMTPChannel):
    def smtp_AUTH(self, arg):
        # RFC 4954's AUTH command allows for an optional initial-response.
        # Not all AUTH methods support this; some require a challenge.  AUTH
        # PLAIN does those, so test that here.  See issue #15014.
        args = arg.split()
        if args[0].lower() == 'plain':
            if len(args) == 2:
                # AUTH PLAIN <initial-response> with the response base 64
                # encoded.  Hard code the expected response for the test.
                if args[1] == EXPECTED_RESPONSE:
                    self.push('235 Ok')
                    return
        self.push('571 Bad authentication')
Exemplo n.º 34
0
 def encode_cram_md5(challenge, user, password):
     challenge = base64.decodestring(challenge)
     response = user + " " + hmac.HMAC(password, challenge).hexdigest()
     return encode_base64(response, eol="")
Exemplo n.º 35
0
 def encode_plain(user, password):
     s = "\0%s\0%s" % (user, password)
     return encode_base64(s.encode('ascii'), eol='')
Exemplo n.º 36
0
 def encode_plain(user, password):
     s = "\0%s\0%s" % (user, password)
     return encode_base64(s.encode("ascii"), eol="")
Exemplo n.º 37
0
 def generate_cnonce():
     s = ""
     for i in range(16):
         s = s + chr(random.randint(0, 0xff))
     return encode_base64(s, eol="")
Exemplo n.º 38
0
 def encode_cram_md5(challenge, username, password):
     challenge = base64.decodebytes(challenge)
     response = username + " " + hmac.HMAC(password.encode("ascii"), challenge, "md5").hexdigest()
     return encode_base64(response.encode("ascii"), eol="")
Exemplo n.º 39
0
def auth_plain(login, password):
    if send("AUTH PLAIN " + encode_base64("\0%s\0%s" % (login, password), eol=""))[0] == "2":
        return True
    return False
Exemplo n.º 40
0
    def login(self, user, password):
        """Log in on an SMTP server that requires authentication.
        
        The arguments are:
            - user:     The user name to authenticate with.
            - password: The password for the authentication.
        
        If there has been no previous EHLO or HELO command this session, this
        method tries ESMTP EHLO first.
        
        This method will return normally if the authentication was successful.
        
        This method may raise the following exceptions:
        
         SMTPHeloError            The server didn't reply properly to
                                  the helo greeting.
         SMTPAuthenticationError  The server didn't accept the username/
                                  password combination.
         SMTPException            No suitable authentication method was
                                  found.
        """

        def encode_cram_md5(challenge, user, password):
            challenge = base64.decodestring(challenge)
            response = user + ' ' + hmac.HMAC(password, challenge).hexdigest()
            return encode_base64(response, eol='')

        def encode_plain(user, password):
            return encode_base64('\x00%s\x00%s' % (user, password), eol='')

        AUTH_PLAIN = 'PLAIN'
        AUTH_CRAM_MD5 = 'CRAM-MD5'
        AUTH_LOGIN = '******'
        self.ehlo_or_helo_if_needed()
        if not self.has_extn('auth'):
            raise SMTPException('SMTP AUTH extension not supported by server.')
        authlist = self.esmtp_features['auth'].split()
        preferred_auths = [AUTH_CRAM_MD5, AUTH_PLAIN, AUTH_LOGIN]
        authmethod = None
        for method in preferred_auths:
            if method in authlist:
                authmethod = method
                break

        if authmethod == AUTH_CRAM_MD5:
            code, resp = self.docmd('AUTH', AUTH_CRAM_MD5)
            if code == 503:
                return (code, resp)
            code, resp = self.docmd(encode_cram_md5(resp, user, password))
        elif authmethod == AUTH_PLAIN:
            code, resp = self.docmd('AUTH', AUTH_PLAIN + ' ' + encode_plain(user, password))
        elif authmethod == AUTH_LOGIN:
            code, resp = self.docmd('AUTH', '%s %s' % (AUTH_LOGIN, encode_base64(user, eol='')))
            if code != 334:
                raise SMTPAuthenticationError(code, resp)
            code, resp = self.docmd(encode_base64(password, eol=''))
        elif authmethod is None:
            raise SMTPException('No suitable authentication method found.')
        if code not in (235, 503):
            raise SMTPAuthenticationError(code, resp)
        return (code, resp)
Exemplo n.º 41
0
 def encode_cram_md5(challenge, user, password):
     challenge = base64.decodebytes(challenge)
     response = user + " " + hmac.HMAC(password.encode('ascii'),
                                       challenge).hexdigest()
     return encode_base64(response.encode('ascii'), eol='')
Exemplo n.º 42
0
    def login(self, user, password):
        """Log in on an SMTP server that requires authentication.

        The arguments are:
            - user:     The user name to authenticate with.
            - password: The password for the authentication.

        If there has been no previous EHLO or HELO command this session, this
        method tries ESMTP EHLO first.

        This method will return normally if the authentication was successful.

        This method may raise the following exceptions:

         SMTPHeloError            The server didn't reply properly to
                                  the helo greeting.
         SMTPAuthenticationError  The server didn't accept the username/
                                  password combination.
         SMTPException            No suitable authentication method was
                                  found.
        """

        def encode_cram_md5(challenge, user, password):
            challenge = base64.decodebytes(challenge)
            response = user + " " + hmac.HMAC(password.encode('ascii'),
                                              challenge, 'md5').hexdigest()
            return encode_base64(response.encode('ascii'), eol='')

        def encode_plain(user, password):
            s = "\0%s\0%s" % (user, password)
            return encode_base64(s.encode('ascii'), eol='')

        AUTH_PLAIN = "PLAIN"
        AUTH_CRAM_MD5 = "CRAM-MD5"
        AUTH_LOGIN = "******"

        self.ehlo_or_helo_if_needed()

        if not self.has_extn("auth"):
            raise SMTPException("SMTP AUTH extension not supported by server.")

        # Authentication methods the server claims to support
        advertised_authlist = self.esmtp_features["auth"].split()

        # List of authentication methods we support: from preferred to
        # less preferred methods. Except for the purpose of testing the weaker
        # ones, we prefer stronger methods like CRAM-MD5:
        preferred_auths = [AUTH_CRAM_MD5, AUTH_PLAIN, AUTH_LOGIN]

        # We try the authentication methods the server advertises, but only the
        # ones *we* support. And in our preferred order.
        authlist = [auth for auth in preferred_auths if auth in advertised_authlist]
        if not authlist:
            raise SMTPException("No suitable authentication method found.")

        # Some servers advertise authentication methods they don't really
        # support, so if authentication fails, we continue until we've tried
        # all methods.
        for authmethod in authlist:
            if authmethod == AUTH_CRAM_MD5:
                (code, resp) = self.docmd("AUTH", AUTH_CRAM_MD5)
                if code == 334:
                    (code, resp) = self.docmd(encode_cram_md5(resp, user, password))
            elif authmethod == AUTH_PLAIN:
                (code, resp) = self.docmd("AUTH",
                    AUTH_PLAIN + " " + encode_plain(user, password))
            elif authmethod == AUTH_LOGIN:
                (code, resp) = self.docmd("AUTH",
                    "%s %s" % (AUTH_LOGIN, encode_base64(user.encode('ascii'), eol='')))
                if code == 334:
                    (code, resp) = self.docmd(encode_base64(password.encode('ascii'), eol=''))

            # 235 == 'Authentication successful'
            # 503 == 'Error: already authenticated'
            if code in (235, 503):
                return (code, resp)

        # We could not login sucessfully. Return result of last attempt.
        raise SMTPAuthenticationError(code, resp)
Exemplo n.º 43
0
 def encode_cram_md5(challenge, user, password):
     challenge = base64.decodebytes(challenge)
     response = user + " " + hmac.HMAC(password.encode('ascii'),
                                       challenge, 'md5').hexdigest()
     return encode_base64(response.encode('ascii'), eol='')
Exemplo n.º 44
0
    def login(self, user, password):
        """Log in on an SMTP server that requires authentication.

        The arguments are:
            - user:     The user name to authenticate with.
            - password: The password for the authentication.

        If there has been no previous EHLO or HELO command this session, this
        method tries ESMTP EHLO first.

        This method will return normally if the authentication was successful.

        This method may raise the following exceptions:

         SMTPHeloError            The server didn't reply properly to
                                  the helo greeting.
         SMTPAuthenticationError  The server didn't accept the username/
                                  password combination.
         SMTPException            No suitable authentication method was
                                  found.
        """
        def encode_cram_md5(challenge, user, password):
            challenge = base64.decodestring(challenge)
            response = user + " " + hmac.HMAC(password, challenge).hexdigest()
            return encode_base64(response, eol="")

        def digest_md5_decode_challenge(challenge):
            # Challenge is formed with these pairs separated by comma.
            #   realm="hostname" (multiple allowed)
            #   nonce="randomized data, at least 64bit"
            #   qop="auth,auth-int,auth-conf"
            #   maxbuf=number (with auth-int, auth-conf, defaults to 64k)
            #   charset="utf-8" (iso-8859-1 if it doesn't exist)
            #   algorithm="md5-sess"
            #   cipher="3des,des,rc4-40,rc4,rc4-56" (with auth-conf)
            #
            # XXX: multiple realms are not supported
            c = {}
            for e in challenge.split(','):
                off = e.index('=')
                v = e[off + 1:].strip()
                if v[0] == '"':
                    v = v[1:-1]
                c[e[:off].strip()] = v
            return c

        def generate_cnonce():
            s = ""
            for i in range(16):
                s = s + chr(random.randint(0, 0xff))
            return encode_base64(s, eol="")

        def md5(indata):
            try:
                import hashlib
                md5 = hashlib.md5(indata)
            except ImportError:
                import md5
                md5 = md5.new(indata)
            return md5.digest()

        def encode_digest_md5(challenge, user, password):
            challenge = base64.decodestring(challenge)
            c = digest_md5_decode_challenge(challenge)

            realm = c["realm"]
            nonce = c["nonce"]
            qop = c["qop"]
            cnonce = generate_cnonce()
            if "realm" in c:
                digest_uri = "smtp/%s" % realm
                realmPair = ',realm="%s"' % realm
            else:
                digest_uri = "smtp/localhost"
                realmPair = ""

            credential = md5("%s:%s:%s" % (user, realm, password))
            # XXX: not support authorization ID
            a1 = "%s:%s:%s" % (credential, nonce, cnonce)
            if qop == "auth":
                a2 = "AUTHENTICATE:%s" % digest_uri
            else:
                # XXX: most servers and clients don't implement auth-int/auth-conf,
                # they use dummy MD5 digest for body.
                a2 = "AUTHENTICATE:%s:00000000000000000000000000000000" % digest_uri

            a1 = hexlify(md5(a1))
            a2 = hexlify(md5(a2))
            response = hexlify(
                md5("%s:%s:00000001:%s:%s:%s" % (a1, nonce, cnonce, qop, a2)))
            response = (
                'username="******"%s,nonce="%s",cnonce="%s",'
                'nc=00000001,qop=%s,digest-uri="%s",response=%s' %
                (user, realmPair, nonce, cnonce, qop, digest_uri, response))
            return encode_base64(response, eol="")

        def encode_plain(user, password):
            return encode_base64("\0%s\0%s" % (user, password), eol="")

        AUTH_PLAIN = "PLAIN"
        AUTH_CRAM_MD5 = "CRAM-MD5"
        AUTH_DIGEST_MD5 = "DIGEST-MD5"
        AUTH_LOGIN = "******"

        self.ehlo_or_helo_if_needed()

        if not self.has_extn("auth"):
            raise SMTPException("SMTP AUTH extension not supported by server.")

        # Authentication methods the server supports:
        authlist = self.esmtp_features["auth"].split()

        # List of authentication methods we support: from preferred to
        # less preferred methods. Except for the purpose of testing the weaker
        # ones, we prefer stronger methods like CRAM-MD5:
        preferred_auths = [
            AUTH_DIGEST_MD5, AUTH_CRAM_MD5, AUTH_PLAIN, AUTH_LOGIN
        ]

        # Determine the authentication method we'll use
        authmethod = None
        for method in preferred_auths:
            if method in authlist:
                authmethod = method
                break

        if authmethod == AUTH_DIGEST_MD5:
            (code, resp) = self.docmd("AUTH", AUTH_DIGEST_MD5)
            if code == 503:
                # 503 == 'Error: already authenticated'
                return (code, resp)
            (code, resp) = self.docmd(encode_digest_md5(resp, user, password))
            if code == 334:
                # XXX: need validate "resp"?
                (code, resp) = self.docmd("")
        elif authmethod == AUTH_CRAM_MD5:
            (code, resp) = self.docmd("AUTH", AUTH_CRAM_MD5)
            if code == 503:
                # 503 == 'Error: already authenticated'
                return (code, resp)
            (code, resp) = self.docmd(encode_cram_md5(resp, user, password))
        elif authmethod == AUTH_PLAIN:
            (code, resp) = self.docmd(
                "AUTH", AUTH_PLAIN + " " + encode_plain(user, password))
        elif authmethod == AUTH_LOGIN:
            (code, resp) = self.docmd(
                "AUTH", "%s %s" % (AUTH_LOGIN, encode_base64(user, eol="")))
            if code != 334:
                raise SMTPAuthenticationError(code, resp)
            (code, resp) = self.docmd(encode_base64(password, eol=""))
        elif authmethod is None:
            raise SMTPException("No suitable authentication method found.")
        if code not in (235, 503):
            # 235 == 'Authentication successful'
            # 503 == 'Error: already authenticated'
            raise SMTPAuthenticationError(code, resp)
        return (code, resp)
Exemplo n.º 45
0
    def login(self, user, password):
        """Log in on an SMTP server that requires authentication.

        The arguments are:
            - user:     The user name to authenticate with.
            - password: The password for the authentication.

        If there has been no previous EHLO or HELO command this session, this
        method tries ESMTP EHLO first.

        This method will return normally if the authentication was successful.

        This method may raise the following exceptions:

         SMTPHeloError            The server didn't reply properly to
                                  the helo greeting.
         SMTPAuthenticationError  The server didn't accept the username/
                                  password combination.
         SMTPException            No suitable authentication method was
                                  found.
        """

        def encode_cram_md5(challenge, user, password):
            challenge = base64.decodestring(challenge)
            response = user + " " + hmac.HMAC(password, challenge).hexdigest()
            return encode_base64(response, eol="")

        def encode_plain(user, password):
            return encode_base64("\0%s\0%s" % (user, password), eol="")


        AUTH_PLAIN = "PLAIN"
        AUTH_CRAM_MD5 = "CRAM-MD5"
        AUTH_LOGIN = "******"

        self.ehlo_or_helo_if_needed()

        if not self.has_extn("auth"):
            raise SMTPException("SMTP AUTH extension not supported by server.")

        # Authentication methods the server supports:
        authlist = self.esmtp_features["auth"].split()

        # List of authentication methods we support: from preferred to
        # less preferred methods. Except for the purpose of testing the weaker
        # ones, we prefer stronger methods like CRAM-MD5:
        preferred_auths = [AUTH_CRAM_MD5, AUTH_PLAIN, AUTH_LOGIN]

        # Determine the authentication method we'll use
        authmethod = None
        for method in preferred_auths:
            if method in authlist:
                authmethod = method
                break

        if authmethod == AUTH_CRAM_MD5:
            (code, resp) = self.docmd("AUTH", AUTH_CRAM_MD5)
            if code == 503:
                # 503 == 'Error: already authenticated'
                return (code, resp)
            (code, resp) = self.docmd(encode_cram_md5(resp, user, password))
        elif authmethod == AUTH_PLAIN:
            (code, resp) = self.docmd("AUTH",
                AUTH_PLAIN + " " + encode_plain(user, password))
        elif authmethod == AUTH_LOGIN:
            (code, resp) = self.docmd("AUTH",
                "%s %s" % (AUTH_LOGIN, encode_base64(user, eol="")))
            if code != 334:
                raise SMTPAuthenticationError(code, resp)
            (code, resp) = self.docmd(encode_base64(password, eol=""))
        elif authmethod is None:
            raise SMTPException("No suitable authentication method found.")
        if code not in (235, 503):
            # 235 == 'Authentication successful'
            # 503 == 'Error: already authenticated'
            raise SMTPAuthenticationError(code, resp)
        return (code, resp)
Exemplo n.º 46
0
        self.assertIn('SMTPUTF8', self.serv.last_mail_options)
        self.assertEqual(self.serv.last_rcpt_options, [])

    def test_send_message_error_on_non_ascii_addrs_if_no_smtputf8(self):
        msg = EmailMessage()
        msg['From'] = "Páolo <fő[email protected]>"
        msg['To'] = 'Dinsdale'
        msg['Subject'] = 'Nudge nudge, wink, wink \u1F609'
        smtp = smtplib.SMTP(
            HOST, self.port, local_hostname='localhost', timeout=3)
        self.addCleanup(smtp.close)
        self.assertRaises(smtplib.SMTPNotSupportedError,
                          smtp.send_message(msg))


EXPECTED_RESPONSE = encode_base64(b'\0psu\0doesnotexist', eol='')

class SimSMTPAUTHInitialResponseChannel(SimSMTPChannel):
    def smtp_AUTH(self, arg):
        # RFC 4954's AUTH command allows for an optional initial-response.
        # Not all AUTH methods support this; some require a challenge.  AUTH
        # PLAIN does those, so test that here.  See issue #15014.
        args = arg.split()
        if args[0].lower() == 'plain':
            if len(args) == 2:
                # AUTH PLAIN <initial-response> with the response base 64
                # encoded.  Hard code the expected response for the test.
                if args[1] == EXPECTED_RESPONSE:
                    self.push('235 Ok')
                    return
        self.push('571 Bad authentication')
Exemplo n.º 47
0
 def encode_plain(user, password):
     return encode_base64("\0%s\0%s" % (user, password), eol="")
Exemplo n.º 48
0
 def encode_plain(user, password): 
     return encode_base64(("\0%s\0%s" % (user, password)).encode('ascii'), eol="")
Exemplo n.º 49
0
    def login(self, user, password):
        """Log in on an SMTP server that requires authentication.

        The arguments are:
            - user:     The user name to authenticate with.
            - password: The password for the authentication.

        If there has been no previous EHLO or HELO command this session, this
        method tries ESMTP EHLO first.

        This method will return normally if the authentication was successful.

        This method may raise the following exceptions:

         SMTPHeloError            The server didn't reply properly to
                                  the helo greeting.
         SMTPAuthenticationError  The server didn't accept the username/
                                  password combination.
         SMTPException            No suitable authentication method was
                                  found.
        """
        def encode_cram_md5(challenge, user, password):
            challenge = base64.decodebytes(challenge)
            response = user + " " + hmac.HMAC(password.encode('ascii'),
                                              challenge).hexdigest()
            return encode_base64(response.encode('ascii'), eol='')

        def encode_plain(user, password):
            s = "\0%s\0%s" % (user, password)
            return encode_base64(s.encode('ascii'), eol='')

        AUTH_PLAIN = "PLAIN"
        AUTH_CRAM_MD5 = "CRAM-MD5"
        AUTH_LOGIN = "******"

        self.ehlo_or_helo_if_needed()

        if not self.has_extn("auth"):
            raise SMTPException("SMTP AUTH extension not supported by server.")

        # Authentication methods the server claims to support
        advertised_authlist = self.esmtp_features["auth"].split()

        # List of authentication methods we support: from preferred to
        # less preferred methods. Except for the purpose of testing the weaker
        # ones, we prefer stronger methods like CRAM-MD5:
        preferred_auths = [AUTH_CRAM_MD5, AUTH_PLAIN, AUTH_LOGIN]

        # We try the authentication methods the server advertises, but only the
        # ones *we* support. And in our preferred order.
        authlist = [
            auth for auth in preferred_auths if auth in advertised_authlist
        ]
        if not authlist:
            raise SMTPException("No suitable authentication method found.")

        # Some servers advertise authentication methods they don't really
        # support, so if authentication fails, we continue until we've tried
        # all methods.
        for authmethod in authlist:
            if authmethod == AUTH_CRAM_MD5:
                (code, resp) = self.docmd("AUTH", AUTH_CRAM_MD5)
                if code == 334:
                    (code,
                     resp) = self.docmd(encode_cram_md5(resp, user, password))
            elif authmethod == AUTH_PLAIN:
                (code, resp) = self.docmd(
                    "AUTH", AUTH_PLAIN + " " + encode_plain(user, password))
            elif authmethod == AUTH_LOGIN:
                (code, resp) = self.docmd(
                    "AUTH", "%s %s" %
                    (AUTH_LOGIN, encode_base64(user.encode('ascii'), eol='')))
                if code == 334:
                    (code, resp) = self.docmd(
                        encode_base64(password.encode('ascii'), eol=''))

            # 235 == 'Authentication successful'
            # 503 == 'Error: already authenticated'
            if code in (235, 503):
                return (code, resp)

        # We could not login sucessfully. Return result of last attempt.
        raise SMTPAuthenticationError(code, resp)
Exemplo n.º 50
0
def auth_login(user, password):
    login_base64 = encode_base64(user, eol="")
    password_base64 = encode_base64(password, eol="")
    if send("AUTH LOGIN")[0] == '3' and send(login_base64)[0] == '3' and send(password_base64)[0] == '2':
        return True
    return False
Exemplo n.º 51
0
 def encode_plain(user, password):
     s = "\0%s\0%s" % (user, password)
     return encode_base64(s.encode('ascii'), eol='')
Exemplo n.º 52
0
    def login(self, user, password):
        """Log in on an SMTP server that requires authentication.
        
        The arguments are:
            - user:     The user name to authenticate with.
            - password: The password for the authentication.
        
        If there has been no previous EHLO or HELO command this session, this
        method tries ESMTP EHLO first.
        
        This method will return normally if the authentication was successful.
        
        This method may raise the following exceptions:
        
         SMTPHeloError            The server didn't reply properly to
                                  the helo greeting.
         SMTPAuthenticationError  The server didn't accept the username/
                                  password combination.
         SMTPException            No suitable authentication method was
                                  found.
        """
        def encode_cram_md5(challenge, user, password):
            challenge = base64.decodestring(challenge)
            response = user + ' ' + hmac.HMAC(password, challenge).hexdigest()
            return encode_base64(response, eol='')

        def encode_plain(user, password):
            return encode_base64('\x00%s\x00%s' % (user, password), eol='')

        AUTH_PLAIN = 'PLAIN'
        AUTH_CRAM_MD5 = 'CRAM-MD5'
        AUTH_LOGIN = '******'
        self.ehlo_or_helo_if_needed()
        if not self.has_extn('auth'):
            raise SMTPException('SMTP AUTH extension not supported by server.')
        authlist = self.esmtp_features['auth'].split()
        preferred_auths = [AUTH_CRAM_MD5, AUTH_PLAIN, AUTH_LOGIN]
        authmethod = None
        for method in preferred_auths:
            if method in authlist:
                authmethod = method
                break

        if authmethod == AUTH_CRAM_MD5:
            code, resp = self.docmd('AUTH', AUTH_CRAM_MD5)
            if code == 503:
                return (code, resp)
            code, resp = self.docmd(encode_cram_md5(resp, user, password))
        elif authmethod == AUTH_PLAIN:
            code, resp = self.docmd(
                'AUTH', AUTH_PLAIN + ' ' + encode_plain(user, password))
        elif authmethod == AUTH_LOGIN:
            code, resp = self.docmd(
                'AUTH', '%s %s' % (AUTH_LOGIN, encode_base64(user, eol='')))
            if code != 334:
                raise SMTPAuthenticationError(code, resp)
            code, resp = self.docmd(encode_base64(password, eol=''))
        elif authmethod is None:
            raise SMTPException('No suitable authentication method found.')
        if code not in (235, 503):
            raise SMTPAuthenticationError(code, resp)
        return (code, resp)
Exemplo n.º 53
0
 def encode_plain(user, password):
     return encode_base64('\x00%s\x00%s' % (user, password), eol='')
Exemplo n.º 54
0
 def encode_plain(user, password):
     return encode_base64('\x00%s\x00%s' % (user, password), eol='')
Exemplo n.º 55
0
    def login(self, user, password, callback=None):
        """Log in on an SMTP server that requires authentication.

        The arguments are:
            - user:     The user name to authenticate with.
            - password: The password for the authentication.

        If there has been no previous EHLO or HELO command this session, this
        method tries ESMTP EHLO first.

        This method will return normally if the authentication was successful.

        This method may raise the following exceptions:

         SMTPHeloError            The server didn't reply properly to
                                  the helo greeting.
         SMTPAuthenticationError  The server didn't accept the username/
                                  password combination.
         SMTPException            No suitable authentication method was
                                  found.
        """

        def encode_cram_md5(challenge, user, password):
            challenge = base64.decodestring(challenge)
            response = user + " " + hmac.HMAC(password, challenge).hexdigest()
            return encode_base64(response, eol="")

        def encode_plain(user, password):
            return encode_base64("\0%s\0%s" % (user, password), eol="")


        AUTH_PLAIN = "PLAIN"
        AUTH_CRAM_MD5 = "CRAM-MD5"
        AUTH_LOGIN = "******"

        yield gen.Task(self.ehlo_or_helo_if_needed)

        if not self.has_extn("auth"):
            raise SMTPException("SMTP AUTH extension not supported by server.")

        # Authentication methods the server supports:
        authlist = self.esmtp_features["auth"].split()

        # List of authentication methods we support: from preferred to
        # less preferred methods. Except for the purpose of testing the weaker
        # ones, we prefer stronger methods like CRAM-MD5:
        preferred_auths = [AUTH_CRAM_MD5, AUTH_PLAIN, AUTH_LOGIN]

        # Determine the authentication method we'll use
        authmethod = None
        for method in preferred_auths:
            if method in authlist:
                authmethod = method
                break

        if authmethod == AUTH_CRAM_MD5:
            (code, resp) = yield gen.Task(self.docmd, "AUTH", AUTH_CRAM_MD5)
            if code == 503:
                # 503 == 'Error: already authenticated'
                if callback:
                    callback((code, resp))
                return
            (code, resp) = yield gen.Task(self.docmd, encode_cram_md5(resp, user, password))
        elif authmethod == AUTH_PLAIN:
            (code, resp) = yield gen.Task(self.docmd, "AUTH",
                AUTH_PLAIN + " " + encode_plain(user, password))
        elif authmethod == AUTH_LOGIN:
            (code, resp) = yield gen.Task(self.docmd, "AUTH",
                "%s %s" % (AUTH_LOGIN, encode_base64(user, eol="")))
            if code != 334:
                raise SMTPAuthenticationError(code, resp)
            (code, resp) = yield gen.Task(self.docmd, encode_base64(password, eol=""))
        elif authmethod is None:
            raise SMTPException("No suitable authentication method found.")
        if code not in (235, 503):
            # 235 == 'Authentication successful'
            # 503 == 'Error: already authenticated'
            raise SMTPAuthenticationError(code, resp)
        if callback:
            callback((code, resp))
Exemplo n.º 56
0
def plain_auth(user, password):
    if request("AUTH PLAIN " + encode_base64("\0%s\0%s" % (user, password), eol=""))[0] == "2":
        return True
    return False
Exemplo n.º 57
0
 def encode_plain(user, password):
     return encode_base64("\0%s\0%s" % (user, password), eol="")
Exemplo n.º 58
0
 def encode_cram_md5(challenge, user, password):
     challenge = base64.decodestring(challenge)
     if isinstance(password, unicode):  # Added by Kovid, see http://bugs.python.org/issue5285
         password = password.encode('utf-8')
     response = user + " " + hmac.HMAC(password, challenge).hexdigest()
     return encode_base64(response, eol="")