2265: Prevent an exception from being thrown if the username isn't an email address r=mergify[bot] a=nextgens

## What type of PR?

enhancement

## What does this PR do?

Mailu expects users to identify using an email address; some brute-force script don't send just an username and this leads to an exception... that makes the error message and return code vary.

This PR prevents the exceptions from being thrown in the first place

```
WARNING in nginx: Invalid user 'xxxx': (builtins.ValueError) invalid email address (no "`@")"`
```

### Related issue(s)
- closes #2261
- closes #1750

Co-authored-by: Florent Daigniere <nextgens@freenetproject.org>
Co-authored-by: Florent Daigniere <nextgens@users.noreply.github.com>
master
bors[bot] 3 years ago committed by GitHub
commit fe7397bedf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -93,8 +93,8 @@ def handle_authentication(headers):
app.logger.warn(f'Received undecodable user/password from nginx: {raw_user_email!r}/{raw_password!r}') app.logger.warn(f'Received undecodable user/password from nginx: {raw_user_email!r}/{raw_password!r}')
else: else:
try: try:
user = models.User.query.get(user_email) user = models.User.query.get(user_email) if '@' in user_email else None
is_valid_user = True is_valid_user = user is not None
except sqlalchemy.exc.StatementError as exc: except sqlalchemy.exc.StatementError as exc:
exc = str(exc).split('\n', 1)[0] exc = str(exc).split('\n', 1)[0]
app.logger.warn(f'Invalid user {user_email!r}: {exc}') app.logger.warn(f'Invalid user {user_email!r}: {exc}')

@ -12,7 +12,7 @@ def nginx_authentication():
""" """
client_ip = flask.request.headers["Client-Ip"] client_ip = flask.request.headers["Client-Ip"]
headers = flask.request.headers headers = flask.request.headers
if headers["Auth-Port"] == '25' and headers['Auth-Method'] == 'plain': if headers["Auth-Port"] == '25':
response = flask.Response() response = flask.Response()
response.headers['Auth-Status'] = 'AUTH not supported' response.headers['Auth-Status'] = 'AUTH not supported'
response.headers['Auth-Error-Code'] = '502 5.5.1' response.headers['Auth-Error-Code'] = '502 5.5.1'

@ -5,6 +5,7 @@ from flask import current_app as app
import flask import flask
import idna import idna
import re import re
import sqlalchemy.exc
import srslib import srslib
@internal.route("/postfix/dane/<domain_name>") @internal.route("/postfix/dane/<domain_name>")
@ -158,18 +159,13 @@ def postfix_sender_rate(sender):
def postfix_sender_access(sender): def postfix_sender_access(sender):
""" Simply reject any sender that pretends to be from a local domain """ Simply reject any sender that pretends to be from a local domain
""" """
if not is_void_address(sender): if '@' in sender:
localpart, domain_name = models.Email.resolve_domain(sender) if sender.startswith('<') and sender.endswith('>'):
return flask.jsonify("REJECT") if models.Domain.query.get(domain_name) else flask.abort(404) sender = sender[1:-1]
else: try:
return flask.abort(404) localpart, domain_name = models.Email.resolve_domain(sender)
if models.Domain.query.get(domain_name):
return flask.jsonify("REJECT")
def is_void_address(email): except sqlalchemy.exc.StatementError:
'''True if the email is void (null) email address. pass
''' return flask.abort(404)
if email.startswith('<') and email.endswith('>'):
email = email[1:-1]
# Some MTAs use things like '<MAILER-DAEMON>' instead of '<>'; so let's
# consider void any such thing.
return '@' not in email

Loading…
Cancel
Save