Exemplo n.º 1
0
    def sendmail(self, username, password, message):
        '''Method to connect to the SMTP server (using TLS security if
        available) and sending the message through email.'''

        try:
            s = smtplib.SMTP(self.server)
            # Establish TLS
            code = s.ehlo()[0]
            usesmtp = 1
            if not (200 < code < 299):
                usesmtp = 0
                code = s.helo()[0]
                if not (200 <= code <= 299):
                    raise smtplib.SMTPHeloError(code)

            if usesmtp and s.has_extn('starttls'):
                self.log("Negotiating TLS...")
                s.starttls()
                code = s.ehlo()[0]
                if not (200 <= code <= 299):
                    self.log("Could not EHLO after STARTTLS.")
                    return 0
                self.log("Using TLS connection.")
            else:
                self.log(
                    "Server does not support TLS; using normal connection.")
            try:
                s.login(username, password)
            except smtplib.SMTPException, e:
                self.log("Authentication failed: %s" % e)
                return 0
            # mes = self.getmessage(message)
            s.sendmail(self.fromaddr, self.toaddrs, message)
            self.log('Message: %s' % message)
Exemplo n.º 2
0
 def send(self, email):
     self.container = self.getEmailContainer()
     if not self.enabled():
         self.queue(email, 10)
         return False
     server_info = '%s:%d' % (self.container.hostname, self.container.port
                              or 25)
     try:
         connection = self.smtp_factory()
         if self.container.port:
             port = str(self.container.port)
         else:
             port = '25'
         connection.connect(self.container.hostname, port)
         code, response = connection.ehlo()
         if code < 200 or code >= 300:
             code, response = connection.helo()
             if code < 200 or code >= 300:
                 raise smtplib.SMTPHeloError(code, response)
         if connection.has_extn('starttls') and self.container.tls:
             connection.starttls()
             connection.ehlo()
         if connection.does_esmtp:
             if self.container.username is not None and \
                self.container.password is not None:
                 connection.login(self.container.username,
                                  self.container.password)
     except (socket.error, ), e:
         self.queue(email, 20, {'info': server_info})
         return False
Exemplo n.º 3
0
    def authTLS(self):
        '''
        TLS连接方式的验证
        :return:smtp实例
        '''
        s = smtplib.SMTP()
        s.connect(mail_server, mail_port)

        code = s.ehlo()[0]
        usesesmtp = 1
        if not (200 <= code <= 299):
            usesesmtp = 0
            code = s.helo()[0]
            if not (200 <= code <= 299):
                raise smtplib.SMTPHeloError(code, resp)

        if usesesmtp and s.has_extn('starttls'):
            s.starttls()
            code = s.ehlo()[0]
            if not (200 <= code <= 299):
                sys.exit(5)
        if s.has_extn('auth'):
            try:
                s.login(mail_username, mail_password)
            except:
                logger.error("验证失败!")
                sys.exit(1)
        self.server = s
    def test_expecting_SMTP_helo_error(self) -> None:
        check = UnitTestSmtpCredentials._create_mocked_method_raising(
            smtplib.SMTPHeloError(0, ''))
        status, message = UnitTestSmtpCredentials._run_mocked_check(
            self.test_expecting_SMTP_helo_error.__name__, check)

        self.assertEqual(
            (status, message),
            (False, smtpcheck.Messages.SMTP_HELO_OR_EHLO_ERROR.value))
Exemplo n.º 5
0
 def smtp_ehlo_or_helo_if_needed(self,
                                 smtp: smtplib.SMTP,
                                 name: str = '',
                                 disable_ehlo: bool = False) -> NoReturn:
     if smtp.helo_resp is None and smtp.ehlo_resp is None:
         if disable_ehlo or not (200 <= smtp.ehlo(name)[0] <= 299):
             (code, resp) = smtp.helo(name)
             if not (200 <= code <= 299):
                 raise smtplib.SMTPHeloError(code, resp)
