Bugs: Browse | Submit New | Admin

[#1475] A patch to obtain component sessions

Date:
2005-02-08 15:43
Priority:
3
Submitted By:
Nobody
Assigned To:
Nobody (None)
Category:
None
State:
Open
Summary:
A patch to obtain component sessions

Detailed description
This is a quick hack to allow for component sessions (to conect as a component). It works for me on Debian+ ejabberd
0.75. YMMV.

Hope it helps somebody.

Add A Comment: Notepad

Please login


Followup

Message
Date: 2005-02-08 15:44
Sender: Nobody

Logged In: NO 

Forgot to attach the file :-(.



require 'xmlparser'
require 'jabber4r/jabber4r'



module Jabber
  ##
  # The Jabber ID class is used to hold a parsed jabber identifier
(account+host+resource)
  #
  class JID
	#If not node then don't add the @ sign since components do not
use node
	def to_s
		if (@node!=nil and @node!='')
			result = (@node.to_s+"@"+@host.to_s) 
		else
			result = @host.to_s
		end
	  result += ("/"+@resource) if @resource
	  return result
	end
	

	end
	module Protocol
		class Iq
			#PATCH: Component  iq stanzas *must* be sent with from
attribute
			def to_xml
				elem = XMLElement.new("iq",
{ "type"=>@type})
				elem.add_attribute("to" ,@to) if @to
				elem.add_attribute("from" ,@from) if @from
				elem.add_attribute("id", @id) if @id
				elem.add_child("query").add_attribute("xmlns&q
uot;,@xmlns).add_data(@data.to_s)
				if @type=="error" then
					e=elem.add_child("error");
					e.add_attribute("code",@errorcode) if @errorcode
					e.add_data(@error) if @error
				end
				return elem.to_s
			end
		end
			#PATCH: Component message stanzas *must* be sent with from
attribute
		class Message
			def to_xml
				@thread = Jabber.gen_random_thread if @thread.nil? and (not
@is_reply)
				elem = XMLElement.new("message",
{"to"=>@to, "type"=>@type,
"from"=>@from})
				elem.add_attribute("id", @id) if @id
				elem.add_child("thread").add_data(@thread)
if @thread
				elem.add_child("subject").add_data(@subject) if
@subject
				elem.add_child("body").add_data(@body) if @body
				if @xhtml then
				  t=elem.add_child("xhtml").add_attribute("xml
ns","http://www.w3.org/1999/xhtml")
				  t.add_child("body").add_data(@xhtml)
				end
				if @type=="error" then
				  e=elem.add_child("error");
				  e.add_attribute("code",@errorcode) if @errorcode
				  e.add_data(@error) if @error
				end
				elem.add_child("x").add_attribute("xmlns",
"jabber:x:oob").add_data(@oobData) if @oobData
				elem.add_xml(@x.to_s) if @x
			  return elem.to_s
			end
		end

	end
	
		#PATCH: New class represents a component
	class SessionComponent < Session
		
		def SessionComponent.bind_component(component_name, password,
host, port=5347)
			session = SessionComponent.new(component_name, host, port)			
			raise "Authentication failed" unless
session.authenticate_component(component_name, password)
			session.register_presence_filter
			session.register_iq_filter
			session.register_message_filter
			return session			
		end
		#Standard component greeting according to JEP 0114
		def gen_component_stream(host)		
		  return ('<?xml version="1.0"
encoding="UTF-8" ?><stream:stream
to="'+host+'" xmlns="jabber:component:accept"
xmlns:stream="http://etherx.jabber.org/streams">')
		end

		#Start XMPP stream with router
		def initialize(component, host, port)
			@id = 1
			@host = host
			@port = port
			@roster = Roster.new(self)
			@messageListeners = Hash.new
			@iqHandlers=Hash.new
			@subscriptionHandler = nil
			@connection = Jabber::Protocol::Connection.new(host, port)
			
			@connection.connect
			
			unless @connection.is_connected?
				raise "Session Error: Could not connected
to #{host}:#{port}"
			else 
				@connection.send(gen_component_stream(host)) do |element| 
					if element.element_tag=="stream:stream"
						element.consume_element 
						@session_id = element.attr_id
					end
				end
				@connection.on_connection_exception do
				  if @session_failure_block
					self.release
					@session_failure_block.call
				  end
				end
			Thread.stop
			end
		end
		# Implement JEP 0114 authentication
		def authenticate_component(component_name, password)
			@username = component_name
			@password = password
			
			authHandler = Proc.new  do |element| 
					element.consume_element
					if element.element_tag=="handshake" 
						@authenticated = true
						
					elsif element.attr_type=="error"
						@authenticated = false
					end		
					
			end		
			authdigest=Digest::SHA1.new(@session_id + password)
			authdigest="<handshake>"+authdigest.to_s+"
;</handshake>"
			@connection.send(authdigest) do |element|
					if element.element_tag=="handshake" 
						element.consume_element
						@authenticated = true						
					elsif element.attr_type=="error"
						@authenticated = false
					end		
					
			end			
			Thread.stop			
			return @authenticated
		end



	end
	
end

Attached Files:

Name Description Download
No Files Currently Attached

Changes:

No Changes Have Been Made to This Item