Software /
code /
prosody-modules
Comparison
mod_rest/mod_rest.lua @ 5960:d5e6617e47cc
mod_rest: Fix to allow case sensitive HTTP authentication scheme
Per RFC 9110 section 11
> It uses a case-insensitive token to identify the authentication scheme
author | Kim Alvefur <zash@zash.se> |
---|---|
date | Sun, 14 Jul 2024 17:58:48 +0200 |
parent | 5954:9bcc26406b47 |
child | 5961:2739d3db591f |
comparison
equal
deleted
inserted
replaced
5959:ca3479c67e48 | 5960:d5e6617e47cc |
---|---|
21 local tokens = module:depends("tokenauth"); | 21 local tokens = module:depends("tokenauth"); |
22 | 22 |
23 -- Lower than the default c2s size limit to account for possible JSON->XML size increase | 23 -- Lower than the default c2s size limit to account for possible JSON->XML size increase |
24 local stanza_size_limit = module:get_option_number("rest_stanza_size_limit", 1024 * 192); | 24 local stanza_size_limit = module:get_option_number("rest_stanza_size_limit", 1024 * 192); |
25 | 25 |
26 local auth_mechanisms = module:get_option_set("rest_auth_mechanisms", { "Basic", "Bearer" }); | 26 local auth_mechanisms = module:get_option_set("rest_auth_mechanisms", { "Basic", "Bearer" }) / string.lower; |
27 | 27 |
28 local www_authenticate_header; | 28 local www_authenticate_header; |
29 do | 29 do |
30 local header, realm = {}, module.host.."/"..module.name; | 30 local header, realm = {}, module.host.."/"..module.name; |
31 for mech in auth_mechanisms do | 31 for mech in auth_mechanisms do |
51 size = { code = 413; type = "modify"; condition = "resource-constraint", text = "Payload too large" }; | 51 size = { code = 413; type = "modify"; condition = "resource-constraint", text = "Payload too large" }; |
52 }); | 52 }); |
53 | 53 |
54 local function check_credentials(request) -- > session | boolean, error | 54 local function check_credentials(request) -- > session | boolean, error |
55 local auth_type, auth_data = string.match(request.headers.authorization, "^(%S+)%s(.+)$"); | 55 local auth_type, auth_data = string.match(request.headers.authorization, "^(%S+)%s(.+)$"); |
56 auth_type = auth_type:lower(); | |
56 if not (auth_type and auth_data) or not auth_mechanisms:contains(auth_type) then | 57 if not (auth_type and auth_data) or not auth_mechanisms:contains(auth_type) then |
57 return nil, post_errors.new("noauthz", { request = request }); | 58 return nil, post_errors.new("noauthz", { request = request }); |
58 end | 59 end |
59 | 60 |
60 if auth_type == "Basic" then | 61 if auth_type == "basic" then |
61 local creds = base64.decode(auth_data); | 62 local creds = base64.decode(auth_data); |
62 if not creds then | 63 if not creds then |
63 return nil, post_errors.new("malformauthz", { request = request }); | 64 return nil, post_errors.new("malformauthz", { request = request }); |
64 end | 65 end |
65 local username, password = string.match(creds, "^([^:]+):(.*)$"); | 66 local username, password = string.match(creds, "^([^:]+):(.*)$"); |
72 end | 73 end |
73 if not um.test_password(username, module.host, password) then | 74 if not um.test_password(username, module.host, password) then |
74 return false, post_errors.new("unauthz", { request = request }); | 75 return false, post_errors.new("unauthz", { request = request }); |
75 end | 76 end |
76 return { username = username; host = module.host }; | 77 return { username = username; host = module.host }; |
77 elseif auth_type == "Bearer" then | 78 elseif auth_type == "bearer" then |
78 if tokens.get_token_session then | 79 if tokens.get_token_session then |
79 return tokens.get_token_session(auth_data); | 80 return tokens.get_token_session(auth_data); |
80 else -- COMPAT w/0.12 | 81 else -- COMPAT w/0.12 |
81 local token_info = tokens.get_token_info(auth_data); | 82 local token_info = tokens.get_token_info(auth_data); |
82 if not token_info or not token_info.session then | 83 if not token_info or not token_info.session then |