Exemplo n.º 6
0
def connect():
    """ Establish an smtp connection.
    """
    logger.info('establishing smtp connection with %s using port %d' %
                (EMAIL_DELIVERY_HOST, EMAIL_DELIVERY_PORT))
    conn = smtplib.SMTP(EMAIL_DELIVERY_HOST, EMAIL_DELIVERY_PORT)
    logger.info('logged in')
    (code, resp) = conn.ehlo()
    if not (200 <= code <= 299):
        raise smtplib.SMTPHeloError(code, resp)
    conn.starttls()
    (code, resp) = conn.ehlo()
    if not (200 <= code <= 299):
        raise smtplib.SMTPHeloError(code, resp)

    i = 0
    while i <= EMAIL_CONNECTION_RETRIES:
        i += 1
        err = None
        try:
            conn.login(EMAIL_DELIVERY_HOST_USER, EMAIL_DELIVERY_HOST_PASSWORD)
        except smtplib.SMTPAuthenticationError as err:
            pass

        if err is None:
            break
        else:
            logger.error('{err.__class__.__name__}: {err}'.format(err=err))
            try:
                conn.quit()
            except smtplib.SMTPServerDisconnected:
                pass
            sleep_time = handle_error(i >= EMAIL_CONNECTION_RETRIES,
                                      err,
                                      'connection error',
                                      raise_=True)
            if sleep_time is not None:
                time.sleep(sleep_time)

    return conn
Exemplo n.º 7
0
    async def ehlo_or_helo_if_needed(self):
        """Call self.ehlo() and/or self.helo() if needed.

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

        This method may raise the following exceptions:

         SMTPHeloError            The server didn't reply properly to
                                  the helo greeting.
        """
        if self.helo_resp is None and self.ehlo_resp is None:
            if not (200 <= await self.ehlo()[0] <= 299):
                raise smtplib.SMTPHeloError(code, resp)
Exemplo n.º 8
0
 def test_fallimento_helo(self, mock_smtp):
     """
     In caso di fallimento durante helo il messaggio viene rimesso in coda, tranne che in caso
     di errore 5XX che è permanente
     """
     self.assertEqual(Messaggio.in_coda().count(), 0)
     codici = (500, 501, 504, 521, 421)
     for codice in codici:
         msg = 'code {}'.format(codice)
         instance = mock_smtp.return_value
         instance.sendmail.side_effect = smtplib.SMTPHeloError(code=codice,
                                                               msg=msg)
         self._invia_msg_singolo()
         if codice == 501:
             self.assertEqual(Messaggio.in_coda().count(), 0)
         else:
             self.assertEqual(Messaggio.in_coda().count(), 1)
         self._reset_coda()
Exemplo n.º 9
0
def test_email_plugin(mock_smtp, mock_smtpssl):
    """
    API: NotifyEmail Plugin()

    """
    # Disable Throttling to speed testing
    plugins.NotifyBase.NotifyBase.request_rate_per_sec = 0

    # iterate over our dictionary and test it out
    for (url, meta) in TEST_URLS:

        # Our expected instance
        instance = meta.get('instance', None)

        # Our expected server objects
        self = meta.get('self', None)

        # Our expected Query response (True, False, or exception type)
        response = meta.get('response', True)

        test_smtplib_exceptions = meta.get('test_smtplib_exceptions', False)

        # Our mock of our socket action
        mock_socket = mock.Mock()
        mock_socket.starttls.return_value = True
        mock_socket.login.return_value = True

        # Create a mock SMTP Object
        mock_smtp.return_value = mock_socket
        mock_smtpssl.return_value = mock_socket

        if test_smtplib_exceptions:
            # Handle exception testing; first we turn the boolean flag ito
            # a list of exceptions
            test_smtplib_exceptions = (
                smtplib.SMTPHeloError(0,
                                      'smtplib.SMTPHeloError() not handled'),
                smtplib.SMTPException(0,
                                      'smtplib.SMTPException() not handled'),
                RuntimeError(0, 'smtplib.HTTPError() not handled'),
                smtplib.SMTPRecipientsRefused(
                    'smtplib.SMTPRecipientsRefused() not handled'),
                smtplib.SMTPSenderRefused(
                    0, 'smtplib.SMTPSenderRefused() not handled',
                    '*****@*****.**'),
                smtplib.SMTPDataError(0,
                                      'smtplib.SMTPDataError() not handled'),
                smtplib.SMTPServerDisconnected(
                    'smtplib.SMTPServerDisconnected() not handled'),
            )

        try:
            obj = Apprise.instantiate(url, suppress_exceptions=False)

            if obj is None:
                # We're done (assuming this is what we were expecting)
                assert instance is None
                continue

            if instance is None:
                # Expected None but didn't get it
                print('%s instantiated %s (but expected None)' %
                      (url, str(obj)))
                assert (False)

            assert (isinstance(obj, instance))

            if isinstance(obj, plugins.NotifyBase.NotifyBase):
                # We loaded okay; now lets make sure we can reverse this url
                assert (isinstance(obj.url(), six.string_types) is True)

                # Instantiate the exact same object again using the URL from
                # the one that was already created properly
                obj_cmp = Apprise.instantiate(obj.url())

                # Our object should be the same instance as what we had
                # originally expected above.
                if not isinstance(obj_cmp, plugins.NotifyBase.NotifyBase):
                    # Assert messages are hard to trace back with the way
                    # these tests work. Just printing before throwing our
                    # assertion failure makes things easier to debug later on
                    print('TEST FAIL: {} regenerated as {}'.format(
                        url, obj.url()))
                    assert (False)

            if self:
                # Iterate over our expected entries inside of our object
                for key, val in self.items():
                    # Test that our object has the desired key
                    assert (hasattr(key, obj))
                    assert (getattr(key, obj) == val)

            try:
                if test_smtplib_exceptions is False:
                    # check that we're as expected
                    assert obj.notify(title='test',
                                      body='body',
                                      notify_type=NotifyType.INFO) == response

                else:
                    for exception in test_smtplib_exceptions:
                        mock_socket.sendmail.side_effect = exception
                        try:
                            assert obj.notify(
                                title='test',
                                body='body',
                                notify_type=NotifyType.INFO) is False

                        except AssertionError:
                            # Don't mess with these entries
                            raise

                        except Exception:
                            # We can't handle this exception type
                            raise

            except AssertionError:
                # Don't mess with these entries
                print('%s AssertionError' % url)
                raise

            except Exception as e:
                # Check that we were expecting this exception to happen
                if not isinstance(e, response):
                    raise

        except AssertionError:
            # Don't mess with these entries
            print('%s AssertionError' % url)
            raise

        except Exception as e:
            # Handle our exception
            if (instance is None):
                raise

            if not isinstance(e, instance):
                raise
