/usr/share/lua/5.1/http/hsts.lua is in lua-http 0.1-3.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 | --[[
Data structures useful for HSTS (HTTP Strict Transport Security)
HSTS is described in RFC 6797
]]
local EOF = require "lpeg".P(-1)
local IPv4address = require "lpeg_patterns.IPv4".IPv4address
local IPv6address = require "lpeg_patterns.IPv6".IPv6address
local IPaddress = (IPv4address + IPv6address) * EOF
local store_methods = {
time = function() return os.time() end;
}
local store_mt = {
__name = "http.hsts.store";
__index = store_methods;
}
local store_item_methods = {}
local store_item_mt = {
__name = "http.hsts.store_item";
__index = store_item_methods;
}
local function host_is_ip(host)
if IPaddress:match(host) then
return true
else
return false
end
end
local function new_store()
return setmetatable({
domains = {};
}, store_mt)
end
function store_methods:clone()
local r = new_store()
r.time = rawget(self, "time")
for host, item in pairs(self.domains) do
r.domains[host] = item
end
return r
end
function store_methods:store(host, directives)
local now = self.time()
local max_age = directives["max-age"]
if max_age == nil then
return nil, "max-age directive is required"
elseif type(max_age) ~= "string" or max_age:match("[^0-9]") then
return nil, "max-age directive does not match grammar"
else
max_age = tonumber(max_age, 10)
end
if host_is_ip(host) then
return false
end
if max_age == 0 then
-- delete from store
self.domains[host] = nil
else
-- add to store
self.domains[host] = setmetatable({
includeSubdomains = directives.includeSubdomains;
expires = now + max_age;
}, store_item_mt)
end
return true
end
function store_methods:check(host)
if host_is_ip(host) then
return false
end
local now = self.time()
local h = host
repeat
local item = self.domains[h]
if item then
if item.expires < now then
self:clean()
elseif host == h or item.includeSubdomains then
return true
end
end
local n
h, n = h:gsub("^[^%.]+%.", "", 1)
until n == 0
return false
end
function store_methods:clean()
local now = self.time()
for host, item in pairs(self.domains) do
if item.expires < now then
self.domains[host] = nil
end
end
return true
end
return {
new_store = new_store;
store_mt = store_mt;
store_methods = store_methods;
}
|