diff --git a/extensions/amavis_quarantine/lib.py b/extensions/amavis_quarantine/lib.py new file mode 100644 index 000000000..f40425f99 --- /dev/null +++ b/extensions/amavis_quarantine/lib.py @@ -0,0 +1,48 @@ +import socket +import re +import struct +import string +from django.conf import settings + +def getParam(param, default=None): + try: + res = getattr(settings, param) + except AttributeError: + res = default + return res + +class AMrelease(object): + def __init__(self): + mode = getParam('AM_PDP_MODE', "unix") + if mode == "inet": + host = getParam('AM_PDP_HOST', 'localhost') + port = getParam('AM_PDP_PORT', '9998') + self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + self.sock.connect((host, int(port))) + else: + path = getParam('AM_PDP_SOCKET', '/var/amavis/amavisd.sock') + self.sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) + self.sock.connect(path) + + def decode(self, answer): + def repl(match): + return struct.pack("B", string.atoi(match.group(0)[1:], 16)) + + return re.sub(r"%([0-9a-fA-F]{2})", repl, answer) + + def __del__(self): + self.sock.close() + + def sendreq(self, mailid, secretid, recipient, *others): + self.sock.send("""request=release +mail_id=%s +secret_id=%s +quar_type=Q +recipient=%s + +""" % (mailid, secretid, recipient)) + answer = self.sock.recv(1024) + answer = self.decode(answer) + if re.search("250 [\d\.]+ Ok", answer): + return True + return False diff --git a/extensions/amavis_quarantine/main.py b/extensions/amavis_quarantine/main.py index a40e875e8..cc8a50211 100644 --- a/extensions/amavis_quarantine/main.py +++ b/extensions/amavis_quarantine/main.py @@ -17,6 +17,7 @@ from mailng.lib import events from mailng.lib import _render, _ctx_ok, _ctx_ko, decode from mailng.lib import db from mailng.admin.models import Mailbox +from lib import AMrelease from datetime import datetime import email import re @@ -219,8 +220,6 @@ def _redirect_to_index(request, message, count): @login_required def delete(request, mail_id, count=1): conn = db.getconnection("amavis_quarantine") - if count == 1: - mail_id = "'%s'" % mail_id status, error = db.execute(conn, "DELETE FROM msgs WHERE mail_id IN (%s)" % mail_id) if status: @@ -233,13 +232,12 @@ def delete(request, mail_id, count=1): @login_required def release(request, mail_id, count=1): conn = db.getconnection("amavis_quarantine") - if count == 1: - mail_id = "'%s'" % mail_id status, cursor = db.execute(conn, """ SELECT msgs.mail_id,secret_id,quar_type,maddr.email FROM msgs, maddr, msgrcpt WHERE msgrcpt.mail_id=msgs.mail_id AND msgrcpt.rid=maddr.id AND msgs.mail_id IN (%s) """ % (mail_id)) emails = {} + amr = AMrelease() for row in cursor.fetchall(): if not emails.has_key(row[0]): emails[row[0]] = {} @@ -249,14 +247,15 @@ WHERE msgrcpt.mail_id=msgs.mail_id AND msgrcpt.rid=maddr.id AND msgs.mail_id IN count = 0 error = None for k, values in emails.iteritems(): - cmd = "/tmp/amavisd-release " - cmd += "%s %s" % (k, values["secret"]) - for rcpt in values["rcpts"]: - cmd += " %s" % rcpt - cmd += "\n" - result = os.system(cmd) + result = amr.sendreq(k, values["secret"], *values["rcpts"]) +# cmd = "/tmp/amavisd-release " +# cmd += "%s %s" % (k, values["secret"]) +# for rcpt in values["rcpts"]: +# cmd += " %s" % rcpt +# cmd += "\n" +# result = os.system(cmd) # if re.search("250 [^\s]+ Ok", result): - if not result: + if result: count += 1 else: error = result @@ -278,10 +277,10 @@ def process(request): ids += "'%s'" % id if ids == "": return HttpResponseRedirect(reverse(index)) - if request.POST.has_key("release"): + if request.POST["action"] == "release": release(request, ids, count) - if request.POST.has_key("delete"): + if request.POST["action"] == "delete": delete(request, ids, count) try: diff --git a/extensions/amavis_quarantine/release.py b/extensions/amavis_quarantine/release.py deleted file mode 100755 index bbae5e83f..000000000 --- a/extensions/amavis_quarantine/release.py +++ /dev/null @@ -1,63 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -import socket -import sys -import re -import struct -from optparse import OptionParser - -def getsocket(options): - if options.mode == "net": - s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - s.connect((options.host, options.port)) - - return s - -def from_stdin(): - res = [] - for line in sys.stdin: - res += [line] - return res - -def decodevalue(val): - def pack(match): - return struct.pack('B', match.group(0)) - res = re.sub("%([0-9a-fA-F]{2})", pack, val) - -if __name__ == "__main__": - parser = OptionParser() - parser.add_option("-o", "--host", default="127.0.0.1", - help="") - parser.add_option("-p", "--port", default=9998, - help="") - parser.add_option("-s", "--socket", default="", - help="") - parser.add_option("-m", "--mode", default="unix", - help="") - (options, args) = parser.parse_args() - - if not len(args): - print "Nothing to do, exiting." - sys.exit(1) - - s = getsocket(options) -# if args[0] == '-': -# worklist = from_stdin() -# else: -# worklist = [args[0]] - -# for message in worklist: -# params = message.split() - params = ["k1URJIk76bKa", "k1URJIk76bKa", "antoine.nguyen@streamcore.com"] - cmd = """request=release -mail_id=%s -secret_id=%s -quar_type=Q -recipient=%s - -""" % (params[0], params[1], params[2]) - s.send(cmd) - answer = s.recv(1024) - print answer - - s.close() diff --git a/extensions/amavis_quarantine/templates/index.html b/extensions/amavis_quarantine/templates/index.html index 635b40edb..0424e96fc 100644 --- a/extensions/amavis_quarantine/templates/index.html +++ b/extensions/amavis_quarantine/templates/index.html @@ -64,8 +64,8 @@ window.addEvent("domready", function() { mysubmit = function(event, name) { event.stop(); new Element('input', { - 'type' : 'submit', 'name' : name, style: "display:none" - }).inject($("quarlistingform")); + 'type' : 'hidden', 'name' : "action", style: "display:none", 'value' : name + }).inject($("quarlistingform"), "top"); $("quarlistingform").set("send", { onSuccess : function(res) { response = JSON.decode(res); diff --git a/settings_sample.py b/settings_sample.py index ee83363d3..c4d18fe93 100644 --- a/settings_sample.py +++ b/settings_sample.py @@ -108,3 +108,13 @@ VIRTUAL_GID = "vmail" # Quarantine messages maximum age (in days) before deletion # MAX_MESSAGES_AGE = 14 + +# AM.PDP daemon +# Modify above parameters if you want MailNG to be able +# to release messages from the quarantine. Mode can be +# either "inet" or "unix". + +# AM_PDP_MODE = "inet" +# AM_PDP_HOST = "localhost" +# AM_PDP_PORT = 9998 +# AM_PDP_SOCKET = "/var/amavis/amavisd.sock" diff --git a/static/stylesheets/basic.css b/static/stylesheets/basic.css index 8e6104166..923f5ba43 100644 --- a/static/stylesheets/basic.css +++ b/static/stylesheets/basic.css @@ -309,12 +309,15 @@ body { } .header { - margin-left: 20px; - margin-bottom: 20px; + margin: 10px 0px 20px 20px; + padding-bottom: 10px; } .header h1 { font-size: medium; + width: 50%; + float: left; + margin: 0; } #setcontent h4 { @@ -323,9 +326,11 @@ body { #infos { float: right; + width: 40%; color: green; font-weight: bold; margin-right: 10px; + margin-bottom: 5px; } .info { diff --git a/templates/layout.html b/templates/layout.html index 1cc2f4262..efa6c57b2 100644 --- a/templates/layout.html +++ b/templates/layout.html @@ -95,12 +95,13 @@ {% endif %}

{% block middletitle %}{% endblock %}

- {% if messages %}
+ {% if messages %} {% for m in messages %}{{ m }}{% endfor %} -
{% endif %} +
+