Software /
code /
prosody
Comparison
util/sasl/scram.lua @ 2199:08a6b91bfe7b
SASLprep usernames and passwords.
author | Tobias Markmann <tm@ayena.de> |
---|---|
date | Wed, 18 Nov 2009 11:59:50 +0100 |
parent | 2198:d18b4d22b8da |
child | 2205:e091b308732f |
comparison
equal
deleted
inserted
replaced
2198:d18b4d22b8da | 2199:08a6b91bfe7b |
---|---|
17 local base64 = require "util.encodings".base64; | 17 local base64 = require "util.encodings".base64; |
18 local xor = require "bit".bxor | 18 local xor = require "bit".bxor |
19 local hmac_sha1 = require "util.hmac".sha1; | 19 local hmac_sha1 = require "util.hmac".sha1; |
20 local sha1 = require "util.hashes".sha1; | 20 local sha1 = require "util.hashes".sha1; |
21 local generate_uuid = require "util.uuid".generate; | 21 local generate_uuid = require "util.uuid".generate; |
22 local saslprep = require "util.encodings".stringprep.saslprep; | |
23 local log = require "util.logger".init("sasl"); | |
22 | 24 |
23 module "plain" | 25 module "plain" |
24 | 26 |
25 --========================= | 27 --========================= |
26 --SASL SCRAM-SHA-1 according to draft-ietf-sasl-scram-10 | 28 --SASL SCRAM-SHA-1 according to draft-ietf-sasl-scram-10 |
68 end | 70 end |
69 | 71 |
70 -- replace =2D with , and =3D with = | 72 -- replace =2D with , and =3D with = |
71 | 73 |
72 -- apply SASLprep | 74 -- apply SASLprep |
75 username = saslprep(username); | |
73 return username; | 76 return username; |
74 end | 77 end |
75 | 78 |
76 local function scram_sha_1(self, message) | 79 local function scram_sha_1(self, message) |
77 if not self.state then self["state"] = {} end | 80 if not self.state then self["state"] = {} end |
81 local client_first_message = message; | 84 local client_first_message = message; |
82 self.state["client_first_message"] = client_first_message; | 85 self.state["client_first_message"] = client_first_message; |
83 self.state["name"] = client_first_message:match("n=(.+),r=") | 86 self.state["name"] = client_first_message:match("n=(.+),r=") |
84 self.state["clientnonce"] = client_first_message:match("r=([^,]+)") | 87 self.state["clientnonce"] = client_first_message:match("r=([^,]+)") |
85 | 88 |
86 self.state.name = validate_username(self.state.name); | |
87 if not self.state.name or not self.state.clientnonce then | 89 if not self.state.name or not self.state.clientnonce then |
88 return "failure", "malformed-request"; | 90 return "failure", "malformed-request"; |
89 end | 91 end |
92 | |
93 self.state.name = validate_username(self.state.name); | |
94 if not self.state.name then | |
95 log("debug", "Username violates either SASLprep or contains forbidden character sequences.") | |
96 return "failure", "malformed-request"; | |
97 end | |
98 | |
90 self.state["servernonce"] = generate_uuid(); | 99 self.state["servernonce"] = generate_uuid(); |
91 self.state["salt"] = generate_uuid(); | 100 self.state["salt"] = generate_uuid(); |
92 | 101 |
93 local server_first_message = "r="..self.state.clientnonce..self.state.servernonce..",s="..base64.encode(self.state.salt)..",i="..default_i; | 102 local server_first_message = "r="..self.state.clientnonce..self.state.servernonce..",s="..base64.encode(self.state.salt)..",i="..default_i; |
94 self.state["server_first_message"] = server_first_message; | 103 self.state["server_first_message"] = server_first_message; |
108 local password; | 117 local password; |
109 if self.profile.plain then | 118 if self.profile.plain then |
110 password, state = self.profile.plain(self.state.name, self.realm) | 119 password, state = self.profile.plain(self.state.name, self.realm) |
111 if state == nil then return "failure", "not-authorized" | 120 if state == nil then return "failure", "not-authorized" |
112 elseif state == false then return "failure", "account-disabled" end | 121 elseif state == false then return "failure", "account-disabled" end |
122 password = saslprep(password); | |
123 if not password then | |
124 log("debug", "Password violates SASLprep."); | |
125 return "failure", "not-authorized" | |
126 end | |
113 end | 127 end |
114 | 128 |
115 local SaltedPassword = Hi(hmac_sha1, password, self.state.salt, default_i) | 129 local SaltedPassword = Hi(hmac_sha1, password, self.state.salt, default_i) |
116 local ClientKey = hmac_sha1(SaltedPassword, "Client Key") | 130 local ClientKey = hmac_sha1(SaltedPassword, "Client Key") |
117 local ServerKey = hmac_sha1(SaltedPassword, "Server Key") | 131 local ServerKey = hmac_sha1(SaltedPassword, "Server Key") |