Sat, 13 Nov 2010 04:12:40 +0000
Backed out changeset bfc47564aaef (No need for _M with module.environment)
2182
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
1 | -- sasl.lua v0.4 |
3094
5f625411b463
util.sasl: 2009 -> 2010 in copyright header.
Tobias Markmann <tm@ayena.de>
parents:
3092
diff
changeset
|
2 | -- Copyright (C) 2008-2010 Tobias Markmann |
2182
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
3 | -- |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
4 | -- All rights reserved. |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
5 | -- |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
6 | -- Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
7 | -- |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
8 | -- * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
9 | -- * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
10 | -- * Neither the name of Tobias Markmann nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
11 | -- |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
12 | -- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
13 | |
2184
1fd38975addd
Add support for plain profile in digest-md5 implementation.
Tobias Markmann <tm@ayena.de>
parents:
2182
diff
changeset
|
14 | local tostring = tostring; |
1fd38975addd
Add support for plain profile in digest-md5 implementation.
Tobias Markmann <tm@ayena.de>
parents:
2182
diff
changeset
|
15 | local type = type; |
1fd38975addd
Add support for plain profile in digest-md5 implementation.
Tobias Markmann <tm@ayena.de>
parents:
2182
diff
changeset
|
16 | |
1fd38975addd
Add support for plain profile in digest-md5 implementation.
Tobias Markmann <tm@ayena.de>
parents:
2182
diff
changeset
|
17 | local s_gmatch = string.gmatch; |
1fd38975addd
Add support for plain profile in digest-md5 implementation.
Tobias Markmann <tm@ayena.de>
parents:
2182
diff
changeset
|
18 | local s_match = string.match; |
1fd38975addd
Add support for plain profile in digest-md5 implementation.
Tobias Markmann <tm@ayena.de>
parents:
2182
diff
changeset
|
19 | local t_concat = table.concat; |
1fd38975addd
Add support for plain profile in digest-md5 implementation.
Tobias Markmann <tm@ayena.de>
parents:
2182
diff
changeset
|
20 | local t_insert = table.insert; |
1fd38975addd
Add support for plain profile in digest-md5 implementation.
Tobias Markmann <tm@ayena.de>
parents:
2182
diff
changeset
|
21 | local to_byte, to_char = string.byte, string.char; |
1fd38975addd
Add support for plain profile in digest-md5 implementation.
Tobias Markmann <tm@ayena.de>
parents:
2182
diff
changeset
|
22 | |
1fd38975addd
Add support for plain profile in digest-md5 implementation.
Tobias Markmann <tm@ayena.de>
parents:
2182
diff
changeset
|
23 | local md5 = require "util.hashes".md5; |
1fd38975addd
Add support for plain profile in digest-md5 implementation.
Tobias Markmann <tm@ayena.de>
parents:
2182
diff
changeset
|
24 | local log = require "util.logger".init("sasl"); |
1fd38975addd
Add support for plain profile in digest-md5 implementation.
Tobias Markmann <tm@ayena.de>
parents:
2182
diff
changeset
|
25 | local generate_uuid = require "util.uuid".generate; |
1fd38975addd
Add support for plain profile in digest-md5 implementation.
Tobias Markmann <tm@ayena.de>
parents:
2182
diff
changeset
|
26 | |
2202 | 27 | module "digest-md5" |
2182
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
28 | |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
29 | --========================= |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
30 | --SASL DIGEST-MD5 according to RFC 2831 |
2184
1fd38975addd
Add support for plain profile in digest-md5 implementation.
Tobias Markmann <tm@ayena.de>
parents:
2182
diff
changeset
|
31 | |
3092
d32935878661
util.sasl: Moving SASL authentication backends documentation to the mechanism files.
Tobias Markmann <tm@ayena.de>
parents:
2936
diff
changeset
|
32 | --[[ |
d32935878661
util.sasl: Moving SASL authentication backends documentation to the mechanism files.
Tobias Markmann <tm@ayena.de>
parents:
2936
diff
changeset
|
33 | Supported Authentication Backends |
d32935878661
util.sasl: Moving SASL authentication backends documentation to the mechanism files.
Tobias Markmann <tm@ayena.de>
parents:
2936
diff
changeset
|
34 | |
3122
579f17b9f948
util.sasl.*: Adjusting authentication provider names. All '-' replaced with '_'
Tobias Markmann <tm@ayena.de>
parents:
3094
diff
changeset
|
35 | digest_md5: |
3092
d32935878661
util.sasl: Moving SASL authentication backends documentation to the mechanism files.
Tobias Markmann <tm@ayena.de>
parents:
2936
diff
changeset
|
36 | function(username, domain, realm, encoding) -- domain and realm are usually the same; for some broken |
d32935878661
util.sasl: Moving SASL authentication backends documentation to the mechanism files.
Tobias Markmann <tm@ayena.de>
parents:
2936
diff
changeset
|
37 | -- implementations it's not |
d32935878661
util.sasl: Moving SASL authentication backends documentation to the mechanism files.
Tobias Markmann <tm@ayena.de>
parents:
2936
diff
changeset
|
38 | return digesthash, state; |
d32935878661
util.sasl: Moving SASL authentication backends documentation to the mechanism files.
Tobias Markmann <tm@ayena.de>
parents:
2936
diff
changeset
|
39 | end |
d32935878661
util.sasl: Moving SASL authentication backends documentation to the mechanism files.
Tobias Markmann <tm@ayena.de>
parents:
2936
diff
changeset
|
40 | |
3122
579f17b9f948
util.sasl.*: Adjusting authentication provider names. All '-' replaced with '_'
Tobias Markmann <tm@ayena.de>
parents:
3094
diff
changeset
|
41 | digest_md5_test: |
3092
d32935878661
util.sasl: Moving SASL authentication backends documentation to the mechanism files.
Tobias Markmann <tm@ayena.de>
parents:
2936
diff
changeset
|
42 | function(username, domain, realm, encoding, digesthash) |
d32935878661
util.sasl: Moving SASL authentication backends documentation to the mechanism files.
Tobias Markmann <tm@ayena.de>
parents:
2936
diff
changeset
|
43 | return true or false, state; |
d32935878661
util.sasl: Moving SASL authentication backends documentation to the mechanism files.
Tobias Markmann <tm@ayena.de>
parents:
2936
diff
changeset
|
44 | end |
d32935878661
util.sasl: Moving SASL authentication backends documentation to the mechanism files.
Tobias Markmann <tm@ayena.de>
parents:
2936
diff
changeset
|
45 | ]] |
d32935878661
util.sasl: Moving SASL authentication backends documentation to the mechanism files.
Tobias Markmann <tm@ayena.de>
parents:
2936
diff
changeset
|
46 | |
2184
1fd38975addd
Add support for plain profile in digest-md5 implementation.
Tobias Markmann <tm@ayena.de>
parents:
2182
diff
changeset
|
47 | local function digest(self, message) |
2182
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
48 | --TODO complete support for authzid |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
49 | |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
50 | local function serialize(message) |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
51 | local data = "" |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
52 | |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
53 | -- testing all possible values |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
54 | if message["realm"] then data = data..[[realm="]]..message.realm..[[",]] end |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
55 | if message["nonce"] then data = data..[[nonce="]]..message.nonce..[[",]] end |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
56 | if message["qop"] then data = data..[[qop="]]..message.qop..[[",]] end |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
57 | if message["charset"] then data = data..[[charset=]]..message.charset.."," end |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
58 | if message["algorithm"] then data = data..[[algorithm=]]..message.algorithm.."," end |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
59 | if message["rspauth"] then data = data..[[rspauth=]]..message.rspauth.."," end |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
60 | data = data:gsub(",$", "") |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
61 | return data |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
62 | end |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
63 | |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
64 | local function utf8tolatin1ifpossible(passwd) |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
65 | local i = 1; |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
66 | while i <= #passwd do |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
67 | local passwd_i = to_byte(passwd:sub(i, i)); |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
68 | if passwd_i > 0x7F then |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
69 | if passwd_i < 0xC0 or passwd_i > 0xC3 then |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
70 | return passwd; |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
71 | end |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
72 | i = i + 1; |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
73 | passwd_i = to_byte(passwd:sub(i, i)); |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
74 | if passwd_i < 0x80 or passwd_i > 0xBF then |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
75 | return passwd; |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
76 | end |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
77 | end |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
78 | i = i + 1; |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
79 | end |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
80 | |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
81 | local p = {}; |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
82 | local j = 0; |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
83 | i = 1; |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
84 | while (i <= #passwd) do |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
85 | local passwd_i = to_byte(passwd:sub(i, i)); |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
86 | if passwd_i > 0x7F then |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
87 | i = i + 1; |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
88 | local passwd_i_1 = to_byte(passwd:sub(i, i)); |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
89 | t_insert(p, to_char(passwd_i%4*64 + passwd_i_1%64)); -- I'm so clever |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
90 | else |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
91 | t_insert(p, to_char(passwd_i)); |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
92 | end |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
93 | i = i + 1; |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
94 | end |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
95 | return t_concat(p); |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
96 | end |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
97 | local function latin1toutf8(str) |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
98 | local p = {}; |
2184
1fd38975addd
Add support for plain profile in digest-md5 implementation.
Tobias Markmann <tm@ayena.de>
parents:
2182
diff
changeset
|
99 | for ch in s_gmatch(str, ".") do |
2182
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
100 | ch = to_byte(ch); |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
101 | if (ch < 0x80) then |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
102 | t_insert(p, to_char(ch)); |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
103 | elseif (ch < 0xC0) then |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
104 | t_insert(p, to_char(0xC2, ch)); |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
105 | else |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
106 | t_insert(p, to_char(0xC3, ch - 64)); |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
107 | end |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
108 | end |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
109 | return t_concat(p); |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
110 | end |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
111 | local function parse(data) |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
112 | local message = {} |
2208 | 113 | -- COMPAT: %z in the pattern to work around jwchat bug (sends "charset=utf-8\0") |
2215
4678aa4567c8
SASL: Using locally mapped s_gmatch instead of unavailable gmatch.
Tobias Markmann <tm@ayena.de>
parents:
2208
diff
changeset
|
114 | for k, v in s_gmatch(data, [[([%w%-]+)="?([^",%z]*)"?,?]]) do -- FIXME The hacky regex makes me shudder |
2182
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
115 | message[k] = v; |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
116 | end |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
117 | return message; |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
118 | end |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
119 | |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
120 | if not self.nonce then |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
121 | self.nonce = generate_uuid(); |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
122 | self.step = 0; |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
123 | self.nonce_count = {}; |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
124 | end |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
125 | |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
126 | self.step = self.step + 1; |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
127 | if (self.step == 1) then |
2184
1fd38975addd
Add support for plain profile in digest-md5 implementation.
Tobias Markmann <tm@ayena.de>
parents:
2182
diff
changeset
|
128 | local challenge = serialize({ nonce = self.nonce, |
2182
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
129 | qop = "auth", |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
130 | charset = "utf-8", |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
131 | algorithm = "md5-sess", |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
132 | realm = self.realm}); |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
133 | return "challenge", challenge; |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
134 | elseif (self.step == 2) then |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
135 | local response = parse(message); |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
136 | -- check for replay attack |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
137 | if response["nc"] then |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
138 | if self.nonce_count[response["nc"]] then return "failure", "not-authorized" end |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
139 | end |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
140 | |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
141 | -- check for username, it's REQUIRED by RFC 2831 |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
142 | if not response["username"] then |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
143 | return "failure", "malformed-request"; |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
144 | end |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
145 | self["username"] = response["username"]; |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
146 | |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
147 | -- check for nonce, ... |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
148 | if not response["nonce"] then |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
149 | return "failure", "malformed-request"; |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
150 | else |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
151 | -- check if it's the right nonce |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
152 | if response["nonce"] ~= tostring(self.nonce) then return "failure", "malformed-request" end |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
153 | end |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
154 | |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
155 | if not response["cnonce"] then return "failure", "malformed-request", "Missing entry for cnonce in SASL message." end |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
156 | if not response["qop"] then response["qop"] = "auth" end |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
157 | |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
158 | if response["realm"] == nil or response["realm"] == "" then |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
159 | response["realm"] = ""; |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
160 | elseif response["realm"] ~= self.realm then |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
161 | return "failure", "not-authorized", "Incorrect realm value"; |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
162 | end |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
163 | |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
164 | local decoder; |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
165 | if response["charset"] == nil then |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
166 | decoder = utf8tolatin1ifpossible; |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
167 | elseif response["charset"] ~= "utf-8" then |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
168 | return "failure", "incorrect-encoding", "The client's response uses "..response["charset"].." for encoding with isn't supported by sasl.lua. Supported encodings are latin or utf-8."; |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
169 | end |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
170 | |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
171 | local domain = ""; |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
172 | local protocol = ""; |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
173 | if response["digest-uri"] then |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
174 | protocol, domain = response["digest-uri"]:match("(%w+)/(.*)$"); |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
175 | if protocol == nil or domain == nil then return "failure", "malformed-request" end |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
176 | else |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
177 | return "failure", "malformed-request", "Missing entry for digest-uri in SASL message." |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
178 | end |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
179 | |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
180 | --TODO maybe realm support |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
181 | self.username = response["username"]; |
2258
e4c5d0d21ac7
util.sasl.digest-md5: Fixing some variable access.
Tobias Markmann <tm@ayena.de>
parents:
2255
diff
changeset
|
182 | local Y, state; |
2184
1fd38975addd
Add support for plain profile in digest-md5 implementation.
Tobias Markmann <tm@ayena.de>
parents:
2182
diff
changeset
|
183 | if self.profile.plain then |
1fd38975addd
Add support for plain profile in digest-md5 implementation.
Tobias Markmann <tm@ayena.de>
parents:
2182
diff
changeset
|
184 | local password, state = self.profile.plain(response["username"], self.realm) |
1fd38975addd
Add support for plain profile in digest-md5 implementation.
Tobias Markmann <tm@ayena.de>
parents:
2182
diff
changeset
|
185 | if state == nil then return "failure", "not-authorized" |
1fd38975addd
Add support for plain profile in digest-md5 implementation.
Tobias Markmann <tm@ayena.de>
parents:
2182
diff
changeset
|
186 | elseif state == false then return "failure", "account-disabled" end |
2185
1182e7ae2964
Broken DIGEST-MD5 client support again.
Tobias Markmann <tm@ayena.de>
parents:
2184
diff
changeset
|
187 | Y = md5(response["username"]..":"..response["realm"]..":"..password); |
2184
1fd38975addd
Add support for plain profile in digest-md5 implementation.
Tobias Markmann <tm@ayena.de>
parents:
2182
diff
changeset
|
188 | elseif self.profile["digest-md5"] then |
2258
e4c5d0d21ac7
util.sasl.digest-md5: Fixing some variable access.
Tobias Markmann <tm@ayena.de>
parents:
2255
diff
changeset
|
189 | Y, state = self.profile["digest-md5"](response["username"], self.realm, response["realm"], response["charset"]) |
2187
e79c0ce6cf54
Adding support for digest-md5 profile in DIGEST-MD5 implementation.
Tobias Markmann <tm@ayena.de>
parents:
2185
diff
changeset
|
190 | if state == nil then return "failure", "not-authorized" |
e79c0ce6cf54
Adding support for digest-md5 profile in DIGEST-MD5 implementation.
Tobias Markmann <tm@ayena.de>
parents:
2185
diff
changeset
|
191 | elseif state == false then return "failure", "account-disabled" end |
2184
1fd38975addd
Add support for plain profile in digest-md5 implementation.
Tobias Markmann <tm@ayena.de>
parents:
2182
diff
changeset
|
192 | elseif self.profile["digest-md5-test"] then |
2185
1182e7ae2964
Broken DIGEST-MD5 client support again.
Tobias Markmann <tm@ayena.de>
parents:
2184
diff
changeset
|
193 | -- TODO |
2184
1fd38975addd
Add support for plain profile in digest-md5 implementation.
Tobias Markmann <tm@ayena.de>
parents:
2182
diff
changeset
|
194 | end |
1fd38975addd
Add support for plain profile in digest-md5 implementation.
Tobias Markmann <tm@ayena.de>
parents:
2182
diff
changeset
|
195 | --local password_encoding, Y = self.credentials_handler("DIGEST-MD5", response["username"], self.realm, response["realm"], decoder); |
1fd38975addd
Add support for plain profile in digest-md5 implementation.
Tobias Markmann <tm@ayena.de>
parents:
2182
diff
changeset
|
196 | --if Y == nil then return "failure", "not-authorized" |
1fd38975addd
Add support for plain profile in digest-md5 implementation.
Tobias Markmann <tm@ayena.de>
parents:
2182
diff
changeset
|
197 | --elseif Y == false then return "failure", "account-disabled" end |
2182
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
198 | local A1 = ""; |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
199 | if response.authzid then |
2189 | 200 | if response.authzid == self.username or response.authzid == self.username.."@"..self.realm then |
2182
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
201 | -- COMPAT |
2189 | 202 | log("warn", "Client is violating RFC 3920 (section 6.1, point 7)."); |
2182
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
203 | A1 = Y..":"..response["nonce"]..":"..response["cnonce"]..":"..response.authzid; |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
204 | else |
2189 | 205 | return "failure", "invalid-authzid"; |
2182
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
206 | end |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
207 | else |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
208 | A1 = Y..":"..response["nonce"]..":"..response["cnonce"]; |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
209 | end |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
210 | local A2 = "AUTHENTICATE:"..protocol.."/"..domain; |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
211 | |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
212 | local HA1 = md5(A1, true); |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
213 | local HA2 = md5(A2, true); |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
214 | |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
215 | local KD = HA1..":"..response["nonce"]..":"..response["nc"]..":"..response["cnonce"]..":"..response["qop"]..":"..HA2; |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
216 | local response_value = md5(KD, true); |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
217 | |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
218 | if response_value == response["response"] then |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
219 | -- calculate rspauth |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
220 | A2 = ":"..protocol.."/"..domain; |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
221 | |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
222 | HA1 = md5(A1, true); |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
223 | HA2 = md5(A2, true); |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
224 | |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
225 | KD = HA1..":"..response["nonce"]..":"..response["nc"]..":"..response["cnonce"]..":"..response["qop"]..":"..HA2 |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
226 | local rspauth = md5(KD, true); |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
227 | self.authenticated = true; |
2568
25e1a544a096
util.sasl.digest-md5: Revert changeset 6094a4e2b6f3 as it breaks some clients, re-visit some time down the line
Matthew Wild <mwild1@gmail.com>
parents:
2207
diff
changeset
|
228 | --TODO: considering sending the rspauth in a success node for saving one roundtrip; allowed according to http://tools.ietf.org/html/draft-saintandre-rfc3920bis-09#section-7.3.6 |
25e1a544a096
util.sasl.digest-md5: Revert changeset 6094a4e2b6f3 as it breaks some clients, re-visit some time down the line
Matthew Wild <mwild1@gmail.com>
parents:
2207
diff
changeset
|
229 | return "challenge", serialize({rspauth = rspauth}); |
2182
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
230 | else |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
231 | return "failure", "not-authorized", "The response provided by the client doesn't match the one we calculated." |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
232 | end |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
233 | elseif self.step == 3 then |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
234 | if self.authenticated ~= nil then return "success" |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
235 | else return "failure", "malformed-request" end |
1112871916eb
Move each mechanism in an own file.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
236 | end |
2184
1fd38975addd
Add support for plain profile in digest-md5 implementation.
Tobias Markmann <tm@ayena.de>
parents:
2182
diff
changeset
|
237 | end |
1fd38975addd
Add support for plain profile in digest-md5 implementation.
Tobias Markmann <tm@ayena.de>
parents:
2182
diff
changeset
|
238 | |
1fd38975addd
Add support for plain profile in digest-md5 implementation.
Tobias Markmann <tm@ayena.de>
parents:
2182
diff
changeset
|
239 | function init(registerMechanism) |
1fd38975addd
Add support for plain profile in digest-md5 implementation.
Tobias Markmann <tm@ayena.de>
parents:
2182
diff
changeset
|
240 | registerMechanism("DIGEST-MD5", {"plain"}, digest); |
1fd38975addd
Add support for plain profile in digest-md5 implementation.
Tobias Markmann <tm@ayena.de>
parents:
2182
diff
changeset
|
241 | end |
1fd38975addd
Add support for plain profile in digest-md5 implementation.
Tobias Markmann <tm@ayena.de>
parents:
2182
diff
changeset
|
242 | |
1fd38975addd
Add support for plain profile in digest-md5 implementation.
Tobias Markmann <tm@ayena.de>
parents:
2182
diff
changeset
|
243 | return _M; |