PageRenderTime 49ms CodeModel.GetById 21ms RepoModel.GetById 1ms app.codeStats 0ms

/dports/ruby/rb-rjab-connection/files/patch-conn_connection.rb

https://bitbucket.org/seanfarley/macports
Ruby | 383 lines | 334 code | 43 blank | 6 comment | 48 complexity | fbf01eeacb04e9aaa4552f5225df1f8d MD5 | raw file
Possible License(s): CC-BY-3.0, MPL-2.0-no-copyleft-exception, BSD-3-Clause, MPL-2.0
  1. --- lib/rjab/conn/connection.rb Mon Jan 21 20:49:48 2002
  2. +++ ../rjab-connection.jdp/src/lib/rjab/conn/connection.rb Wed Jan 28 09:46:41 2004
  3. @@ -6,31 +6,32 @@
  4. # Connection::Client and Connection::Component
  5. #
  6. -require 'sha1'
  7. -require 'socket'
  8. +module Jabber
  9. -require 'rjab/conn/node'
  10. -require 'rjab/conn/ns'
  11. -require 'rjab/conn/xmllistener'
  12. + class Connection
  13. -module Jabber
  14. + require 'rjab/conn/node'
  15. + require 'rjab/conn/ns'
  16. + require 'rjab/conn/xmllistener'
  17. +
  18. + require 'digest/sha1'
  19. +
  20. + require 'socket'
  21. -class Connection
  22. include Jabber::NS
  23. include Jabber::XMLListener
  24. - def initialize(server, port, ns, localname, log=nil)
  25. + def initialize(server = 'localhost', port = 5222, \
  26. + ns = NS_CLIENT, localname = 'local', log=nil)
  27. # instance vars instantiated at object creation
  28. - @server, @port = server, port || 5222
  29. - @ns = ns || NS_CLIENT
  30. - @localname = localname
  31. - @log = log
  32. + @server, @port, @ns, @localname, @log = server, port, ns, \
  33. + localname, log
  34. # instance vars instantiated later in program
  35. @answer, @ask_id = nil
  36. @beatcount = 0
  37. @connected = false
  38. - @handlers = []
  39. + @handlers = {}
  40. # vars for XMLListener
  41. @depth = 1
  42. @@ -39,40 +40,46 @@
  43. @confirmedhost, @streamid, @errortext = ""
  44. end
  45. - def connect
  46. - # FIXME: wrap in begin / rescue block
  47. - @socket = TCPSocket.open(@server, @port)
  48. - self.write(stream_header)
  49. - self.read
  50. - @connected = true
  51. + def ask(node)
  52. + unless @ask_id = node.root.attributes['id']
  53. + debug("Ask: no ID - getting one")
  54. + @ask_id = get_id
  55. + node.root.attributes['id'] = @ask_id
  56. end
  57. + debug("Ask: id = #{@ask_id}")
  58. - def disconnect
  59. - self.write(STREAM_END)
  60. - @socket.shutdown
  61. - end
  62. + str = ""
  63. + node.write str, -1
  64. + _write str
  65. - def process(time)
  66. - if IO.select([@socket], nil, nil, time)
  67. - return self.read
  68. - end
  69. + while (@answer == nil)
  70. + debug("Ask: waiting for answer")
  71. + process(1)
  72. end
  73. - def parse_data(source) # TODO?: subclass REXML::Source
  74. - REXML::Document.parse_stream(source, self) # so that it works properly with
  75. - end # sockets
  76. + answer = @answer
  77. + @answer = nil
  78. + debug("Ask: got answer") # FIXME: write out XML of answer
  79. + return answer
  80. + end
  81. def auth(*args)
  82. + raise_unless_connected
  83. +
  84. # FIXME: wrap in begin/rescue block
  85. - if @ns == NS_CLIENT
  86. - @user, @pass = args[0], args[1]
  87. - @resource = args[2]
  88. + case @ns
  89. + when NS_CLIENT
  90. + if args.length < 3
  91. + raise ArgumentError, \
  92. + "Wrong number of arguments (#{auth.length} for 3)"
  93. + end
  94. + user, pass, resource = args[0..2]
  95. auth_node = Node.new('iq')
  96. auth_node.root.attributes['type'] = IQ_GET
  97. query = auth_node.root.add_element('query')
  98. query.attributes['xmlns'] = NS_AUTH
  99. - query.add_element('username').text = @user
  100. + query.add_element('username').text = user
  101. get_result = ask(auth_node)
  102. @@ -80,145 +87,189 @@
  103. auth_node.root.attributes['id'] = get_id
  104. if get_result.root.elements['token']
  105. - hash = SHA1.new(@pass).hexdigest
  106. + hash = sha1(pass)
  107. seq = get_result.root.elements['sequence'].text.to_i
  108. token = get_result.root.elements['token'].text
  109. - hash = SHA1.new(hash + token).hexdigest
  110. - seq.downto(1) { hash = SHA1.new(hash).hexdigest }
  111. + hash = sha1(hash + token)
  112. + seq.downto(1) { hash = sha1(hash) }
  113. query.add_element('hash').text = hash
  114. +
  115. elsif get_result.root.elements['digest']
  116. - query.add_element('digest').text = SHA1.new(@streamid + @pass).hexdigest
  117. + query.add_element('digest').text = sha1(@streamid + pass)
  118. +
  119. elsif get_result.root.elements['password']
  120. debug("auth: plaintext supported")
  121. - query.add_element('password').text = @pass
  122. + query.add_element('password').text = pass
  123. else
  124. - debug("auth: no authentication methods supported...")
  125. - raise
  126. + raise RuntimeError, "No authentication methods supported."
  127. end
  128. - query.add_element('resource').text = @resource
  129. + query.add_element('resource').text = resource
  130. set_result = ask(auth_node)
  131. - unless (set_result.root.attributes['type'] == IQ_RESULT)
  132. - puts "AUTH FAILED!!!"
  133. +
  134. + if (set_result.root.attributes['type'] != IQ_RESULT)
  135. disconnect
  136. - raise
  137. - else
  138. - puts "Auth succeeded!!!"
  139. - end
  140. - elsif @ns == NS_ACCEPT
  141. - @secret = args[0]
  142. + raise RuntimeError, "Authentication failed."
  143. end
  144. +
  145. + when NS_ACCEPT
  146. + raise NotImplementedError, "Component support not ready"
  147. end
  148. - def stream_header
  149. - # FIXME: find a way to move this crap into Jabber::NS and still allow for
  150. - # variable substitution
  151. - header = "<?xml version=\'1.0\'?><stream:stream to=\'#{@server}\' xmlns=\'jabber:client\' xmlns:stream=\'http://etherx.jabber.org/streams\'>"
  152. + true
  153. end
  154. - def send(data)
  155. - # FIXME: compact method
  156. - if data.instance_of? Node
  157. - str = ""
  158. - data.write str, -1
  159. - self.write str
  160. + def connect(sock=nil)
  161. + # FIXME: wrap in begin / rescue block
  162. + if not @connected
  163. + if defined? Test::Unit::TestCase
  164. + @socket = sock
  165. else
  166. - self.write data
  167. + @socket = TCPSocket.open(@server, @port)
  168. + end
  169. + _write(stream_header)
  170. + read()
  171. + @connected = true
  172. end
  173. + @connected
  174. end
  175. - def write(data)
  176. - debug("Write: #{data}")
  177. - @socket.write(data)
  178. + def disconnect
  179. + _write(STREAM_END)
  180. + @socket.shutdown
  181. + @connected = false
  182. end
  183. - def read
  184. - recieved = ""
  185. - while data = @socket.recv(1024)
  186. - recieved += data
  187. - break if data != 1024
  188. + def process(time = 0)
  189. + if defined? Test::Unit::TestCase
  190. + def select(r, w, e, t)
  191. + return [r, w, e, t]
  192. + end
  193. + end
  194. + handle = select([@socket], nil, nil, time)
  195. + if not handle.nil? and handle[0][0] = @socket
  196. + return read
  197. + end
  198. + return true
  199. end
  200. - debug("Read: #{recieved}")
  201. + def register_handler(tag, &handler)
  202. + debug("Register_handler: tag type: #{tag}")
  203. + if not @handlers.has_key?(tag)
  204. + @handlers[tag] = []
  205. + end
  206. + @handlers[tag].push(handler)
  207. + end
  208. - # ewww... grotesque
  209. - if recieved =~ /<stream/
  210. - debug("Read: munging so REXML is happy")
  211. - recieved.chop!.concat('/>')
  212. + def write(data)
  213. + raise_unless_connected
  214. +
  215. + if data.instance_of? Node
  216. + str = ""
  217. + data.write str, -1
  218. + _write str
  219. + else
  220. + _write data
  221. + end
  222. end
  223. - parse_data(recieved)
  224. - return recieved
  225. + def connected?
  226. + @connected
  227. end
  228. - def log(log_string)
  229. - if @log then puts "LOG: #{log_string}" end
  230. + if defined? Test::Unit::TestCase
  231. + def set_server(server)
  232. + @server = server
  233. + @server
  234. + end
  235. end
  236. + private
  237. +
  238. def debug(debug_string)
  239. if $DEBUG then puts "DEBUG: #{debug_string}" end
  240. end
  241. - def last_error; end
  242. -
  243. def dispatch(node)
  244. debug("dispatching: #{node.root.name}")
  245. - if @ask_id != nil
  246. + if not @ask_id.nil?
  247. + debug("ask_id: #{@ask_id}")
  248. + if @ask_id == node.root.attributes['id']
  249. @ask_id = nil
  250. @answer = node
  251. end
  252. + end
  253. - @handlers.each do |name, obj|
  254. - if name == node.root.name
  255. - obj.call(node)
  256. + if @handlers.has_key?(node.root.name)
  257. + @handlers[node.root.name].each { |handler|
  258. + parcel = handler.call(node, parcel) || parcel
  259. + break if (not parcel.nil?) and parcel == R_HANDLED
  260. + }
  261. end
  262. end
  263. +
  264. + def get_id
  265. + "rjab_#{Time.now.tv_sec}" # "rjab_seconds_since_epoch"
  266. end
  267. - def ask(node)
  268. - unless @ask_id = node.root.attributes['id']
  269. - debug("Ask: no ID - getting one")
  270. - @ask_id = get_id
  271. - node.root.attributes['id'] = @ask_id
  272. + def heartbeat; end
  273. +
  274. + def last_error; end
  275. +
  276. + def log(log_string)
  277. + if @log then puts "LOG: #{log_string}" end
  278. end
  279. - debug("Ask: id = #{@ask_id}")
  280. - str = ""
  281. - node.write str, -1
  282. - self.write str
  283. + def parse_data(source)
  284. + REXML::Document.parse_stream(source, self)
  285. + end
  286. - while (@answer == nil)
  287. - debug("Ask: waiting for answer")
  288. - process(1)
  289. + def raise_unless_connected
  290. + if not @connected
  291. + raise RuntimeError, "No connection/stream established!"
  292. + end
  293. end
  294. - answer = @answer
  295. - @answer = nil
  296. - debug("Ask: got answer") # FIXME: write out XML of answer
  297. - return answer
  298. + def read
  299. + rec_len = 1024
  300. + received = ''
  301. + while (data = @socket.recv(rec_len))
  302. + debug("recv (#{data.length}): #{data}\n")
  303. + received += data
  304. + break if data.length != 1024
  305. end
  306. - def register_handler(tag, &handler)
  307. - debug("Register_handler: tag type: #{tag}")
  308. - @handlers << [tag, handler]
  309. + # ewww... grotesque
  310. + if received =~ /<stream/
  311. + debug("Read: munging so REXML is happy")
  312. + received.chop!.concat('/>')
  313. end
  314. - def register_beat; end
  315. + parse_data(received)
  316. + return received
  317. + end
  318. - def start; end
  319. + def register_beat; end
  320. - def connected; end
  321. + def sha1(string)
  322. + return Digest::SHA1.new(string).hexdigest
  323. + end
  324. - def check_connected; end
  325. + def start; end
  326. - def get_id
  327. - "rjab_#{Time.now.tv_sec}" # "rjab_seconds_since_epoch"
  328. + def stream_header
  329. + # FIXME: find a way to move this crap into Jabber::NS and still allow for
  330. + # variable substitution
  331. + header = "<?xml version=\'1.0\'?><stream:stream to=\'#{@server}\' xmlns=\'jabber:client\' xmlns:stream=\'http://etherx.jabber.org/streams\'>"
  332. end
  333. - def heartbeat; end
  334. + def _write(data)
  335. + debug("Write: #{data}")
  336. + @socket.write(data)
  337. + end
  338. -end # Class: Connection
  339. + end # Class: Connection
  340. end # Module: Jabber