Software /
code /
prosody
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 |