Software /
code /
prosody
Annotate
util/sasl/oauthbearer.lua @ 12911:ab1164eda011
util.sasl: Add SASL OAUTHBEARER mechanism (RFC 7628)
author | Matthew Wild <mwild1@gmail.com> |
---|---|
date | Wed, 01 Mar 2023 12:55:00 +0000 |
child | 12918:ed20555f163a |
rev | line source |
---|---|
12911
ab1164eda011
util.sasl: Add SASL OAUTHBEARER mechanism (RFC 7628)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
1 local saslprep = require "util.encodings".stringprep.saslprep; |
ab1164eda011
util.sasl: Add SASL OAUTHBEARER mechanism (RFC 7628)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
2 local nodeprep = require "util.encodings".stringprep.nodeprep; |
ab1164eda011
util.sasl: Add SASL OAUTHBEARER mechanism (RFC 7628)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
3 local jid = require "util.jid"; |
ab1164eda011
util.sasl: Add SASL OAUTHBEARER mechanism (RFC 7628)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
4 local json = require "util.json"; |
ab1164eda011
util.sasl: Add SASL OAUTHBEARER mechanism (RFC 7628)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
5 local log = require "util.logger".init("sasl"); |
ab1164eda011
util.sasl: Add SASL OAUTHBEARER mechanism (RFC 7628)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
6 local _ENV = nil; |
ab1164eda011
util.sasl: Add SASL OAUTHBEARER mechanism (RFC 7628)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
7 |
ab1164eda011
util.sasl: Add SASL OAUTHBEARER mechanism (RFC 7628)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
8 |
ab1164eda011
util.sasl: Add SASL OAUTHBEARER mechanism (RFC 7628)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
9 local function oauthbearer(self, message) |
ab1164eda011
util.sasl: Add SASL OAUTHBEARER mechanism (RFC 7628)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
10 if not message then |
ab1164eda011
util.sasl: Add SASL OAUTHBEARER mechanism (RFC 7628)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
11 return "failure", "malformed-request"; |
ab1164eda011
util.sasl: Add SASL OAUTHBEARER mechanism (RFC 7628)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
12 end |
ab1164eda011
util.sasl: Add SASL OAUTHBEARER mechanism (RFC 7628)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
13 |
ab1164eda011
util.sasl: Add SASL OAUTHBEARER mechanism (RFC 7628)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
14 if message == "\001" then |
ab1164eda011
util.sasl: Add SASL OAUTHBEARER mechanism (RFC 7628)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
15 return "failure", "not-authorized"; |
ab1164eda011
util.sasl: Add SASL OAUTHBEARER mechanism (RFC 7628)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
16 end |
ab1164eda011
util.sasl: Add SASL OAUTHBEARER mechanism (RFC 7628)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
17 |
ab1164eda011
util.sasl: Add SASL OAUTHBEARER mechanism (RFC 7628)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
18 local gs2_authzid, kvpairs = message:match("n,a=([^,]+),(.+)$"); |
ab1164eda011
util.sasl: Add SASL OAUTHBEARER mechanism (RFC 7628)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
19 if not gs2_authzid then |
ab1164eda011
util.sasl: Add SASL OAUTHBEARER mechanism (RFC 7628)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
20 return "failure", "malformed-request"; |
ab1164eda011
util.sasl: Add SASL OAUTHBEARER mechanism (RFC 7628)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
21 end |
ab1164eda011
util.sasl: Add SASL OAUTHBEARER mechanism (RFC 7628)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
22 |
ab1164eda011
util.sasl: Add SASL OAUTHBEARER mechanism (RFC 7628)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
23 local auth_header; |
ab1164eda011
util.sasl: Add SASL OAUTHBEARER mechanism (RFC 7628)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
24 for k, v in kvpairs:gmatch("([a-zA-Z]+)=([\033-\126 \009\r\n]*)\001") do |
ab1164eda011
util.sasl: Add SASL OAUTHBEARER mechanism (RFC 7628)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
25 if k == "auth" then |
ab1164eda011
util.sasl: Add SASL OAUTHBEARER mechanism (RFC 7628)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
26 auth_header = v; |
ab1164eda011
util.sasl: Add SASL OAUTHBEARER mechanism (RFC 7628)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
27 break; |
ab1164eda011
util.sasl: Add SASL OAUTHBEARER mechanism (RFC 7628)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
28 end |
ab1164eda011
util.sasl: Add SASL OAUTHBEARER mechanism (RFC 7628)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
29 end |
ab1164eda011
util.sasl: Add SASL OAUTHBEARER mechanism (RFC 7628)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
30 |
ab1164eda011
util.sasl: Add SASL OAUTHBEARER mechanism (RFC 7628)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
31 if not auth_header then |
ab1164eda011
util.sasl: Add SASL OAUTHBEARER mechanism (RFC 7628)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
32 return "failure", "malformed-request"; |
ab1164eda011
util.sasl: Add SASL OAUTHBEARER mechanism (RFC 7628)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
33 end |
ab1164eda011
util.sasl: Add SASL OAUTHBEARER mechanism (RFC 7628)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
34 |
ab1164eda011
util.sasl: Add SASL OAUTHBEARER mechanism (RFC 7628)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
35 local username = jid.prepped_split(gs2_authzid); |
ab1164eda011
util.sasl: Add SASL OAUTHBEARER mechanism (RFC 7628)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
36 |
ab1164eda011
util.sasl: Add SASL OAUTHBEARER mechanism (RFC 7628)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
37 -- SASLprep username |
ab1164eda011
util.sasl: Add SASL OAUTHBEARER mechanism (RFC 7628)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
38 username = saslprep(username); |
ab1164eda011
util.sasl: Add SASL OAUTHBEARER mechanism (RFC 7628)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
39 |
ab1164eda011
util.sasl: Add SASL OAUTHBEARER mechanism (RFC 7628)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
40 if not username or username == "" then |
ab1164eda011
util.sasl: Add SASL OAUTHBEARER mechanism (RFC 7628)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
41 log("debug", "Username violates SASLprep."); |
ab1164eda011
util.sasl: Add SASL OAUTHBEARER mechanism (RFC 7628)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
42 return "failure", "malformed-request", "Invalid username."; |
ab1164eda011
util.sasl: Add SASL OAUTHBEARER mechanism (RFC 7628)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
43 end |
ab1164eda011
util.sasl: Add SASL OAUTHBEARER mechanism (RFC 7628)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
44 |
ab1164eda011
util.sasl: Add SASL OAUTHBEARER mechanism (RFC 7628)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
45 local _nodeprep = self.profile.nodeprep; |
ab1164eda011
util.sasl: Add SASL OAUTHBEARER mechanism (RFC 7628)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
46 if _nodeprep ~= false then |
ab1164eda011
util.sasl: Add SASL OAUTHBEARER mechanism (RFC 7628)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
47 username = (_nodeprep or nodeprep)(username); |
ab1164eda011
util.sasl: Add SASL OAUTHBEARER mechanism (RFC 7628)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
48 if not username or username == "" then |
ab1164eda011
util.sasl: Add SASL OAUTHBEARER mechanism (RFC 7628)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
49 return "failure", "malformed-request", "Invalid username or password." |
ab1164eda011
util.sasl: Add SASL OAUTHBEARER mechanism (RFC 7628)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
50 end |
ab1164eda011
util.sasl: Add SASL OAUTHBEARER mechanism (RFC 7628)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
51 end |
ab1164eda011
util.sasl: Add SASL OAUTHBEARER mechanism (RFC 7628)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
52 |
ab1164eda011
util.sasl: Add SASL OAUTHBEARER mechanism (RFC 7628)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
53 self.username = username; |
ab1164eda011
util.sasl: Add SASL OAUTHBEARER mechanism (RFC 7628)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
54 |
ab1164eda011
util.sasl: Add SASL OAUTHBEARER mechanism (RFC 7628)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
55 local token = auth_header:match("^Bearer (.+)$"); |
ab1164eda011
util.sasl: Add SASL OAUTHBEARER mechanism (RFC 7628)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
56 |
ab1164eda011
util.sasl: Add SASL OAUTHBEARER mechanism (RFC 7628)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
57 local correct, state, token_info = self.profile.oauthbearer(self, username, token, self.realm); |
ab1164eda011
util.sasl: Add SASL OAUTHBEARER mechanism (RFC 7628)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
58 |
ab1164eda011
util.sasl: Add SASL OAUTHBEARER mechanism (RFC 7628)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
59 if state == false then |
ab1164eda011
util.sasl: Add SASL OAUTHBEARER mechanism (RFC 7628)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
60 return "failure", "account-disabled"; |
ab1164eda011
util.sasl: Add SASL OAUTHBEARER mechanism (RFC 7628)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
61 elseif state == nil or not correct then |
ab1164eda011
util.sasl: Add SASL OAUTHBEARER mechanism (RFC 7628)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
62 -- For token-level errors, RFC 7628 demands use of a JSON-encoded |
ab1164eda011
util.sasl: Add SASL OAUTHBEARER mechanism (RFC 7628)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
63 -- challenge response upon failure. We relay additional info from |
ab1164eda011
util.sasl: Add SASL OAUTHBEARER mechanism (RFC 7628)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
64 -- the auth backend if available. |
ab1164eda011
util.sasl: Add SASL OAUTHBEARER mechanism (RFC 7628)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
65 return "challenge", json.encode({ |
ab1164eda011
util.sasl: Add SASL OAUTHBEARER mechanism (RFC 7628)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
66 status = token_info and token_info.status or "invalid_token"; |
ab1164eda011
util.sasl: Add SASL OAUTHBEARER mechanism (RFC 7628)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
67 scope = token_info and token_info.scope or nil; |
ab1164eda011
util.sasl: Add SASL OAUTHBEARER mechanism (RFC 7628)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
68 ["openid-configuration"] = token_info and token_info.oidc_discovery_url or nil; |
ab1164eda011
util.sasl: Add SASL OAUTHBEARER mechanism (RFC 7628)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
69 }); |
ab1164eda011
util.sasl: Add SASL OAUTHBEARER mechanism (RFC 7628)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
70 end |
ab1164eda011
util.sasl: Add SASL OAUTHBEARER mechanism (RFC 7628)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
71 |
ab1164eda011
util.sasl: Add SASL OAUTHBEARER mechanism (RFC 7628)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
72 self.resource = token_info.resource; |
ab1164eda011
util.sasl: Add SASL OAUTHBEARER mechanism (RFC 7628)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
73 self.role = token_info.role; |
ab1164eda011
util.sasl: Add SASL OAUTHBEARER mechanism (RFC 7628)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
74 return "success"; |
ab1164eda011
util.sasl: Add SASL OAUTHBEARER mechanism (RFC 7628)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
75 end |
ab1164eda011
util.sasl: Add SASL OAUTHBEARER mechanism (RFC 7628)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
76 |
ab1164eda011
util.sasl: Add SASL OAUTHBEARER mechanism (RFC 7628)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
77 local function init(registerMechanism) |
ab1164eda011
util.sasl: Add SASL OAUTHBEARER mechanism (RFC 7628)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
78 registerMechanism("OAUTHBEARER", {"oauthbearer"}, oauthbearer); |
ab1164eda011
util.sasl: Add SASL OAUTHBEARER mechanism (RFC 7628)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
79 end |
ab1164eda011
util.sasl: Add SASL OAUTHBEARER mechanism (RFC 7628)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
80 |
ab1164eda011
util.sasl: Add SASL OAUTHBEARER mechanism (RFC 7628)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
81 return { |
ab1164eda011
util.sasl: Add SASL OAUTHBEARER mechanism (RFC 7628)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
82 init = init; |
ab1164eda011
util.sasl: Add SASL OAUTHBEARER mechanism (RFC 7628)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
83 } |