feat: ignore client-supplied POP3 credentials (#15)
Build and publish container / build (push) Successful in 12m15s
Build and publish container / build (push) Successful in 12m15s
Accept any POP3 `USER`/`PASS` from the client and discard them. The proxy always authenticates to the IMAP backend with the configured `BACKEND_IMAP_USER` / `BACKEND_IMAP_PASS`. ## Changes - `handle_user` / `handle_pass`: accept client credentials unconditionally, no validation. - `authenticate`: always use backend credentials; remove the fallback that connected with client-supplied credentials when backend credentials were unset. Raise a clear configuration error when backend credentials are missing. - Tests: client credentials are ignored; missing backend credentials are reported. Closes #14 --------- Co-authored-by: Emma Thorpe <emma.thorpe@citrix.com> Reviewed-on: #15
This commit was merged in pull request #15.
This commit is contained in:
+17
-16
@@ -253,30 +253,31 @@ class POP3Session:
|
||||
return await self.send_line("-ERR Unsupported command")
|
||||
|
||||
async def handle_user(self, args):
|
||||
if len(args) != 1:
|
||||
return await self.send_line("-ERR USER requires username")
|
||||
self.username = args[0]
|
||||
# Accept any username. Client credentials are intentionally ignored;
|
||||
# some legacy clients insist on supplying them, so they are accepted
|
||||
# blindly. The backend is always reached with the proxy's own creds.
|
||||
self.username = args[0] if args else None
|
||||
return await self.send_line("+OK")
|
||||
|
||||
async def handle_pass(self, args):
|
||||
if len(args) != 1:
|
||||
return await self.send_line("-ERR PASS requires password")
|
||||
self.password = args[0]
|
||||
# Accept any password. See handle_user: client credentials are
|
||||
# accepted but never used or validated.
|
||||
self.password = args[0] if args else None
|
||||
await asyncio.to_thread(self.authenticate)
|
||||
return await self.send_line("+OK User authenticated")
|
||||
|
||||
def authenticate(self):
|
||||
"""Authenticate to the IMAP backend using configured credentials."""
|
||||
if Settings.BACKEND_IMAP_USER and Settings.BACKEND_IMAP_PASS:
|
||||
username = Settings.BACKEND_IMAP_USER
|
||||
password = Settings.BACKEND_IMAP_PASS
|
||||
elif self.username and self.password:
|
||||
username = self.username
|
||||
password = self.password
|
||||
else:
|
||||
raise RuntimeError("No IMAP credentials available")
|
||||
"""Authenticate to the IMAP backend using the configured proxy credentials.
|
||||
|
||||
backend = IMAPBackend(username, password)
|
||||
Client-supplied POP3 credentials are deliberately ignored: the proxy
|
||||
always connects to the backend with ``BACKEND_IMAP_USER`` /
|
||||
``BACKEND_IMAP_PASS``. This is by design for legacy clients that require
|
||||
credentials to be entered even though the proxy does not use them.
|
||||
"""
|
||||
if not (Settings.BACKEND_IMAP_USER and Settings.BACKEND_IMAP_PASS):
|
||||
raise RuntimeError("Backend IMAP credentials are not configured")
|
||||
|
||||
backend = IMAPBackend(Settings.BACKEND_IMAP_USER, Settings.BACKEND_IMAP_PASS)
|
||||
backend.login()
|
||||
self._imap = backend
|
||||
# Snapshot the maildrop once; it stays static for the session lifetime
|
||||
|
||||
Reference in New Issue
Block a user