--- /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