124 lines
3 KiB
Lua
124 lines
3 KiB
Lua
|
|
||
|
function mysplit (inputstr, sep)
|
||
|
if sep == nil then
|
||
|
sep = "%s"
|
||
|
end
|
||
|
local t={}
|
||
|
for str in string.gmatch(inputstr, "([^"..sep.."]+)") do
|
||
|
table.insert(t, str)
|
||
|
end
|
||
|
return t
|
||
|
end
|
||
|
|
||
|
|
||
|
function table.slice(tbl, first, last, step)
|
||
|
local sliced = {}
|
||
|
|
||
|
for i = first or 1, last or #tbl, step or 1 do
|
||
|
sliced[#sliced+1] = tbl[i]
|
||
|
end
|
||
|
|
||
|
return sliced
|
||
|
end
|
||
|
|
||
|
|
||
|
function validate(data,from,to)
|
||
|
headers = {}
|
||
|
begindata = false
|
||
|
i = 1
|
||
|
while true do
|
||
|
line = mysplit(data,"\n")[i]
|
||
|
if line == nil then break end
|
||
|
if begindata == false then
|
||
|
line = mysplit(line, ":")
|
||
|
if line[1] == nil then
|
||
|
begindata = true
|
||
|
else
|
||
|
headers[line[1]] = line[2]
|
||
|
end
|
||
|
|
||
|
else
|
||
|
headers["body"] = (headers["body"] or "") .. line .. "\n"
|
||
|
end
|
||
|
i = i + 1
|
||
|
end
|
||
|
if not headers["From"] or not headers["From"]:find(from) then return false end
|
||
|
if not to:find("@doesnm.cc") then return false end
|
||
|
return headers
|
||
|
end
|
||
|
|
||
|
function string.starts(String,Start)
|
||
|
return string.sub(String,1,string.len(Start))==Start
|
||
|
end
|
||
|
|
||
|
from = nil
|
||
|
to = nil
|
||
|
data = false
|
||
|
dataBuf = ""
|
||
|
print("220 doesnm.cc Simple Mail Transfer Service Ready")
|
||
|
|
||
|
while true do
|
||
|
line = io.read("*line")
|
||
|
line = mysplit(line)
|
||
|
if line[1] == "NOOP" and data == false then
|
||
|
print("250 OK")
|
||
|
elseif line[1] == "HELO" then
|
||
|
if #line < 2 then
|
||
|
print("251 Command requires argument")
|
||
|
else
|
||
|
print("250 Hello " .. line[2])
|
||
|
end
|
||
|
elseif line[1] == "EHLO" then
|
||
|
if #line < 2 then
|
||
|
print("251 Command requires argument")
|
||
|
else
|
||
|
print("250-Hello " .. line[2])
|
||
|
print("250 SIZE 1000000")
|
||
|
end
|
||
|
elseif line[1] == "VRFY" and data == false then
|
||
|
print("252 Cannot VRFY user, but will accept message")
|
||
|
elseif line[1] == "QUIT" and data == false then
|
||
|
print("221 Bye!")
|
||
|
os.exit()
|
||
|
elseif line[1] == "MAIL" and data == false then
|
||
|
if #line < 2 then print("501 Incorrent number of arguments")
|
||
|
else
|
||
|
if string.starts(line[2],"FROM:") then
|
||
|
from = table.concat(table.slice(mysplit(table.concat(line," "),":"),2))
|
||
|
print("250 OK")
|
||
|
else
|
||
|
print("501 Incorrect number of arguments")
|
||
|
end
|
||
|
end
|
||
|
elseif line[1] == "RCPT" and data == false then
|
||
|
if #line < 2 then
|
||
|
print("501 Incorrent number of arguments")
|
||
|
else
|
||
|
if string.starts(line[2],"TO:") then
|
||
|
to = table.concat(table.slice(mysplit(table.concat(line," "),":"),2))
|
||
|
print("250 OK")
|
||
|
else
|
||
|
print("502 Unrecognized command")
|
||
|
end
|
||
|
end
|
||
|
elseif line[1] == "DATA" and from ~= nil and to ~= nil then
|
||
|
data = true
|
||
|
print("354 Send message content; End with <CRLF>.<CRLF>")
|
||
|
elseif line[1] == "." and data == true then
|
||
|
if not validate(dataBuf,from,to) then print("250 NOTOK")
|
||
|
data = false else
|
||
|
out = io.open("/var/mail/root","a")
|
||
|
out:write("From " .. from .." ".. os.date("%a %b %d %H:%M:%S %Y") .. "\n")
|
||
|
out:write(dataBuf)
|
||
|
out:close()
|
||
|
print("250 OK")
|
||
|
data = false
|
||
|
end
|
||
|
else
|
||
|
if data == true then
|
||
|
dataBuf = dataBuf .. table.concat(line, " ") .. "\n"
|
||
|
else
|
||
|
print("502 Unrecognized command")
|
||
|
end
|
||
|
end
|
||
|
end
|