diff options
author | Ted Trask <ttrask01@yahoo.com> | 2008-08-21 15:18:15 +0000 |
---|---|---|
committer | Ted Trask <ttrask01@yahoo.com> | 2008-08-21 15:18:15 +0000 |
commit | 1d1f5083ddbb17148f8b1a68544890b34c2c8f96 (patch) | |
tree | 6e70c9d002dcf28ac5bd8882dc7cac0f3f9d31bd | |
parent | 8730ef0997957b46d392b981913d8934373e980a (diff) | |
download | acf-tcpproxy-1d1f5083ddbb17148f8b1a68544890b34c2c8f96.tar.bz2 acf-tcpproxy-1d1f5083ddbb17148f8b1a68544890b34c2c8f96.tar.xz |
Implemented tcpproxy SMTP entriesv0.0.1
git-svn-id: svn://svn.alpinelinux.org/acf/tcpproxy/trunk@1389 ab2d0c66-481e-0410-8bed-d214d4d58bed
-rw-r--r-- | tcpproxy-editsmtpentry-html.lsp | 2 | ||||
-rw-r--r-- | tcpproxy-model.lua | 204 |
2 files changed, 169 insertions, 37 deletions
diff --git a/tcpproxy-editsmtpentry-html.lsp b/tcpproxy-editsmtpentry-html.lsp index 61579d4..7c242ab 100644 --- a/tcpproxy-editsmtpentry-html.lsp +++ b/tcpproxy-editsmtpentry-html.lsp @@ -6,6 +6,6 @@ require("viewfunctions") <% form.action = page_info.script .. page_info.prefix .. page_info.controller .. "/" .. page_info.action form.value.ipaddr.contenteditable = false - local order = {"ipaddr"} + local order = {"ipaddr", "server", "addressonly", "domain", "optionalserver", "optionalrewritelist", "senderlistfile", "rcptlistfile"} displayform(form, order) %> diff --git a/tcpproxy-model.lua b/tcpproxy-model.lua index b1caf83..d812bb3 100644 --- a/tcpproxy-model.lua +++ b/tcpproxy-model.lua @@ -5,6 +5,7 @@ require("modelfunctions") require("validator") require("fs") require("posix") +require("getopts") -- Set variables local configfile = "/etc/tcpproxy.conf" @@ -35,26 +36,6 @@ local function parseconfigfile(file) return retval end --- ################################################################################ --- PUBLIC FUNCTIONS - -function startstop_service(action) - return modelfunctions.startstop_service(processname, action) -end - -function getstatus() - return modelfunctions.getstatus(processname, packagename, "TCP Proxy Status") -end - -function getconfigfile() - return modelfunctions.getfiledetails(configfile) -end - -function setconfigfile(filedetails) - filedetails.value.filename.value = configfile - return modelfunctions.setfiledetails(filedetails) -end - local function getsmtpconfig(config) -- parse the TCP proxy config file for smtp entries local retval = {} @@ -102,7 +83,7 @@ local function setsmtpcmd(ipaddr, cmd) -- We're leaving the interface and we haven't written line yet if cmd then if string.find(lines[#lines], "^%s*$") then lines[#lines] = nil end - lines[#lines + 1] = "exec "..cmd + lines[#lines + 1] = cmd lines[#lines + 1] = "" end done = true @@ -112,7 +93,7 @@ local function setsmtpcmd(ipaddr, cmd) -- we're leaving port 25 and we haven't written line yet if cmd then lines[#lines + 1] = "interface "..ipaddr - lines[#lines + 1] = "exec "..cmd + lines[#lines + 1] = cmd lines[#lines + 1] = "" end done = true @@ -125,10 +106,103 @@ local function setsmtpcmd(ipaddr, cmd) if not done and cmd then if not inport25 then lines[#lines + 1] = "port 25" end if not ininterface then lines[#lines + 1] = "interface "..ipaddr end - lines[#lines + 1] = "exec "..cmd + lines[#lines + 1] = cmd + end + + fs.write_file(configfile, string.gsub(table.concat(lines, "\n"), "\n+$", "")) +end + +local function parsesmtpcmd(exec) + -- parse the command line into a table + exec = exec or "" + local options = getopts.opts_to_table(exec) or {} + local server = string.match(exec, "rxmtp.*%s(%S+)%s*$") + if server and not string.match(server, "^%-") then + local test = string.match(exec, "rxmtp.*%s(%S+)%s+%S+%s*$") + if test then + local optionswithvalues = {["-l"]=1, ["-o"]=1, ["-r"]=1, ['-s']=1, ['-t']=1, ['-x']=1, ['-X']=1} + if not optionswithvalues[test] then + options[""] = server + end + else + options[""] = server + end end + return options +end + +local function validatesmtpentry(entry) + local success = true - fs.write_file(configfile, table.concat(lines, "\n")) + if string.find(entry.value.ipaddr.value, "[^%w.]") then + entry.value.ipaddr.errtxt = "Invalid interface / address" + success = false + end + if string.find(entry.value.server.value, "[^%w.-]") and not fs.is_file(entry.value.server.value) then + entry.value.server.errtxt = "Cannot find server binary" + success = false + end + if string.find(entry.value.domain.value, "[^%w.-]") then + entry.value.domain.errtxt = "Invalid domain" + success = false + end + if entry.value.optionalserver.value ~= "" then + if string.find(string.match(entry.value.optionalserver.value, "^[^:]+"), "[^%w.-]") then + entry.value.optionalserver.errtxt = "Invalid server" + success = false + elseif string.match(entry.value.optionalserver.value, ":(.*)") and not validator.is_port(string.match(entry.value.optionalserver.value, ":(.*)")) then + entry.value.optionalserver.errtxt = "Invalid port" + success = false + elseif entry.value.domain.value == "" then + entry.value.optionalserver.errtxt = "Cannot define server without Custom Domain" + success = false + end + elseif entry.value.domain.value ~= "" then + entry.value.optionalserver.errtxt = "Must define server if Custom Domain defined" + success = false + end + success = modelfunctions.validateselect(entry.value.optionalrewritelist) and success + if entry.value.domain.value == "" and entry.value.optionalrewritelist.value ~= "" then + entry.value.optionalrewritelist.errtxt = "Cannot define rewrite list without Custom Domain" + success = false + end + success = modelfunctions.validateselect(entry.value.senderlistfile) and success + success = modelfunctions.validateselect(entry.value.rcptlistfile) and success + + return success, entry +end + +local function getsmtpcmd(ipaddr) + config = config or parseconfigfile(fs.read_file(configfile)) + local smtpconfig = getsmtpconfig(config) + local exec = "" + for i,entry in ipairs(smtpconfig) do + if entry.ipaddr == ipaddr then + exec = entry.cmd + break + end + end + return exec +end + +-- ################################################################################ +-- PUBLIC FUNCTIONS + +function startstop_service(action) + return modelfunctions.startstop_service(processname, action) +end + +function getstatus() + return modelfunctions.getstatus(processname, packagename, "TCP Proxy Status") +end + +function getconfigfile() + return modelfunctions.getfiledetails(configfile) +end + +function setconfigfile(filedetails) + filedetails.value.filename.value = configfile + return modelfunctions.setfiledetails(filedetails) end function getsmtpstatus() @@ -176,24 +250,82 @@ function listsmtpentries(self) end function readsmtpentry(ipaddr) - config = config or parseconfigfile(fs.read_file(configfile)) - local smtpconfig = getsmtpconfig(config) - local exec = "" - for i,entry in ipairs(smtpconfig) do - if entry.ipaddr == ipaddr then - exec = entry.cmd - break + local exec = getsmtpcmd(ipaddr) + + local listfiles = listsmtpfiles() + table.insert(listfiles.value, 1, "") + + local ipaddrcfe = cfe({ value=ipaddr, label="Interface / IP Address" }) + local server = cfe({ label="SMTP Server", descr="Domain name / address of different machine or local binary" }) + local addressonly = cfe({ type="boolean", value=false, label="Address Only", descr="Removes everything in the from field except address" }) + local domain = cfe({ label="Custom Domain" }) + local optionalserver = cfe({ label="Custom Domain Server", descr="Use this SMTP server[:port] for e-mails to Custom Domain" }) + local optionalrewritelist = cfe({ type="select", label="Custom Domain Rewrite List", descr="File with a list for sender rewriting for Custom Domain", option=listfiles.value }) + local senderlistfile = cfe({ type="select", label="Sender List File", descr="File with a list for sender rewriting (and valid senders)", option=listfiles.value }) + local rcptlistfile = cfe({ type="select", label="Recipient List File", descr="File with a list for recipient rewriting (and valid recipients)", option=listfiles.value }) + + if exec and exec ~= "" then + local options = parsesmtpcmd(exec) + server.value = options[""] or server.value + addressonly.value = (options["-b"] ~= nil) + if options["-o"] then + domain.value = string.match(options["-o"], "^[^=]*") + optionalserver.value = string.match(options["-o"], "=([^=]*)") + optionalrewritelist.value = string.match(options["-o"], "=.*=(.*)") end + senderlistfile.value = options["-x"] or senderlistfile.value + rcptlistfile.value = options["-X"] or rcptlistfile.value end - local ipaddrcfe = cfe({ value=ipaddr, label="Interface / IP Address" }) - local execcfe = cfe({ value=exec, label="Command" }) - return cfe({ type="group", value={exec=execcfe, ipaddr=ipaddrcfe}, label="SMTP Proxy Entry" }) + return cfe({ type="group", value={ipaddr=ipaddrcfe, server=server, addressonly=addressonly, domain=domain, optionalserver=optionalserver, optionalrewritelist=optionalrewritelist, senderlistfile=senderlistfile, rcptlistfile=rcptlistfile}, label="SMTP Proxy Entry" }) end function updatesmtpentry(entry) - -- validate? - setsmtpcmd(entry.value.ipaddr.value, entry.value.exec.value) + local success, entry = validatesmtpentry(entry) + + if success then + local options = parsesmtpcmd(getsmtpcmd(entry.value.ipaddr.value)) + + options[""] = entry.value.server.value + if entry.value.addressonly.value then options["-b"] = "" else options["-b"] = nil end + if entry.value.domain.value == "" then + options["-o"] = nil + else + options["-o"] = entry.value.domain.value .. "=" .. entry.value.optionalserver.value + end + if entry.value.optionalrewritelist.value ~= "" then + options["-o"] = options["-o"] .. "=" .. entry.value.optionalrewritelist.value + end + if entry.value.senderlistfile.value ~= "" then + options["-x"] = entry.value.senderlistfile.value + else + options["-x"] = nil + end + if entry.value.rcptlistfile.value ~= "" then + options["-X"] = entry.value.rcptlistfile.value + else + options["-X"] = nil + end + + local exec = {"/usr/sbin/rxmtp"} + for option,value in pairs(options) do + if option ~= "" then + if value ~= "" then + exec[#exec + 1] = option .. " " .. value + else + exec[#exec + 1] = option + end + end + end + if options[""] ~= "" then + exec[#exec + 1] = options[""] + end + + setsmtpcmd(entry.value.ipaddr.value, table.concat(exec, " ")) + else + entry.errtxt = "Failed to set SMTP Proxy Entry" + end + return entry end |