#!/usr/bin/python3 '''sgfilter - sagator's filer daemon client (c) 2005-2018 Jan ONDREJ (SAL) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. ''' from __future__ import print_function import sys, socket, getopt, shutil from version import * SERVER = ('127.0.0.1', 27) mail_from = 'vscan@'+socket.gethostname() rcpt_to = 'vscan@'+socket.gethostname() JUST_EXIT_CODE = False SAFE = True try: opts, files = getopt.gnu_getopt(sys.argv[1:], 'h:p:cx', ['help', 'host=', 'port=', 'codes', 'non-safe']) except getopt.GetoptError as err: (msg, opt) = err.args print("Error:", msg) sys.exit(1) for key, value in opts: if key=='--help': print("SgFilter for SAGATOR %s-%s" % (VERSION, RELEASE)) print("") print("Usage: sgfilter [options...] [filename]") print("") print("Params: --help this help") print(" --host hostname sagator's filterd() hostname") print(" --port X sagator's filterd() port number") print(" --codes -c exit code=1 for spam, 0 for clean or error") print(" --non-safe -x disable safe fallback") print(" filename filename to scan (stdin is used, when") print(" no filename is defined)") sys.exit(0) elif key in ('--host', '-h'): SERVER = (value, SERVER[1]) elif key in ('--port', '-p'): SERVER = (SERVER[0], int(value)) elif key in ('--codes', '-c'): JUST_EXIT_CODE = True elif key in ('--non-safe', '-x'): SAFE = False if files: f = open(files[0], 'r') else: f = sys.stdin if __name__ == '__main__': try: s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect(SERVER) s.sendall('MAIL FROM: %s\r\n' % mail_from) s.sendall('RCPT TO: %s\r\n' % rcpt_to) # skip bad mailbox firstline firstline = f.readline() if firstline[:5]=='From ': data = f.read() else: data = firstline+f.read() firstline = '' s.sendall('DATA %d\r\n' % len(data)) s.sendall(data) f = s.makefile('rw', 0) status = f.readline() if status[:3]=='551': # drop sys.exit(0) # return silently elif status[:3]=='550': # reject if JUST_EXIT_CODE: print(status.rstrip()) sys.exit(1) elif status[0]!='2': # non clean, temp_fail or unknown if not SAFE: print(status.rstrip()) sys.exit(64) # clean or SAFE or without exit code forcing sys.stdout.write(firstline) shutil.copyfileobj(f, sys.stdout, 1024*1024) except socket.error as err: print("ERROR:", err) sys.exit(65)