From 429ea15d8b1470965fa09707e38d1c66977c20c5 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Fri, 11 Dec 2015 20:07:22 +0100 Subject: util.datamanager: Factor out code for appending bytes to a file --- util/datamanager.lua | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/util/datamanager.lua b/util/datamanager.lua index 4b722851..13aed78f 100644 --- a/util/datamanager.lua +++ b/util/datamanager.lua @@ -209,32 +209,40 @@ local function store(username, host, datastore, data) return true; 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+"); +local function append(username, host, datastore, ext, data) + local f, msg = io_open(getpath(username, host, datastore, ext, true), "r+"); if not f then - f, msg = io_open(getpath(username, host, datastore, "list", true), "w"); + f, msg = io_open(getpath(username, host, datastore, ext, 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; + return nil, msg; 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 - 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 +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 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 + return true; +end + local function list_store(username, host, datastore, data) if not data then data = {}; -- cgit v1.2.3 From 06725746573f7d9800ceed1cb442c993e014fdc4 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Fri, 11 Dec 2015 20:11:48 +0100 Subject: util.datamanager: Overwrite 'data' variable instead of shadownig it [luacheck] --- util/datamanager.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/util/datamanager.lua b/util/datamanager.lua index 13aed78f..1993d6a3 100644 --- a/util/datamanager.lua +++ b/util/datamanager.lua @@ -234,7 +234,7 @@ local function list_append(username, host, datastore, data) if callback(username, host, datastore) == false then return true; end -- save the datastore - local data = "item(" .. serialize(data) .. ");\n"; + 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"); -- cgit v1.2.3 From 51302e343c590e887b3b53de95b4afed0df453bb Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Fri, 11 Dec 2015 20:13:37 +0100 Subject: util.datamanager: In append() collect status when closing file handle as it may fail (eg the implied flush) --- util/datamanager.lua | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/util/datamanager.lua b/util/datamanager.lua index 1993d6a3..4a371d2c 100644 --- a/util/datamanager.lua +++ b/util/datamanager.lua @@ -210,9 +210,10 @@ local function store(username, host, datastore, data) end local function append(username, host, datastore, ext, data) - local f, msg = io_open(getpath(username, host, datastore, ext, true), "r+"); + local filename = getpath(username, host, datastore, ext, true); + local f, msg = io_open(filename, "r+"); if not f then - f, msg = io_open(getpath(username, host, datastore, ext, true), "w"); + f, msg = io_open(filename, "w"); end if not f then return nil, msg; @@ -225,7 +226,12 @@ local function append(username, host, datastore, ext, data) else return ok, msg; end - f:close(); + + ok, msg = f:close(); + if not ok then + return ok, msg; + end + return true; end -- cgit v1.2.3 From c54585b91c729ef71c2fd272dcf2675311f5a96a Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Fri, 11 Dec 2015 20:18:24 +0100 Subject: util.datamanager: Skip past second check if first attemtp to open file succeeds --- util/datamanager.lua | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/util/datamanager.lua b/util/datamanager.lua index 4a371d2c..b7c514ad 100644 --- a/util/datamanager.lua +++ b/util/datamanager.lua @@ -214,9 +214,9 @@ local function append(username, host, datastore, ext, data) local f, msg = io_open(filename, "r+"); if not f then f, msg = io_open(filename, "w"); - end - if not f then - return nil, msg; + if not f then + return nil, msg; + end end local pos = f:seek("end"); local ok, msg = fallocate(f, pos, #data); -- cgit v1.2.3 From da98f6463936788e85bff956434c308f6bb66058 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Fri, 11 Dec 2015 20:22:54 +0100 Subject: util.datamanager: No shadowing of variable [luacheck] --- util/datamanager.lua | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/util/datamanager.lua b/util/datamanager.lua index b7c514ad..786abd95 100644 --- a/util/datamanager.lua +++ b/util/datamanager.lua @@ -211,6 +211,8 @@ end local function append(username, host, datastore, ext, data) local filename = getpath(username, host, datastore, ext, true); + + local ok; local f, msg = io_open(filename, "r+"); if not f then f, msg = io_open(filename, "w"); @@ -219,7 +221,7 @@ local function append(username, host, datastore, ext, data) end end local pos = f:seek("end"); - local ok, msg = fallocate(f, pos, #data); + ok, msg = fallocate(f, pos, #data); f:seek("set", pos); if ok then f:write(data); -- cgit v1.2.3 From 93304d3439bdf8479bf24971487275432045dd41 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Fri, 11 Dec 2015 20:24:36 +0100 Subject: util.datamanager: Handle potential issues from fallocate --- util/datamanager.lua | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/util/datamanager.lua b/util/datamanager.lua index 786abd95..3016feed 100644 --- a/util/datamanager.lua +++ b/util/datamanager.lua @@ -222,7 +222,16 @@ local function append(username, host, datastore, ext, data) end local pos = f:seek("end"); ok, msg = fallocate(f, pos, #data); - f:seek("set", pos); + 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 + if ok then f:write(data); else -- cgit v1.2.3 From 1099fb8dd73854dcf77e618378034869ca096638 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Fri, 11 Dec 2015 20:26:04 +0100 Subject: util.datamanager: Handle potential error from :write() call --- util/datamanager.lua | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/util/datamanager.lua b/util/datamanager.lua index 3016feed..ce4c5b5a 100644 --- a/util/datamanager.lua +++ b/util/datamanager.lua @@ -232,9 +232,9 @@ local function append(username, host, datastore, ext, data) f:seek("set", pos); end - if ok then - f:write(data); - else + ok, msg = f:write(data); + if not ok then + f:close(); return ok, msg; end -- cgit v1.2.3 From 25a50fa01abd5e64f203b4ec9c47f9113998d030 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Fri, 11 Dec 2015 20:29:55 +0100 Subject: util.datamanager: Add some comments about the append function --- util/datamanager.lua | 3 +++ 1 file changed, 3 insertions(+) diff --git a/util/datamanager.lua b/util/datamanager.lua index ce4c5b5a..510c0161 100644 --- a/util/datamanager.lua +++ b/util/datamanager.lua @@ -209,17 +209,20 @@ 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) 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; end end + local pos = f:seek("end"); ok, msg = fallocate(f, pos, #data); if not ok then -- cgit v1.2.3 From 2482f0614a927f7cf733c4a86a85183009778efd Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Fri, 11 Dec 2015 20:30:39 +0100 Subject: util.datamanager: Make sure only strings are passed as data to append() --- util/datamanager.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/util/datamanager.lua b/util/datamanager.lua index 510c0161..e57d5fdc 100644 --- a/util/datamanager.lua +++ b/util/datamanager.lua @@ -211,6 +211,7 @@ 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; -- cgit v1.2.3 From 6a9821a8c759da11b237ed55ae6c0357589f0312 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Fri, 11 Dec 2015 20:31:19 +0100 Subject: util.datamanager: Return extra location info --- util/datamanager.lua | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/util/datamanager.lua b/util/datamanager.lua index e57d5fdc..c8dbaae9 100644 --- a/util/datamanager.lua +++ b/util/datamanager.lua @@ -220,7 +220,7 @@ local function append(username, host, datastore, ext, data) -- File did probably not exist, let's create it f, msg = io_open(filename, "w"); if not f then - return nil, msg; + return nil, msg, "open"; end end @@ -239,7 +239,7 @@ local function append(username, host, datastore, ext, data) ok, msg = f:write(data); if not ok then f:close(); - return ok, msg; + return ok, msg, "write"; end ok, msg = f:close(); @@ -247,7 +247,7 @@ local function append(username, host, datastore, ext, data) return ok, msg; end - return true; + return true, pos; end local function list_append(username, host, datastore, data) -- cgit v1.2.3 From 46fa4549336de1b2f38d35c07bd0a24c866c0f7a Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Fri, 11 Dec 2015 20:31:55 +0100 Subject: util.datamanager: Add append to public api --- util/datamanager.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/util/datamanager.lua b/util/datamanager.lua index c8dbaae9..83f3dd13 100644 --- a/util/datamanager.lua +++ b/util/datamanager.lua @@ -402,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; -- cgit v1.2.3 From 04d9feb7f3cdd5fe98147813c8ad766723305b8e Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Sun, 13 Dec 2015 21:21:09 +0100 Subject: util.sslconfig: More descriptive variable names and also comments --- util/sslconfig.lua | 87 +++++++++++++++++++++++++++++++++++------------------- 1 file changed, 56 insertions(+), 31 deletions(-) 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 = { -- cgit v1.2.3 From 41c42960d763d99927cdeeaae855cccde3920fde Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Tue, 15 Dec 2015 13:15:30 +0100 Subject: mod_storage_sql: Fix use of SQLite3 in-memory database (no path expansion) --- plugins/mod_storage_sql.lua | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/plugins/mod_storage_sql.lua b/plugins/mod_storage_sql.lua index adf9f9b6..57d964e2 100644 --- a/plugins/mod_storage_sql.lua +++ b/plugins/mod_storage_sql.lua @@ -417,7 +417,9 @@ end local function normalize_params(params) if params.driver == "SQLite3" then - params.database = resolve_relative_path(prosody.paths.data or ".", params.database or "prosody.sqlite"); + if params.database ~= ":memory:" then + params.database = resolve_relative_path(prosody.paths.data or ".", params.database or "prosody.sqlite"); + end end assert(params.driver and params.database, "Configuration error: Both the SQL driver and the database need to be specified"); return params; -- cgit v1.2.3