Annotate

mod_auth_imap/auth_imap/sasl_imap.lib.lua @ 5551:8bfcedd93a72

mod_rest: List all error conditions in OpenAPI spec These are not handled by datamanager but by util.stanza and util.error, so they are not represented in the JSON schema file.
author Kim Alvefur <zash@zash.se>
date Sat, 17 Jun 2023 16:26:33 +0200
parent 5013:a106477f1a65
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1196
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
1 -- Dovecot authentication backend for Prosody
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
2 --
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
3 -- Copyright (C) 2011 Kim Alvefur
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
4 --
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
5
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
6 local log = require "util.logger".init("sasl_imap");
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
7
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
8 local setmetatable = setmetatable;
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
9
1199
5d46281a5d23 mod_auth_imap: Minor cleanup of imports
Matthew Wild <mwild1@gmail.com>
parents: 1196
diff changeset
10 local s_match = string.match;
1196
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
11 local t_concat = table.concat;
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
12 local tostring, tonumber = tostring, tonumber;
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
13
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
14 local socket = require "socket"
1200
34216cdffda6 mod_auth_imap: unfortunately large commit which adds support for SSL (including cert verification), appending the realm to usernames, and various IMAP protocol fixes
Matthew Wild <mwild1@gmail.com>
parents: 1199
diff changeset
15 local ssl = require "ssl"
34216cdffda6 mod_auth_imap: unfortunately large commit which adds support for SSL (including cert verification), appending the realm to usernames, and various IMAP protocol fixes
Matthew Wild <mwild1@gmail.com>
parents: 1199
diff changeset
16 local x509 = require "util.x509";
1196
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
17 local base64 = require "util.encodings".base64;
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
18 local b64, unb64 = base64.encode, base64.decode;
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
19
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
20 local _M = {};
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
21
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
22 local method = {};
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
23 method.__index = method;
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
24
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
25 -- For extracting the username.
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
26 local mitm = {
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
27 PLAIN = function(message)
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
28 return s_match(message, "^[^%z]*%z([^%z]+)%z[^%z]+");
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
29 end,
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
30 ["SCRAM-SHA-1"] = function(message)
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
31 return s_match(message, "^[^,]+,[^,]*,n=([^,]*)");
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
32 end,
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
33 ["DIGEST-MD5"] = function(message)
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
34 return s_match(message, "username=\"([^\"]*)\"");
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
35 end,
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
36 }
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
37
1200
34216cdffda6 mod_auth_imap: unfortunately large commit which adds support for SSL (including cert verification), appending the realm to usernames, and various IMAP protocol fixes
Matthew Wild <mwild1@gmail.com>
parents: 1199
diff changeset
38 local function connect(host, port, ssl_params)
34216cdffda6 mod_auth_imap: unfortunately large commit which adds support for SSL (including cert verification), appending the realm to usernames, and various IMAP protocol fixes
Matthew Wild <mwild1@gmail.com>
parents: 1199
diff changeset
39 port = tonumber(port) or (ssl_params and 993 or 143);
34216cdffda6 mod_auth_imap: unfortunately large commit which adds support for SSL (including cert verification), appending the realm to usernames, and various IMAP protocol fixes
Matthew Wild <mwild1@gmail.com>
parents: 1199
diff changeset
40 log("debug", "connect() to %s:%s:%d", ssl_params and "ssl" or "tcp", host, tonumber(port));
1196
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
41 local conn = socket.tcp();
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
42
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
43 -- Create a connection to imap socket
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
44 log("debug", "connecting to imap at '%s:%d'", host, port);
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
45 local ok, err = conn:connect(host, port);
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
46 conn:settimeout(10);
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
47 if not ok then
1200
34216cdffda6 mod_auth_imap: unfortunately large commit which adds support for SSL (including cert verification), appending the realm to usernames, and various IMAP protocol fixes
Matthew Wild <mwild1@gmail.com>
parents: 1199
diff changeset
48 log("error", "error connecting to imap at '%s:%d': %s", host, port, err);
1196
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
49 return false;
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
50 end
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
51
1200
34216cdffda6 mod_auth_imap: unfortunately large commit which adds support for SSL (including cert verification), appending the realm to usernames, and various IMAP protocol fixes
Matthew Wild <mwild1@gmail.com>
parents: 1199
diff changeset
52 if ssl_params then
34216cdffda6 mod_auth_imap: unfortunately large commit which adds support for SSL (including cert verification), appending the realm to usernames, and various IMAP protocol fixes
Matthew Wild <mwild1@gmail.com>
parents: 1199
diff changeset
53 -- Perform SSL handshake
34216cdffda6 mod_auth_imap: unfortunately large commit which adds support for SSL (including cert verification), appending the realm to usernames, and various IMAP protocol fixes
Matthew Wild <mwild1@gmail.com>
parents: 1199
diff changeset
54 local ok, err = ssl.wrap(conn, ssl_params);
34216cdffda6 mod_auth_imap: unfortunately large commit which adds support for SSL (including cert verification), appending the realm to usernames, and various IMAP protocol fixes
Matthew Wild <mwild1@gmail.com>
parents: 1199
diff changeset
55 if ok then
34216cdffda6 mod_auth_imap: unfortunately large commit which adds support for SSL (including cert verification), appending the realm to usernames, and various IMAP protocol fixes
Matthew Wild <mwild1@gmail.com>
parents: 1199
diff changeset
56 conn = ok;
34216cdffda6 mod_auth_imap: unfortunately large commit which adds support for SSL (including cert verification), appending the realm to usernames, and various IMAP protocol fixes
Matthew Wild <mwild1@gmail.com>
parents: 1199
diff changeset
57 ok, err = conn:dohandshake();
34216cdffda6 mod_auth_imap: unfortunately large commit which adds support for SSL (including cert verification), appending the realm to usernames, and various IMAP protocol fixes
Matthew Wild <mwild1@gmail.com>
parents: 1199
diff changeset
58 end
34216cdffda6 mod_auth_imap: unfortunately large commit which adds support for SSL (including cert verification), appending the realm to usernames, and various IMAP protocol fixes
Matthew Wild <mwild1@gmail.com>
parents: 1199
diff changeset
59 if not ok then
34216cdffda6 mod_auth_imap: unfortunately large commit which adds support for SSL (including cert verification), appending the realm to usernames, and various IMAP protocol fixes
Matthew Wild <mwild1@gmail.com>
parents: 1199
diff changeset
60 log("error", "error initializing ssl connection to imap at '%s:%d': %s", host, port, err);
34216cdffda6 mod_auth_imap: unfortunately large commit which adds support for SSL (including cert verification), appending the realm to usernames, and various IMAP protocol fixes
Matthew Wild <mwild1@gmail.com>
parents: 1199
diff changeset
61 conn:close();
34216cdffda6 mod_auth_imap: unfortunately large commit which adds support for SSL (including cert verification), appending the realm to usernames, and various IMAP protocol fixes
Matthew Wild <mwild1@gmail.com>
parents: 1199
diff changeset
62 return false;
34216cdffda6 mod_auth_imap: unfortunately large commit which adds support for SSL (including cert verification), appending the realm to usernames, and various IMAP protocol fixes
Matthew Wild <mwild1@gmail.com>
parents: 1199
diff changeset
63 end
34216cdffda6 mod_auth_imap: unfortunately large commit which adds support for SSL (including cert verification), appending the realm to usernames, and various IMAP protocol fixes
Matthew Wild <mwild1@gmail.com>
parents: 1199
diff changeset
64
34216cdffda6 mod_auth_imap: unfortunately large commit which adds support for SSL (including cert verification), appending the realm to usernames, and various IMAP protocol fixes
Matthew Wild <mwild1@gmail.com>
parents: 1199
diff changeset
65 -- Verify certificate
34216cdffda6 mod_auth_imap: unfortunately large commit which adds support for SSL (including cert verification), appending the realm to usernames, and various IMAP protocol fixes
Matthew Wild <mwild1@gmail.com>
parents: 1199
diff changeset
66 if ssl_params.verify then
34216cdffda6 mod_auth_imap: unfortunately large commit which adds support for SSL (including cert verification), appending the realm to usernames, and various IMAP protocol fixes
Matthew Wild <mwild1@gmail.com>
parents: 1199
diff changeset
67 if not conn.getpeercertificate then
34216cdffda6 mod_auth_imap: unfortunately large commit which adds support for SSL (including cert verification), appending the realm to usernames, and various IMAP protocol fixes
Matthew Wild <mwild1@gmail.com>
parents: 1199
diff changeset
68 log("error", "unable to verify certificate, newer LuaSec required: https://prosody.im/doc/depends#luasec");
34216cdffda6 mod_auth_imap: unfortunately large commit which adds support for SSL (including cert verification), appending the realm to usernames, and various IMAP protocol fixes
Matthew Wild <mwild1@gmail.com>
parents: 1199
diff changeset
69 conn:close();
34216cdffda6 mod_auth_imap: unfortunately large commit which adds support for SSL (including cert verification), appending the realm to usernames, and various IMAP protocol fixes
Matthew Wild <mwild1@gmail.com>
parents: 1199
diff changeset
70 return false;
34216cdffda6 mod_auth_imap: unfortunately large commit which adds support for SSL (including cert verification), appending the realm to usernames, and various IMAP protocol fixes
Matthew Wild <mwild1@gmail.com>
parents: 1199
diff changeset
71 end
34216cdffda6 mod_auth_imap: unfortunately large commit which adds support for SSL (including cert verification), appending the realm to usernames, and various IMAP protocol fixes
Matthew Wild <mwild1@gmail.com>
parents: 1199
diff changeset
72 if not x509.verify_identity(host, nil, conn:getpeercertificate()) then
34216cdffda6 mod_auth_imap: unfortunately large commit which adds support for SSL (including cert verification), appending the realm to usernames, and various IMAP protocol fixes
Matthew Wild <mwild1@gmail.com>
parents: 1199
diff changeset
73 log("warn", "invalid certificate for imap service %s:%d, denying connection", host, port);
34216cdffda6 mod_auth_imap: unfortunately large commit which adds support for SSL (including cert verification), appending the realm to usernames, and various IMAP protocol fixes
Matthew Wild <mwild1@gmail.com>
parents: 1199
diff changeset
74 return false;
34216cdffda6 mod_auth_imap: unfortunately large commit which adds support for SSL (including cert verification), appending the realm to usernames, and various IMAP protocol fixes
Matthew Wild <mwild1@gmail.com>
parents: 1199
diff changeset
75 end
34216cdffda6 mod_auth_imap: unfortunately large commit which adds support for SSL (including cert verification), appending the realm to usernames, and various IMAP protocol fixes
Matthew Wild <mwild1@gmail.com>
parents: 1199
diff changeset
76 end
34216cdffda6 mod_auth_imap: unfortunately large commit which adds support for SSL (including cert verification), appending the realm to usernames, and various IMAP protocol fixes
Matthew Wild <mwild1@gmail.com>
parents: 1199
diff changeset
77 end
34216cdffda6 mod_auth_imap: unfortunately large commit which adds support for SSL (including cert verification), appending the realm to usernames, and various IMAP protocol fixes
Matthew Wild <mwild1@gmail.com>
parents: 1199
diff changeset
78
1196
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
79 -- Parse IMAP handshake
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
80 local supported_mechs = {};
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
81 local line = conn:receive("*l");
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
82 if not line then
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
83 return false;
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
84 end
1200
34216cdffda6 mod_auth_imap: unfortunately large commit which adds support for SSL (including cert verification), appending the realm to usernames, and various IMAP protocol fixes
Matthew Wild <mwild1@gmail.com>
parents: 1199
diff changeset
85 log("debug", "imap greeting: '%s'", line);
1196
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
86 local caps = line:match("^%*%s+OK%s+(%b[])");
1200
34216cdffda6 mod_auth_imap: unfortunately large commit which adds support for SSL (including cert verification), appending the realm to usernames, and various IMAP protocol fixes
Matthew Wild <mwild1@gmail.com>
parents: 1199
diff changeset
87 if not caps or not caps:match("^%[CAPABILITY ") then
3763
f384669a9359 mod_auth_imap: send CRLF instead LF, in order to be compliant with RFC3501
andrewhotlab <andrew.hotlab@hotmail.com>
parents: 1343
diff changeset
88 conn:send("A CAPABILITY\r\n");
1200
34216cdffda6 mod_auth_imap: unfortunately large commit which adds support for SSL (including cert verification), appending the realm to usernames, and various IMAP protocol fixes
Matthew Wild <mwild1@gmail.com>
parents: 1199
diff changeset
89 line = conn:receive("*l");
34216cdffda6 mod_auth_imap: unfortunately large commit which adds support for SSL (including cert verification), appending the realm to usernames, and various IMAP protocol fixes
Matthew Wild <mwild1@gmail.com>
parents: 1199
diff changeset
90 log("debug", "imap capabilities response: '%s'", line);
34216cdffda6 mod_auth_imap: unfortunately large commit which adds support for SSL (including cert verification), appending the realm to usernames, and various IMAP protocol fixes
Matthew Wild <mwild1@gmail.com>
parents: 1199
diff changeset
91 caps = line:match("^%*%s+CAPABILITY%s+(.*)$");
34216cdffda6 mod_auth_imap: unfortunately large commit which adds support for SSL (including cert verification), appending the realm to usernames, and various IMAP protocol fixes
Matthew Wild <mwild1@gmail.com>
parents: 1199
diff changeset
92 if not conn:receive("*l"):match("^A OK") then
34216cdffda6 mod_auth_imap: unfortunately large commit which adds support for SSL (including cert verification), appending the realm to usernames, and various IMAP protocol fixes
Matthew Wild <mwild1@gmail.com>
parents: 1199
diff changeset
93 log("debug", "imap capabilities command failed")
34216cdffda6 mod_auth_imap: unfortunately large commit which adds support for SSL (including cert verification), appending the realm to usernames, and various IMAP protocol fixes
Matthew Wild <mwild1@gmail.com>
parents: 1199
diff changeset
94 conn:close();
34216cdffda6 mod_auth_imap: unfortunately large commit which adds support for SSL (including cert verification), appending the realm to usernames, and various IMAP protocol fixes
Matthew Wild <mwild1@gmail.com>
parents: 1199
diff changeset
95 return false;
34216cdffda6 mod_auth_imap: unfortunately large commit which adds support for SSL (including cert verification), appending the realm to usernames, and various IMAP protocol fixes
Matthew Wild <mwild1@gmail.com>
parents: 1199
diff changeset
96 end
34216cdffda6 mod_auth_imap: unfortunately large commit which adds support for SSL (including cert verification), appending the realm to usernames, and various IMAP protocol fixes
Matthew Wild <mwild1@gmail.com>
parents: 1199
diff changeset
97 elseif caps then
34216cdffda6 mod_auth_imap: unfortunately large commit which adds support for SSL (including cert verification), appending the realm to usernames, and various IMAP protocol fixes
Matthew Wild <mwild1@gmail.com>
parents: 1199
diff changeset
98 caps = caps:sub(2,-2); -- Strip surrounding []
34216cdffda6 mod_auth_imap: unfortunately large commit which adds support for SSL (including cert verification), appending the realm to usernames, and various IMAP protocol fixes
Matthew Wild <mwild1@gmail.com>
parents: 1199
diff changeset
99 end
1196
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
100 if caps then
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
101 for cap in caps:gmatch("%S+") do
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
102 log("debug", "Capability: %s", cap);
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
103 local mech = cap:match("AUTH=(.*)");
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
104 if mech then
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
105 log("debug", "Supported SASL mechanism: %s", mech);
1343
7dbde05b48a9 all the things: Remove trailing whitespace
Florian Zeitz <florob@babelmonkeys.de>
parents: 1200
diff changeset
106 supported_mechs[mech] = mitm[mech] and true or nil;
1196
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
107 end
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
108 end
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
109 end
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
110
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
111 return conn, supported_mechs;
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
112 end
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
113
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
114 -- create a new SASL object which can be used to authenticate clients
1200
34216cdffda6 mod_auth_imap: unfortunately large commit which adds support for SSL (including cert verification), appending the realm to usernames, and various IMAP protocol fixes
Matthew Wild <mwild1@gmail.com>
parents: 1199
diff changeset
115 function _M.new(realm, service_name, host, port, ssl_params, append_host)
1196
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
116 log("debug", "new(%q, %q, %q, %d)", realm or "", service_name or "", host or "", port or 0);
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
117 local sasl_i = {
1200
34216cdffda6 mod_auth_imap: unfortunately large commit which adds support for SSL (including cert verification), appending the realm to usernames, and various IMAP protocol fixes
Matthew Wild <mwild1@gmail.com>
parents: 1199
diff changeset
118 realm = realm;
34216cdffda6 mod_auth_imap: unfortunately large commit which adds support for SSL (including cert verification), appending the realm to usernames, and various IMAP protocol fixes
Matthew Wild <mwild1@gmail.com>
parents: 1199
diff changeset
119 service_name = service_name;
34216cdffda6 mod_auth_imap: unfortunately large commit which adds support for SSL (including cert verification), appending the realm to usernames, and various IMAP protocol fixes
Matthew Wild <mwild1@gmail.com>
parents: 1199
diff changeset
120 _host = host;
34216cdffda6 mod_auth_imap: unfortunately large commit which adds support for SSL (including cert verification), appending the realm to usernames, and various IMAP protocol fixes
Matthew Wild <mwild1@gmail.com>
parents: 1199
diff changeset
121 _port = port;
34216cdffda6 mod_auth_imap: unfortunately large commit which adds support for SSL (including cert verification), appending the realm to usernames, and various IMAP protocol fixes
Matthew Wild <mwild1@gmail.com>
parents: 1199
diff changeset
122 _ssl_params = ssl_params;
34216cdffda6 mod_auth_imap: unfortunately large commit which adds support for SSL (including cert verification), appending the realm to usernames, and various IMAP protocol fixes
Matthew Wild <mwild1@gmail.com>
parents: 1199
diff changeset
123 _append_host = append_host;
1196
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
124 };
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
125
1200
34216cdffda6 mod_auth_imap: unfortunately large commit which adds support for SSL (including cert verification), appending the realm to usernames, and various IMAP protocol fixes
Matthew Wild <mwild1@gmail.com>
parents: 1199
diff changeset
126 local conn, mechs = connect(host, port, ssl_params);
1196
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
127 if not conn then
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
128 return nil, "Socket connection failure";
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
129 end
1200
34216cdffda6 mod_auth_imap: unfortunately large commit which adds support for SSL (including cert verification), appending the realm to usernames, and various IMAP protocol fixes
Matthew Wild <mwild1@gmail.com>
parents: 1199
diff changeset
130 if append_host then
34216cdffda6 mod_auth_imap: unfortunately large commit which adds support for SSL (including cert verification), appending the realm to usernames, and various IMAP protocol fixes
Matthew Wild <mwild1@gmail.com>
parents: 1199
diff changeset
131 mechs = { PLAIN = mechs.PLAIN };
34216cdffda6 mod_auth_imap: unfortunately large commit which adds support for SSL (including cert verification), appending the realm to usernames, and various IMAP protocol fixes
Matthew Wild <mwild1@gmail.com>
parents: 1199
diff changeset
132 end
1196
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
133 sasl_i.conn, sasl_i.mechs = conn, mechs;
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
134 return setmetatable(sasl_i, method);
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
135 end
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
136
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
137 -- get a fresh clone with the same realm and service name
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
138 function method:clean_clone()
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
139 if self.conn then
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
140 self.conn:close();
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
141 self.conn = nil;
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
142 end
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
143 log("debug", "method:clean_clone()");
1200
34216cdffda6 mod_auth_imap: unfortunately large commit which adds support for SSL (including cert verification), appending the realm to usernames, and various IMAP protocol fixes
Matthew Wild <mwild1@gmail.com>
parents: 1199
diff changeset
144 return _M.new(self.realm, self.service_name, self._host, self._port, self._ssl_params, self._append_host)
1196
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
145 end
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
146
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
147 -- get a list of possible SASL mechanisms to use
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
148 function method:mechanisms()
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
149 log("debug", "method:mechanisms()");
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
150 return self.mechs;
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
151 end
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
152
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
153 -- select a mechanism to use
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
154 function method:select(mechanism)
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
155 log("debug", "method:select(%q)", mechanism);
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
156 if not self.selected and self.mechs[mechanism] then
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
157 self.tag = tostring({}):match("0x(%x*)$");
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
158 self.selected = mechanism;
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
159 local selectmsg = t_concat({ self.tag, "AUTHENTICATE", mechanism }, " ");
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
160 log("debug", "Sending %d bytes: %q", #selectmsg, selectmsg);
3763
f384669a9359 mod_auth_imap: send CRLF instead LF, in order to be compliant with RFC3501
andrewhotlab <andrew.hotlab@hotmail.com>
parents: 1343
diff changeset
161 local ok, err = self.conn:send(selectmsg.."\r\n");
1196
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
162 if not ok then
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
163 log("error", "Could not write to socket: %s", err);
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
164 return "failure", "internal-server-error", err
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
165 end
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
166 local line, err = self.conn:receive("*l");
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
167 if not line then
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
168 log("error", "Could not read from socket: %s", err);
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
169 return "failure", "internal-server-error", err
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
170 end
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
171 log("debug", "Received %d bytes: %q", #line, line);
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
172 return line:match("^+")
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
173 end
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
174 end
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
175
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
176 -- feed new messages to process into the library
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
177 function method:process(message)
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
178 local username = mitm[self.selected](message);
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
179 if username then self.username = username; end
1200
34216cdffda6 mod_auth_imap: unfortunately large commit which adds support for SSL (including cert verification), appending the realm to usernames, and various IMAP protocol fixes
Matthew Wild <mwild1@gmail.com>
parents: 1199
diff changeset
180 if self._append_host and self.selected == "PLAIN" then
34216cdffda6 mod_auth_imap: unfortunately large commit which adds support for SSL (including cert verification), appending the realm to usernames, and various IMAP protocol fixes
Matthew Wild <mwild1@gmail.com>
parents: 1199
diff changeset
181 message = message:gsub("^([^%z]*%z[^%z]+)(%z[^%z]+)$", "%1@"..self.realm.."%2");
34216cdffda6 mod_auth_imap: unfortunately large commit which adds support for SSL (including cert verification), appending the realm to usernames, and various IMAP protocol fixes
Matthew Wild <mwild1@gmail.com>
parents: 1199
diff changeset
182 end
34216cdffda6 mod_auth_imap: unfortunately large commit which adds support for SSL (including cert verification), appending the realm to usernames, and various IMAP protocol fixes
Matthew Wild <mwild1@gmail.com>
parents: 1199
diff changeset
183 log("debug", "method:process(%d bytes): %q", #message, message:gsub("%z", "."));
3763
f384669a9359 mod_auth_imap: send CRLF instead LF, in order to be compliant with RFC3501
andrewhotlab <andrew.hotlab@hotmail.com>
parents: 1343
diff changeset
184 local ok, err = self.conn:send(b64(message).."\r\n");
1196
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
185 if not ok then
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
186 log("error", "Could not write to socket: %s", err);
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
187 return "failure", "internal-server-error", err
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
188 end
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
189 log("debug", "Sent %d bytes to socket", ok);
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
190 local line, err = self.conn:receive("*l");
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
191 if not line then
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
192 log("error", "Could not read from socket: %s", err);
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
193 return "failure", "internal-server-error", err
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
194 end
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
195 log("debug", "Received %d bytes from socket: %s", #line, line);
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
196
1200
34216cdffda6 mod_auth_imap: unfortunately large commit which adds support for SSL (including cert verification), appending the realm to usernames, and various IMAP protocol fixes
Matthew Wild <mwild1@gmail.com>
parents: 1199
diff changeset
197 while line and line:match("^%* ") do
5013
a106477f1a65 mod_auth_imap: Remove unused variable [luacheck]
Kim Alvefur <zash@zash.se>
parents: 3763
diff changeset
198 line = self.conn:receive("*l");
1200
34216cdffda6 mod_auth_imap: unfortunately large commit which adds support for SSL (including cert verification), appending the realm to usernames, and various IMAP protocol fixes
Matthew Wild <mwild1@gmail.com>
parents: 1199
diff changeset
199 end
34216cdffda6 mod_auth_imap: unfortunately large commit which adds support for SSL (including cert verification), appending the realm to usernames, and various IMAP protocol fixes
Matthew Wild <mwild1@gmail.com>
parents: 1199
diff changeset
200
1196
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
201 if line:match("^%+") and #line > 2 then
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
202 local data = line:sub(3);
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
203 data = data and unb64(data);
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
204 return "challenge", unb64(data);
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
205 elseif line:sub(1, #self.tag) == self.tag then
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
206 local ok, rest = line:sub(#self.tag+1):match("(%w+)%s+(.*)");
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
207 ok = ok:lower();
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
208 log("debug", "%s: %s", ok, rest);
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
209 if ok == "ok" then
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
210 return "success"
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
211 elseif ok == "no" then
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
212 return "failure", "not-authorized", rest;
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
213 end
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
214 elseif line:match("^%* BYE") then
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
215 local err = line:match("BYE%s*(.*)");
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
216 return "failure", "not-authorized", err;
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
217 end
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
218 end
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
219
f45ca6edc159 mod_auth_imap: Authentication module that works by passing through SASL to a IMAP connection
Kim Alvefur <zash@zash.se>
parents:
diff changeset
220 return _M;