Mercurial > prosody-modules
comparison mod_auth_dovecot/mod_auth_dovecot.lua @ 269:74846ec9c29f
mod_auth_dovecot: Close socket on error
author | Javier Torres <javitonino@gmail.com> |
---|---|
date | Sat, 30 Oct 2010 23:38:52 +0200 |
parents | cfcd4efb0fa4 |
children | 853ae6ae87bf |
comparison
equal
deleted
inserted
replaced
268:cfcd4efb0fa4 | 269:74846ec9c29f |
---|---|
17 | 17 |
18 function new_default_provider(host) | 18 function new_default_provider(host) |
19 local provider = { name = "dovecot", c = nil }; | 19 local provider = { name = "dovecot", c = nil }; |
20 log("debug", "initializing dovecot authentication provider for host '%s'", host); | 20 log("debug", "initializing dovecot authentication provider for host '%s'", host); |
21 | 21 |
22 -- Closes the socket | |
23 function provider.close(self) | |
24 if (provider.c ~= nil) then | |
25 provider.c:close(); | |
26 end | |
27 provider.c = nil; | |
28 end | |
29 | |
22 -- The following connects to a new socket and send the handshake | 30 -- The following connects to a new socket and send the handshake |
23 function provider.connect(self) | 31 function provider.connect(self) |
24 -- Destroy old socket | 32 -- Destroy old socket |
25 if (provider.c ~= nil) then | 33 provider:close(); |
26 provider.c:close(); | |
27 end | |
28 | 34 |
29 provider.c = socket.unix(); | 35 provider.c = socket.unix(); |
30 | 36 |
31 -- Create a connection to dovecot socket | 37 -- Create a connection to dovecot socket |
32 local socket = "/var/run/dovecot/auth-login"; | 38 local socket = "/var/run/dovecot/auth-login"; |
33 local r, e = provider.c:connect(socket); | 39 local r, e = provider.c:connect(socket); |
34 if (not r) then | 40 if (not r) then |
35 log("warn", "error connecting to dovecot socket at '%s'. error was '%s'. check permissions", socket, e); | 41 log("warn", "error connecting to dovecot socket at '%s'. error was '%s'. check permissions", socket, e); |
42 provider:close(); | |
36 return false; | 43 return false; |
37 end | 44 end |
38 | 45 |
39 -- Send our handshake | 46 -- Send our handshake |
40 local pid = pposix.getpid(); | 47 local pid = pposix.getpid(); |
60 local v1 = parts(); | 67 local v1 = parts(); |
61 local v2 = parts(); | 68 local v2 = parts(); |
62 | 69 |
63 if (not (v1 == "1" and v2 == "1")) then | 70 if (not (v1 == "1" and v2 == "1")) then |
64 log("warn", "server version is not 1.1. it is %s.%s", v1, v2); | 71 log("warn", "server version is not 1.1. it is %s.%s", v1, v2); |
72 provider:close(); | |
65 return false; | 73 return false; |
66 end | 74 end |
67 elseif (first == "MECH") then | 75 elseif (first == "MECH") then |
68 -- Mechanisms should include PLAIN | 76 -- Mechanisms should include PLAIN |
69 local ok = false; | 77 local ok = false; |
72 ok = true; | 80 ok = true; |
73 end | 81 end |
74 end | 82 end |
75 if (not ok) then | 83 if (not ok) then |
76 log("warn", "server doesn't support PLAIN mechanism. It supports '%s'", l); | 84 log("warn", "server doesn't support PLAIN mechanism. It supports '%s'", l); |
85 provider:close(); | |
77 return false; | 86 return false; |
78 end | 87 end |
79 elseif (first == "DONE") then | 88 elseif (first == "DONE") then |
80 done = true; | 89 done = true; |
81 end | 90 end |
82 end | 91 end |
83 return true; | 92 return true; |
84 end | 93 end |
85 | 94 |
95 -- Wrapper for send(). Handles errors | |
86 function provider.send(self, data) | 96 function provider.send(self, data) |
87 local r, e = provider.c:send(data); | 97 local r, e = provider.c:send(data); |
88 if (not r) then | 98 if (not r) then |
89 log("warn", "error sending '%s' to dovecot. error was '%s'", data, e); | 99 log("warn", "error sending '%s' to dovecot. error was '%s'", data, e); |
100 provider:close(); | |
90 return false; | 101 return false; |
91 end | 102 end |
92 return true; | 103 return true; |
93 end | 104 end |
94 | 105 |
106 -- Wrapper for receive(). Handles errors | |
95 function provider.receive(self) | 107 function provider.receive(self) |
96 local r, e = provider.c:receive(); | 108 local r, e = provider.c:receive(); |
97 if (not r) then | 109 if (not r) then |
98 log("warn", "error receiving data from dovecot. error was '%s'", socket, e); | 110 log("warn", "error receiving data from dovecot. error was '%s'", socket, e); |
111 provider:close(); | |
99 return false; | 112 return false; |
100 end | 113 end |
101 return r; | 114 return r; |
102 end | 115 end |
103 | 116 |
104 function provider.test_password(username, password) | 117 function provider.test_password(username, password) |
105 log("debug", "test password '%s' for user %s at host %s", password, username, module.host); | 118 log("debug", "test password '%s' for user %s at host %s", password, username, module.host); |
106 | 119 |
107 if (not provider:connect()) then | 120 local tries = 0; |
108 return nil, "Auth failed. Dovecot communications error"; | 121 |
122 if (provider.c == nil or tries > 0) then | |
123 if (not provider:connect()) then | |
124 return nil, "Auth failed. Dovecot communications error"; | |
125 end | |
109 end | 126 end |
110 | 127 |
111 -- Send auth data | 128 -- Send auth data |
112 username = username .. "@" .. module.host; -- FIXME: this is actually a hack for my server | 129 username = username .. "@" .. module.host; -- FIXME: this is actually a hack for my server |
113 local b64 = base64.encode(username .. "\0" .. username .. "\0" .. password); | 130 local b64 = base64.encode(username .. "\0" .. username .. "\0" .. password); |
128 return true; | 145 return true; |
129 else | 146 else |
130 return nil, "Auth failed. Invalid username or password."; | 147 return nil, "Auth failed. Invalid username or password."; |
131 end | 148 end |
132 end | 149 end |
133 | 150 |
134 function provider.get_password(username) | 151 function provider.get_password(username) |
135 return nil, "Cannot get_password in dovecot backend."; | 152 return nil, "Cannot get_password in dovecot backend."; |
136 end | 153 end |
137 | 154 |
138 function provider.set_password(username, password) | 155 function provider.set_password(username, password) |
139 return nil, "Cannot set_password in dovecot backend."; | 156 return nil, "Cannot set_password in dovecot backend."; |
140 end | 157 end |
141 | 158 |
142 function provider.user_exists(username) | 159 function provider.user_exists(username) |
143 --TODO: Send an auth request. If it returns FAIL <id> user=<user> then user exists. | 160 --TODO: Send an auth request. If it returns FAIL <id> user=<user> then user exists. |
144 return nil, "user_exists not yet implemented in dovecot backend."; | 161 return nil, "user_exists not yet implemented in dovecot backend."; |
145 end | 162 end |
146 | 163 |
147 function provider.create_user(username, password) | 164 function provider.create_user(username, password) |
148 return nil, "Cannot create_user in dovecot backend."; | 165 return nil, "Cannot create_user in dovecot backend."; |
149 end | 166 end |
150 | 167 |
151 function provider.get_sasl_handler() | 168 function provider.get_sasl_handler() |
152 local realm = module:get_option("sasl_realm") or module.host; | 169 local realm = module:get_option("sasl_realm") or module.host; |
153 local getpass_authentication_profile = { | 170 local getpass_authentication_profile = { |
154 plain_test = function(username, password, realm) | 171 plain_test = function(username, password, realm) |
155 local prepped_username = nodeprep(username); | 172 local prepped_username = nodeprep(username); |
157 log("debug", "NODEprep failed on username: %s", username); | 174 log("debug", "NODEprep failed on username: %s", username); |
158 return "", nil; | 175 return "", nil; |
159 end | 176 end |
160 return usermanager.test_password(prepped_username, realm, password), true; | 177 return usermanager.test_password(prepped_username, realm, password), true; |
161 end | 178 end |
162 }; | 179 }; |
163 return new_sasl(realm, getpass_authentication_profile); | 180 return new_sasl(realm, getpass_authentication_profile); |
164 end | 181 end |
165 | 182 |
166 return provider; | 183 return provider; |
167 end | 184 end |
168 | 185 |
169 module:add_item("auth-provider", new_default_provider(module.host)); | 186 module:add_item("auth-provider", new_default_provider(module.host)); |
170 |