plugins/mod_admin_socket.lua
author Matthew Wild <mwild1@gmail.com>
Wed, 27 Mar 2024 15:35:15 +0000
branch0.12
changeset 13469 54a936345aaa
parent 12891 68df46926c26
child 12892 b8504b71735d
permissions -rw-r--r--
prosodyctl check: Warn about invalid domain names in the config file This ensures that domain names of virtual hosts and components are valid in XMPP, and that they are encoded correctly.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
10859
70ac7d23673d mod_admin_socket, util.adminstream: New module to manage a local unix domain socket for admin functionality
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     1
module:set_global();
70ac7d23673d mod_admin_socket, util.adminstream: New module to manage a local unix domain socket for admin functionality
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     2
70ac7d23673d mod_admin_socket, util.adminstream: New module to manage a local unix domain socket for admin functionality
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     3
local have_unix, unix = pcall(require, "socket.unix");
70ac7d23673d mod_admin_socket, util.adminstream: New module to manage a local unix domain socket for admin functionality
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     4
12396
5373724e08a5 mod_admin_socket: Compat for luasocket prior to unix datagram support
Kim Alvefur <zash@zash.se>
parents: 10870
diff changeset
     5
if have_unix and type(unix) == "function" then
12397
6966026262f4 mod_admin_socket: Comment on LuaSocket UNIX compat code
Kim Alvefur <zash@zash.se>
parents: 12396
diff changeset
     6
	-- COMPAT #1717
6966026262f4 mod_admin_socket: Comment on LuaSocket UNIX compat code
Kim Alvefur <zash@zash.se>
parents: 12396
diff changeset
     7
	-- Before the introduction of datagram support, only the stream socket
6966026262f4 mod_admin_socket: Comment on LuaSocket UNIX compat code
Kim Alvefur <zash@zash.se>
parents: 12396
diff changeset
     8
	-- constructor was exported instead of a module table. Due to the lack of a
6966026262f4 mod_admin_socket: Comment on LuaSocket UNIX compat code
Kim Alvefur <zash@zash.se>
parents: 12396
diff changeset
     9
	-- proper release of LuaSocket, distros have settled on shipping either the
6966026262f4 mod_admin_socket: Comment on LuaSocket UNIX compat code
Kim Alvefur <zash@zash.se>
parents: 12396
diff changeset
    10
	-- last RC tag or some commit since then.
6966026262f4 mod_admin_socket: Comment on LuaSocket UNIX compat code
Kim Alvefur <zash@zash.se>
parents: 12396
diff changeset
    11
	-- Here we accomodate both variants.
12396
5373724e08a5 mod_admin_socket: Compat for luasocket prior to unix datagram support
Kim Alvefur <zash@zash.se>
parents: 10870
diff changeset
    12
	unix = { stream = unix };
5373724e08a5 mod_admin_socket: Compat for luasocket prior to unix datagram support
Kim Alvefur <zash@zash.se>
parents: 10870
diff changeset
    13
end
10859
70ac7d23673d mod_admin_socket, util.adminstream: New module to manage a local unix domain socket for admin functionality
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    14
if not have_unix or type(unix) ~= "table" then
70ac7d23673d mod_admin_socket, util.adminstream: New module to manage a local unix domain socket for admin functionality
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    15
	module:log_status("error", "LuaSocket unix socket support not available or incompatible, ensure it is up to date");
70ac7d23673d mod_admin_socket, util.adminstream: New module to manage a local unix domain socket for admin functionality
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    16
	return;
70ac7d23673d mod_admin_socket, util.adminstream: New module to manage a local unix domain socket for admin functionality
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    17
end
70ac7d23673d mod_admin_socket, util.adminstream: New module to manage a local unix domain socket for admin functionality
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    18
70ac7d23673d mod_admin_socket, util.adminstream: New module to manage a local unix domain socket for admin functionality
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    19
local server = require "net.server";
70ac7d23673d mod_admin_socket, util.adminstream: New module to manage a local unix domain socket for admin functionality
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    20
70ac7d23673d mod_admin_socket, util.adminstream: New module to manage a local unix domain socket for admin functionality
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    21
local adminstream = require "util.adminstream";
12891
68df46926c26 mod_admin_socket: Return error on unhandled input to prevent apparent freeze
Kim Alvefur <zash@zash.se>
parents: 12422
diff changeset
    22
