# HG changeset patch # User Kim Alvefur # Date 1379816967 -7200 # Node ID 4f545674b0bcd1e806a21bb87953a98e8a3833bc # Parent fb6573e191cf7e41fab48f68ad80c828863b8179 util.sasl.scram: Simplify validation of client-first-message diff -r fb6573e191cf -r 4f545674b0bc util/sasl/scram.lua --- a/util/sasl/scram.lua Sun Sep 22 00:44:20 2013 +0200 +++ b/util/sasl/scram.lua Sun Sep 22 04:29:27 2013 +0200 @@ -13,7 +13,6 @@ local s_match = string.match; local type = type -local string = string local tostring = tostring; local base64 = require "util.encodings".base64; local hmac_sha1 = require "util.hashes".hmac_sha1; @@ -124,28 +123,33 @@ -- TODO: fail if authzid is provided, since we don't support them yet self.state["client_first_message"] = client_first_message; self.state["gs2_cbind_flag"], self.state["gs2_cbind_name"], self.state["authzid"], self.state["name"], self.state["clientnonce"] - = client_first_message:match("^(%a)=?([%a%-]*),(.*),n=(.*),r=([^,]*).*"); + = client_first_message:match("^([ynp])=?([%a%-]*),(.*),n=(.*),r=([^,]*).*"); - -- check for invalid gs2_flag_type start - local gs2_flag_type = string.sub(self.state.gs2_cbind_flag, 0, 1) - if gs2_flag_type ~= "y" and gs2_flag_type ~= "n" and gs2_flag_type ~= "p" then - return "failure", "malformed-request", "The GS2 header has to start with 'y', 'n', or 'p'." + local gs2_cbind_flag = self.state.gs2_cbind_flag; + + if not gs2_cbind_flag then + return "failure", "malformed-request"; end - if support_channel_binding then - if string.sub(self.state.gs2_cbind_flag, 0, 1) == "y" then + if support_channel_binding and gs2_cbind_flag == "y" then + -- "y" -> client does support channel binding + -- but thinks the server does not. return "failure", "malformed-request"; end - + + if gs2_cbind_flag == "n" then + -- "n" -> client doesn't support channel binding. + support_channel_binding = false; + end + + if support_channel_binding and gs2_cbind_flag == "p" then -- check whether we support the proposed channel binding type if not self.profile.cb[self.state.gs2_cbind_name] then return "failure", "malformed-request", "Proposed channel binding type isn't supported."; end else - -- we don't support channelbinding, - if self.state.gs2_cbind_flag ~= "n" and self.state.gs2_cbind_flag ~= "y" then - return "failure", "malformed-request"; - end + -- no channel binding, + self.state.gs2_cbind_name = nil; end if not self.state.name or not self.state.clientnonce then @@ -242,7 +246,7 @@ function init(registerMechanism) local function registerSCRAMMechanism(hash_name, hash, hmac_hash) registerMechanism("SCRAM-"..hash_name, {"plain", "scram_"..(hashprep(hash_name))}, scram_gen(hash_name:lower(), hash, hmac_hash)); - + -- register channel binding equivalent registerMechanism("SCRAM-"..hash_name.."-PLUS", {"plain", "scram_"..(hashprep(hash_name))}, scram_gen(hash_name:lower(), hash, hmac_hash), {"tls-unique"}); end