diff options
author | Ted Trask <ttrask01@yahoo.com> | 2008-08-20 19:02:16 +0000 |
---|---|---|
committer | Ted Trask <ttrask01@yahoo.com> | 2008-08-20 19:02:16 +0000 |
commit | 8730ef0997957b46d392b981913d8934373e980a (patch) | |
tree | b9cd2e28088756e1441e76790242a5890c14b945 /tcpproxy-model.lua | |
parent | 4f7c42c67f5e22295d178b924861f150c35132c0 (diff) | |
download | acf-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.lua | 240 |
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 + |