local st = require "util.stanza";
10859
70ac7d23673d mod_admin_socket, util.adminstream: New module to manage a local unix domain socket for admin functionality
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    23
10870
5265f7fe11dd mod_admin_socket: Use module API meant for file paths
Kim Alvefur <zash@zash.se>
parents: 10866
diff changeset
    24
local socket_path = module:get_option_path("admin_socket", "prosody.sock", "data");
10859
70ac7d23673d mod_admin_socket, util.adminstream: New module to manage a local unix domain socket for admin functionality
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    25
70ac7d23673d mod_admin_socket, util.adminstream: New module to manage a local unix domain socket for admin functionality
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    26
local sessions = module:shared("sessions");
70ac7d23673d mod_admin_socket, util.adminstream: New module to manage a local unix domain socket for admin functionality
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    27
70ac7d23673d mod_admin_socket, util.adminstream: New module to manage a local unix domain socket for admin functionality
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    28
local function fire_admin_event(session, stanza)
70ac7d23673d mod_admin_socket, util.adminstream: New module to manage a local unix domain socket for admin functionality
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    29
	local event_data = {
70ac7d23673d mod_admin_socket, util.adminstream: New module to manage a local unix domain socket for admin functionality
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    30
		origin = session, stanza = stanza;
70ac7d23673d mod_admin_socket, util.adminstream: New module to manage a local unix domain socket for admin functionality
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    31
	};
70ac7d23673d mod_admin_socket, util.adminstream: New module to manage a local unix domain socket for admin functionality
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    32
	local event_name;
70ac7d23673d mod_admin_socket, util.adminstream: New module to manage a local unix domain socket for admin functionality
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    33
	if stanza.attr.xmlns then
70ac7d23673d mod_admin_socket, util.adminstream: New module to manage a local unix domain socket for admin functionality
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    34
		event_name = "admin/"..stanza.attr.xmlns..":"..stanza.name;
70ac7d23673d mod_admin_socket, util.adminstream: New module to manage a local unix domain socket for admin functionality
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    35
	else
70ac7d23673d mod_admin_socket, util.adminstream: New module to manage a local unix domain socket for admin functionality
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    36
		event_name = "admin/"..stanza.name;
70ac7d23673d mod_admin_socket, util.adminstream: New module to manage a local unix domain socket for admin functionality
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    37
	end
70ac7d23673d mod_admin_socket, util.adminstream: New module to manage a local unix domain socket for admin functionality
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    38
	module:log("debug", "Firing %s", event_name);
12891
68df46926c26 mod_admin_socket: Return error on unhandled input to prevent apparent freeze
Kim Alvefur <zash@zash.se>
parents: 12422
diff changeset
    39
	local ret = module:fire_event(event_name, event_data);
68df46926c26 mod_admin_socket: Return error on unhandled input to prevent apparent freeze
Kim Alvefur <zash@zash.se>
parents: 12422
diff changeset
    40
	if ret == nil then
68df46926c26 mod_admin_socket: Return error on unhandled input to prevent apparent freeze
Kim Alvefur <zash@zash.se>
parents: 12422
diff changeset
    41
		session.send(st.stanza("repl-result", { type = "error" }):text("No module handled this query. Is mod_admin_shell enabled?"));
68df46926c26 mod_admin_socket: Return error on unhandled input to prevent apparent freeze
Kim Alvefur <zash@zash.se>
parents: 12422
diff changeset
    42
	end
68df46926c26 mod_admin_socket: Return error on unhandled input to prevent apparent freeze
Kim Alvefur <zash@zash.se>
parents: 12422
diff changeset
    43
	return ret;
