webmcp
diff framework/env/auth/openid/_normalize_url.lua @ 20:47ddf0f86009
OpenID 2.0 Relying Party support
author | jbe/bsw |
---|---|
date | Fri Apr 02 02:11:32 2010 +0200 (2010-04-02) |
parents | |
children | e3e2a03f75b2 |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/framework/env/auth/openid/_normalize_url.lua Fri Apr 02 02:11:32 2010 +0200 1.3 @@ -0,0 +1,93 @@ 1.4 +--[[-- 1.5 +url, -- normalized URL or nil 1.6 +auth.openid._normalize_url( 1.7 + url -- unnormalized URL 1.8 +) 1.9 + 1.10 +This function normalizes an URL, and returns nil if the given URL is not a 1.11 +valid absolute URL. For security reasons only a restricted set of URLs is 1.12 +valid. 1.13 + 1.14 +--]]-- 1.15 + 1.16 +function auth.openid._normalize_url(url) 1.17 + local url = string.match(url, "^(.-)??$") -- remove "?" at end 1.18 + local proto, host, path = string.match( 1.19 + url, 1.20 + "([A-Za-z]+)://([0-9A-Za-z.:_-]+)/?([0-9A-Za-z%%/._~-]*)$" 1.21 + ) 1.22 + if not proto then 1.23 + return nil 1.24 + end 1.25 + proto = string.lower(proto) 1.26 + host = string.lower(host) 1.27 + local port = string.match(host, ":(.*)") 1.28 + if port then 1.29 + if string.find(port, "^[0-9]+$") then 1.30 + port = tonumber(port) 1.31 + host = string.match(host, "^(.-):") 1.32 + if port < 1 or port > 65535 then 1.33 + return nil 1.34 + end 1.35 + else 1.36 + return nil 1.37 + end 1.38 + end 1.39 + if proto == "http" then 1.40 + if port == 80 then port = nil end 1.41 + elseif proto == "https" then 1.42 + if port == 443 then port = nil end 1.43 + else 1.44 + return nil 1.45 + end 1.46 + if 1.47 + string.find(host, "^%.") or 1.48 + string.find(host, "%.$") or 1.49 + string.find(host, "%.%.") 1.50 + then 1.51 + return nil 1.52 + end 1.53 + for part in string.gmatch(host, "[^.]+") do 1.54 + if not string.find(part, "[A-Za-z]") then 1.55 + return nil 1.56 + end 1.57 + end 1.58 + local path_parts = {} 1.59 + for part in string.gmatch(path, "[^/]+") do 1.60 + if part == "." then 1.61 + -- do nothing 1.62 + elseif part == ".." then 1.63 + path_parts[#path_parts] = nil 1.64 + else 1.65 + local fail = false 1.66 + local part = string.gsub( 1.67 + part, 1.68 + "%%([0-9A-Fa-f]?[0-9A-Fa-f]?)", 1.69 + function (hex) 1.70 + if #hex ~= 2 then 1.71 + fail = true 1.72 + return 1.73 + end 1.74 + local char = string.char(tonumber("0x" .. hex)) 1.75 + if string.find(char, "[0-9A-Za-z._~-]") then 1.76 + return char 1.77 + else 1.78 + return "%" .. string.upper(hex) 1.79 + end 1.80 + end 1.81 + ) 1.82 + if fail then 1.83 + return nil 1.84 + end 1.85 + path_parts[#path_parts+1] = part 1.86 + end 1.87 + end 1.88 + if string.find(path, "/$") then 1.89 + path_parts[#path_parts+1] = "" 1.90 + end 1.91 + path = table.concat(path_parts, "/") 1.92 + if port then 1.93 + host = host .. ":" .. tostring(port) 1.94 + end 1.95 + return proto .. "://" .. host .. "/" .. path 1.96 +end