mod_auth_dovecot/auth_dovecot/sasl_dovecot.lib.lua
author Matthew Wild <mwild1@gmail.com>
Mon, 19 Mar 2012 17:06:02 +0000
changeset 625 2c07bcf56a36
parent 474 942738953ff3
child 700 0c130c45b7c1
permissions -rw-r--r--
mod_smacks: Don't hibernate session on graceful stream close
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
474
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     1
-- Dovecot authentication backend for Prosody
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     2
--
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     3
-- Copyright (C) 2008-2009 Tobias Markmann
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     4
-- Copyright (C) 2010 Javier Torres
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     5
-- Copyright (C) 2010-2011 Matthew Wild
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     6
-- Copyright (C) 2010-2011 Waqas Hussain
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     7
-- Copyright (C) 2011 Kim Alvefur
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     8
--
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     9
--    Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    10
--
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    11
--        * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    12
--        * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    13
--        * Neither the name of Tobias Markmann nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    14
--
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    15
--    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    16
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    17
-- This code is based on util.sasl_cyrus and the old mod_auth_dovecot
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    18
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    19
local log = require "util.logger".init("sasl_dovecot");
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    20
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    21
local setmetatable = setmetatable;
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    22
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    23
local s_match, s_gmatch = string.match, string.gmatch
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    24
local t_concat = table.concat;
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    25
local m_random = math.random;
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    26
local tostring, tonumber = tostring, tonumber;
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    27
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    28
local socket = require "socket"
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    29
pcall(require, "socket.unix");
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    30
local base64 = require "util.encodings".base64;
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    31
local b64, unb64 = base64.encode, base64.decode;
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    32
local jid_escape = require "util.jid".escape;
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    33
local prepped_split = require "util.jid".prepped_split;
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    34
local nodeprep = require "util.encodings".stringprep.nodeprep;
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    35
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    36
--module "sasl_dovecot"
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    37
local _M = {};
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    38
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    39
local request_id = 0;
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    40
local method = {};
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    41
method.__index = method;
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    42
local conn, supported_mechs, pid;
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    43
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    44
local function connect(socket_info)
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    45
	--log("debug", "connect(%q)", socket_path);
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    46
	if conn then conn:close(); pid = nil; end
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    47
	if not pid then pid = tonumber(tostring(conn):match("0x%x*$")) end
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    48
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    49
	local socket_type = (type(socket_info) == "string") and "UNIX" or "TCP";
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    50
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    51
	local ok, err;
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    52
	if socket_type == "TCP" then
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    53
		local socket_host, socket_port = unpack(socket_info);
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    54
		conn = socket.tcp();
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    55
		ok, err = conn:connect(socket_host, socket_port);
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    56
		socket_path = ("%s:%d"):format(socket_host, socket_port);
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    57
	elseif socket.unix then
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    58
		conn = socket.unix();
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    59
		ok, err = conn:connect(socket_path);
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    60
	else
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    61
		err = "luasocket was not compiled with UNIX sockets support";
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    62
	end
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    63
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    64
	if not ok then
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    65
		log("error", "error connecting to dovecot %s socket at '%s'. error was '%s'", socket_type, socket_path, err);
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    66
		return false;
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    67
	end
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    68
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    69
	-- Send our handshake
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    70
	log("debug", "sending handshake to dovecot. version 1.1, cpid '%d'", pid);
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    71
	if not conn:send("VERSION\t1\t1\n") then
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    72
		return false
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    73
	end
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    74
	if not conn:send("CPID\t" .. pid .. "\n") then
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    75
		return false
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    76
	end
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    77
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    78
	-- Parse Dovecot's handshake
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    79
	local done = false;
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    80
	supported_mechs = {};
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    81
	while (not done) do
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    82
		local line = conn:receive();
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    83
		if not line then
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    84
			return false;
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    85
		end
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    86
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    87
		--log("debug", "dovecot handshake: '%s'", line);
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    88
		local parts = line:gmatch("[^\t]+");
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    89
		local first = parts();
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    90
		if first == "VERSION" then
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    91
			-- Version should be 1.1
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    92
			local major_version = parts();
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    93
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    94
			if major_version ~= "1" then
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    95
				log("error", "dovecot server version is not 1.x. it is %s.x", major_version);
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    96
				conn:close();
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    97
				return false;
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    98
			end
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    99
		elseif first == "MECH" then
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   100
			local mech = parts();
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   101
			supported_mechs[mech] = true;
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   102
		elseif first == "DONE" then
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   103
			done = true;
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   104
		end
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   105
	end
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   106
	return conn, supported_mechs;
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   107
end
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   108
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   109
-- create a new SASL object which can be used to authenticate clients
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   110
function _M.new(realm, service_name, socket_info, config)
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   111
	--log("debug", "new(%q, %q, %q)", realm or "", service_name or "", socket_info or "");
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   112
	local sasl_i = { realm = realm, service_name = service_name, socket_info = socket_info, config = config or {} };
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   113
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   114
	request_id = request_id + 1;
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   115
	sasl_i.request_id = request_id;
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   116
	local conn, mechs = conn, supported_mechs;
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   117
	if not conn then
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   118
		conn, mechs = connect(socket_info);
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   119
		if not conn then
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   120
			return nil, "Socket connection failure";
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   121
		end
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   122
	end
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   123
	sasl_i.conn, sasl_i.mechs = conn, mechs;
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   124
	return setmetatable(sasl_i, method);
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   125
end
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   126
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   127
-- [[
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   128
function method:send(...)
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   129
	local msg = t_concat({...}, "\t");
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   130
	local ok, err = self.conn:send(authmsg.."\n");
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   131
	if not ok then
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   132
		log("error", "Could not write to socket: %s", err);
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   133
		return nil, err;
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   134
	end
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   135
	return true;
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   136
end
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   137
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   138
function method:recv()
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   139
	local line, err = self.conn:receive();
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   140
	--log("debug", "Sent %d bytes to socket", ok);
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   141
	local line, err = self.conn:receive();
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   142
	if not line then
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   143
		log("error", "Could not read from socket: %s", err);
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   144
		return nil, err;
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   145
	end
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   146
	return line;
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   147
end
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   148
-- ]]
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   149
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   150
function method:plain_test(username, password, realm)
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   151
	if self:select("PLAIN") then
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   152
		return self:process(("\0%s\0%s"):format(username, password));
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   153
	end
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   154
end
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   155
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   156
-- get a fresh clone with the same realm and service name
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   157
function method:clean_clone()
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   158
	--log("debug", "method:clean_clone()");
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   159
	return _M.new(self.realm, self.service_name, self.socket_info, self.config)
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   160
end
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   161
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   162
-- get a list of possible SASL mechanims to use
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   163
function method:mechanisms()
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   164
	--log("debug", "method:mechanisms()");
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   165
	return self.mechs;
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   166
end
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   167
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   168
-- select a mechanism to use
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   169
function method:select(mechanism)
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   170
	--log("debug", "method:select(%q)", mechanism);
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   171
	if not self.selected and self.mechs[mechanism] then
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   172
		self.selected = mechanism;
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   173
		return true;
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   174
	end
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   175
end
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   176
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   177
-- feed new messages to process into the library
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   178
function method:process(message)
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   179
	--log("debug", "method:process"..(message and "(%q)" or "()"), message);
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   180
	--if not message then
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   181
		--return "challenge";
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   182
		--return "failure", "malformed-request";
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   183
	--end
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   184
	local request_id = self.request_id;
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   185
	local authmsg;
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   186
	if not self.started then
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   187
		self.started = true;
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   188
		authmsg = t_concat({
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   189
			"AUTH",
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   190
			request_id,
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   191
			self.selected,
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   192
			"service="..self.service_name,
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   193
			"resp="..(message and b64(message) or "=")
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   194
		}, "\t");
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   195
	else
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   196
		authmsg = t_concat({
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   197
			"CONT",
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   198
			request_id,
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   199
			(message and b64(message) or "=")
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   200
		}, "\t");
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   201
	end
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   202
	--log("debug", "Sending %d bytes: %q", #authmsg, authmsg);
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   203
	local ok, err = self.conn:send(authmsg.."\n");
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   204
	if not ok then
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   205
		log("error", "Could not write to socket: %s", err);
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   206
		return "failure", "internal-server-error", err
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   207
	end
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   208
	--log("debug", "Sent %d bytes to socket", ok);
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   209
	local line, err = self.conn:receive();
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   210
	if not line then
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   211
		log("error", "Could not read from socket: %s", err);
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   212
		return "failure", "internal-server-error", err
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   213
	end
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   214
	--log("debug", "Received %d bytes from socket: %s", #line, line);
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   215
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   216
	local parts = line:gmatch("[^\t]+");
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   217
	local resp = parts();
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   218
	local id = tonumber(parts());
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   219
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   220
	if id ~= request_id then
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   221
		return "failure", "internal-server-error", "Unexpected request id"
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   222
	end
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   223
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   224
	local data = {};
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   225
	for param in parts do
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   226
		data[#data+1]=param;
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   227
		local k,v = param:match("^([^=]*)=?(.*)$");
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   228
		if k and #k>0 then
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   229
			data[k]=v or true;
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   230
		end
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   231
	end
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   232
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   233
	if data.user then
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   234
		local handle_domain = self.config.handle_domain;
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   235
		local validate_domain = self.config.validate_domain;
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   236
		if handle_domain == "split" then
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   237
			local domain;
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   238
			self.username, domain = prepped_split(data.user);
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   239
			if validate_domain and domain ~= self.realm then
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   240
				return "failure", "not-authorized", "Domain mismatch";
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   241
			end
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   242
		elseif handle_domain == "escape" then
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   243
			self.username = nodeprep(jid_escape(data.user));
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   244
		else
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   245
			self.username = nodeprep(data.user);
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   246
		end
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   247
		if not self.username then 
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   248
			return "failure", "not-authorized", "Username failed NODEprep"
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   249
		end
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   250
	end
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   251
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   252
	if resp == "FAIL" then
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   253
		if data.temp then
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   254
			return "failure", "temporary-auth-failure", data.reason;
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   255
		elseif data.authz then
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   256
			return "failure", "invalid-authzid", data.reason;
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   257
		else
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   258
			return "failure", "not-authorized", data.reason;
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   259
		end
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   260
	elseif resp == "CONT" then
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   261
		return "challenge", unb64(data[1]);
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   262
	elseif resp == "OK" then
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   263
		return "success", data.resp and unb64(data.resp) or nil; 
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   264
	end
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   265
end
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   266
942738953ff3 mod_auth_dovecot: Replace with SASL proxying version.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   267
return _M;