Exemplo n.º 10
0
def test_email_plugin(mock_smtp, mock_smtpssl):
    """
    API: NotifyEmail Plugin()

    """

    # iterate over our dictionary and test it out
    for (url, meta) in TEST_URLS:

        # Our expected instance
        instance = meta.get('instance', None)

        # Our expected exception
        exception = meta.get('exception', None)

        # Our expected server objects
        self = meta.get('self', None)

        # Our expected Query response (True, False, or exception type)
        response = meta.get('response', True)

        test_smtplib_exceptions = meta.get('test_smtplib_exceptions', False)

        # Our mock of our socket action
        mock_socket = mock.Mock()
        mock_socket.starttls.return_value = True
        mock_socket.login.return_value = True

        # Create a mock SMTP Object
        mock_smtp.return_value = mock_socket
        mock_smtpssl.return_value = mock_socket

        if test_smtplib_exceptions:
            # Handle exception testing; first we turn the boolean flag ito
            # a list of exceptions
            test_smtplib_exceptions = (
                smtplib.SMTPHeloError(0,
                                      'smtplib.SMTPHeloError() not handled'),
                smtplib.SMTPException(0,
                                      'smtplib.SMTPException() not handled'),
                RuntimeError(0, 'smtplib.HTTPError() not handled'),
                smtplib.SMTPRecipientsRefused(
                    'smtplib.SMTPRecipientsRefused() not handled'),
                smtplib.SMTPSenderRefused(
                    0, 'smtplib.SMTPSenderRefused() not handled',
                    '*****@*****.**'),
                smtplib.SMTPDataError(0,
                                      'smtplib.SMTPDataError() not handled'),
                smtplib.SMTPServerDisconnected(
                    'smtplib.SMTPServerDisconnected() not handled'),
            )

        try:
            obj = Apprise.instantiate(url, suppress_exceptions=False)

            assert (exception is None)

            if obj is None:
                # We're done
                continue

            if instance is None:
                # Expected None but didn't get it
                print('%s instantiated %s' % (url, str(obj)))
                assert (False)

            assert (isinstance(obj, instance))

            if self:
                # Iterate over our expected entries inside of our object
                for key, val in self.items():
                    # Test that our object has the desired key
                    assert (hasattr(key, obj))
                    assert (getattr(key, obj) == val)

            try:
                if test_smtplib_exceptions is False:
                    # check that we're as expected
                    assert obj.notify(title='test',
                                      body='body',
                                      notify_type=NotifyType.INFO) == response

                else:
                    for exception in test_smtplib_exceptions:
                        mock_socket.sendmail.side_effect = exception
                        try:
                            assert obj.notify(
                                title='test',
                                body='body',
                                notify_type=NotifyType.INFO) is False

                        except AssertionError:
                            # Don't mess with these entries
                            raise

                        except Exception as e:
                            # We can't handle this exception type
                            print('%s / %s' % (url, str(e)))
                            assert False

            except AssertionError:
                # Don't mess with these entries
                raise

            except Exception as e:
                # Check that we were expecting this exception to happen
                assert isinstance(e, response)

        except AssertionError:
            # Don't mess with these entries
            print('%s AssertionError' % url)
            raise

        except Exception as e:
            # Handle our exception
            print('%s / %s' % (url, str(e)))
            assert (exception is not None)
            assert (isinstance(e, exception))