10859
70ac7d23673d mod_admin_socket, util.adminstream: New module to manage a local unix domain socket for admin functionality
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    44
end
70ac7d23673d mod_admin_socket, util.adminstream: New module to manage a local unix domain socket for admin functionality
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    45
70ac7d23673d mod_admin_socket, util.adminstream: New module to manage a local unix domain socket for admin functionality
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    46
module:hook("server-stopping", function ()
70ac7d23673d mod_admin_socket, util.adminstream: New module to manage a local unix domain socket for admin functionality
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    47
	for _, session in pairs(sessions) do
70ac7d23673d mod_admin_socket, util.adminstream: New module to manage a local unix domain socket for admin functionality
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    48
		session:close("system-shutdown");
70ac7d23673d mod_admin_socket, util.adminstream: New module to manage a local unix domain socket for admin functionality
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    49
	end
70ac7d23673d mod_admin_socket, util.adminstream: New module to manage a local unix domain socket for admin functionality
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    50
	os.remove(socket_path);
70ac7d23673d mod_admin_socket, util.adminstream: New module to manage a local unix domain socket for admin functionality
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    51
end);
70ac7d23673d mod_admin_socket, util.adminstream: New module to manage a local unix domain socket for admin functionality
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    52
70ac7d23673d mod_admin_socket, util.adminstream: New module to manage a local unix domain socket for admin functionality
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    53
--- Unix domain socket management
70ac7d23673d mod_admin_socket, util.adminstream: New module to manage a local unix domain socket for admin functionality
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    54
70ac7d23673d mod_admin_socket, util.adminstream: New module to manage a local unix domain socket for admin functionality
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    55
local conn, sock;
70ac7d23673d mod_admin_socket, util.adminstream: New module to manage a local unix domain socket for admin functionality
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    56
70ac7d23673d mod_admin_socket, util.adminstream: New module to manage a local unix domain socket for admin functionality
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    57
local listeners = adminstream.server(sessions, fire_admin_event).listeners;
70ac7d23673d mod_admin_socket, util.adminstream: New module to manage a local unix domain socket for admin functionality
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    58
70ac7d23673d mod_admin_socket, util.adminstream: New module to manage a local unix domain socket for admin functionality
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    59
local function accept_connection()
70ac7d23673d mod_admin_socket, util.adminstream: New module to manage a local unix domain socket for admin functionality
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    60
	module:log("debug", "accepting...");
70ac7d23673d mod_admin_socket, util.adminstream: New module to manage a local unix domain socket for admin functionality
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    61
	local client = sock:accept();
70ac7d23673d mod_admin_socket, util.adminstream: New module to manage a local unix domain socket for admin functionality
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    62
	if not client then return; end
70ac7d23673d mod_admin_socket, util.adminstream: New module to manage a local unix domain socket for admin functionality
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    63
	server.wrapclient(client, "unix", 0, listeners, "*a");
70ac7d23673d mod_admin_socket, util.adminstream: New module to manage a local unix domain socket for admin functionality
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    64
end
70ac7d23673d mod_admin_socket, util.adminstream: New module to manage a local unix domain socket for admin functionality
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    65
70ac7d23673d mod_admin_socket, util.adminstream: New module to manage a local unix domain socket for admin functionality
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    66
function module.load()
70ac7d23673d mod_admin_socket, util.adminstream: New module to manage a local unix domain socket for admin functionality
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    67
	sock = unix.stream();
70ac7d23673d mod_admin_socket, util.adminstream: New module to manage a local unix domain socket for admin functionality
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    68
	sock:settimeout(0);
70ac7d23673d mod_admin_socket, util.adminstream: New module to manage a local unix domain socket for admin functionality
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    69
	os.remove(socket_path);
12422
dd47adf74e93 mod_admin_socket: Improve error reporting when socket can't be created (fixes #1719)
Matthew Wild <mwild1@gmail.com>
parents: 12397
diff changeset
    70
	local ok, err = sock:bind(socket_path);
dd47adf74e93 mod_admin_socket: Improve error reporting when socket can't be created (fixes #1719)
Matthew Wild <mwild1@gmail.com>
parents: 12397
diff changeset
    71
	if not ok then
dd47adf74e93 mod_admin_socket: Improve error reporting when socket can't be created (fixes #1719)
Matthew Wild <mwild1@gmail.com>
parents: 12397
diff changeset
    72
		module:log_status("error", "Unable to bind admin socket %s: %s", socket_path, err);
