60 else |
60 else |
61 err = "luasocket was not compiled with UNIX sockets support"; |
61 err = "luasocket was not compiled with UNIX sockets support"; |
62 end |
62 end |
63 |
63 |
64 if not ok then |
64 if not ok then |
65 log("error", "error connecting to dovecot %s socket at '%s'. error was '%s'", socket_type, socket_path or socket_info, err); |
65 return false, "error connecting to dovecot "..tostring(socket_type).." socket at '" |
66 return false; |
66 ..tostring(socket_path or socket_info).."'. error was '"..tostring(err).."'"; |
67 end |
67 end |
68 |
68 |
69 -- Send our handshake |
69 -- Send our handshake |
70 pid = tonumber(tostring(conn):match("0x%x*$")); |
70 pid = tonumber(tostring(conn):match("0x%x*$")); |
71 log("debug", "sending handshake to dovecot. version 1.1, cpid '%d'", pid); |
71 log("debug", "sending handshake to dovecot. version 1.1, cpid '%d'", pid); |
72 if not conn:send("VERSION\t1\t1\n") then |
72 local success,err = conn:send("VERSION\t1\t1\n"); |
73 return false |
73 if not success then |
74 end |
74 return false, "Unable to send version data to socket: "..tostring(err); |
75 if not conn:send("CPID\t" .. pid .. "\n") then |
75 end |
76 return false |
76 local success,err = conn:send("CPID\t" .. pid .. "\n"); |
|
77 if not success then |
|
78 return false, "Unable to send PID to socket: "..tostring(err); |
77 end |
79 end |
78 |
80 |
79 -- Parse Dovecot's handshake |
81 -- Parse Dovecot's handshake |
80 local done = false; |
82 local done = false; |
81 supported_mechs = {}; |
83 supported_mechs = {}; |
82 while (not done) do |
84 while (not done) do |
83 local line = conn:receive(); |
85 local line, err = conn:receive(); |
84 if not line then |
86 if not line then |
85 return false; |
87 return false, "No data read from socket: "..tostring(err); |
86 end |
88 end |
87 |
89 |
88 --log("debug", "dovecot handshake: '%s'", line); |
90 --log("debug", "dovecot handshake: '%s'", line); |
89 local parts = line:gmatch("[^\t]+"); |
91 local parts = line:gmatch("[^\t]+"); |
90 local first = parts(); |
92 local first = parts(); |
91 if first == "VERSION" then |
93 if first == "VERSION" then |
92 -- Version should be 1.1 |
94 -- Version should be 1.1 |
93 local major_version = parts(); |
95 local major_version = parts(); |
94 |
96 |
95 if major_version ~= "1" then |
97 if major_version ~= "1" then |
96 log("error", "dovecot server version is not 1.x. it is %s.x", major_version); |
|
97 conn:close(); |
98 conn:close(); |
98 return false; |
99 return false, "dovecot server version is not 1.x. it is "..tostring(major_version)..".x"; |
99 end |
100 end |
100 elseif first == "MECH" then |
101 elseif first == "MECH" then |
101 local mech = parts(); |
102 local mech = parts(); |
102 supported_mechs[mech] = true; |
103 supported_mechs[mech] = true; |
103 elseif first == "DONE" then |
104 elseif first == "DONE" then |
116 sasl_i.request_id = request_id; |
117 sasl_i.request_id = request_id; |
117 local conn, mechs = conn, supported_mechs; |
118 local conn, mechs = conn, supported_mechs; |
118 if not conn then |
119 if not conn then |
119 conn, mechs = connect(socket_info); |
120 conn, mechs = connect(socket_info); |
120 if not conn then |
121 if not conn then |
121 return nil, "Socket connection failure"; |
122 return nil, "Dovecot connection failure: "..tostring(mechs); |
122 end |
123 end |
123 end |
124 end |
124 sasl_i.conn, sasl_i.mechs = conn, mechs; |
125 sasl_i.conn, sasl_i.mechs = conn, mechs; |
125 return setmetatable(sasl_i, method); |
126 return setmetatable(sasl_i, method); |
126 end |
127 end |