Exemplo n.º 11
0
message = """To: %s
From:%s
Subject: Test Message from simple.py
Hello, 
This is a test message sent to you from simple.py and smtplib.
""" % (", ".join(toaddr), fromaddr)

try:
    s = smtplib.SMTP(server)
    code = s.ehlo()[0]
    usesesmtp = 1
    if not (200 <= code <= 299):
        usesesmtp = 0
        code = s.helo()[0]
        if not (200 <= code <= 299):
            raise smtplib.SMTPHeloError(code, msg)
    if usesesmtp and s.has_extn('starttls'):
        print("Negotiating TLS...")
        s.starttls()
        code = s.ehlo()[0]
        if not (200 <= code <= 299):
            print("Couldn't Ehlo after STARTTLS")
            sys.exit(5)
            print("Using TLS Connection")
        else:
            print("Server does not suppose TLS; using normal connection.")
        s.sendmail(fromaddr, toaddr, message)
except (socket.gaierror, socket.error, socket.herror,
        smtplib.SMTPException) as e:
    print("*** Your message may not have been sent !")
    print(e)
Exemplo n.º 12
0
def send_dsn(mailfrom,receiver,msg=None,timeout=600,session=None,ourfrom=''):
  """Send DSN.  If msg is None, do callback verification.
     Mailfrom is original sender we are sending DSN or CBV to.
     Receiver is the MTA sending the DSN.
     Return None for success or (code,msg) for failure."""
  user,domain = mailfrom.rsplit('@',1)
  if not session: session = dns.Session()
  try:
    mxlist = session.dns(domain,'MX')
  except dns.DNSError:
    return (450,'DNS Timeout: %s MX'%domain)	# temp error
  if not mxlist:
    mxlist = (0,domain),	# fallback to A record when no MX
  else:
    mxlist.sort()
  smtp = smtplib.SMTP()
  toolate = time.time() + timeout
  for prior,host in mxlist:
    try:
      smtp.connect(host)
      code,resp = smtp.helo(receiver)
      # some wiley spammers have MX records that resolve to 127.0.0.1
      a = resp.split()
      if not a:
        return (553,'MX for %s has no hostname in banner: %s' % (domain,host))
      if a[0] == receiver:
        return (553,'Fraudulent MX for %s: %s' % (domain,host))
      if not (200 <= code <= 299):
        raise smtplib.SMTPHeloError(code, resp)
      if msg:
        try:
          smtp.sendmail('<%s>'%ourfrom,mailfrom,msg)
        except smtplib.SMTPSenderRefused:
	  # does not accept DSN, try postmaster (at the risk of mail loops)
          smtp.sendmail('<postmaster@%s>'%receiver,mailfrom,msg)
      else:	# CBV
        code,resp = smtp.docmd('MAIL FROM: <%s>'%ourfrom)
        if code != 250:
          raise smtplib.SMTPSenderRefused(code, resp, '<%s>'%ourfrom)
        if isinstance(mailfrom,basestring):
          mailfrom = [mailfrom]
        badrcpts = {}
        for rcpt in mailfrom:
          code,resp = smtp.rcpt(rcpt)
          if code not in (250,251):
            badrcpts[rcpt] = (code,resp)# permanent error
        smtp.quit()
        if len(badrcpts) == 1:
          return badrcpts.values()[0]	# permanent error
        if badrcpts:
          return badrcpts
      return None			# success
    except smtplib.SMTPRecipientsRefused as x:
      if len(x.recipients) == 1:
        return x.recipients.values()[0]	# permanent error
      return x.recipients
    except smtplib.SMTPSenderRefused as x:
      return x.args[:2]			# does not accept DSN
    except smtplib.SMTPDataError as x:
      return x.args			# permanent error
    except smtplib.SMTPException:
      pass		# any other error, try next MX
    except socket.error:
      pass		# MX didn't accept connections, try next one
    except socket.timeout:
      pass		# MX too slow, try next one
    if hasattr(smtp,'sock'): smtp.close()
    if time.time() > toolate:
      return (450,'No MX response within %f minutes'%(timeout/60.0))
  return (450,'No MX servers available')	# temp error