aboutsummaryrefslogtreecommitdiffstats
path: root/util
diff options
context:
space:
mode:
authorMatthew Wild <mwild1@gmail.com>2015-12-16 16:44:40 +0000
committerMatthew Wild <mwild1@gmail.com>2015-12-16 16:44:40 +0000
commited274d1253637e39f3bcaadcfc817cdf3f705c63 (patch)
tree79a466a05ccdcbb3172d75db20a4996be3ab8aa3 /util
parentc2c82b591a34d539692cb6b36f0edafdfb4ef9dd (diff)
parent275bfb45fa0972832ffc760d512845d4b0f9be44 (diff)
downloadprosody-ed274d1253637e39f3bcaadcfc817cdf3f705c63.tar.gz
prosody-ed274d1253637e39f3bcaadcfc817cdf3f705c63.zip
Merge
Diffstat (limited to 'util')
-rw-r--r--util/datamanager.lua62
-rw-r--r--util/sslconfig.lua87
2 files changed, 102 insertions, 47 deletions
diff --git a/util/datamanager.lua b/util/datamanager.lua
index 4b722851..83f3dd13 100644
--- a/util/datamanager.lua
+++ b/util/datamanager.lua
@@ -209,29 +209,58 @@ local function store(username, host, datastore, data)
return true;
end
+-- Append a blob of data to a file
+local function append(username, host, datastore, ext, data)
+ if type(data) ~= "string" then return; end
+ local filename = getpath(username, host, datastore, ext, true);
+
+ local ok;
+ local f, msg = io_open(filename, "r+");
+ if not f then
+ -- File did probably not exist, let's create it
+ f, msg = io_open(filename, "w");
+ if not f then
+ return nil, msg, "open";
+ end
+ end
+
+ local pos = f:seek("end");
+ ok, msg = fallocate(f, pos, #data);
+ if not ok then
+ log("warn", "fallocate() failed: %s", tostring(msg));
+ -- This doesn't work on every file system
+ end
+
+ if f:seek() ~= pos then
+ log("debug", "fallocate() changed file position");
+ f:seek("set", pos);
+ end
+
+ ok, msg = f:write(data);
+ if not ok then
+ f:close();
+ return ok, msg, "write";
+ end
+
+ ok, msg = f:close();
+ if not ok then
+ return ok, msg;
+ end
+
+ return true, pos;
+end
+
local function list_append(username, host, datastore, data)
if not data then return; end
if callback(username, host, datastore) == false then return true; end
-- save the datastore
- local f, msg = io_open(getpath(username, host, datastore, "list", true), "r+");
- if not f then
- f, msg = io_open(getpath(username, host, datastore, "list", true), "w");
- end
- if not f then
- log("error", "Unable to write to %s storage ('%s') for user: %s@%s", datastore, msg, username or "nil", host or "nil");
- return;
- end
- local data = "item(" .. serialize(data) .. ");\n";
- local pos = f:seek("end");
- local ok, msg = fallocate(f, pos, #data);
- f:seek("set", pos);
- if ok then
- f:write(data);
- else
+
+ data = "item(" .. serialize(data) .. ");\n";
+ local ok, msg = append(username, host, datastore, "list", data);
+ if not ok then
log("error", "Unable to write to %s storage ('%s') for user: %s@%s", datastore, msg, username or "nil", host or "nil");
return ok, msg;
end
- f:close();
return true;
end
@@ -373,6 +402,7 @@ return {
getpath = getpath;
load = load;
store = store;
+ append_raw = append;
list_append = list_append;
list_store = list_store;
list_load = list_load;
diff --git a/util/sslconfig.lua b/util/sslconfig.lua
index 71f27c94..c849aa28 100644
--- a/util/sslconfig.lua
+++ b/util/sslconfig.lua
@@ -1,3 +1,5 @@
+-- util to easily merge multiple sets of LuaSec context options
+
local type = type;
local pairs = pairs;
local rawset = rawset;
@@ -11,70 +13,93 @@ local handlers = { };
local finalisers = { };
local id = function (v) return v end
-function handlers.options(a, k, b)
- local o = a[k] or { };
- if type(b) ~= "table" then b = { b } end
- for key, value in pairs(b) do
+-- All "handlers" behave like extended rawset(table, key, value) with extra
+-- processing usually merging the new value with the old in some reasonable
+-- way
+-- If a field does not have a defined handler then a new value simply
+-- replaces the old.
+
+
+-- Convert either a list or a set into a special type of set where each
+-- item is either positive or negative in order for a later set of options
+-- to be able to remove options from this set by filtering out the negative ones
+function handlers.options(config, field, new)
+ local options = config[field] or { };
+ if type(new) ~= "table" then new = { new } end
+ for key, value in pairs(new) do
if value == true or value == false then
- o[key] = value;
- else
- o[value] = true;
+ options[key] = value;
+ else -- list item
+ options[value] = true;
end
end
- a[k] = o;
+ config[field] = options;
end
handlers.verify = handlers.options;
handlers.verifyext = handlers.options;
-function finalisers.options(a)
- local o = {};
- for opt, enable in pairs(a) do
+-- finalisers take something produced by handlers and return what luasec
+-- expects it to be
+
+-- Produce a list of "positive" options from the set
+function finalisers.options(options)
+ local output = {};
+ for opt, enable in pairs(options) do
if enable then
- o[#o+1] = opt;
+ output[#output+1] = opt;
end
end
- return o;
+ return output;
end
finalisers.verify = finalisers.options;
finalisers.verifyext = finalisers.options;
-function finalisers.ciphers(a)
- if type(a) == "table" then
- return t_concat(a, ":");
+-- We allow ciphers to be a list
+
+function finalisers.ciphers(cipherlist)
+ if type(cipherlist) == "table" then
+ return t_concat(cipherlist, ":");
end
- return a;
+ return cipherlist;
end
+-- protocol = "x" should enable only that protocol
+-- protocol = "x+" should enable x and later versions
+
local protocols = { "sslv2", "sslv3", "tlsv1", "tlsv1_1", "tlsv1_2" };
for i = 1, #protocols do protocols[protocols[i] .. "+"] = i - 1; end
-local function protocol(a)
- local min_protocol = protocols[a.protocol];
+-- this interacts with ssl.options as well to add no_x
+local function protocol(config)
+ local min_protocol = protocols[config.protocol];
if min_protocol then
- a.protocol = "sslv23";
+ config.protocol = "sslv23";
for i = 1, min_protocol do
- t_insert(a.options, "no_"..protocols[i]);
+ t_insert(config.options, "no_"..protocols[i]);
end
end
end
-local function apply(a, b)
- if type(b) == "table" then
- for k,v in pairs(b) do
- (handlers[k] or rawset)(a, k, v);
+-- Merge options from 'new' config into 'config'
+local function apply(config, new)
+ if type(new) == "table" then
+ for field, value in pairs(new) do
+ (handlers[field] or rawset)(config, field, value);
end
end
end
-local function final(a)
- local f = { };
- for k,v in pairs(a) do
- f[k] = (finalisers[k] or id)(v);
+-- Finalize the config into the form LuaSec expects
+local function final(config)
+ local output = { };
+ for field, value in pairs(config) do
+ output[field] = (finalisers[field] or id)(value);
end
- protocol(f);
- return f;
+ -- Need to handle protocols last because it adds to the options list
+ protocol(output);
+ return output;
end
local sslopts_mt = {