Software /
code /
prosody
Changeset
390:160d69c6eb89
Merge from waqas
author | Matthew Wild <mwild1@gmail.com> |
---|---|
date | Sun, 23 Nov 2008 05:03:36 +0000 |
parents | 383:32b586d9e915 (diff) 389:c747d6963d95 (current diff) |
children | 391:79bd7a3e906c |
files | |
diffstat | 9 files changed, 310 insertions(+), 43 deletions(-) [+] |
line wrap: on
line diff
--- a/core/configmanager.lua Sun Nov 23 03:32:57 2008 +0500 +++ b/core/configmanager.lua Sun Nov 23 05:03:36 2008 +0000 @@ -1,5 +1,7 @@ local _G = _G; +local setmetatable, loadfile, pcall, rawget, rawset, io = + setmetatable, loadfile, pcall, rawget, rawset, io; module "configmanager" local parsers = {}; @@ -21,6 +23,10 @@ end }; end +function getconfig() + return config; +end + function get(host, section, key) local sec = config[host][section]; if sec then @@ -45,15 +51,20 @@ end function load(filename, format) + format = format or filename:match("%w+$"); if parsers[format] and parsers[format].load then local f = io.open(filename); if f then - local ok, err = parsers[format](f:read("*a")); + local ok, err = parsers[format].load(f:read("*a")); f:close(); return ok, err; end end - return false, "no parser"; + if not format then + return nil, "no parser specified"; + else + return false, "no parser"; + end end function save(filename, format) @@ -65,21 +76,28 @@ end end +-- Built-in Lua parser do + local loadstring, pcall, setmetatable = _G.loadstring, _G.pcall, _G.setmetatable; + local setfenv, rawget, tostring = _G.setfenv, _G.rawget, _G.tostring; parsers.lua = {}; function parsers.lua.load(data) - local env = setmetatable({}, { __index = function (t, k) - if k:match("^mod_") then - return function (settings_table) + local env; + env = setmetatable({ Host = true; host = true; }, { __index = function (t, k) + return rawget(_G, k) or + function (settings_table) config[__currenthost or "*"][k] = settings_table; end; - end - return rawget(_G, k); + end, + __newindex = function (t, k, v) + set(env.__currenthost or "*", "core", k, v); end}); function env.Host(name) - env.__currenthost = name; + rawset(env, "__currenthost", name); + set(name or "*", "core", "defined", true); end + env.host = env.Host; local chunk, err = loadstring(data); @@ -95,8 +113,6 @@ return nil, err; end - - return true; end
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lxmppd.cfg.lua.dist Sun Nov 23 05:03:36 2008 +0000 @@ -0,0 +1,74 @@ +-- lxmppd Example Configuration File +-- +-- If it wasn't already obvious, -- starts a comment, and all +-- text after it is ignored by lxmppd. +-- +-- The config is split into sections, a global section, and one +-- for each defined host that we serve. You can add as many host +-- sections as you like. +-- +-- Lists are written { "like", "this", "one" } +-- Lists can also be of { 1, 2, 3 } numbers, etc. +-- Either commas, or semi-colons; may be used +-- as seperators. +-- +-- A table is a list of values, except each value has a name. An +-- example would be: +-- +-- logging = { type = "html", directory = "/var/logs", rotate = "daily" } +-- +-- Whitespace (that is tabs, spaces, line breaks) is insignificant, so can +-- be placed anywhere +-- that you deem fitting. Youcouldalsoremoveitentirely,butforobviousrea +--sonsIdon'trecommendit. +-- +-- Tip: You can check that the syntax of this file is correct when you have finished +-- by running: luac -p lxmppd.cfg.lua +-- If there are any errors, it will let you know what and where they are, otherwise it +-- will keep quiet. +-- +-- The only thing left to do is rename this file to remove the .dist ending, and fill in the +-- blanks. Good luck, and happy Jabbering! + +-- Global settings go in this section +Host "*" + + -- This is the list of modules lxmppd will load on startup. + -- It looks for plugins/mod_modulename.lua, so make sure that exists too. + modules_enabled = { + "saslauth"; -- Authentication for clients and servers. Recommended if you want to log in. + "legacyauth"; -- Legacy authentication. Only used by some old clients and bots. + "roster"; -- Allow users to have a roster. Recommended ;) + "register"; -- Allow users to register on this server using a client + "tls"; -- Add support for secure TLS on c2s/s2s connections + "vcard"; -- Allow users to set vCards + "private"; -- Private XML storage (for room bookmarks, etc.) + "version"; -- Replies to server version requests + "dialback"; -- s2s dialback support + }; + + -- These are the SSL/TLS-related settings. If you don't want + -- to use SSL/TLS, you may comment or remove this + ssl = { + key = "certs/server.key"; + certificate = "certs/server.crt"; + } + +-- This allows clients to connect to localhost. No harm in it. +Host "localhost" + +-- Section for example.com +-- (replace example.com with your domain name) +Host "example.com" + -- Assign this host a certificate for TLS, otherwise it would use the one + -- set in the global section (if any). + -- Note that old-style SSL on port 5223 only supports one certificate, and will always + -- use the global one. + ssl = { + key = "certs/example.com.key"; + certificate = "certs/example.com.crt"; + } + +Host "example.org" + enabled = false -- This will disable the host, preserving the config, but denying connections +
--- a/main.lua Sun Nov 23 03:32:57 2008 +0500 +++ b/main.lua Sun Nov 23 05:03:36 2008 +0000 @@ -4,22 +4,42 @@ require "lxp" require "socket" require "ssl" +local config = require "core.configmanager" -function log(type, area, message) - print(type, area, message); +log = require "util.logger".init("general"); + +do + -- TODO: Check for other formats when we add support for them + -- Use lfs? Make a new conf/ dir? + local ok, err = config.load("lxmppd.cfg.lua"); + if not ok then + log("error", "Couldn't load config file: %s", err); + log("info", "Falling back to old config file format...") + ok, err = pcall(dofile, "lxmppd.cfg"); + if not ok then + log("error", "Old config format loading failed too: %s", err); + else + for _, host in ipairs(_G.config.hosts) do + config.set(host, "core", "defined", true); + end + + config.set("*", "core", "modules_enabled", _G.config.modules); + config.set("*", "core", "ssl", _G.config.ssl_ctx); + end + end end -dofile "lxmppd.cfg" - -- Maps connections to sessions -- sessions = {}; hosts = {}; -if config.hosts and #config.hosts > 0 then - for _, host in pairs(config.hosts) do +local defined_hosts = config.getconfig(); + +for host, host_config in pairs(defined_hosts) do + if host ~= "*" and (host_config.core.enabled == nil or host_config.core.enabled) then hosts[host] = {type = "local", connected = true, sessions = {}, host = host, s2sout = {} }; end -else error("No hosts defined in the configuration file"); end +end -- Load and initialise core modules -- @@ -32,8 +52,10 @@ require "core.sessionmanager" require "core.stanza_router" +--[[ pcall(require, "remdebug.engine"); if remdebug then remdebug.engine.start() end +]] local start = require "net.connlisteners".start; require "util.stanza" @@ -42,11 +64,12 @@ ------------------------------------------------------------------------ -- Initialise modules -if config.modules and #config.modules > 0 then - for _, module in pairs(config.modules) do +local modules_enabled = config.get("*", "core", "modules_enabled"); +if modules_enabled then + for _, module in pairs(modules_enabled) do modulemanager.load(module); end -else error("No modules enabled in the configuration file"); end +end -- setup error handling setmetatable(_G, { __index = function (t, k) print("WARNING: ATTEMPT TO READ A NIL GLOBAL!!!", k); error("Attempt to read a non-existent global. Naughty boy.", 2); end, __newindex = function (t, k, v) print("ATTEMPT TO SET A GLOBAL!!!!", tostring(k).." = "..tostring(v)); error("Attempt to set a global. Naughty boy.", 2); end }) --]][][[]][]; @@ -54,9 +77,20 @@ local protected_handler = function (conn, data, err) local success, ret = pcall(handler, conn, data, err); if not success then print("ERROR on "..tostring(conn)..": "..ret); conn:close(); end end; local protected_disconnect = function (conn, err) local success, ret = pcall(disconnect, conn, err); if not success then print("ERROR on "..tostring(conn).." disconnect: "..ret); conn:close(); end end; + +local global_ssl_ctx = config.get("*", "core", "ssl"); +if global_ssl_ctx then + local default_ssl_ctx = { mode = "server", protocol = "sslv23", capath = "/etc/ssl/certs", verify = "none"; }; + setmetatable(global_ssl_ctx, { __index = default_ssl_ctx }); +end + -- start listening on sockets -start("xmppclient", { ssl = config.ssl_ctx }) -start("xmppserver", { ssl = config.ssl_ctx }) +start("xmppclient", { ssl = global_ssl_ctx }) +start("xmppserver", { ssl = global_ssl_ctx }) + +if config.get("*", "core", "console_enabled") then + start("console") +end modulemanager.fire_event("server-started");
--- a/net/connlisteners.lua Sun Nov 23 03:32:57 2008 +0500 +++ b/net/connlisteners.lua Sun Nov 23 05:03:36 2008 +0000 @@ -38,8 +38,8 @@ error("No such connection module: "..name, 0); end return server_add(h, - udata.port or h.default_port or error("Can't start listener "..name.." because no port was specified, and it has no default port", 0), - udata.interface or "*", udata.mode or h.default_mode or 1, udata.ssl ); + (udata and udata.port) or h.default_port or error("Can't start listener "..name.." because no port was specified, and it has no default port", 0), + (udata and udata.interface) or "*", (udata and udata.mode) or h.default_mode or 1, (udata and udata.ssl) or nil ); end return _M; \ No newline at end of file
--- a/net/dns.lua Sun Nov 23 03:32:57 2008 +0500 +++ b/net/dns.lua Sun Nov 23 05:03:36 2008 +0000 @@ -19,8 +19,8 @@ local coroutine, io, math, socket, string, table = coroutine, io, math, socket, string, table -local ipairs, next, pairs, print, setmetatable, tostring = - ipairs, next, pairs, print, setmetatable, tostring +local ipairs, next, pairs, print, setmetatable, tostring, assert, error = + ipairs, next, pairs, print, setmetatable, tostring, assert, error local get, set = ztact.get, ztact.set @@ -130,7 +130,7 @@ local rrs_metatable = {} -- - - - - - - - - - - - - - - - - - rrs_metatable function rrs_metatable.__tostring (rrs) - t = {} + local t = {} for i,rr in pairs (rrs) do append (t, tostring (rr)..'\n') end return table.concat (t) end @@ -501,8 +501,10 @@ function resolver:adddefaultnameservers () -- - - - - adddefaultnameservers - for line in io.lines ('/etc/resolv.conf') do - address = string.match (line, 'nameserver%s+(%d+%.%d+%.%d+%.%d+)') + local resolv_conf = io.open("/etc/resolv.conf"); + if not resolv_conf then return nil; end + for line in resolv_conf:lines() do + local address = string.match (line, 'nameserver%s+(%d+%.%d+%.%d+%.%d+)') if address then self:addnameserver (address) end end end @@ -580,7 +582,7 @@ for class,types in pairs (self.cache or {}) do for type,names in pairs (types) do for name,rrs in pairs (names) do - prune (rrs, time, 'soft') + prune (rrs, self.time, 'soft') end end end else self.cache = {} end end @@ -592,7 +594,7 @@ if not self.server then self:adddefaultnameservers () end - local question = question or encodeQuestion (qname, qtype, qclass) + local question = encodeQuestion (qname, qtype, qclass) local peek = self:peek (qname, qtype, qclass) if peek then return peek end @@ -765,7 +767,7 @@ -- this function seems to be redundant with resolver.new () - r = { active = {}, cache = {}, unsorted = {}, wanted = {}, yielded = {} } + local r = { active = {}, cache = {}, unsorted = {}, wanted = {}, yielded = {} } setmetatable (r, resolver) setmetatable (r.cache, cache_metatable) setmetatable (r.unsorted, { __mode = 'kv' })
--- a/net/server.lua Sun Nov 23 03:32:57 2008 +0500 +++ b/net/server.lua Sun Nov 23 05:03:36 2008 +0000 @@ -619,7 +619,7 @@ return shutdown( socket, pattern ) end handler.close = function( closed ) - if eol and not fatal_send_error then handler._dispatchdata(); end + if eol and not fatal_send_error then handler.dispatchdata(); end _ = not closed and shutdown( socket ) _ = not closed and close( socket ) writelen = ( eol and removesocket( writelist, socket, writelen ) ) or writelen
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plugins/mod_console.lua Sun Nov 23 05:03:36 2008 +0000 @@ -0,0 +1,140 @@ + +local connlisteners_register = require "net.connlisteners".register; + +local console_listener = { default_port = 5582; default_mode = "*l"; }; + +local commands = {}; +local default_env = {}; +local default_env_mt = { __index = default_env }; + +console = {}; + +function console:new_session(conn) + local w = conn.write; + return { conn = conn; + send = function (t) w(tostring(t)); end; + print = function (t) w("| "..tostring(t).."\n"); end; + disconnect = function () conn.close(); end; + env = setmetatable({}, default_env_mt); + }; +end + +local sessions = {}; + +function console_listener.listener(conn, data) + local session = sessions[conn]; + + if not session then + -- Handle new connection + session = console:new_session(conn); + sessions[conn] = session; + session.print("Welcome to the lxmppd admin console!"); + end + if data then + -- Handle data + + if data:match("[!.]$") then + local command = data:lower(); + command = data:match("^%w+") or data:match("%p"); + if commands[command] then + commands[command](session, data); + return; + end + end + + session.env._ = data; + + local chunk, err = loadstring("return "..data); + if not chunk then + chunk, err = loadstring(data); + if not chunk then + err = err:gsub("^%[string .-%]:%d+: ", ""); + err = err:gsub("^:%d+: ", ""); + err = err:gsub("'<eof>'", "the end of the line"); + session.print("Sorry, I couldn't understand that... "..err); + return; + end + end + + setfenv(chunk, session.env); + local ranok, taskok, message = pcall(chunk); + + if not ranok then + session.print("Fatal error while running command, it did not complete"); + session.print("Error: "..taskok); + return; + end + + if not message then + session.print("Result: "..tostring(taskok)); + return; + elseif (not taskok) and message then + session.print("Command completed with a problem"); + session.print("Message: "..tostring(message)); + return; + end + + session.print("OK: "..tostring(message)); + end +end + +function console_listener.disconnect(conn, err) + +end + +connlisteners_register('console', console_listener); + +-- Console commands -- +-- These are simple commands, not valid standalone in Lua + +function commands.bye(session) + session.print("See you! :)"); + session.disconnect(); +end + +commands["!"] = function (session, data) + if data:match("^!!") then + session.print("!> "..session.env._); + return console_listener.listener(session.conn, session.env._); + end + local old, new = data:match("^!(.-[^\\])!(.-)!$"); + if old and new then + local ok, res = pcall(string.gsub, session.env._, old, new); + if not ok then + session.print(res) + return; + end + session.print("!> "..res); + return console_listener.listener(session.conn, res); + end + session.print("Sorry, not sure what you want"); +end + +-- Session environment -- +-- Anything in default_env will be accessible within the session as a global variable + +default_env.server = {}; +function default_env.server.reload() + dofile "main.lua" + return true, "Server reloaded"; +end + +default_env.module = {}; +function default_env.module.load(name) + local mm = require "modulemanager"; + local ok, err = mm.load(name); + if not ok then + return false, err or "Unknown error loading module"; + end + return true, "Module loaded"; +end + +default_env.config = {}; +function default_env.config.load(filename, format) + local cfgm_load = require "core.configmanager".load; + local ok, err = cfgm_load(filename, format); + if not ok then + return false, err or "Unknown error loading config"; + end + return true, "Config loaded"; +end
--- a/plugins/mod_selftests.lua Sun Nov 23 03:32:57 2008 +0500 +++ b/plugins/mod_selftests.lua Sun Nov 23 05:03:36 2008 +0000 @@ -3,6 +3,8 @@ local register_component = require "core.componentmanager".register_component; local core_route_stanza = core_route_stanza; local socket = require "socket"; +local config = require "core.configmanager"; +local ping_hosts = config.get("*", "mod_selftests", "ping_hosts") or { "jabber.org" }; local open_pings = {}; @@ -10,7 +12,7 @@ local log = require "util.logger".init("mod_selftests"); -local tests_jid, host; "self_tests@getjabber.ath.cx"; +local tests_jid = "self_tests@getjabber.ath.cx"; local host = "getjabber.ath.cx"; if not (tests_jid and host) then @@ -44,14 +46,8 @@ open_pings[id] = socket.gettime(); end - send_ping "matthewwild.co.uk" - send_ping "snikket.com" - send_ping "gmail.com" - send_ping "isode.com" - send_ping "jabber.org" - send_ping "chrome.pl" - send_ping "swissjabber.ch" - send_ping "soapbox.net" - send_ping "jabber.ccc.de" + for _, host in ipairs(ping_hosts) do + send_ping(host); + end end); end
--- a/util/stanza.lua Sun Nov 23 03:32:57 2008 +0500 +++ b/util/stanza.lua Sun Nov 23 05:03:36 2008 +0000 @@ -30,6 +30,11 @@ function stanza_mt:query(xmlns) return self:tag("query", { xmlns = xmlns }); end + +function stanza_mt:body(text, attr) + return self:tag("body", attr):text(text); +end + function stanza_mt:tag(name, attrs) local s = stanza(name, attrs); (self.last_add[#self.last_add] or self):add_direct_child(s);