util/sasl/scram.lua

changeset 453
e60c776b7760
parent 407
c99db5172309
child 454
9f27a2075e9e
equal deleted inserted replaced
452:628896d39d8e 453:e60c776b7760
33 33
34 local function value_safe(str) 34 local function value_safe(str)
35 return (gsub(str, "[,=]", { [","] = "=2C", ["="] = "=3D" })); 35 return (gsub(str, "[,=]", { [","] = "=2C", ["="] = "=3D" }));
36 end 36 end
37 37
38 local function cb(conn)
39 if conn:ssl() then
40 if sock.getfinished then
41 return "p=tls-unique", sock:getfinished();
42 end
43 end
44 end
45
38 local function scram(stream, name) 46 local function scram(stream, name)
39 local username = "n=" .. value_safe(stream.username); 47 local username = "n=" .. value_safe(stream.username);
40 local c_nonce = base64(random.bytes(15)); 48 local c_nonce = base64(random.bytes(15));
41 local our_nonce = "r=" .. c_nonce; 49 local our_nonce = "r=" .. c_nonce;
42 local client_first_message_bare = username .. "," .. our_nonce; 50 local client_first_message_bare = username .. "," .. our_nonce;
43 local cbind_data = ""; 51 local cbind_data = "";
44 local gs2_cbind_flag = stream.conn:ssl() and "y" or "n"; 52 local gs2_cbind_flag = "n";
45 if name == "SCRAM-SHA-1-PLUS" then 53 if name == "SCRAM-SHA-1-PLUS" then
46 cbind_data = stream.conn:socket():getfinished(); 54 gs2_cbind_flag, cbind_data = cb(stream.conn);
47 gs2_cbind_flag = "p=tls-unique"; 55 elseif cb(stream.conn) then
56 gs2_cbind_flag = "y";
48 end 57 end
49 local gs2_header = gs2_cbind_flag .. ",,"; 58 local gs2_header = gs2_cbind_flag .. ",,";
50 local client_first_message = gs2_header .. client_first_message_bare; 59 local client_first_message = gs2_header .. client_first_message_bare;
51 local cont, server_first_message = coroutine.yield(client_first_message); 60 local cont, server_first_message = coroutine.yield(client_first_message);
52 if cont ~= "challenge" then return false end 61 if cont ~= "challenge" then return false end
105 return function (stream, name) 114 return function (stream, name)
106 if stream.username and (stream.password or (stream.client_key or stream.server_key)) then 115 if stream.username and (stream.password or (stream.client_key or stream.server_key)) then
107 if name == "SCRAM-SHA-1" then 116 if name == "SCRAM-SHA-1" then
108 return scram, 99; 117 return scram, 99;
109 elseif name == "SCRAM-SHA-1-PLUS" then 118 elseif name == "SCRAM-SHA-1-PLUS" then
110 local sock = stream.conn:ssl() and stream.conn:socket(); 119 if cb(stream.conn) then
111 if sock and sock.getfinished then
112 return scram, 100; 120 return scram, 100;
113 end 121 end
114 end 122 end
115 end 123 end
116 end 124 end

mercurial