Software /
code /
verse
Comparison
util/sasl/scram.lua @ 453:e60c776b7760
util.sasl.scram: Refactor channel binding
This will ease support for new channel binding methods.
author | Kim Alvefur <zash@zash.se> |
---|---|
date | Wed, 03 Aug 2022 03:04:17 +0200 |
parent | 407:c99db5172309 |
child | 454:9f27a2075e9e |
comparison
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 |