You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
	
	
		
			84 lines
		
	
	
		
			2.2 KiB
		
	
	
	
		
			Lua
		
	
			
		
		
	
	
			84 lines
		
	
	
		
			2.2 KiB
		
	
	
	
		
			Lua
		
	
local cqueues = require'cqueues'
 | 
						|
local socket = require'cqueues.socket'
 | 
						|
local openssl_context = require'openssl.ssl.context'
 | 
						|
local base64 = require'base64'
 | 
						|
 | 
						|
 | 
						|
 | 
						|
local get_default_ehlo_host = function()
 | 
						|
  return 'debian' -- TODO read from /etc/hosts
 | 
						|
end
 | 
						|
 | 
						|
local send_auth_plain = function(opts)
 | 
						|
  if opts.host==nil or opts.from==nil or opts.to==nil then error('`host`, `from`, and `to` are required.') end
 | 
						|
 | 
						|
  local host = opts.host
 | 
						|
  local port = opts.port or 25 --587
 | 
						|
  local username = opts.username
 | 
						|
  local password = opts.password
 | 
						|
 | 
						|
  local ehlo_host = opts.ehlo_host or get_default_ehlo_host()
 | 
						|
 | 
						|
  local from = opts.from
 | 
						|
  local to = opts.to
 | 
						|
  -- `message` includes Subject and other headers. Use stmp-message.lua to construct a message string.
 | 
						|
  local message = opts.message or 'Subject: \r\n\r\n\r\n.\r\n'
 | 
						|
  --local subject = opts.subject or ''
 | 
						|
  --local body = opts.body or ''
 | 
						|
  
 | 
						|
  local connection = socket.connect(host, port)
 | 
						|
  connection:settimeout(5)
 | 
						|
 | 
						|
  local read = function()
 | 
						|
    local m = connection:read('*l') or ''
 | 
						|
    print('<-- '..m)
 | 
						|
    return m
 | 
						|
  end
 | 
						|
 | 
						|
  local read_until = function(code_desired, substring)
 | 
						|
    local substring_needed = (substring ~= nil)
 | 
						|
    local code, line
 | 
						|
    repeat
 | 
						|
      line = read()
 | 
						|
      code = string.sub(line,1,3)
 | 
						|
    until code == code_desired and (not substring_needed or line:find(substring) ~= nil)
 | 
						|
  end
 | 
						|
 | 
						|
  local write = function(m)
 | 
						|
    print('--> '..m)
 | 
						|
    connection:write(m)
 | 
						|
  end
 | 
						|
 | 
						|
  read_until('220')
 | 
						|
  write('STARTTLS\r\n')
 | 
						|
 | 
						|
  read_until('220')
 | 
						|
  local ctx = openssl_context.new('TLSv1_2', false)
 | 
						|
 | 
						|
  local ok, err = connection:starttls(ctx)
 | 
						|
  if not ok then print('starttls error', err) end
 | 
						|
 | 
						|
  write('EHLO '..ehlo_host..'\r\n')
 | 
						|
  read_until('250','PLAIN')
 | 
						|
 | 
						|
  write('AUTH PLAIN '..base64.encode(username..'\0'..username..'\0'..password)..'\r\n')
 | 
						|
 | 
						|
  read_until('235') -- auth successful
 | 
						|
  write('MAIL FROM:<'..from..'>\r\n')
 | 
						|
  read_until('250')
 | 
						|
  write('RCPT TO:<'..to..'>\r\n')
 | 
						|
  read_until('250')
 | 
						|
  write('DATA\r\n')
 | 
						|
  read_until('354')
 | 
						|
  write(message)
 | 
						|
  --write('Subject: '..subject..'\r\n\r\n')
 | 
						|
  --write(body..'\r\n')
 | 
						|
  write('\r\n.\r\n')
 | 
						|
  read_until('250')
 | 
						|
  write('QUIT')
 | 
						|
  --read_until('221')
 | 
						|
  connection:close()
 | 
						|
end
 | 
						|
 | 
						|
return send_auth_plain
 |