diff options
author | Waqas Hussain <waqas20@gmail.com> | 2013-01-22 08:30:38 +0500 |
---|---|---|
committer | Waqas Hussain <waqas20@gmail.com> | 2013-01-22 08:30:38 +0500 |
commit | 8c8ebcc4aeb65184408557a5d3f967dd2b0e7e51 (patch) | |
tree | 9938dd9411cf02b2c7cc7a82103633f7378030b8 | |
parent | f9b9d6c4d2b71e142bc7cd254bc91171e32b2825 (diff) | |
parent | 4808daf39fd7b3d3de0e2c25e871dcbacbed1299 (diff) | |
download | prosody-8c8ebcc4aeb65184408557a5d3f967dd2b0e7e51.tar.gz prosody-8c8ebcc4aeb65184408557a5d3f967dd2b0e7e51.zip |
Merge 0.9->trunk
-rw-r--r-- | certs/Makefile | 6 | ||||
-rw-r--r-- | certs/localhost.crt (renamed from certs/localhost.cert) | 0 | ||||
-rw-r--r-- | core/certmanager.lua | 2 | ||||
-rw-r--r-- | net/http/parser.lua | 1 | ||||
-rw-r--r-- | net/http/server.lua | 17 | ||||
-rw-r--r-- | net/server_event.lua | 14 | ||||
-rw-r--r-- | net/server_select.lua | 2 | ||||
-rw-r--r-- | plugins/mod_auth_internal_hashed.lua | 8 | ||||
-rw-r--r-- | plugins/mod_auth_internal_plain.lua | 8 | ||||
-rw-r--r-- | plugins/mod_component.lua | 1 | ||||
-rw-r--r-- | plugins/mod_presence.lua | 2 | ||||
-rw-r--r-- | plugins/muc/muc.lib.lua | 2 | ||||
-rwxr-xr-x | prosody | 2 | ||||
-rw-r--r-- | prosody.cfg.lua.dist | 2 | ||||
-rwxr-xr-x | prosodyctl | 13 | ||||
-rw-r--r-- | util/http.lua | 15 | ||||
-rw-r--r-- | util/openssl.lua | 12 | ||||
-rw-r--r-- | util/sasl/digest-md5.lua | 11 | ||||
-rw-r--r-- | util/sasl/plain.lua | 9 | ||||
-rw-r--r-- | util/sasl/scram.lua | 10 |
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 @@ -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 @@ -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."; |