dd47adf74e93 mod_admin_socket: Improve error reporting when socket can't be created (fixes #1719)
Matthew Wild <mwild1@gmail.com>
parents: 12397
diff changeset
    73
		return;
dd47adf74e93 mod_admin_socket: Improve error reporting when socket can't be created (fixes #1719)
Matthew Wild <mwild1@gmail.com>
parents: 12397
diff changeset
    74
	end
dd47adf74e93 mod_admin_socket: Improve error reporting when socket can't be created (fixes #1719)
Matthew Wild <mwild1@gmail.com>
parents: 12397
diff changeset
    75
	local ok, err = sock:listen();
dd47adf74e93 mod_admin_socket: Improve error reporting when socket can't be created (fixes #1719)
Matthew Wild <mwild1@gmail.com>
parents: 12397
diff changeset
    76
	if not ok then
dd47adf74e93 mod_admin_socket: Improve error reporting when socket can't be created (fixes #1719)
Matthew Wild <mwild1@gmail.com>
parents: 12397
diff changeset
    77
		module:log_status("error", "Unable to listen on admin socket %s: %s", socket_path, err);
dd47adf74e93 mod_admin_socket: Improve error reporting when socket can't be created (fixes #1719)
Matthew Wild <mwild1@gmail.com>
parents: 12397
diff changeset
    78
		return;
dd47adf74e93 mod_admin_socket: Improve error reporting when socket can't be created (fixes #1719)
Matthew Wild <mwild1@gmail.com>
parents: 12397
diff changeset
    79
	end
10866
1cfae9e85021 mod_admin_socket: Use wrapserver if available
Kim Alvefur <zash@zash.se>
parents: 10859
diff changeset
    80
	if server.wrapserver then
1cfae9e85021 mod_admin_socket: Use wrapserver if available
Kim Alvefur <zash@zash.se>
parents: 10859
diff changeset
    81
		conn = server.wrapserver(sock, socket_path, 0, listeners);
1cfae9e85021 mod_admin_socket: Use wrapserver if available
Kim Alvefur <zash@zash.se>
parents: 10859
diff changeset
    82
	else
1cfae9e85021 mod_admin_socket: Use wrapserver if available
Kim Alvefur <zash@zash.se>
parents: 10859
diff changeset
    83
		conn = server.watchfd(sock:getfd(), accept_connection);
1cfae9e85021 mod_admin_socket: Use wrapserver if available
Kim Alvefur <zash@zash.se>
parents: 10859
diff changeset
    84
	end
10859
70ac7d23673d mod_admin_socket, util.adminstream: New module to manage a local unix domain socket for admin functionality
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    85
end
70ac7d23673d mod_admin_socket, util.adminstream: New module to manage a local unix domain socket for admin functionality
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    86
70ac7d23673d mod_admin_socket, util.adminstream: New module to manage a local unix domain socket for admin functionality
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    87
function module.unload()
70ac7d23673d mod_admin_socket, util.adminstream: New module to manage a local unix domain socket for admin functionality
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    88
	if conn then
70ac7d23673d mod_admin_socket, util.adminstream: New module to manage a local unix domain socket for admin functionality
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    89
		conn:close();
70ac7d23673d mod_admin_socket, util.adminstream: New module to manage a local unix domain socket for admin functionality
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    90
	end
70ac7d23673d mod_admin_socket, util.adminstream: New module to manage a local unix domain socket for admin functionality
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    91
	if sock then
70ac7d23673d mod_admin_socket, util.adminstream: New module to manage a local unix domain socket for admin functionality
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    92
		sock:close();
70ac7d23673d mod_admin_socket, util.adminstream: New module to manage a local unix domain socket for admin functionality
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    93
	end
70ac7d23673d mod_admin_socket, util.adminstream: New module to manage a local unix domain socket for admin functionality
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    94
	os.remove(socket_path);
70ac7d23673d mod_admin_socket, util.adminstream: New module to manage a local unix domain socket for admin functionality
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    95
end