diff --git a/mail.lua b/mail.lua new file mode 100644 index 0000000..6651386 --- /dev/null +++ b/mail.lua @@ -0,0 +1,124 @@ + +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 .") + 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 \ No newline at end of file