From 8178f7bd884410b53329d6fc0b9c49891081a91d Mon Sep 17 00:00:00 2001
From: Matthew Wild <mwild1@gmail.com>
Date: Wed, 6 Jan 2016 00:24:06 +0000
Subject: tests/test.lua: Fix fake module() function to prevent _M from being
 _G (test.lua's environment), which caused modules to break the sandbox when
 they set _M.*

---
 tests/test.lua | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/tests/test.lua b/tests/test.lua
index de1e40fd..bb11ab26 100644
--- a/tests/test.lua
+++ b/tests/test.lua
@@ -137,7 +137,10 @@ function dotest(unitname)
 	end
 	
 	local oldmodule, old_M = _fakeG.module, _fakeG._M;
-	_fakeG.module = function () _M = _G end
+	_fakeG.module = function ()
+		setmetatable(unit, nil);
+		unit._M = unit;
+	end
 	setfenv(chunk, unit);
 	local success, err = pcall(chunk);
 	_fakeG.module, _fakeG._M = oldmodule, old_M;
-- 
cgit v1.2.3


From 2ab42c8dbf95ea250e4dd16b21b12c2b6dddb5b1 Mon Sep 17 00:00:00 2001
From: Matthew Wild <mwild1@gmail.com>
Date: Fri, 17 May 2013 14:52:52 +0100
Subject: util.ip: Automatically determine protocol of IP address if none
 specified. Return error if invalid. [Backported from 0.10]

---
 util/ip.lua | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/util/ip.lua b/util/ip.lua
index 856bf034..226432cc 100644
--- a/util/ip.lua
+++ b/util/ip.lua
@@ -12,7 +12,15 @@ local ip_mt = { __index = function (ip, key) return (ip_methods[key])(ip); end,
 local hex2bits = { ["0"] = "0000", ["1"] = "0001", ["2"] = "0010", ["3"] = "0011", ["4"] = "0100", ["5"] = "0101", ["6"] = "0110", ["7"] = "0111", ["8"] = "1000", ["9"] = "1001", ["A"] = "1010", ["B"] = "1011", ["C"] = "1100", ["D"] = "1101", ["E"] = "1110", ["F"] = "1111" };
 
 local function new_ip(ipStr, proto)
-	if proto ~= "IPv4" and proto ~= "IPv6" then
+	if not proto then
+		local sep = ipStr:match("^%x+(.)");
+		if sep == ":" then proto = "IPv6"
+		elseif sep == "." then proto = "IPv4"
+		end
+		if not proto then
+			return nil, "invalid address";
+		end
+	elseif proto ~= "IPv4" and proto ~= "IPv6" then
 		return nil, "invalid protocol";
 	end
 	if proto == "IPv6" and ipStr:find('.', 1, true) then
-- 
cgit v1.2.3


From 2b6402720494ef8632a2f26970b9cc935dee8d41 Mon Sep 17 00:00:00 2001
From: Matthew Wild <mwild1@gmail.com>
Date: Sat, 18 May 2013 21:41:17 +0100
Subject: util.ip: Fix protocol detection of IPv6 addresses beginning with :
 [Backported from 0.10]

---
 util/ip.lua | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/util/ip.lua b/util/ip.lua
index 226432cc..043303ee 100644
--- a/util/ip.lua
+++ b/util/ip.lua
@@ -14,8 +14,10 @@ local hex2bits = { ["0"] = "0000", ["1"] = "0001", ["2"] = "0010", ["3"] = "0011
 local function new_ip(ipStr, proto)
 	if not proto then
 		local sep = ipStr:match("^%x+(.)");
-		if sep == ":" then proto = "IPv6"
-		elseif sep == "." then proto = "IPv4"
+		if sep == ":" or (not(sep) and ipStr:sub(1,1) == ":") then
+			proto = "IPv6"
+		elseif sep == "." then
+			proto = "IPv4"
 		end
 		if not proto then
 			return nil, "invalid address";
-- 
cgit v1.2.3


From 4f709973f8079e8e6deaa78c195d44f221590933 Mon Sep 17 00:00:00 2001
From: Florian Zeitz <florob@babelmonkeys.de>
Date: Tue, 18 Jun 2013 23:02:20 +0200
Subject: net.dns: Support IPv6 addresses in resolv.conf [Backported from 0.10]

---
 net/dns.lua | 19 +++++++++++++------
 1 file changed, 13 insertions(+), 6 deletions(-)

diff --git a/net/dns.lua b/net/dns.lua
index 7ec13c81..9d90c24c 100644
--- a/net/dns.lua
+++ b/net/dns.lua
@@ -14,6 +14,7 @@
 
 local socket = require "socket";
 local timer = require "util.timer";
+local new_ip = require "util.ip".new_ip;
 
 local _, windows = pcall(require, "util.windows");
 local is_windows = (_ and windows) or os.getenv("WINDIR");
@@ -599,11 +600,12 @@ function resolver:adddefaultnameservers()    -- - - - -  adddefaultnameservers
 		if resolv_conf then
 			for line in resolv_conf:lines() do
 				line = line:gsub("#.*$", "")
-					:match('^%s*nameserver%s+(.*)%s*$');
+					:match('^%s*nameserver%s+([%x:%.]*)%s*$');
 				if line then
-					line:gsub("%f[%d.](%d+%.%d+%.%d+%.%d+)%f[^%d.]", function (address)
-						self:addnameserver(address)
-					end);
+					local ip = new_ip(line);
+					if ip then
+						self:addnameserver(ip.addr);
+					end
 				end
 			end
 		end
@@ -623,7 +625,12 @@ function resolver:getsocket(servernum)    -- - - - - - - - - - - - - getsocket
 	if sock then return sock; end
 
 	local ok, err;
-	sock, err = socket.udp();
+	local peer = self.server[servernum];
+	if peer:find(":") then
+		sock, err = socket.udp6();
+	else
+		sock, err = socket.udp();
+	end
 	if sock and self.socket_wrapper then sock, err = self.socket_wrapper(sock, self); end
 	if not sock then
 		return nil, err;
@@ -636,7 +643,7 @@ function resolver:getsocket(servernum)    -- - - - - - - - - - - - - getsocket
 	-- if so, try the next server
 	ok, err = sock:setsockname('*', 0);
 	if not ok then return self:servfail(sock, err); end
-	ok, err = sock:setpeername(self.server[servernum], 53);
+	ok, err = sock:setpeername(peer, 53);
 	if not ok then return self:servfail(sock, err); end
 	return sock;
 end
-- 
cgit v1.2.3


From e03302f412a0c4fa2c239251851baf9e99fbff3a Mon Sep 17 00:00:00 2001
From: Kim Alvefur <zash@zash.se>
Date: Mon, 4 Jan 2016 17:47:40 +0100
Subject: util.ip: Support zone id syntax in IPv6 addresses

---
 util/ip.lua | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/util/ip.lua b/util/ip.lua
index 043303ee..acfd7f24 100644
--- a/util/ip.lua
+++ b/util/ip.lua
@@ -25,6 +25,10 @@ local function new_ip(ipStr, proto)
 	elseif proto ~= "IPv4" and proto ~= "IPv6" then
 		return nil, "invalid protocol";
 	end
+	local zone;
+	if proto == "IPv6" and ipStr:find('%', 1, true) then
+		ipStr, zone = ipStr:match("^(.-)%%(.*)");
+	end
 	if proto == "IPv6" and ipStr:find('.', 1, true) then
 		local changed;
 		ipStr, changed = ipStr:gsub(":(%d+)%.(%d+)%.(%d+)%.(%d+)$", function(a,b,c,d)
@@ -33,7 +37,7 @@ local function new_ip(ipStr, proto)
 		if changed ~= 1 then return nil, "invalid-address"; end
 	end
 
-	return setmetatable({ addr = ipStr, proto = proto }, ip_mt);
+	return setmetatable({ addr = ipStr, proto = proto, zone = zone }, ip_mt);
 end
 
 local function toBits(ip)
-- 
cgit v1.2.3


From 58885565fee199cba81a0d113eb6839d1f5fc727 Mon Sep 17 00:00:00 2001
From: Kim Alvefur <zash@zash.se>
Date: Mon, 4 Jan 2016 15:46:06 +0100
Subject: net.dns: Allow a zone id in resolv.conf (eg like %eth0)

---
 net/dns.lua | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/net/dns.lua b/net/dns.lua
index 9d90c24c..49958ed7 100644
--- a/net/dns.lua
+++ b/net/dns.lua
@@ -600,7 +600,7 @@ function resolver:adddefaultnameservers()    -- - - - -  adddefaultnameservers
 		if resolv_conf then
 			for line in resolv_conf:lines() do
 				line = line:gsub("#.*$", "")
-					:match('^%s*nameserver%s+([%x:%.]*)%s*$');
+					:match('^%s*nameserver%s+([%x:%.]*%%?%S*)%s*$');
 				if line then
 					local ip = new_ip(line);
 					if ip then
-- 
cgit v1.2.3


From 8a8f379272deeb7dbaeb35c3aadb0b03def8849e Mon Sep 17 00:00:00 2001
From: Kim Alvefur <zash@zash.se>
Date: Wed, 6 Jan 2016 02:46:47 +0100
Subject: util.uuid: Use /dev/urandom

---
 util/uuid.lua | 43 ++++++++++++++++---------------------------
 1 file changed, 16 insertions(+), 27 deletions(-)

diff --git a/util/uuid.lua b/util/uuid.lua
index bb70d000..58f792fd 100644
--- a/util/uuid.lua
+++ b/util/uuid.lua
@@ -6,44 +6,33 @@
 -- COPYING file in the source package for more information.
 --
 
-
-local tostring = tostring;
-local os_time = os.time;
-local os_clock = os.clock;
-local sha1 = require "util.hashes".sha1;
+local error = error;
+local round_up = math.ceil;
+local urandom, urandom_err = io.open("/dev/urandom", "r+");
 
 module "uuid"
 
-local last_uniq_time = 0;
-local function uniq_time()
-	local new_uniq_time = os_time();
-	if last_uniq_time >= new_uniq_time then new_uniq_time = last_uniq_time + 1; end
-	last_uniq_time = new_uniq_time;
-	return new_uniq_time;
-end
-
-local function new_random(x)
-	return sha1(x..os_clock()..tostring({}), true);
-end
-
-local buffer = new_random(uniq_time());
-local function _seed(x)
-	buffer = new_random(buffer..x);
-end
 local function get_nibbles(n)
-	if #buffer < n then _seed(uniq_time()); end
-	local r = buffer:sub(0, n);
-	buffer = buffer:sub(n+1);
-	return r;
+	local binary_random = urandom:read(round_up(n/2));
+	local hex_random = binary_random:gsub(".",
+		function (x) return ("%02x"):format(x:byte()) end);
+	return hex_random:sub(1, n);
 end
 local function get_twobits()
-	return ("%x"):format(get_nibbles(1):byte() % 4 + 8);
+	return ("%x"):format(urandom:read(1):byte() % 4 + 8);
 end
 
 function generate()
+	if not urandom then
+		error("Unable to obtain a secure random number generator, please see https://prosody.im/doc/random ("..urandom_err..")");
+	end
 	-- generate RFC 4122 complaint UUIDs (version 4 - random)
 	return get_nibbles(8).."-"..get_nibbles(4).."-4"..get_nibbles(3).."-"..(get_twobits())..get_nibbles(3).."-"..get_nibbles(12);
 end
-seed = _seed;
+
+function seed(x)
+	urandom:write(x);
+	urandom:flush();
+end
 
 return _M;
-- 
cgit v1.2.3


From c515c93724a691a3fdbcc97e7684c09fbeaa338f Mon Sep 17 00:00:00 2001
From: Kim Alvefur <zash@zash.se>
Date: Wed, 6 Jan 2016 03:28:31 +0100
Subject: util.uuid: Take random byte directly instead of the low bits from the
 ascii value of a hex nibble

---
 util/uuid.lua | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/util/uuid.lua b/util/uuid.lua
index e10fc0f7..f4fd21f6 100644
--- a/util/uuid.lua
+++ b/util/uuid.lua
@@ -16,7 +16,7 @@ local function get_nibbles(n)
 end
 
 local function get_twobits()
-	return ("%x"):format(get_nibbles(1):byte() % 4 + 8);
+	return ("%x"):format(random_bytes(1):byte() % 4 + 8);
 end
 
 local function generate()
-- 
cgit v1.2.3


From b057664428d529b182ac9a69800402d2f517b43b Mon Sep 17 00:00:00 2001
From: Kim Alvefur <zash@zash.se>
Date: Wed, 6 Jan 2016 03:28:56 +0100
Subject: util.random: Use /dev/urandom

---
 util/random.lua | 28 ++++------------------------
 1 file changed, 4 insertions(+), 24 deletions(-)

diff --git a/util/random.lua b/util/random.lua
index 5938a94f..4963e98c 100644
--- a/util/random.lua
+++ b/util/random.lua
@@ -6,35 +6,15 @@
 -- COPYING file in the source package for more information.
 --
 
-local tostring = tostring;
-local os_time = os.time;
-local os_clock = os.clock;
-local ceil = math.ceil;
-local H = require "util.hashes".sha512;
-
-local last_uniq_time = 0;
-local function uniq_time()
-	local new_uniq_time = os_time();
-	if last_uniq_time >= new_uniq_time then new_uniq_time = last_uniq_time + 1; end
-	last_uniq_time = new_uniq_time;
-	return new_uniq_time;
-end
-
-local function new_random(x)
-	return H(x..os_clock()..tostring({}));
-end
-
-local buffer = new_random(uniq_time());
+local urandom = assert(io.open("/dev/urandom", "r+"));
 
 local function seed(x)
-	buffer = new_random(buffer..x);
+	urandom:write(x);
+	urandom:flush();
 end
 
 local function bytes(n)
-	if #buffer < n+4 then seed(uniq_time()); end
-	local r = buffer:sub(1, n);
-	buffer = buffer:sub(n+1);
-	return r;
+	return urandom:read(n);
 end
 
 return {
-- 
cgit v1.2.3


From cb1eeb23869d5207f2fad1ef557d8f453be6f15e Mon Sep 17 00:00:00 2001
From: Matthew Wild <mwild1@gmail.com>
Date: Thu, 7 Jan 2016 15:37:47 +0000
Subject: mod_http_files: Santize the path relative to our base URL before
 translating it to a filesystem path, fixes a relative path traversal
 vulnerability

---
 plugins/mod_http_files.lua | 34 +++++++++++++++++++++++++++++++++-
 1 file changed, 33 insertions(+), 1 deletion(-)

diff --git a/plugins/mod_http_files.lua b/plugins/mod_http_files.lua
index 9839fed9..6275cca5 100644
--- a/plugins/mod_http_files.lua
+++ b/plugins/mod_http_files.lua
@@ -49,6 +49,34 @@ if not mime_map then
 	end
 end
 
+local forbidden_chars_pattern = "[/%z]";
+if prosody.platform == "windows" then
+	forbidden_chars_pattern = "[/%z\001-\031\127\"*:<>?|]"
+end
+
+local urldecode = require "util.http".urldecode;
+function sanitize_path(path)
+	local out = {};
+
+	local c = 0;
+	for component in path:gmatch("([^/]+)") do
+		component = urldecode(component);
+		if component:find(forbidden_chars_pattern) then
+			return nil;
+		elseif component == ".." then
+			if c <= 0 then
+				return nil;
+			end
+			out[c] = nil;
+			c = c - 1;
+		elseif component ~= "." then
+			c = c + 1;
+			out[c] = component;
+		end
+	end
+	return "/"..table.concat(out, "/");
+end
+
 local cache = setmetatable({}, { __mode = "kv" }); -- Let the garbage collector have it if it wants to.
 
 function serve(opts)
@@ -60,7 +88,11 @@ function serve(opts)
 	local directory_index = opts.directory_index;
 	local function serve_file(event, path)
 		local request, response = event.request, event.response;
-		local orig_path = request.path;
+		path = sanitize_path(path);
+		if not path then
+			return 400;
+		end
+		local orig_path = sanitize_path(request.path);
 		local full_path = base_path .. (path and "/"..path or ""):gsub("/", path_sep);
 		local attr = stat(full_path:match("^.*[^\\/]")); -- Strip trailing path separator because Windows
 		if not attr then
-- 
cgit v1.2.3


From 76de073eea372f346476b15aa5abe65233762e72 Mon Sep 17 00:00:00 2001
From: Matthew Wild <mwild1@gmail.com>
Date: Fri, 8 Jan 2016 13:01:27 +0000
Subject: Backout 88d54bec26b7 prior to release, as it certainly requires more
 testing

---
 net/dns.lua | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/net/dns.lua b/net/dns.lua
index 49958ed7..f56157d0 100644
--- a/net/dns.lua
+++ b/net/dns.lua
@@ -862,7 +862,9 @@ function resolver:receive(rset)    -- - - - - - - - - - - - - - - - -  receive
 					--self.print(response);
 
 					for j,rr in pairs(response.answer) do
-						self:remember(rr, response.question[1].type)
+						if rr.name:sub(-#response.question[1].name, -1) == response.question[1].name then
+							self:remember(rr, response.question[1].type)
+						end
 					end
 
 					-- retire the query
-- 
cgit v1.2.3

-- 
cgit v1.2.3


From b3d9c810676d288d193e4dcc3d95456e8a050f0e Mon Sep 17 00:00:00 2001
From: Kim Alvefur <zash@zash.se>
Date: Fri, 8 Jan 2016 16:20:02 +0100
Subject: tests: Fix merge, modulemanager test was removed

---
 tests/test.lua | 1 -
 1 file changed, 1 deletion(-)

diff --git a/tests/test.lua b/tests/test.lua
index 5d5851e1..1192b7b8 100644
--- a/tests/test.lua
+++ b/tests/test.lua
@@ -14,7 +14,6 @@ function run_all_tests()
 	dotest "util.multitable"
 	dotest "util.rfc6724"
 	dotest "util.http"
-	dotest "core.modulemanager"
 	dotest "core.stanza_router"
 	dotest "core.s2smanager"
 	dotest "core.configmanager"
-- 
cgit v1.2.3