fix(smtp): use implicit TLS (SMTPS) for port 465 registration emails

The cabinet email service called smtplib.SMTP() and conditionally ran
starttls() regardless of port, which is wrong for port 465. Port 465
is SMTPS (implicit TLS, RFC 8314): the TLS handshake must happen on
connect, before any EHLO. With the old code, switching to 465
produced a corrupted handshake — sometimes one garbled message went
through, then the server dropped the source.

Now SMTP_SSL is used when SMTP_USE_SSL is true OR when SMTP_PORT is
465 (auto-detect). The new SMTP_USE_SSL setting defaults to false
to keep existing 587/25 deployments unchanged.
This commit is contained in:
Fringg
2026-05-10 10:02:46 +03:00
parent b5a066628f
commit 29d3e8984b
3 changed files with 19 additions and 6 deletions
+4 -1
View File
@@ -72,8 +72,11 @@ SMTP_PASSWORD=
# Email отправителя (если не указан, используется SMTP_USER)
SMTP_FROM_EMAIL=
SMTP_FROM_NAME=VPN Service
# Использовать TLS шифрование
# Использовать STARTTLS (порт 587 / 25). Не путать с SMTP_USE_SSL.
SMTP_USE_TLS=true
# Использовать implicit TLS (SMTPS). Автоматически включается при SMTP_PORT=465.
# Для портов 25/587 оставить false.
SMTP_USE_SSL=false
# Уведомления администраторов
ADMIN_NOTIFICATIONS_ENABLED=true
+13 -5
View File
@@ -45,18 +45,26 @@ class EmailService:
def use_tls(self) -> bool:
return settings.SMTP_USE_TLS
@property
def use_ssl(self) -> bool:
# Port 465 always implies implicit TLS (SMTPS, RFC 8314).
return settings.SMTP_USE_SSL or self.port == 465
def is_configured(self) -> bool:
"""Check if SMTP is properly configured."""
return settings.is_smtp_configured()
def _get_smtp_connection(self) -> smtplib.SMTP:
"""Create and return SMTP connection."""
smtp = smtplib.SMTP(self.host, self.port, timeout=30)
smtp.ehlo()
if self.use_tls:
smtp.starttls()
if self.use_ssl:
smtp: smtplib.SMTP = smtplib.SMTP_SSL(self.host, self.port, timeout=30)
smtp.ehlo()
else:
smtp = smtplib.SMTP(self.host, self.port, timeout=30)
smtp.ehlo()
if self.use_tls:
smtp.starttls()
smtp.ehlo()
# Only attempt login if credentials are provided AND server supports AUTH
if self.user and self.password:
+2
View File
@@ -1014,6 +1014,8 @@ class Settings(BaseSettings):
SMTP_FROM_EMAIL: str | None = None
SMTP_FROM_NAME: str = 'VPN Service'
SMTP_USE_TLS: bool = True
# Implicit TLS (SMTPS) — required for port 465. Auto-enabled when SMTP_PORT == 465.
SMTP_USE_SSL: bool = False
# Ban System Integration (BedolagaBan monitoring)
BAN_SYSTEM_ENABLED: bool = False