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

Impressum / About Us