Changeset View
Changeset View
Standalone View
Standalone View
extras/kolab_policy_spf
#!/usr/bin/python | #!/usr/bin/python | ||||
""" | """ | ||||
This is the implementation of a (postfix) MTA policy service to enforce the | This is the implementation of a (postfix) MTA policy service to enforce the | ||||
Sender Policy Framework. | Sender Policy Framework. | ||||
""" | """ | ||||
import json | import json | ||||
import time | import time | ||||
import sys | import sys | ||||
import logging | |||||
from logging.handlers import SysLogHandler | |||||
import requests | import requests | ||||
logger = logging.getLogger(__name__) | |||||
logger.setLevel(logging.INFO) | |||||
logger.addHandler(SysLogHandler()) | |||||
def read_request_input(): | def read_request_input(): | ||||
""" | """ | ||||
Read a single policy request from sys.stdin, and return a dictionary | Read a single policy request from sys.stdin, and return a dictionary | ||||
containing the request. | containing the request. | ||||
""" | """ | ||||
start_time = time.time() | start_time = time.time() | ||||
policy_request = {} | policy_request = {} | ||||
end_of_request = False | end_of_request = False | ||||
while not end_of_request: | while not end_of_request: | ||||
if (time.time() - start_time) >= 10: | if (time.time() - start_time) >= 10: | ||||
logger.warning("policy/spf took too long reading the request.") | |||||
print("action=DEFER_IF_PERMIT Temporary error, try again later.\n") | print("action=DEFER_IF_PERMIT Temporary error, try again later.\n") | ||||
sys.stdout.flush() | sys.stdout.flush() | ||||
sys.exit(0) | sys.exit(0) | ||||
request_line = sys.stdin.readline() | request_line = sys.stdin.readline() | ||||
if request_line.strip() == '': | if request_line.strip() == '': | ||||
if 'request' in policy_request: | if 'request' in policy_request: | ||||
Show All 18 Lines | while True: | ||||
try: | try: | ||||
RESPONSE = requests.post( | RESPONSE = requests.post( | ||||
URL, | URL, | ||||
data=REQUEST, | data=REQUEST, | ||||
verify=True | verify=True | ||||
) | ) | ||||
# pylint: disable=broad-except | # pylint: disable=broad-except | ||||
except Exception: | except Exception: | ||||
logger.warning("policy/spf request failed.") | |||||
print("action=DEFER_IF_PERMIT Temporary error, try again later.\n") | print("action=DEFER_IF_PERMIT Temporary error, try again later.\n") | ||||
sys.stdout.flush() | sys.stdout.flush() | ||||
sys.exit(0) | sys.exit(0) | ||||
try: | try: | ||||
R = json.loads(RESPONSE.text) | R = json.loads(RESPONSE.text) | ||||
# pylint: disable=broad-except | # pylint: disable=broad-except | ||||
except Exception: | except Exception: | ||||
logger.warning("Failed to load json from policy/spf request.") | |||||
print("action=DEFER_IF_PERMIT Temporary error, try again later.\n") | print("action=DEFER_IF_PERMIT Temporary error, try again later.\n") | ||||
sys.stdout.flush() | sys.stdout.flush() | ||||
sys.exit(0) | sys.exit(0) | ||||
if 'prepend' in R: | if 'prepend' in R: | ||||
for prepend in R['prepend']: | for prepend in R['prepend']: | ||||
print("action=PREPEND {0}".format(prepend)) | print("action=PREPEND {0}".format(prepend)) | ||||
if 'log' in R: | |||||
for line in R['log']: | |||||
logger.warning(line) | |||||
if RESPONSE.ok: | if RESPONSE.ok: | ||||
print("action={0}\n".format(R['response'])) | print("action={0}\n".format(R['response'])) | ||||
else: | else: | ||||
print("action={0} {1}\n".format(R['response'], R['reason'])) | print("action={0} {1}\n".format(R['response'], R['reason'])) | ||||
logger.warning("spf failed with reason: %s" % R['reason']) | |||||
sys.stdout.flush() | sys.stdout.flush() | ||||
sys.exit(0) | sys.exit(0) |