util/sasl.lua

changeset 277
00c2fc751f50
parent 276
30893439d5d1
child 278
770a78cd38d7
equal deleted inserted replaced
276:30893439d5d1 277:00c2fc751f50
5 local log = require "util.logger".init("sasl"); 5 local log = require "util.logger".init("sasl");
6 local tostring = tostring; 6 local tostring = tostring;
7 local st = require "util.stanza"; 7 local st = require "util.stanza";
8 local generate_uuid = require "util.uuid".generate; 8 local generate_uuid = require "util.uuid".generate;
9 local s_match = string.match; 9 local s_match = string.match;
10 local gmatch = string.gmatch
10 local math = require "math" 11 local math = require "math"
11 local type = type 12 local type = type
12 local error = error 13 local error = error
13 local print = print 14 local print = print
14 15
80 return data 81 return data
81 end 82 end
82 83
83 local function parse(data) 84 local function parse(data)
84 message = {} 85 message = {}
85 for k, v in string.gmatch(data, [[([%w%-])="?[%w%-]"?,?]]) do 86 for k, v in gmatch(data, [[([%w%-]+)="?([%w%-%/%.]+)"?,?]]) do
86 message[k] = v 87 message[k] = v
87 end 88 end
88 return message 89 return message
89 end 90 end
90 91
100 qop = "auth", 101 qop = "auth",
101 charset = "utf-8", 102 charset = "utf-8",
102 algorithm = "md5-sess"} )); 103 algorithm = "md5-sess"} ));
103 object.onWrite(st.stanza("challenge", {xmlns = "urn:ietf:params:xml:ns:xmpp-sasl"}):text(challenge)) 104 object.onWrite(st.stanza("challenge", {xmlns = "urn:ietf:params:xml:ns:xmpp-sasl"}):text(challenge))
104 object.feed = function(self, stanza) 105 object.feed = function(self, stanza)
105 print(tostring(stanza))
106 if stanza.name ~= "response" and stanza.name ~= "auth" then self.onFail("invalid-stanza-tag") end 106 if stanza.name ~= "response" and stanza.name ~= "auth" then self.onFail("invalid-stanza-tag") end
107 if stanza.attr.xmlns ~= "urn:ietf:params:xml:ns:xmpp-sasl" then self.onFail("invalid-stanza-namespace") end 107 if stanza.attr.xmlns ~= "urn:ietf:params:xml:ns:xmpp-sasl" then self.onFail("invalid-stanza-namespace") end
108 if stanza.name == "auth" then return end 108 if stanza.name == "auth" then return end
109 self.step = self.step + 1 109 self.step = self.step + 1
110 if (self.step == 2) then 110 if (self.step == 2) then
111
112 log("debug", tostring(stanza[1]))
113 local response = parse(base64.decode(stanza[1])) 111 local response = parse(base64.decode(stanza[1]))
114 -- check for replay attack 112 -- check for replay attack
115 if response["nonce-count"] then 113 if response["nonce-count"] then
116 if self.nonce_count[response["nonce-count"]] then self.onFail("not-authorized") end 114 if self.nonce_count[response["nonce-count"]] then self.onFail("not-authorized") end
117 end 115 end
131 129
132 if not response["cnonce"] then self.onFail("malformed-request") end 130 if not response["cnonce"] then self.onFail("malformed-request") end
133 if not response["qop"] then response["qop"] = "auth" end 131 if not response["qop"] then response["qop"] = "auth" end
134 132
135 local hostname = "" 133 local hostname = ""
134 local protocol = ""
136 if response["digest-uri"] then 135 if response["digest-uri"] then
137 local uri = response["digest-uri"]:gmatch("^(%w)/(%w)") 136 protocol, hostname = response["digest-uri"]:match("(%w+)/(.*)$")
138 local protocol = uri[1] 137 else
139 log(protocol) 138 error("No digest-uri")
140 local hostname = uri[2]
141 log(hostname)
142 end 139 end
143 140
144 -- compare response_value with own calculation 141 -- compare response_value with own calculation
145 local A1-- = H(response["username"]..":"..realm-value, ":", passwd } ), 142 local A1-- = H(response["username"]..":"..realm-value, ":", passwd } ),
146 -- ":", nonce-value, ":", cnonce-value) 143 -- ":", nonce-value, ":", cnonce-value)
147 local A2 144 local A2
148 145
149 local response_value = HEX(KD(HEX(H(A1)), response["nonce"]..":"..response["nonce-count"]..":"..response["cnonce-value"]..":"..response["qop"]..":"..HEX(H(A2)))) 146 --local response_value = HEX(KD(HEX(H(A1)), response["nonce"]..":"..response["nonce-count"]..":"..response["cnonce-value"]..":"..response["qop"]..":"..HEX(H(A2))))
150 147
151 if response["qop"] == "auth" then 148 if response["qop"] == "auth" then
152 149
153 else 150 else
154 151
155 end 152 end
156 153
157 local response_value = HEX(KD(HEX(H(A1)), response["nonce"]..":"..response["nonce-count"]..":"..response["cnonce-value"]..":"..response["qop"]..":"..HEX(H(A2)))) 154 --local response_value = HEX(KD(HEX(H(A1)), response["nonce"]..":"..response["nonce-count"]..":"..response["cnonce-value"]..":"..response["qop"]..":"..HEX(H(A2))))
158 155
159 end 156 end
160 --[[ 157 --[[
161 local authorization = s_match(response, "([^&%z]+)") 158 local authorization = s_match(response, "([^&%z]+)")
162 local authentication = s_match(response, "%z([^&%z]+)%z") 159 local authentication = s_match(response, "%z([^&%z]+)%z")

mercurial