Comparison

util/sasl/scram.lua @ 5776:bd0ff8ae98a8

Remove all trailing whitespace
author Florian Zeitz <florob@babelmonkeys.de>
date Fri, 09 Aug 2013 17:48:21 +0200
parent 5538:62089c9c142d
child 5843:fb6573e191cf
comparison
equal deleted inserted replaced
5775:a6c2b8933507 5776:bd0ff8ae98a8
71 for eq in username:gmatch("=(.?.?)") do 71 for eq in username:gmatch("=(.?.?)") do
72 if eq ~= "2C" and eq ~= "3D" then 72 if eq ~= "2C" and eq ~= "3D" then
73 return false 73 return false
74 end 74 end
75 end 75 end
76 76
77 -- replace =2C with , and =3D with = 77 -- replace =2C with , and =3D with =
78 username = username:gsub("=2C", ","); 78 username = username:gsub("=2C", ",");
79 username = username:gsub("=3D", "="); 79 username = username:gsub("=3D", "=");
80 80
81 -- apply SASLprep 81 -- apply SASLprep
82 username = saslprep(username); 82 username = saslprep(username);
83 83
84 if username and _nodeprep ~= false then 84 if username and _nodeprep ~= false then
85 username = (_nodeprep or nodeprep)(username); 85 username = (_nodeprep or nodeprep)(username);
106 end 106 end
107 107
108 local function scram_gen(hash_name, H_f, HMAC_f) 108 local function scram_gen(hash_name, H_f, HMAC_f)
109 local function scram_hash(self, message) 109 local function scram_hash(self, message)
110 if not self.state then self["state"] = {} end 110 if not self.state then self["state"] = {} end
111 111
112 if type(message) ~= "string" or #message == 0 then return "failure", "malformed-request" end 112 if type(message) ~= "string" or #message == 0 then return "failure", "malformed-request" end
113 if not self.state.name then 113 if not self.state.name then
114 -- we are processing client_first_message 114 -- we are processing client_first_message
115 local client_first_message = message; 115 local client_first_message = message;
116 116
117 -- TODO: fail if authzid is provided, since we don't support them yet 117 -- TODO: fail if authzid is provided, since we don't support them yet
118 self.state["client_first_message"] = client_first_message; 118 self.state["client_first_message"] = client_first_message;
119 self.state["gs2_cbind_flag"], self.state["authzid"], self.state["name"], self.state["clientnonce"] 119 self.state["gs2_cbind_flag"], self.state["authzid"], self.state["name"], self.state["clientnonce"]
120 = client_first_message:match("^(%a),(.*),n=(.*),r=([^,]*).*"); 120 = client_first_message:match("^(%a),(.*),n=(.*),r=([^,]*).*");
121 121
125 end 125 end
126 126
127 if not self.state.name or not self.state.clientnonce then 127 if not self.state.name or not self.state.clientnonce then
128 return "failure", "malformed-request", "Channel binding isn't support at this time."; 128 return "failure", "malformed-request", "Channel binding isn't support at this time.";
129 end 129 end
130 130
131 self.state.name = validate_username(self.state.name, self.profile.nodeprep); 131 self.state.name = validate_username(self.state.name, self.profile.nodeprep);
132 if not self.state.name then 132 if not self.state.name then
133 log("debug", "Username violates either SASLprep or contains forbidden character sequences.") 133 log("debug", "Username violates either SASLprep or contains forbidden character sequences.")
134 return "failure", "malformed-request", "Invalid username."; 134 return "failure", "malformed-request", "Invalid username.";
135 end 135 end
136 136
137 self.state["servernonce"] = generate_uuid(); 137 self.state["servernonce"] = generate_uuid();
138 138
139 -- retreive credentials 139 -- retreive credentials
140 if self.profile.plain then 140 if self.profile.plain then
141 local password, state = self.profile.plain(self, self.state.name, self.realm) 141 local password, state = self.profile.plain(self, self.state.name, self.realm)
142 if state == nil then return "failure", "not-authorized" 142 if state == nil then return "failure", "not-authorized"
143 elseif state == false then return "failure", "account-disabled" end 143 elseif state == false then return "failure", "account-disabled" end
144 144
145 password = saslprep(password); 145 password = saslprep(password);
146 if not password then 146 if not password then
147 log("debug", "Password violates SASLprep."); 147 log("debug", "Password violates SASLprep.");
148 return "failure", "not-authorized", "Invalid password." 148 return "failure", "not-authorized", "Invalid password."
149 end 149 end
159 end 159 end
160 elseif self.profile["scram_"..hashprep(hash_name)] then 160 elseif self.profile["scram_"..hashprep(hash_name)] then
161 local stored_key, server_key, iteration_count, salt, state = self.profile["scram_"..hashprep(hash_name)](self, self.state.name, self.realm); 161 local stored_key, server_key, iteration_count, salt, state = self.profile["scram_"..hashprep(hash_name)](self, self.state.name, self.realm);
162 if state == nil then return "failure", "not-authorized" 162 if state == nil then return "failure", "not-authorized"
163 elseif state == false then return "failure", "account-disabled" end 163 elseif state == false then return "failure", "account-disabled" end
164 164
165 self.state.stored_key = stored_key; 165 self.state.stored_key = stored_key;
166 self.state.server_key = server_key; 166 self.state.server_key = server_key;
167 self.state.iteration_count = iteration_count; 167 self.state.iteration_count = iteration_count;
168 self.state.salt = salt 168 self.state.salt = salt
169 end 169 end
170 170
171 local server_first_message = "r="..self.state.clientnonce..self.state.servernonce..",s="..base64.encode(self.state.salt)..",i="..self.state.iteration_count; 171 local server_first_message = "r="..self.state.clientnonce..self.state.servernonce..",s="..base64.encode(self.state.salt)..",i="..self.state.iteration_count;
172 self.state["server_first_message"] = server_first_message; 172 self.state["server_first_message"] = server_first_message;
173 return "challenge", server_first_message 173 return "challenge", server_first_message
174 else 174 else
175 -- we are processing client_final_message 175 -- we are processing client_final_message
176 local client_final_message = message; 176 local client_final_message = message;
177 177
178 self.state["channelbinding"], self.state["nonce"], self.state["proof"] = client_final_message:match("^c=(.*),r=(.*),.*p=(.*)"); 178 self.state["channelbinding"], self.state["nonce"], self.state["proof"] = client_final_message:match("^c=(.*),r=(.*),.*p=(.*)");
179 179
180 if not self.state.proof or not self.state.nonce or not self.state.channelbinding then 180 if not self.state.proof or not self.state.nonce or not self.state.channelbinding then
181 return "failure", "malformed-request", "Missing an attribute(p, r or c) in SASL message."; 181 return "failure", "malformed-request", "Missing an attribute(p, r or c) in SASL message.";
182 end 182 end
183 183
184 if self.state.nonce ~= self.state.clientnonce..self.state.servernonce then 184 if self.state.nonce ~= self.state.clientnonce..self.state.servernonce then
185 return "failure", "malformed-request", "Wrong nonce in client-final-message."; 185 return "failure", "malformed-request", "Wrong nonce in client-final-message.";
186 end 186 end
187 187
188 local ServerKey = self.state.server_key; 188 local ServerKey = self.state.server_key;
189 local StoredKey = self.state.stored_key; 189 local StoredKey = self.state.stored_key;
190 190
191 local AuthMessage = "n=" .. s_match(self.state.client_first_message,"n=(.+)") .. "," .. self.state.server_first_message .. "," .. s_match(client_final_message, "(.+),p=.+") 191 local AuthMessage = "n=" .. s_match(self.state.client_first_message,"n=(.+)") .. "," .. self.state.server_first_message .. "," .. s_match(client_final_message, "(.+),p=.+")
192 local ClientSignature = HMAC_f(StoredKey, AuthMessage) 192 local ClientSignature = HMAC_f(StoredKey, AuthMessage)
193 local ClientKey = binaryXOR(ClientSignature, base64.decode(self.state.proof)) 193 local ClientKey = binaryXOR(ClientSignature, base64.decode(self.state.proof))
194 local ServerSignature = HMAC_f(ServerKey, AuthMessage) 194 local ServerSignature = HMAC_f(ServerKey, AuthMessage)
195 195