xmpp-fingerprint.lua

changeset 0
ba1cc6ad649d
child 2
1eabe33d7af7
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/xmpp-fingerprint.lua	Thu Feb 18 16:02:11 2010 +0000
@@ -0,0 +1,131 @@
+#!/usr/bin/env lua
+
+local socket = require "socket";
+
+-- Defaults --
+default_port = 5222;
+default_namespace = "jabber:client";
+default_timeout = 1.5;
+
+-- Print debug output --
+function debug() end -- Keep debug output quiet by default
+
+-- Command-line flag handlers --
+local flags = {};
+function flags.d() -- Show debug
+	debug = print;
+end
+
+function flags.s() -- Use s2s
+	-- Use s2s
+	default_port = 5269;
+	default_namespace = "jabber:server";
+end
+
+function flags.t(arg)
+	default_timeout = tonumber(arg[1] or 1);
+	return 1;
+end
+
+-- Process flags --
+local function process_args(arg)
+	local f = arg[1] and arg[1]:match("^%-(%S+)");
+	if f then
+		table.remove(arg, 1);
+		if flags[f] then
+			local used = flags[f](arg);
+			if used then
+				for i=1,used do
+					table.remove(arg, 1);
+				end
+			end
+		end
+		return process_args(arg);
+	end
+end
+process_args(arg);
+
+local received_cache = {};
+local function _test(server, port, question, answer)
+	local received = received_cache[question];
+	if not received then
+		debug("||", "Connecting to "..server..":"..port.."...");
+		local conn = assert(socket.connect(server, port), "Failed to connect to "..arg[1]);
+		conn:send(question);
+		debug(">>", tostring(question));
+		conn:settimeout(default_timeout);
+		local data, err, partial = conn:receive("*a");
+		received = data or partial or "";
+		conn:close();
+		received_cache[question] = received;
+		debug("<<", #received ~= "" and tostring(received) or nil);
+	end
+	return received ~= "" and received:match(answer);
+end
+
+function test(question, answer)
+	return _test(arg[1], tonumber(arg[2]) or default_port, question, answer);
+end
+
+function server_comment(comment)
+	table.insert(getfenv(2).server_comments, comment);
+end
+
+function literal(s)
+	return s:gsub("%p", "%%%1");
+end
+
+-----
+q_invalid_xml = "abc\n";
+q_empty_message_tag = "<message/>";
+q_invalid_host = "<stream:stream xmlns='"..default_namespace.."' xmlns:stream='http://etherx.jabber.org/streams' version='1.0' id='abc' to='0.0.0.0'>";
+-----
+
+testers = {};
+
+dofile "servers/ejabberd.lua"
+dofile "servers/google_talk.lua"
+dofile "servers/isode_mlink.lua"
+dofile "servers/jabberd14.lua"
+dofile "servers/jabberd2.lua"
+dofile "servers/prosody.lua"
+dofile "servers/tigase.lua"
+dofile "servers/djabberd.lua"
+dofile "servers/openfire.lua"
+dofile "servers/jabber_xcp.lua"
+
+function test_fingerprint(server)
+	local tester = testers[server];
+	local env = setmetatable({server_comments = {}}, { __index = _G });
+	setfenv(tester, env);
+	local ok, err = pcall(tester);
+	if not ok then
+		print("Error while testing for "..server..": "..err);
+	end
+	return env;
+end
+
+------------------------------------------------------------------
+
+local results = {};
+for server in pairs(testers) do
+	local res = test_fingerprint(server);
+	if res.server_name then
+		table.insert(results, res);
+	end
+end
+
+if #results > 1 then
+	print("Note... multiple matches, could be any:");
+end
+
+for _, result in ipairs(results) do
+	io.write(result.server_name);
+	if result.server_min_version then
+		io.write(", version "..result.server_min_version.." or later");
+	end
+	io.write("\n");
+	if #result.server_comments > 0 then
+		print("   Notes:\n", table.concat(result.server_comments, "\n      "));
+	end
+end

mercurial