summaryrefslogtreecommitdiffstats
path: root/tcpproxy-model.lua
diff options
context:
space:
mode:
authorTed Trask <ttrask01@yahoo.com>2008-08-20 19:02:16 +0000
committerTed Trask <ttrask01@yahoo.com>2008-08-20 19:02:16 +0000
commit8730ef0997957b46d392b981913d8934373e980a (patch)
treeb9cd2e28088756e1441e76790242a5890c14b945 /tcpproxy-model.lua
parent4f7c42c67f5e22295d178b924861f150c35132c0 (diff)
downloadacf-tcpproxy-8730ef0997957b46d392b981913d8934373e980a.tar.bz2
acf-tcpproxy-8730ef0997957b46d392b981913d8934373e980a.tar.xz
Modified tcpproxy to add in SMTP proxy support. Entries are directly edited, this still has to be improved.
git-svn-id: svn://svn.alpinelinux.org/acf/tcpproxy/trunk@1388 ab2d0c66-481e-0410-8bed-d214d4d58bed
Diffstat (limited to 'tcpproxy-model.lua')
-rw-r--r--tcpproxy-model.lua240
1 files changed, 240 insertions, 0 deletions
diff --git a/tcpproxy-model.lua b/tcpproxy-model.lua
index 57bb845..b1caf83 100644
--- a/tcpproxy-model.lua
+++ b/tcpproxy-model.lua
@@ -2,15 +2,39 @@ module(..., package.seeall)
-- Load libraries
require("modelfunctions")
+require("validator")
+require("fs")
+require("posix")
-- Set variables
local configfile = "/etc/tcpproxy.conf"
local processname = "tcpproxy"
local packagename = "tcpproxy"
+local smtppackagename = "rxmtp"
+local smtpdirectory = "/etc/rxmtp/"
+
+local keywords = { "standalone", "port", "interface", "rotate", "server", "uid", "gid", "user", "exec", "acp", "logname", "setenv", "timeout", "writefile" }
+local config
-- ################################################################################
-- LOCAL FUNCTIONS
+local function parseconfigfile(file)
+ file = file or ""
+ local retval = {}
+ for line in string.gmatch(file, "([^\n]+)\n?") do
+ line = string.gsub(line, "#.*$", "")
+ if line and line ~= "" then
+ table.insert(retval, {})
+ for word in string.gmatch(line, "%S+") do
+ table.insert(retval[#retval], word)
+ end
+ end
+ end
+
+ return retval
+end
+
-- ################################################################################
-- PUBLIC FUNCTIONS
@@ -30,3 +54,219 @@ 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 = {}
+ local port25 = false
+ local currentint
+ for i,entry in ipairs(config) do
+ if entry[1] == "port" then
+ if entry[2] == "25" then
+ port25 = true
+ currentint = nil
+ else
+ port25 = false
+ currentint = nil
+ end
+ elseif port25 then
+ if entry[1] == "interface" then
+ currentint = entry[2]
+ elseif entry[1] == "exec" and string.find(entry[2], "rxmtp$") then
+ if currentint then
+ table.insert(retval, {ipaddr=currentint, cmd=table.concat(entry, " ", 2)})
+ else
+ -- bad config - exec command without interface
+ end
+ end
+ end
+ end
+
+ return retval
+end
+
+local function setsmtpcmd(ipaddr, cmd)
+ if cmd then cmd = "exec "..cmd end
+ local file = fs.read_file(configfile)
+ local inport25 = false
+ local ininterface = false
+ local done = false
+ local lines = {}
+ for line in string.gmatch(file, "([^\n]*)\n?") do
+ if not done then
+ if ininterface and string.find(line, "^%s*exec%s") then
+ -- We found the line, replace it
+ line = cmd
+ done = true
+ elseif ininterface and string.find(line, "^%s*interface%s") then
+ -- 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] = ""
+ end
+ done = true
+ elseif inport25 and string.find(line, "^%s*interface%s+"..ipaddr) then
+ ininterface = true
+ elseif inport25 and string.find(line, "^%s*port%s") then
+ -- 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] = ""
+ end
+ done = true
+ elseif string.find(line, "^%s*port%s+25") then
+ inport25 = true
+ end
+ end
+ lines[#lines + 1] = line
+ end
+ 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
+ end
+
+ fs.write_file(configfile, table.concat(lines, "\n"))
+end
+
+function getsmtpstatus()
+ local value, errtxt = processinfo.package_version(smtppackagename)
+ local version = cfe({ value=value, label="Program version" })
+ return cfe({ type="group", value={version=version, entries=entries}, label="SMTP Proxy Status" })
+end
+
+function listsmtpentries(self)
+ local entries = cfe({ type="structure", value={}, label="SMTP Command Entries" })
+ if self then
+ local interfacescontroller = self:new("alpine-baselayout/interfaces")
+ local interfaces = interfacescontroller.model:get_addresses()
+ interfacescontroller:destroy()
+ -- add in entries for interfaces (w/o ipaddr)
+ local interface
+ for i,entry in ipairs(interfaces.value) do
+ if interface ~= entry.interface then
+ interface = entry.interface
+ table.insert(entries.value, {interface=interface})
+ end
+ table.insert(entries.value, entry)
+ end
+ end
+
+ local reverseaddress = {}
+ for i,int in ipairs(entries.value) do reverseaddress[int.ipaddr or int.interface] = i end
+
+ config = config or parseconfigfile(fs.read_file(configfile))
+ local smtpconfig = getsmtpconfig(config)
+ for i,int in ipairs(smtpconfig) do
+ local pos = reverseaddress[int.ipaddr]
+ if pos then
+ entries.value[pos].cmd = int.cmd
+ else
+ if not validator.is_ipv4(int.ipaddr) then
+ int.interface = int.ipaddr
+ int.ipaddr = nil
+ end
+ table.insert(entries.value, int)
+ end
+ end
+
+ return entries
+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
+ end
+ 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" })
+end
+
+function updatesmtpentry(entry)
+ -- validate?
+ setsmtpcmd(entry.value.ipaddr.value, entry.value.exec.value)
+ return entry
+end
+
+function delsmtpentry(ipaddr)
+ setsmtpcmd(ipaddr, nil)
+ return cfe({ value="Deleted SMTP Proxy Entry", label="Delete SMTP Entry result" })
+end
+
+function listsmtpfiles()
+ local retval = cfe({ type="list", value={}, label="SMTP Proxy Files" })
+ if not fs.is_dir(smtpdirectory) then posix.mkdir(smtpdirectory) end
+ for file in posix.files(smtpdirectory) do
+ if fs.is_file(smtpdirectory .. file) then
+ table.insert(retval.value, smtpdirectory .. file)
+ end
+ end
+ return retval
+end
+
+function getnewsmtpfile()
+ local filename = cfe({ label="File Name", descr="Must be in "..smtpdirectory })
+ return cfe({ type="group", value={filename=filename}, label="SMTP Proxy File" })
+end
+
+function createsmtpfile(filedetails)
+ local success = true
+
+ if not validator.is_valid_filename(filedetails.value.filename.value, smtpdirectory) then
+ success = false
+ filedetails.value.filename.errtxt = "Invalid filename"
+ else
+ if not fs.is_dir(smtpdirectory) then posix.mkdir(smtpdirectory) end
+ if posix.stat(filedetails.value.filename.value) then
+ success = false
+ filedetails.value.filename.errtxt = "Filename already exists"
+ end
+ end
+
+ if success then
+ fs.create_file(filedetails.value.filename.value)
+ else
+ filedetails.errtxt = "Failed to Create File"
+ end
+
+ return filedetails
+end
+
+function readsmtpfile(filename)
+ if validator.is_valid_filename(filename, smtpdirectory) and fs.is_file(filename) then
+ return modelfunctions.getfiledetails(filename)
+ end
+ local retval = modelfunctions.getfiledetails("")
+ retval.value.filename.value = filename
+ return retval
+end
+
+function updatesmtpfile(filedetails)
+ if validator.is_valid_filename(filedetails.value.filename.value, smtpdirectory) and fs.is_file(filedetails.value.filename.value) then
+ return modelfunctions.setfiledetails(filedetails)
+ end
+ filedetails.value.filename.errtxt = "Invalid Filename"
+ filedetails.errtxt = "Failed to set file"
+ return filedetails
+end
+
+function delsmtpfile(filename)
+ local retval = cfe({ value="Deleted SMTP Proxy File", label="Delete SMTP File result" })
+ if validator.is_valid_filename(filename, smtpdirectory) and fs.is_file(filename) then
+ os.remove(filename)
+ else
+ retval.value = "Failed to delete SMTP Proxy File - invalid filename"
+ end
+
+ return retval
+end
+