-- MALICIOUS STANZAS (XEP-0076)
-- FIXME for now we only can send evil messages
-- also we cannot detect stream-level evil :(
-- library
require 'lm'
local iq = require 'iq'
-- public
evil = {
handler =
function ( mess )
return false
end,
}
function evil.message ( conn, to, mtype, message )
conn:send ( lm.message.create { mtype = 'message-' .. mtype, to = to,
body = { message },
evil = { xmlns = 'http://jabber.org/protocol/evil' },
} )
end
function evil.presence ( conn, to, status, message )
local mtype = 'presence-available'
if status == 'unavailable' then
mtype = 'presence-unavailable'
status = ''
end
conn:send ( lm.message.create { mtype = mtype, from = conn:jid (), to = to,
show = { status },
status = { message },
evil = { xmlns = 'http://jabber.org/protocol/evil' },
} )
end
-- private
local evil_incoming_stanza_handler = lm.message_handler.new (
function ( conn, mess )
local e = mess:child ( 'evil' )
if e and e:attribute ( 'xmlns' ) == 'http://jabber.org/protocol/evil' then
return evil.handler ( mess )
end
end )
-- mcabber
evil.handler =
function ( mess )
local evillevel = tonumber(main.option ( 'lua_evil_sensibility' ))
local mtype, smtype = mess:type ()
if evillevel > 1 then
main.print_info ( mess:attribute ( 'from' ), 'Evil stanza of type ' .. mtype .. '.' .. smtype .. ' detected!' )
elseif evillevel > 0 then
print ( 'Tainted by evil stanza of type ' .. mtype .. '.' .. smtype .. ' from ' .. ( mess:attribute ( 'from' ) or '... unknown in black' ) )
end
return main.yesno ( main.option ( 'lua_filter_evil' ) )
end
local stat2xmpp = {
free = 'chat',
online = '',
away = 'away',
dnd = 'dnd',
notavail = 'xa',
offline = 'unavailable',
}
-- TODO improve interface, check if we sending right thing for offline
main.command ( 'evil',
function ( args )
local conn = lm.connection.bless ( main.connection () )
if args[1] == 'status' then
local text = ''
for i, mesg in ipairs ( args ) do
if i > 2 then
text = text .. ' ' .. mesg
end
end
local st = stat2xmpp[args[2]]
if not st then
st = ''
end
evil.presence ( conn, args.t, st, text:sub ( 2 ) )
else
local text = ''
if args[1] == 'message' then
for i, mesg in ipairs ( args ) do
if i > 1 then
text = text .. ' ' .. mesg
end
end
else
for i, mesg in ipairs ( args ) do
text = text .. ' ' .. mesg
end
end
local mtype = 'chat'
if args.k then
mtype = args.k
end
local who
if args.t then
who = args.t
else
who = main.current_buddy ()
end
evil.message ( conn, who, mtype, text:sub ( 2 ) )
end
end, true )
commands_help['evil'] = "[-t jid] [status stat [message] | [-k message_type] [message] message]\n\nSends evil message or presence.\nmessage_type may be chat, normal, headline.\nNote, that for now it will not change mcabber's status."
local evil_handler_registered = false
hooks_d['hook-post-connect'].evil =
function ( args )
lm.connection.bless( main.connection () ):handler ( evil_incoming_stanza_handler, 'iq', 'first' )
lm.connection.bless( main.connection () ):handler ( evil_incoming_stanza_handler, 'message', 'first' )
lm.connection.bless( main.connection () ):handler ( evil_incoming_stanza_handler, 'presence', 'first' )
evil_handler_registered = true
hooks_d['hook-post-connect'].evil = nil
hooks_d['hook-quit'].evil =
function ( args )
if evil_handler_registered then
lm.connection.bless( main.connection () ):handler ( evil_incoming_stanza_handler, 'iq' )
lm.connection.bless( main.connection () ):handler ( evil_incoming_stanza_handler, 'message' )
lm.connection.bless( main.connection () ):handler ( evil_incoming_stanza_handler, 'presence' )
end
end
end
local char2xmpp = {
f = 'chat',
o = '',
a = 'away',
d = 'dnd',
n = 'xa',
_ = 'unavailable',
}
-- hack, but working ;)
hooks_d['hook-my-status-change'].evil =
function ( args )
if main.yesno ( main.option ( 'lua_evil_mode' ) ) then
evil.presence ( lm.connection.bless ( main.connection () ), nil, char2xmpp[args.new_status], args.message )
end
end
main.add_feature ( 'http://jabber.org/protocol/evil' )
-- vim: se ts=4: --