aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWaqas Hussain <waqas20@gmail.com>2013-01-22 08:30:38 +0500
committerWaqas Hussain <waqas20@gmail.com>2013-01-22 08:30:38 +0500
commit0f2d3d7139c741b6bd8714048694ee16a9b11c91 (patch)
tree9938dd9411cf02b2c7cc7a82103633f7378030b8
parent1ae08f23d712da167747a7d59feac9965d6ef9ac (diff)
parentb1f22daa932ac857022412e734533ff05bad1594 (diff)
downloadprosody-0f2d3d7139c741b6bd8714048694ee16a9b11c91.tar.gz
prosody-0f2d3d7139c741b6bd8714048694ee16a9b11c91.zip
Merge 0.9->trunk
-rw-r--r--certs/Makefile6
-rw-r--r--certs/localhost.crt (renamed from certs/localhost.cert)0
-rw-r--r--core/certmanager.lua2
-rw-r--r--net/http/parser.lua1
-rw-r--r--net/http/server.lua17
-rw-r--r--net/server_event.lua14
-rw-r--r--net/server_select.lua2
-rw-r--r--plugins/mod_auth_internal_hashed.lua8
-rw-r--r--plugins/mod_auth_internal_plain.lua8
-rw-r--r--plugins/mod_component.lua1
-rw-r--r--plugins/mod_presence.lua2
-rw-r--r--plugins/muc/muc.lib.lua2
-rwxr-xr-xprosody2
-rw-r--r--prosody.cfg.lua.dist2
-rwxr-xr-xprosodyctl13
-rw-r--r--util/http.lua15
-rw-r--r--util/openssl.lua12
-rw-r--r--util/sasl/digest-md5.lua11
-rw-r--r--util/sasl/plain.lua9
-rw-r--r--util/sasl/scram.lua10
20 files changed, 91 insertions, 46 deletions
diff --git a/certs/Makefile b/certs/Makefile
index c5e4294c..f3854c5f 100644
--- a/certs/Makefile
+++ b/certs/Makefile
@@ -1,4 +1,4 @@
-.DEFAULT: localhost.cert
+.DEFAULT: localhost.crt
keysize=2048
# How to:
@@ -8,7 +8,7 @@ keysize=2048
# Then `make yourhost.key` to create your private key, you can
# include keysize=number to change the size of the key.
# Then you can either `make yourhost.csr` to generate a certificate
-# signing request that you can submit to a CA, or `make yourhost.cert`
+# signing request that you can submit to a CA, or `make yourhost.crt`
# to generate a self signed certificate.
.PRECIOUS: %.cnf %.key
@@ -18,7 +18,7 @@ keysize=2048
openssl req -new -key $(lastword $^) -out $@ -utf8 -config $(firstword $^)
# Self signed
-%.cert: %.cnf %.key
+%.crt: %.cnf %.key
openssl req -new -x509 -nodes -key $(lastword $^) -days 365 \
-sha1 -out $@ -utf8 -config $(firstword $^)
diff --git a/certs/localhost.cert b/certs/localhost.crt
index 5156d307..5156d307 100644
--- a/certs/localhost.cert
+++ b/certs/localhost.crt
diff --git a/core/certmanager.lua b/core/certmanager.lua
index a9f8b644..8607e618 100644
--- a/core/certmanager.lua
+++ b/core/certmanager.lua
@@ -33,7 +33,7 @@ local default_verify = (ssl and ssl.x509 and { "peer", "client_once", }) or "non
local default_options = { "no_sslv2", luasec_has_noticket and "no_ticket" or nil };
local default_verifyext = { "lsec_continue", "lsec_ignore_purpose" };
-if not luasec_has_verifyext and ssl.x509 then
+if ssl and not luasec_has_verifyext and ssl.x509 then
-- COMPAT mw/luasec-hg
for i=1,#default_verifyext do -- Remove lsec_ prefix
default_verify[#default_verify+1] = default_verifyext[i]:sub(6);
diff --git a/net/http/parser.lua b/net/http/parser.lua
index b53dfa4e..64cf38c0 100644
--- a/net/http/parser.lua
+++ b/net/http/parser.lua
@@ -77,6 +77,7 @@ function httpstream.new(success_cb, error_cb, parser_type, options_cb)
end
end
end
+ if not first_line then error = true; return error_cb("invalid-status-line"); end
len = tonumber(headers["content-length"]); -- TODO check for invalid len
if client then
-- FIXME handle '100 Continue' response (by skipping it)
diff --git a/net/http/server.lua b/net/http/server.lua
index 69908e4e..7cf25009 100644
--- a/net/http/server.lua
+++ b/net/http/server.lua
@@ -156,12 +156,23 @@ function handle_request(conn, request, finish_cb)
local date_header = os_date('!%a, %d %b %Y %H:%M:%S GMT'); -- FIXME use
local conn_header = request.headers.connection;
- local keep_alive = conn_header == "Keep-Alive" or (request.httpversion == "1.1" and conn_header ~= "close");
+ conn_header = conn_header and ","..conn_header:gsub("[ \t]", ""):lower().."," or ""
+ local httpversion = request.httpversion
+ local persistent = conn_header:find(",keep-alive,", 1, true)
+ or (httpversion == "1.1" and not conn_header:find(",close,", 1, true));
+
+ local response_conn_header;
+ if persistent then
+ response_conn_header = "Keep-Alive";
+ else
+ response_conn_header = httpversion == "1.1" and "close" or nil
+ end
local response = {
request = request;
status_code = 200;
- headers = { date = date_header, connection = (keep_alive and "Keep-Alive" or "close") };
+ headers = { date = date_header, connection = response_conn_header };
+ persistent = persistent;
conn = conn;
send = _M.send_response;
finish_cb = finish_cb;
@@ -241,7 +252,7 @@ function _M.send_response(response, body)
response:on_destroy();
response.on_destroy = nil;
end
- if headers.connection == "Keep-Alive" then
+ if response.persistent then
response:finish_cb();
else
response.conn:close();
diff --git a/net/server_event.lua b/net/server_event.lua
index e69530ff..08926939 100644
--- a/net/server_event.lua
+++ b/net/server_event.lua
@@ -40,6 +40,9 @@ local tostring = use "tostring"
local coroutine = use "coroutine"
local setmetatable = use "setmetatable"
+local t_insert = table.insert
+local t_concat = table.concat
+
local ssl = use "ssl"
local socket = use "socket" or require "socket"
@@ -309,7 +312,7 @@ do
debug( "error:", err ) -- to much, check your app
return nil, err
end
- self.writebuffer = self.writebuffer .. data -- new buffer
+ t_insert(self.writebuffer, data) -- new buffer
self.writebufferlen = total
if not self.eventwrite then -- register new write event
--vdebug( "register new write event" )
@@ -466,7 +469,7 @@ do
type = "client";
conn = client;
currenttime = socket_gettime( ); -- safe the origin
- writebuffer = ""; -- writebuffer
+ writebuffer = {}; -- writebuffer
writebufferlen = 0; -- length of writebuffer
send = client.send; -- caching table lookups
receive = client.receive;
@@ -520,10 +523,11 @@ do
interface.eventwritetimeout = false
end
end
- local succ, err, byte = interface.conn:send( interface.writebuffer, 1, interface.writebufferlen )
+ interface.writebuffer = { t_concat(interface.writebuffer) }
+ local succ, err, byte = interface.conn:send( interface.writebuffer[1], 1, interface.writebufferlen )
--vdebug( "write data:", interface.writebuffer, "error:", err, "part:", byte )
if succ then -- writing succesful
- interface.writebuffer = ""
+ interface.writebuffer[1] = nil
interface.writebufferlen = 0
interface:ondrain();
if interface.fatalerror then
@@ -539,7 +543,7 @@ do
return -1
elseif byte and (err == "timeout" or err == "wantwrite") then -- want write again
--vdebug( "writebuffer is not empty:", err )
- interface.writebuffer = string_sub( interface.writebuffer, byte + 1, interface.writebufferlen ) -- new buffer
+ interface.writebuffer[1] = string_sub( interface.writebuffer[1], byte + 1, interface.writebufferlen ) -- new buffer
interface.writebufferlen = interface.writebufferlen - byte
if "wantread" == err then -- happens only with luasec
local callback = function( )
diff --git a/net/server_select.lua b/net/server_select.lua
index 97b9f199..0852d444 100644
--- a/net/server_select.lua
+++ b/net/server_select.lua
@@ -74,6 +74,7 @@ local idfalse
local closeall
local addsocket
local addserver
+local addtimer
local getserver
local wrapserver
local getsettings
@@ -237,7 +238,6 @@ wrapserver = function( listeners, socket, ip, serverport, pattern, sslctx, maxco
local client, err = accept( socket ) -- try to accept
if client then
local ip, clientport = client:getpeername( )
- client:settimeout( 0 )
local handler, client, err = wrapconnection( handler, listeners, client, ip, serverport, clientport, pattern, sslctx ) -- wrap new client socket
if err then -- error while wrapping ssl socket
return false
diff --git a/plugins/mod_auth_internal_hashed.lua b/plugins/mod_auth_internal_hashed.lua
index 4535f9c9..cb6cc8ff 100644
--- a/plugins/mod_auth_internal_hashed.lua
+++ b/plugins/mod_auth_internal_hashed.lua
@@ -13,7 +13,6 @@ local getAuthenticationDatabaseSHA1 = require "util.sasl.scram".getAuthenticatio
local usermanager = require "core.usermanager";
local generate_uuid = require "util.uuid".generate;
local new_sasl = require "util.sasl".new;
-local nodeprep = require "util.encodings".stringprep.nodeprep;
local to_hex;
do
@@ -124,12 +123,7 @@ end
function provider.get_sasl_handler()
local testpass_authentication_profile = {
plain_test = function(sasl, username, password, realm)
- local prepped_username = nodeprep(username);
- if not prepped_username then
- log("debug", "NODEprep failed on username: %s", username);
- return "", nil;
- end
- return usermanager.test_password(prepped_username, realm, password), true;
+ return usermanager.test_password(username, realm, password), true;
end,
scram_sha_1 = function(sasl, username, realm)
local credentials = datamanager.load(username, host, "accounts");
diff --git a/plugins/mod_auth_internal_plain.lua b/plugins/mod_auth_internal_plain.lua
index 7514164d..178ae5a5 100644
--- a/plugins/mod_auth_internal_plain.lua
+++ b/plugins/mod_auth_internal_plain.lua
@@ -9,7 +9,6 @@
local datamanager = require "util.datamanager";
local usermanager = require "core.usermanager";
local new_sasl = require "util.sasl".new;
-local nodeprep = require "util.encodings".stringprep.nodeprep;
local log = module._log;
local host = module.host;
@@ -67,12 +66,7 @@ end
function provider.get_sasl_handler()
local getpass_authentication_profile = {
plain = function(sasl, username, realm)
- local prepped_username = nodeprep(username);
- if not prepped_username then
- log("debug", "NODEprep failed on username: %s", username);
- return "", nil;
- end
- local password = usermanager.get_password(prepped_username, realm);
+ local password = usermanager.get_password(username, realm);
if not password then
return "", nil;
end
diff --git a/plugins/mod_component.lua b/plugins/mod_component.lua
index 6270b403..16084a78 100644
--- a/plugins/mod_component.lua
+++ b/plugins/mod_component.lua
@@ -309,6 +309,7 @@ end
module:provides("net", {
name = "component";
+ private = true;
listener = listener;
default_port = 5347;
multiplex = {
diff --git a/plugins/mod_presence.lua b/plugins/mod_presence.lua
index 20d0adf0..23012750 100644
--- a/plugins/mod_presence.lua
+++ b/plugins/mod_presence.lua
@@ -18,6 +18,7 @@ local core_post_stanza = prosody.core_post_stanza;
local st = require "util.stanza";
local jid_split = require "util.jid".split;
local jid_bare = require "util.jid".bare;
+local datetime = require "util.datetime";
local hosts = hosts;
local NULL = {};
@@ -135,6 +136,7 @@ function handle_normal_presence(origin, stanza)
end
else
origin.presence = stanza;
+ stanza:tag("delay", { xmlns = "urn:xmpp:delay", from = host, stamp = datetime.datetime() }):up();
if origin.priority ~= priority then
origin.priority = priority;
recalc_resource_map(user);
diff --git a/plugins/muc/muc.lib.lua b/plugins/muc/muc.lib.lua
index 9755ba65..16a0238d 100644
--- a/plugins/muc/muc.lib.lua
+++ b/plugins/muc/muc.lib.lua
@@ -529,7 +529,7 @@ function room_mt:handle_to_occupant(origin, stanza) -- PM, vCards, etc
self:_route_stanza(stanza);
end
stanza.attr.from, stanza.attr.to, stanza.attr.id = from, to, id;
- else
+ elseif type ~= "error" then
origin.send(st.error_reply(stanza, "cancel", "not-acceptable"));
end
elseif stanza.name == "message" and type == "groupchat" then -- groupchat messages not allowed in PM
diff --git a/prosody b/prosody
index da77719d..00fde04c 100755
--- a/prosody
+++ b/prosody
@@ -70,6 +70,8 @@ function read_config()
if CFG_CONFIGDIR then
table.insert(filenames, CFG_CONFIGDIR.."/"..arg[2]);
end
+ elseif os.getenv("PROSODY_CONFIG") then -- Passed by prosodyctl
+ table.insert(filenames, os.getenv("PROSODY_CONFIG"));
else
for _, format in ipairs(config.parsers()) do
table.insert(filenames, (CFG_CONFIGDIR or ".").."/prosody.cfg."..format);
diff --git a/prosody.cfg.lua.dist b/prosody.cfg.lua.dist
index c0c729a9..9ca9608a 100644
--- a/prosody.cfg.lua.dist
+++ b/prosody.cfg.lua.dist
@@ -89,7 +89,7 @@ allow_registration = false;
-- to use SSL/TLS, you may comment or remove this
ssl = {
key = "certs/localhost.key";
- certificate = "certs/localhost.cert";
+ certificate = "certs/localhost.crt";
}
-- Only allow encrypted streams? Encryption is already used when
diff --git a/prosodyctl b/prosodyctl
index 4d3c4790..0d1194f4 100755
--- a/prosodyctl
+++ b/prosodyctl
@@ -61,16 +61,17 @@ end
config = require "core.configmanager"
+local ENV_CONFIG;
do
local filenames = {};
local filename;
if arg[1] == "--config" and arg[2] then
table.insert(filenames, arg[2]);
- table.remove(arg, 1); table.remove(arg, 1);
if CFG_CONFIGDIR then
table.insert(filenames, CFG_CONFIGDIR.."/"..arg[2]);
end
+ table.remove(arg, 1); table.remove(arg, 1);
else
for _, format in ipairs(config.parsers()) do
table.insert(filenames, (CFG_CONFIGDIR or ".").."/prosody.cfg."..format);
@@ -81,6 +82,7 @@ do
local file = io.open(filename);
if file then
file:close();
+ ENV_CONFIG = filename;
CFG_CONFIGDIR = filename:match("^(.*)[\\/][^\\/]*$");
break;
end
@@ -162,6 +164,7 @@ if ok and pposix then
-- Set our umask to protect data files
pposix.umask(config.get("*", "core", "umask") or "027");
pposix.setenv("HOME", data_path);
+ pposix.setenv("PROSODY_CONFIG", ENV_CONFIG);
else
print("Error: Unable to load pposix module. Check that Prosody is installed correctly.")
print("For more help send the below error to us through http://prosody.im/discuss");
@@ -639,8 +642,8 @@ function commands.unregister(arg)
return 1;
end
-local openssl = require "util.openssl";
-local lfs = require "lfs";
+local openssl;
+local lfs;
local cert_commands = {};
@@ -723,7 +726,7 @@ end
function cert_commands.generate(arg)
if #arg >= 1 and arg[1] ~= "--help" then
- local cert_filename = (CFG_DATADIR or ".") .. "/" .. arg[1] .. ".cert";
+ local cert_filename = (CFG_DATADIR or ".") .. "/" .. arg[1] .. ".crt";
if ask_overwrite(cert_filename) then
return nil, cert_filename;
end
@@ -744,6 +747,8 @@ end
function commands.cert(arg)
if #arg >= 1 and arg[1] ~= "--help" then
+ openssl = require "util.openssl";
+ lfs = require "lfs";
local subcmd = table.remove(arg, 1);
if type(cert_commands[subcmd]) == "function" then
if not arg[1] then
diff --git a/util/http.lua b/util/http.lua
new file mode 100644
index 00000000..5b49d1d0
--- /dev/null
+++ b/util/http.lua
@@ -0,0 +1,15 @@
+-- Prosody IM
+-- Copyright (C) 2013 Florian Zeitz
+--
+-- This project is MIT/X11 licensed. Please see the
+-- COPYING file in the source package for more information.
+--
+
+local http = {};
+
+function http.contains_token(field, token)
+ field = ","..field:gsub("[ \t]", ""):lower()..",";
+ return field:find(","..token:lower()..",", 1, true) ~= nil;
+end
+
+return http;
diff --git a/util/openssl.lua b/util/openssl.lua
index 8fdb9b4a..b3dc2943 100644
--- a/util/openssl.lua
+++ b/util/openssl.lua
@@ -72,15 +72,11 @@ local function ia5string(s)
return s_format("IA5STRING:%s", s);
end
-local util = {};
_M.util = {
utf8string = utf8string,
ia5string = ia5string,
};
-local function xmppAddr(t, host)
-end
-
function ssl_config:add_dNSName(host)
t_insert(self.subject_alternative_name.DNS, idna_to_ascii(host));
end
@@ -95,12 +91,12 @@ function ssl_config:add_xmppAddr(host)
s_format("%s;%s", oid_xmppaddr, utf8string(host)));
end
-function ssl_config:from_prosody(hosts, config, certhosts, raw)
+function ssl_config:from_prosody(hosts, config, certhosts)
-- TODO Decide if this should go elsewhere
local found_matching_hosts = false;
for i = 1,#certhosts do
local certhost = certhosts[i];
- for name, host in pairs(hosts) do
+ for name in pairs(hosts) do
if name == certhost or name:sub(-1-#certhost) == "."..certhost then
found_matching_hosts = true;
self:add_dNSName(name);
@@ -137,7 +133,7 @@ do -- Lua to shell calls.
end
end
end
- for k,v in ipairs(o) do
+ for _,v in ipairs(o) do
t_insert(r, ("'%s'"):format(shell_escape(tostring(v))));
end
return t_concat(r, " ");
@@ -145,7 +141,7 @@ do -- Lua to shell calls.
local os_execute = os.execute;
setmetatable(_M, {
- __index=function(self,f)
+ __index=function(_,f)
return function(opts)
return 0 == os_execute(serialize(f, type(opts) == "table" and opts or {}));
end;
diff --git a/util/sasl/digest-md5.lua b/util/sasl/digest-md5.lua
index de2538fc..591d8537 100644
--- a/util/sasl/digest-md5.lua
+++ b/util/sasl/digest-md5.lua
@@ -23,6 +23,7 @@ local to_byte, to_char = string.byte, string.char;
local md5 = require "util.hashes".md5;
local log = require "util.logger".init("sasl");
local generate_uuid = require "util.uuid".generate;
+local nodeprep = require "util.encodings".stringprep.nodeprep;
module "sasl.digest-md5"
@@ -139,10 +140,15 @@ local function digest(self, message)
end
-- check for username, it's REQUIRED by RFC 2831
- if not response["username"] then
+ local username = response["username"];
+ local _nodeprep = self.profile.nodeprep;
+ if username and _nodeprep ~= false then
+ username = (_nodeprep or nodeprep)(username); -- FIXME charset
+ end
+ if not username or username == "" then
return "failure", "malformed-request";
end
- self["username"] = response["username"];
+ self.username = username;
-- check for nonce, ...
if not response["nonce"] then
@@ -178,7 +184,6 @@ local function digest(self, message)
end
--TODO maybe realm support
- self.username = response["username"];
local Y, state;
if self.profile.plain then
local password, state = self.profile.plain(self, response["username"], self.realm)
diff --git a/util/sasl/plain.lua b/util/sasl/plain.lua
index d108a40d..c9ec2911 100644
--- a/util/sasl/plain.lua
+++ b/util/sasl/plain.lua
@@ -13,6 +13,7 @@
local s_match = string.match;
local saslprep = require "util.encodings".stringprep.saslprep;
+local nodeprep = require "util.encodings".stringprep.nodeprep;
local log = require "util.logger".init("sasl");
module "sasl.plain"
@@ -54,6 +55,14 @@ local function plain(self, message)
return "failure", "malformed-request", "Invalid username or password.";
end
+ local _nodeprep = self.profile.nodeprep;
+ if _nodeprep ~= false then
+ authentication = (_nodeprep or nodeprep)(authentication);
+ if not authentication or authentication == "" then
+ return "failure", "malformed-request", "Invalid username or password."
+ end
+ end
+
local correct, state = false, false;
if self.profile.plain then
local correct_password;
diff --git a/util/sasl/scram.lua b/util/sasl/scram.lua
index 055ba16a..d0e8987c 100644
--- a/util/sasl/scram.lua
+++ b/util/sasl/scram.lua
@@ -19,6 +19,7 @@ local hmac_sha1 = require "util.hmac".sha1;
local sha1 = require "util.hashes".sha1;
local generate_uuid = require "util.uuid".generate;
local saslprep = require "util.encodings".stringprep.saslprep;
+local nodeprep = require "util.encodings".stringprep.nodeprep;
local log = require "util.logger".init("sasl");
local t_concat = table.concat;
local char = string.char;
@@ -76,7 +77,7 @@ function Hi(hmac, str, salt, i)
return res
end
-local function validate_username(username)
+local function validate_username(username, _nodeprep)
-- check for forbidden char sequences
for eq in username:gmatch("=(.?.?)") do
if eq ~= "2C" and eq ~= "3D" then
@@ -90,6 +91,11 @@ local function validate_username(username)
-- apply SASLprep
username = saslprep(username);
+
+ if username and _nodeprep ~= false then
+ username = (_nodeprep or nodeprep)(username);
+ end
+
return username and #username>0 and username;
end
@@ -133,7 +139,7 @@ local function scram_gen(hash_name, H_f, HMAC_f)
return "failure", "malformed-request", "Channel binding isn't support at this time.";
end
- self.state.name = validate_username(self.state.name);
+ self.state.name = validate_username(self.state.name, self.profile.nodeprep);
if not self.state.name then
log("debug", "Username violates either SASLprep or contains forbidden character sequences.")
return "failure", "malformed-request", "Invalid username.";