Thu, 18 Feb 2010 16:02:11 +0000
Initial commit (dedicated to darkrain)
servers/djabberd.lua | file | annotate | diff | comparison | revisions | |
servers/ejabberd.lua | file | annotate | diff | comparison | revisions | |
servers/google_talk.lua | file | annotate | diff | comparison | revisions | |
servers/isode_mlink.lua | file | annotate | diff | comparison | revisions | |
servers/jabber_xcp.lua | file | annotate | diff | comparison | revisions | |
servers/jabberd14.lua | file | annotate | diff | comparison | revisions | |
servers/jabberd2.lua | file | annotate | diff | comparison | revisions | |
servers/openfire.lua | file | annotate | diff | comparison | revisions | |
servers/prosody.lua | file | annotate | diff | comparison | revisions | |
servers/tigase.lua | file | annotate | diff | comparison | revisions | |
squishy | file | annotate | diff | comparison | revisions | |
xmpp-fingerprint.lua | file | annotate | diff | comparison | revisions |
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/servers/djabberd.lua Thu Feb 18 16:02:11 2010 +0000 @@ -0,0 +1,6 @@ +function testers.djabberd() + if not test(q_invalid_xml, ".") and not test(q_invalid_host, ".") then -- djabberd says nothing + server_name = "djabberd"; + server_comment "djabberd is not very talkative, so this is an assumption"; + end +end
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/servers/ejabberd.lua Thu Feb 18 16:02:11 2010 +0000 @@ -0,0 +1,38 @@ +function testers.ejabberd() + if (test(q_invalid_xml, [=[ id=["']none['"]]=]) or test(q_invalid_xml, " id='%d+'")) + and (not test(q_invalid_xml, literal " xml:lang=")) then + + server_name = "ejabberd"; + + -- Facebook curiosity + if test(q_invalid_xml, " id=(.)") == '"' then + server_comment "Appears to be Facebook's variant of ejabberd"; + end + + local hostname = test(q_invalid_xml, [=[from=["']([^"']+)]=]); + if not hostname then + server_comment "The server did not return a hostname, odd."; + else + local stream_open = [[<stream:stream xmlns=']]..default_namespace..[[' + xmlns:stream='http://etherx.jabber.org/streams' version='1.0' id='abc' to=']]..hostname..[['>]]; + + if not test(stream_open.."<message/>", ":features>$") then -- Oops, not ejabberd + debug("Oops, not ejabberd (please report):", test(stream_open.."<message/>", ".*")); + server_name = nil; + return; + end + + if test(q_invalid_xml, " id='%d+'") then + server_min_version = "2.1.x"; + elseif test(stream_open, literal "<compression ") then -- Only in 2.x + server_min_version = "2.0.x"; + elseif test(stream_open, "") then + server_min_version = "1.x.x"; + else + server_comment "The server did not reply when we tried to open a stream"; + end + + end + end +end +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/servers/google_talk.lua Thu Feb 18 16:02:11 2010 +0000 @@ -0,0 +1,6 @@ +function testers.google_talk() + if test(q_invalid_xml, literal "Location: http://www.google.com/talk/") then + server_name = "Google Talk"; + end +end +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/servers/isode_mlink.lua Thu Feb 18 16:02:11 2010 +0000 @@ -0,0 +1,6 @@ +function testers.isode_mlink() + if test(q_empty_message_tag, literal "<bad-format ") and test(q_empty_message_tag, "^<stream:error>") then + server_name = "Isode M-Link"; + end +end +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/servers/jabber_xcp.lua Thu Feb 18 16:02:11 2010 +0000 @@ -0,0 +1,5 @@ +function testers.jabber_xcp() + if test(q_empty_message_tag, literal "<bad-format ") and test(q_empty_message_tag, literal "Invalid stream header</text>") then + server_name = "Jabber XCP"; + end +end
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/servers/jabberd14.lua Thu Feb 18 16:02:11 2010 +0000 @@ -0,0 +1,6 @@ +function testers.jabberd14() + if test(q_invalid_xml, literal "<stream:error>Invalid XML</stream:error>") then + server_name = "jabberd14"; + end +end +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/servers/jabberd2.lua Thu Feb 18 16:02:11 2010 +0000 @@ -0,0 +1,5 @@ +function testers.jabberd2() + if test(q_invalid_xml, literal ">syntax error</text></stream:error>") then + server_name = "jabberd2"; + end +end
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/servers/openfire.lua Thu Feb 18 16:02:11 2010 +0000 @@ -0,0 +1,5 @@ +function testers.openfire() + if test(q_invalid_host, literal " encoding='UTF-8'?>") and test(q_invalid_host, literal "<stream:features>") then + server_name = "Openfire"; + end +end
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/servers/prosody.lua Thu Feb 18 16:02:11 2010 +0000 @@ -0,0 +1,11 @@ +function testers.prosody() + if test(q_invalid_xml, literal " id=''") + and test(q_invalid_host, "This server does not serve") + and not test(q_invalid_xml, " from=") then + server_name = "Prosody"; + if not test(q_invalid_host, literal "><?xml") then + server_min_version = "0.6"; + end + end +end +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/servers/tigase.lua Thu Feb 18 16:02:11 2010 +0000 @@ -0,0 +1,6 @@ +function testers.tigase() + if test(q_invalid_host, literal " id='tigase-error-tigase'") and not test(q_empty_message_tag, "") then + server_name = "Tigase"; + end +end +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/squishy Thu Feb 18 16:02:11 2010 +0000 @@ -0,0 +1,16 @@ +Option "executable" +Option "virtual-io" + +Output "xmpp-fingerprint" + +Main "xmpp-fingerprint.lua" + +-- Add tests (squished) +for line in io.lines("xmpp-fingerprint.lua") do + local fn = line:match("servers/([a-z_]+).lua"); + if fn then + print("Adding server", fn); + Resource("servers/"..fn..".lua")("servers/"..fn..".lua"); + end +end +
--- /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