PNG IHDR x sBIT|d pHYs + tEXtSoftware www.inkscape.org< ,tEXtComment
# -*- coding: UTF-8 -*-
# Copyright 2012-2018 Fumail Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
#
#
from postomaat.shared import ScannerPlugin, DUNNO, REJECT, apply_template
try:
import SRS
HAVE_SRS=True
except ImportError:
SRS=None
HAVE_SRS=False
class SRSBounceVerify(ScannerPlugin):
"""
This plugin checks the validity of SRS bounces.
Intended to be used in conjunction with after queue SRS mechanisms such as Fuglu's SRS Plugin.
"""
def __init__(self,config,section=None):
ScannerPlugin.__init__(self,config,section)
self.logger=self._logger()
self.requiredvars = {
'forward_domain': {
'default': 'example.com',
'description': 'the SRS envelope sender domain',
},
'secret': {
'default': '',
'description': 'cryptographic secret. set the same random value on all your machines',
},
'maxage': {
'default': '8',
'description': 'maximum lifetime of bounces',
},
'hashlength': {
'default': '8',
'description': 'size of auth code',
},
'separator': {
'default': '=',
'description': 'SRS token separator',
},
'messagetemplate':{
'default':'${from_address} is not a valid SRS bounce address'
},
'accept_unsigned': {
'default': 'True',
'description': 'Accept unsigend (non SRS) recpients. Set to False to reject',
}
}
def _init_srs(self):
secret = self.config.get(self.section, 'secret')
maxage = self.config.getint(self.section, 'maxage')
hashlength = self.config.getint(self.section, 'hashlength')
separator = self.config.get(self.section, 'separator')
srs = SRS.new(secret=secret, maxage=maxage, hashlength=hashlength, separator=separator, alwaysrewrite=True)
return srs
def examine(self, suspect):
if not HAVE_SRS:
return DUNNO
forward_domain = self.config.get(self.section, 'forward_domain')
if suspect.to_domain != forward_domain:
self.logger.debug('SRS: ignoring mail to %s - only accepting %s' % (suspect.to_address, forward_domain))
return DUNNO
action = DUNNO
message = None
srs = self._init_srs()
if suspect.to_address.lower().startswith('srs'):
orig_rcpt = suspect.to_address
try:
recipient = srs.reverse(orig_rcpt)
self.logger.info('SRS: decrypted bounce address %s to %s' % (orig_rcpt, recipient))
except Exception as e:
self.logger.error('SRS: Failed to decrypt %s reason: %s' % (orig_rcpt, str(e)))
action = REJECT
message = apply_template(self.config.get(self.section, 'messagetemplate'), suspect)
else:
self.logger.debug('SRS: ignoring unsigned address %s' % (suspect.to_address))
if not self.config.getboolean(self.section, 'accept_unsigned'):
action = REJECT
message = apply_template(self.config.get(self.section, 'messagetemplate'), suspect)
return action, message
def lint(self):
allok = self.checkConfig()
if not HAVE_SRS:
allok = False
print('SRS library not found')
if self.config.get(self.section, 'secret') == '':
allok = False
print('no secret set in config')
if allok:
srs = self._init_srs()
forward_domain = self.config.get(self.section, 'forward_domain')
srs.forward('foobar@example.com', forward_domain)
return allok
def __str__(self):
return "SRSBounceVerify"
b IDATxytVսϓ22 A@IR:hCiZ[v*E:WũZA ^dQeQ @ !jZ'>gsV仿$|?g)&x-E