Vcard and Evil
authorMyhailo Danylenko <isbear@ukrpost.net>
Mon, 23 Mar 2009 08:15:47 +0200
changeset 62 fb81aeb45e00
parent 61 5182f466da7d
child 63 423555c07763
Vcard and Evil
examples/evil.lua
examples/mcabberrc.lua
examples/vcard.lua
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/evil.lua	Mon Mar 23 08:15:47 2009 +0200
@@ -0,0 +1,136 @@
+
+-- MALICIOUS STANZAS (XEP-0076)
+
+-- FIXME for now we only can send evil messages
+--       also we cannot detect stream-level evil :(
+
+-- library
+
+require 'lm'
+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 mtype, smtype = mess:type ()
+		main.print_info ( mess:attribute ( 'from' ), 'Evil stanza of type ' .. mtype .. ', ' .. ( smtype or '' ) .. ' detected!' )
+		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', 'normal' )
+		lm.connection.bless( main.connection () ):handler ( evil_incoming_stanza_handler, 'message', 'normal' )
+		lm.connection.bless( main.connection () ):handler ( evil_incoming_stanza_handler, 'presence', 'normal' )
+		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
+
+main.add_feature ( 'http://jabber.org/protocol/evil' )
+
+-- vim: se ts=4: --
--- a/examples/mcabberrc.lua	Mon Mar 23 05:06:15 2009 +0200
+++ b/examples/mcabberrc.lua	Mon Mar 23 08:15:47 2009 +0200
@@ -267,6 +267,10 @@
 
 require 'ibb'
 
+-- VCARD-TEMP (XEP-0054)
+
+require 'vcard'
+
 -- PUBLISH-SUBSRIBE (XEP-0060)
 
 require 'pubsub'
@@ -275,6 +279,10 @@
 
 require 'oob'
 
+-- MALICIOUS STANZAS (XEP-0076)
+
+require 'evil'
+
 -- IN-BAND REGISTRATION (XEP-0077)
 
 require 'iq_register'
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/vcard.lua	Mon Mar 23 08:15:47 2009 +0200
@@ -0,0 +1,106 @@
+
+-- VCARD-TEMP (XEP-0054)
+
+-- library
+
+require 'lm'
+require 'iq'
+require 'x_data'
+
+-- public
+
+vcard = { }
+
+local function vcard_parse ( node, path, ret )
+	local item = node:child ()
+	if item then
+		while item do
+			vcard_parse ( item, ( path and path .. '/' or '' ) .. item:name (), ret )
+			item = item:next ()
+		end
+	elseif path then
+		table.insert ( ret, { var = path, type = 'text-single', value = node:value () } )
+	end
+end
+
+function vcard.parse ( card )
+	local form = { xmlns = 'vcard-temp', type = 'form' }
+	vcard_parse ( card, nil, form )
+	form.format =
+		function ( form, root )
+			root.vCard = { xmlns = 'vcard-temp' }
+			for k, field in ipairs ( form ) do
+				local el = root.vCard
+				for k in field.var:gmatch ( '[^/]+' ) do
+					if not el[k] then
+						el[k] = { }
+					end
+					el = el[k]
+				end
+				el[1] = field.value
+			end
+			return root
+		end
+	return form
+end
+
+function vcard.get ( conn, from, success, fail )
+	iq.send ( conn, from, 'get',
+		{
+			vCard = { xmlns = 'vcard-temp' },
+		},
+		function ( mess )
+			local card = mess:child ( 'vCard' )
+			if card and card:attribute ( 'xmlns' ) == 'vcard-temp' then
+				success ( vcard.parse ( mess:child ( 'vCard' ) ),
+					function ( form, success, fail )
+						form.type = 'submit' -- :)
+						iq.send ( conn, from, 'set', form.format ( form, { } ), success, fail )
+					end,
+					function ( form, success, fail )
+						success ()
+					end )
+			else
+				fail ( mess:xml () ) -- XXX
+			end
+		end, fail )
+end
+
+-- mcabber
+
+main.command ( 'vcard-temp',
+	function ( args )
+		vcard.get ( lm.connection.bless ( main.connection () ), args[1],
+			function ( form, submit, reject )
+				local id = #forms + 1
+				forms[id] = {
+					form = form,
+					submit =
+						function ( form )
+							submit ( form,
+								function ()
+									print ( 'Vcard changed' )
+								end,
+								function ( mesg )
+									print ( 'Vcard changing error: ' .. mesg )
+								end )
+						end,
+					reject =
+						function ( form )
+							reject ( form,
+								function ()
+									print ( 'Vcard changing cancelled' )
+								end,
+								function ( mesg )
+									print ( 'Vcard changing cancellation error: ' .. mesg )
+								end )
+						end,
+				}
+				print ( 'You have new form ' .. id )
+			end,
+			function ( mesg )
+				print ( 'Vcard obtaining error: ' .. mesg )
+			end )
+	end, true, 'jid' )
+
+-- vim: se ts=4: --