Skip to content

Commit

Permalink
Allow mail to be sent without starttls() and login creds if desired
Browse files Browse the repository at this point in the history
  • Loading branch information
MaverikMoody committed Jan 22, 2025
1 parent 0a11a9a commit f182dc9
Show file tree
Hide file tree
Showing 4 changed files with 17 additions and 4 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,8 @@ When configuring outgoing SMTP please consider the following:

Restrictions:
* no other provider like Mailgun or Sendgrid must be configured for this to work
* only supports StartTLS right now (you have to use the corresponding port)
* no anonymous SMTP is supported right now (you have to use a username/password to authenticate)
* will not send unecrypted mail unless `CANARY_SMTP_ALLOW_NOTLS` is set to `true`
* will not send unauthenticated mail unless `CANARY_SMTP_ALLOW_NOLOGIN` is set to `true`
* For AWS SES `CANARY_ALERT_EMAIL_FROM_DISPLAY` should be in the format: `CANARY_ALERT_EMAIL_FROM_DISPLAY=CanaryAlert <[email protected]>`

The following settings have to be configured in `switchboard.env` for SMTP to work:
Expand Down
13 changes: 11 additions & 2 deletions canarytokens/channel_output_email.py
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,8 @@ def smtp_send(
smtp_username: str,
smtp_server: str,
smtp_port: str,
smtp_notls: bool,
smtp_nologin: bool,
) -> tuple[EmailResponseStatuses, str]:
email_response = EmailResponseStatuses.ERROR
message_id = uuid.uuid4().hex
Expand All @@ -263,8 +265,13 @@ def smtp_send(
smtpmsg.attach(part2)

with smtplib.SMTP(smtp_server, smtp_port) as server:
server.starttls()
server.login(smtp_username, smtp_password)
try:
server.starttls()
except smtplib.SMTPExxception as e:
if smtp_notls is False:
raise e
if smtp_nologin is False or (smtp_username != "" and smtp_password != ""):
server.login(smtp_username, smtp_password)
server.sendmail(fromaddr, toaddr, smtpmsg.as_string())
except smtplib.SMTPException as e:
log.error("A smtp error occurred: %s - %s" % (e.__class__, e))
Expand Down Expand Up @@ -557,6 +564,8 @@ def do_send_alert(
smtp_username=self.switchboard_settings.SMTP_USERNAME,
smtp_server=self.switchboard_settings.SMTP_SERVER,
smtp_port=self.switchboard_settings.SMTP_PORT,
smtp_notls=self.switchboard_settings.SMTP_ALLOW_NOTLS,
smtp_nologin=self.switchboard_settings.SMTP_ALLOW_NOLOGIN,
)
else:
log.error("No email settings found")
Expand Down
2 changes: 2 additions & 0 deletions canarytokens/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ class SwitchboardSettings(BaseSettings):
SMTP_PASSWORD: Optional[str]
SMTP_SERVER: Optional[str]
SMTP_PORT: Optional[Port] = Port(587)
SMTP_ALLOW_NOTLS: Optional[bool]
SMTP_ALLOW_NOLOGIN: Optional[bool]

SENTRY_DSN: Optional[HttpUrl] = None
SENTRY_ENVIRONMENT: Literal["prod", "staging", "dev", "ci", "local"] = "local"
Expand Down
2 changes: 2 additions & 0 deletions tests/units/test_channel_output_email.py
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,8 @@ def test_smtp_send(
smtp_port=1025,
smtp_server="localhost",
smtp_username="testuser",
smtp_nologin=False,
smtp_notls=False,
)
assert mock_SMTP.return_value.__enter__.return_value.sendmail.call_count == 1
assert len(message_id) == len(uuid.uuid4().hex)
Expand Down

0 comments on commit f182dc9

Please sign in to comment.