ln-xmpp4r 0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (215) hide show
  1. data/CHANGELOG +91 -0
  2. data/COPYING +340 -0
  3. data/LICENSE +59 -0
  4. data/README.rdoc +113 -0
  5. data/README_ruby19.txt +43 -0
  6. data/Rakefile +252 -0
  7. data/data/doc/xmpp4r/examples/advanced/adventure/README +56 -0
  8. data/data/doc/xmpp4r/examples/advanced/adventure/adventure.rb +23 -0
  9. data/data/doc/xmpp4r/examples/advanced/adventure/adventuremuc.rb +136 -0
  10. data/data/doc/xmpp4r/examples/advanced/adventure/cube.xml +15 -0
  11. data/data/doc/xmpp4r/examples/advanced/adventure/tower.xml +69 -0
  12. data/data/doc/xmpp4r/examples/advanced/adventure/world.rb +424 -0
  13. data/data/doc/xmpp4r/examples/advanced/fileserve.conf +11 -0
  14. data/data/doc/xmpp4r/examples/advanced/fileserve.rb +346 -0
  15. data/data/doc/xmpp4r/examples/advanced/getonline.rb +56 -0
  16. data/data/doc/xmpp4r/examples/advanced/gtkmucclient.rb +315 -0
  17. data/data/doc/xmpp4r/examples/advanced/migrate.rb +88 -0
  18. data/data/doc/xmpp4r/examples/advanced/minimuc.rb +266 -0
  19. data/data/doc/xmpp4r/examples/advanced/pep-aggregator/index.xsl +235 -0
  20. data/data/doc/xmpp4r/examples/advanced/pep-aggregator/pep-aggregator.rb +147 -0
  21. data/data/doc/xmpp4r/examples/advanced/recvfile.rb +84 -0
  22. data/data/doc/xmpp4r/examples/advanced/rosterdiscovery.rb +129 -0
  23. data/data/doc/xmpp4r/examples/advanced/sendfile.conf +10 -0
  24. data/data/doc/xmpp4r/examples/advanced/sendfile.rb +72 -0
  25. data/data/doc/xmpp4r/examples/advanced/shellmgr/shellmgr.rb +51 -0
  26. data/data/doc/xmpp4r/examples/advanced/shellmgr/shellmgr_jabber.rb +43 -0
  27. data/data/doc/xmpp4r/examples/advanced/shellmgr/shellmgr_test.rb +10 -0
  28. data/data/doc/xmpp4r/examples/advanced/versionpoll.rb +109 -0
  29. data/data/doc/xmpp4r/examples/advanced/xmpping.rb +146 -0
  30. data/data/doc/xmpp4r/examples/advanced/xmppingrc.sample +14 -0
  31. data/data/doc/xmpp4r/examples/basic/change_password.rb +41 -0
  32. data/data/doc/xmpp4r/examples/basic/client.rb +70 -0
  33. data/data/doc/xmpp4r/examples/basic/component.rb +11 -0
  34. data/data/doc/xmpp4r/examples/basic/echo.rb +37 -0
  35. data/data/doc/xmpp4r/examples/basic/jabbersend.rb +41 -0
  36. data/data/doc/xmpp4r/examples/basic/mass_sender.rb +68 -0
  37. data/data/doc/xmpp4r/examples/basic/muc_owner_config.rb +12 -0
  38. data/data/doc/xmpp4r/examples/basic/mucinfo.rb +41 -0
  39. data/data/doc/xmpp4r/examples/basic/mucsimplebot.rb +82 -0
  40. data/data/doc/xmpp4r/examples/basic/register.rb +42 -0
  41. data/data/doc/xmpp4r/examples/basic/remove_registration.rb +18 -0
  42. data/data/doc/xmpp4r/examples/basic/roster.rb +44 -0
  43. data/data/doc/xmpp4r/examples/basic/rosterprint.rb +50 -0
  44. data/data/doc/xmpp4r/examples/basic/rosterrename.rb +34 -0
  45. data/data/doc/xmpp4r/examples/basic/rosterwatch.rb +171 -0
  46. data/data/doc/xmpp4r/examples/basic/send_vcard.rb +67 -0
  47. data/data/doc/xmpp4r/examples/basic/tune_client.rb +56 -0
  48. data/data/doc/xmpp4r/examples/basic/tune_server.rb +58 -0
  49. data/data/doc/xmpp4r/examples/basic/versionbot.rb +75 -0
  50. data/lib/xmpp4r.rb +116 -0
  51. data/lib/xmpp4r/base64.rb +32 -0
  52. data/lib/xmpp4r/bytestreams.rb +15 -0
  53. data/lib/xmpp4r/bytestreams/helper/filetransfer.rb +319 -0
  54. data/lib/xmpp4r/bytestreams/helper/ibb/base.rb +257 -0
  55. data/lib/xmpp4r/bytestreams/helper/ibb/initiator.rb +31 -0
  56. data/lib/xmpp4r/bytestreams/helper/ibb/target.rb +54 -0
  57. data/lib/xmpp4r/bytestreams/helper/socks5bytestreams/base.rb +152 -0
  58. data/lib/xmpp4r/bytestreams/helper/socks5bytestreams/initiator.rb +86 -0
  59. data/lib/xmpp4r/bytestreams/helper/socks5bytestreams/server.rb +198 -0
  60. data/lib/xmpp4r/bytestreams/helper/socks5bytestreams/socks5.rb +65 -0
  61. data/lib/xmpp4r/bytestreams/helper/socks5bytestreams/target.rb +79 -0
  62. data/lib/xmpp4r/bytestreams/iq/bytestreams.rb +170 -0
  63. data/lib/xmpp4r/bytestreams/iq/si.rb +206 -0
  64. data/lib/xmpp4r/callbacks.rb +133 -0
  65. data/lib/xmpp4r/caps.rb +1 -0
  66. data/lib/xmpp4r/caps/c.rb +67 -0
  67. data/lib/xmpp4r/caps/helper/generator.rb +160 -0
  68. data/lib/xmpp4r/caps/helper/helper.rb +84 -0
  69. data/lib/xmpp4r/client.rb +344 -0
  70. data/lib/xmpp4r/command/helper/responder.rb +53 -0
  71. data/lib/xmpp4r/command/iq/command.rb +154 -0
  72. data/lib/xmpp4r/component.rb +103 -0
  73. data/lib/xmpp4r/connection.rb +223 -0
  74. data/lib/xmpp4r/dataforms.rb +5 -0
  75. data/lib/xmpp4r/dataforms/x/data.rb +297 -0
  76. data/lib/xmpp4r/debuglog.rb +63 -0
  77. data/lib/xmpp4r/delay.rb +5 -0
  78. data/lib/xmpp4r/delay/x/delay.rb +99 -0
  79. data/lib/xmpp4r/discovery.rb +8 -0
  80. data/lib/xmpp4r/discovery/helper/helper.rb +58 -0
  81. data/lib/xmpp4r/discovery/helper/responder.rb +165 -0
  82. data/lib/xmpp4r/discovery/iq/discoinfo.rb +211 -0
  83. data/lib/xmpp4r/discovery/iq/discoitems.rb +147 -0
  84. data/lib/xmpp4r/errors.rb +284 -0
  85. data/lib/xmpp4r/feature_negotiation.rb +5 -0
  86. data/lib/xmpp4r/feature_negotiation/iq/feature.rb +28 -0
  87. data/lib/xmpp4r/framework/base.rb +55 -0
  88. data/lib/xmpp4r/framework/bot.rb +148 -0
  89. data/lib/xmpp4r/httpbinding.rb +5 -0
  90. data/lib/xmpp4r/httpbinding/client.rb +275 -0
  91. data/lib/xmpp4r/idgenerator.rb +37 -0
  92. data/lib/xmpp4r/iq.rb +221 -0
  93. data/lib/xmpp4r/jid.rb +167 -0
  94. data/lib/xmpp4r/last.rb +2 -0
  95. data/lib/xmpp4r/last/helper/helper.rb +37 -0
  96. data/lib/xmpp4r/last/iq/last.rb +67 -0
  97. data/lib/xmpp4r/location.rb +2 -0
  98. data/lib/xmpp4r/location/helper/helper.rb +56 -0
  99. data/lib/xmpp4r/location/location.rb +179 -0
  100. data/lib/xmpp4r/message.rb +180 -0
  101. data/lib/xmpp4r/muc.rb +14 -0
  102. data/lib/xmpp4r/muc/helper/mucbrowser.rb +92 -0
  103. data/lib/xmpp4r/muc/helper/mucclient.rb +462 -0
  104. data/lib/xmpp4r/muc/helper/simplemucclient.rb +332 -0
  105. data/lib/xmpp4r/muc/iq/mucadmin.rb +23 -0
  106. data/lib/xmpp4r/muc/iq/mucadminitem.rb +20 -0
  107. data/lib/xmpp4r/muc/iq/mucowner.rb +15 -0
  108. data/lib/xmpp4r/muc/item.rb +143 -0
  109. data/lib/xmpp4r/muc/x/muc.rb +70 -0
  110. data/lib/xmpp4r/muc/x/mucuserinvite.rb +60 -0
  111. data/lib/xmpp4r/muc/x/mucuseritem.rb +36 -0
  112. data/lib/xmpp4r/presence.rb +232 -0
  113. data/lib/xmpp4r/pubsub.rb +8 -0
  114. data/lib/xmpp4r/pubsub/children/configuration.rb +86 -0
  115. data/lib/xmpp4r/pubsub/children/event.rb +49 -0
  116. data/lib/xmpp4r/pubsub/children/item.rb +35 -0
  117. data/lib/xmpp4r/pubsub/children/items.rb +53 -0
  118. data/lib/xmpp4r/pubsub/children/node_config.rb +48 -0
  119. data/lib/xmpp4r/pubsub/children/publish.rb +38 -0
  120. data/lib/xmpp4r/pubsub/children/retract.rb +41 -0
  121. data/lib/xmpp4r/pubsub/children/subscription.rb +62 -0
  122. data/lib/xmpp4r/pubsub/children/subscription_config.rb +67 -0
  123. data/lib/xmpp4r/pubsub/children/unsubscribe.rb +48 -0
  124. data/lib/xmpp4r/pubsub/helper/nodebrowser.rb +129 -0
  125. data/lib/xmpp4r/pubsub/helper/nodehelper.rb +156 -0
  126. data/lib/xmpp4r/pubsub/helper/oauth_service_helper.rb +90 -0
  127. data/lib/xmpp4r/pubsub/helper/servicehelper.rb +456 -0
  128. data/lib/xmpp4r/pubsub/iq/pubsub.rb +19 -0
  129. data/lib/xmpp4r/query.rb +15 -0
  130. data/lib/xmpp4r/reliable.rb +168 -0
  131. data/lib/xmpp4r/rexmladdons.rb +157 -0
  132. data/lib/xmpp4r/roster.rb +7 -0
  133. data/lib/xmpp4r/roster/helper/roster.rb +522 -0
  134. data/lib/xmpp4r/roster/iq/roster.rb +215 -0
  135. data/lib/xmpp4r/roster/x/roster.rb +138 -0
  136. data/lib/xmpp4r/rpc.rb +2 -0
  137. data/lib/xmpp4r/rpc/helper/client.rb +123 -0
  138. data/lib/xmpp4r/rpc/helper/server.rb +74 -0
  139. data/lib/xmpp4r/rpc/helper/xmlrpcaddons.rb +67 -0
  140. data/lib/xmpp4r/rpc/iq/rpc.rb +23 -0
  141. data/lib/xmpp4r/sasl.rb +248 -0
  142. data/lib/xmpp4r/semaphore.rb +38 -0
  143. data/lib/xmpp4r/stream.rb +599 -0
  144. data/lib/xmpp4r/streamparser.rb +85 -0
  145. data/lib/xmpp4r/test/listener_mocker.rb +118 -0
  146. data/lib/xmpp4r/tune.rb +2 -0
  147. data/lib/xmpp4r/tune/helper/helper.rb +58 -0
  148. data/lib/xmpp4r/tune/tune.rb +113 -0
  149. data/lib/xmpp4r/vcard.rb +6 -0
  150. data/lib/xmpp4r/vcard/helper/vcard.rb +84 -0
  151. data/lib/xmpp4r/vcard/iq/vcard.rb +109 -0
  152. data/lib/xmpp4r/version.rb +7 -0
  153. data/lib/xmpp4r/version/helper/responder.rb +72 -0
  154. data/lib/xmpp4r/version/helper/simpleresponder.rb +44 -0
  155. data/lib/xmpp4r/version/iq/version.rb +105 -0
  156. data/lib/xmpp4r/x.rb +37 -0
  157. data/lib/xmpp4r/xhtml.rb +1 -0
  158. data/lib/xmpp4r/xhtml/html.rb +115 -0
  159. data/lib/xmpp4r/xmpp4r.rb +20 -0
  160. data/lib/xmpp4r/xmppelement.rb +168 -0
  161. data/lib/xmpp4r/xmppstanza.rb +162 -0
  162. data/setup.rb +1586 -0
  163. data/test/bytestreams/tc_ibb.rb +188 -0
  164. data/test/bytestreams/tc_socks5bytestreams.rb +114 -0
  165. data/test/caps/tc_helper.rb +158 -0
  166. data/test/dataforms/tc_data.rb +81 -0
  167. data/test/delay/tc_xdelay.rb +51 -0
  168. data/test/discovery/tc_responder.rb +91 -0
  169. data/test/last/tc_helper.rb +75 -0
  170. data/test/lib/assert_equal_xml.rb +14 -0
  171. data/test/lib/clienttester.rb +149 -0
  172. data/test/muc/tc_muc_mucclient.rb +834 -0
  173. data/test/muc/tc_muc_simplemucclient.rb +114 -0
  174. data/test/muc/tc_mucowner.rb +50 -0
  175. data/test/pubsub/tc_helper.rb +785 -0
  176. data/test/pubsub/tc_nodeconfig.rb +61 -0
  177. data/test/pubsub/tc_subscriptionconfig.rb +41 -0
  178. data/test/reliable/tc_disconnect_cleanup.rb +334 -0
  179. data/test/reliable/tc_disconnect_exception.rb +37 -0
  180. data/test/reliable/tc_listener_mocked_test.rb +68 -0
  181. data/test/reliable/tc_reliable_connection.rb +31 -0
  182. data/test/roster/tc_helper.rb +524 -0
  183. data/test/roster/tc_iqqueryroster.rb +173 -0
  184. data/test/roster/tc_xroster.rb +73 -0
  185. data/test/rpc/tc_helper.rb +96 -0
  186. data/test/tc_callbacks.rb +129 -0
  187. data/test/tc_class_names.rb +146 -0
  188. data/test/tc_client.rb +30 -0
  189. data/test/tc_errors.rb +146 -0
  190. data/test/tc_idgenerator.rb +30 -0
  191. data/test/tc_iq.rb +113 -0
  192. data/test/tc_iqquery.rb +31 -0
  193. data/test/tc_jid.rb +204 -0
  194. data/test/tc_message.rb +131 -0
  195. data/test/tc_presence.rb +150 -0
  196. data/test/tc_rexml.rb +139 -0
  197. data/test/tc_stream.rb +167 -0
  198. data/test/tc_streamComponent.rb +95 -0
  199. data/test/tc_streamError.rb +129 -0
  200. data/test/tc_streamSend.rb +59 -0
  201. data/test/tc_streamparser.rb +125 -0
  202. data/test/tc_xmppstanza.rb +135 -0
  203. data/test/ts_xmpp4r.rb +44 -0
  204. data/test/tune/tc_helper_recv.rb +82 -0
  205. data/test/tune/tc_helper_send.rb +74 -0
  206. data/test/tune/tc_tune.rb +79 -0
  207. data/test/vcard/tc_helper.rb +49 -0
  208. data/test/vcard/tc_iqvcard.rb +62 -0
  209. data/test/version/tc_helper.rb +60 -0
  210. data/test/version/tc_iqqueryversion.rb +97 -0
  211. data/test/xhtml/tc_html.rb +41 -0
  212. data/tools/gen_requires.bash +31 -0
  213. data/tools/xmpp4r-gemspec-test.rb +11 -0
  214. data/xmpp4r.gemspec +238 -0
  215. metadata +280 -0
@@ -0,0 +1,86 @@
1
+ # =XMPP4R - XMPP Library for Ruby
2
+ # License:: Ruby's license (see the LICENSE file) or GNU GPL, at your option.
3
+ # Website::http://home.gna.org/xmpp4r/
4
+
5
+ module Jabber
6
+ module Bytestreams
7
+ ##
8
+ # SOCKS5Bytestreams implementation for the initiator side
9
+ class SOCKS5BytestreamsInitiator < SOCKS5Bytestreams
10
+ attr_reader :streamhosts
11
+
12
+ def initialize(stream, session_id, initiator_jid, target_jid)
13
+ super
14
+ @streamhosts = []
15
+ end
16
+
17
+ ##
18
+ # Add a streamhost which will be offered to the target
19
+ #
20
+ # streamhost:: can be:
21
+ # * [StreamHost] if already got all information (host/port)
22
+ # * [SOCKS5BytestreamsServer] if this is the local streamhost
23
+ # * [String] or [JID] if information should be automatically resolved by SOCKS5Bytestreams::query_streamhost
24
+ def add_streamhost(streamhost)
25
+ if streamhost.kind_of?(StreamHost)
26
+ @streamhosts << streamhost
27
+ elsif streamhost.kind_of?(SOCKS5BytestreamsServer)
28
+ streamhost.each_streamhost(@initiator_jid) { |sh|
29
+ @streamhosts << sh
30
+ }
31
+ elsif streamhost.kind_of?(String) or streamhost.kind_of?(JID)
32
+ @streamhosts << SOCKS5Bytestreams::query_streamhost(@stream, streamhost, @initiator_jid)
33
+ else
34
+ raise "Unknwon streamhost type: #{streamhost.class}"
35
+ end
36
+ end
37
+
38
+ ##
39
+ # Send the configured streamhosts to the target,
40
+ # wait for an answer and
41
+ # connect to the host the target chose.
42
+ def open
43
+ iq1 = Iq.new(:set, @target_jid)
44
+ iq1.from = @initiator_jid
45
+ bs = iq1.add IqQueryBytestreams.new(@session_id)
46
+ @streamhosts.each { |se|
47
+ bs.add(se)
48
+ }
49
+
50
+ peer_used = nil
51
+ @stream.send_with_id(iq1) { |response|
52
+ if response.query.kind_of?(IqQueryBytestreams)
53
+ peer_used = response.query.streamhost_used
54
+ raise "No streamhost-used" unless peer_used
55
+ raise "Invalid streamhost-used" unless peer_used.jid
56
+ end
57
+ }
58
+
59
+ @streamhost_used = nil
60
+ @streamhosts.each { |sh|
61
+ if peer_used.jid == sh.jid
62
+ @streamhost_used = sh
63
+ break
64
+ end
65
+ }
66
+ if @streamhost_used.jid == @initiator_jid
67
+ # This is our own JID, so the target chose SOCKS5BytestreamsServer
68
+ @socks = @streamhost_used.server.peer_sock(stream_address)
69
+ raise "Target didn't connect" unless @socks
70
+ @streamhost_cbs.process(@streamhost_used, :success, nil)
71
+ else
72
+ begin
73
+ @socks = connect_socks(@streamhost_used)
74
+ rescue Exception => e
75
+ Jabber::debuglog("SOCKS5 Bytestreams: #{e.class}: #{e}\n#{e.backtrace.join("\n")}")
76
+ @streamhost_cbs.process(@streamhost_used, :failure, e)
77
+ raise e
78
+ end
79
+ iq2 = Iq.new(:set, @streamhost_used.jid)
80
+ iq2.add(IqQueryBytestreams.new(@session_id)).activate = @target_jid.to_s
81
+ @stream.send_with_id(iq2)
82
+ end
83
+ end
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,198 @@
1
+ # =XMPP4R - XMPP Library for Ruby
2
+ # License:: Ruby's license (see the LICENSE file) or GNU GPL, at your option.
3
+ # Website::http://home.gna.org/xmpp4r/
4
+
5
+ module Jabber
6
+ module Bytestreams
7
+ ##
8
+ # The SOCKS5BytestreamsServer is an implementation of a SOCKS5 server.
9
+ #
10
+ # You can use it if you're reachable by your SOCKS5Bytestreams peers,
11
+ # thus avoiding use of an external proxy.
12
+ #
13
+ # ==Usage:
14
+ # * Instantiate with an unfirewalled port
15
+ # * Add your external IP addresses with SOCKS5BytestreamsServer#add_address
16
+ # * Once you've got an *outgoing* SOCKS5BytestreamsInitiator, do
17
+ # <tt>SOCKS5BytestreamsInitiator#add_streamhost(my_socks5bytestreamsserver)</tt>
18
+ # *before* you do <tt>SOCKS5BytestreamsInitiator#open</tt>
19
+ class SOCKS5BytestreamsServer
20
+ ##
21
+ # Start a local SOCKS5BytestreamsServer
22
+ #
23
+ # Will start to listen on the given TCP port and
24
+ # accept new peers
25
+ # port:: [Fixnum] TCP port to listen on
26
+ # listen_on:: [String] Optional address for the server socket to listen on (i.e. '0.0.0.0' or '::')
27
+ def initialize(port, listen_on=nil)
28
+ @port = port
29
+ @addresses = []
30
+ @peers = []
31
+ @peers_lock = Mutex.new
32
+ if listen_on
33
+ socket = TCPServer.new(listen_on, port)
34
+ else
35
+ socket = TCPServer.new(port)
36
+ end
37
+
38
+ Thread.new do
39
+ Thread.current.abort_on_exception = true
40
+ loop do
41
+ peer = SOCKS5BytestreamsPeer.new(socket.accept)
42
+ Thread.new do
43
+ Thread.current.abort_on_exception = true
44
+ begin
45
+ peer.start
46
+ rescue
47
+ Jabber::debuglog("SOCKS5 BytestreamsServer: Error accepting peer: #{$!}")
48
+ end
49
+ end
50
+ @peers_lock.synchronize do
51
+ @peers << peer
52
+ end
53
+ end
54
+ end
55
+ end
56
+
57
+ ##
58
+ # Find the socket a peer is associated to
59
+ #
60
+ # This method also performs some housekeeping, ie. removing
61
+ # peers with closed sockets.
62
+ # addr:: [String] Address like SOCKS5Bytestreams#stream_address
63
+ # result:: [TCPSocker] or [nil]
64
+ def peer_sock(addr)
65
+ res = nil
66
+ @peers_lock.synchronize {
67
+ removes = []
68
+
69
+ @peers.each { |peer|
70
+ if peer.socket and peer.socket.closed?
71
+ # Queue peers with closed socket for removal
72
+ removes << peer
73
+ elsif peer.address == addr and res.nil?
74
+ res = peer.socket
75
+ end
76
+
77
+ # If we sent multiple addresses of our own, clients may
78
+ # connect multiple times. DO NOT close any other connections
79
+ # here. These may belong to other concurrent bytestreams,
80
+ # believe that the peer will close any unneeded sockets
81
+ # which will then be picked up by the next call to peer_sock.
82
+ }
83
+
84
+ # If we sent multiple addresses of our own, clients may
85
+ # connect multiple times. Close these connections here.
86
+ @peers.delete_if { |peer|
87
+ if removes.include? peer
88
+ peer.socket.close rescue IOError
89
+ true
90
+ else
91
+ false
92
+ end
93
+ }
94
+ }
95
+
96
+ res
97
+ end
98
+
99
+ ##
100
+ # Add an external IP address
101
+ #
102
+ # This is a must-have, as SOCKS5BytestreamsInitiator must inform
103
+ # the target where to connect
104
+ def add_address(address)
105
+ @addresses << address
106
+ end
107
+
108
+ ##
109
+ # Iterate through all configured addresses,
110
+ # yielding SOCKS5BytestreamsServerStreamHost
111
+ # instances, which should be passed to
112
+ # SOCKS5BytestreamsInitiator#add_streamhost
113
+ #
114
+ # This will be automatically invoked if you pass an instance
115
+ # of SOCKS5BytestreamsServer to
116
+ # SOCKS5BytestreamsInitiator#add_streamhost
117
+ # my_jid:: [JID] My Jabber-ID
118
+ def each_streamhost(my_jid, &block)
119
+ @addresses.each { |address|
120
+ yield SOCKS5BytestreamsServerStreamHost.new(self, my_jid, address, @port)
121
+ }
122
+ end
123
+ end
124
+
125
+ ##
126
+ # A subclass of StreamHost which possesses a
127
+ # server attribute, to let SOCKS5BytestreamsInitiator
128
+ # know this is the local SOCKS5BytestreamsServer
129
+ class SOCKS5BytestreamsServerStreamHost < StreamHost
130
+ attr_reader :server
131
+ def initialize(server, jid=nil, host=nil, port=nil)
132
+ super(jid, host, port)
133
+ @server = server
134
+ end
135
+ end
136
+
137
+ ##
138
+ # This class will be instantiated by SOCKS5BytestreamsServer
139
+ # upon accepting a new connection
140
+ class SOCKS5BytestreamsPeer
141
+ attr_reader :address, :socket
142
+
143
+ ##
144
+ # Initialize a new peer
145
+ # socket:: [TCPSocket]
146
+ def initialize(socket)
147
+ @socket = socket
148
+ Jabber::debuglog("SOCKS5 BytestreamsServer: accepted peer #{@socket.peeraddr[2]}:#{@socket.peeraddr[1]}")
149
+ end
150
+
151
+ ##
152
+ # Start handshake process
153
+ def start
154
+ if !@socket.respond_to? :getbyte
155
+ class << @socket; alias getbyte getc; end
156
+ end
157
+
158
+ auth_ver = @socket.getbyte
159
+ if auth_ver != 5
160
+ # Unsupported version
161
+ @socket.close
162
+ return
163
+ end
164
+
165
+ auth_nmethods = @socket.getbyte
166
+ auth_methods = @socket.read(auth_nmethods)
167
+ unless auth_methods.index("\x00")
168
+ # Client won't accept no authentication
169
+ @socket.write("\x05\xff")
170
+ @socket.close
171
+ return
172
+ end
173
+ @socket.write("\x05\x00")
174
+ Jabber::debuglog("SOCKS5 BytestreamsServer: peer #{@socket.peeraddr[2]}:#{@socket.peeraddr[1]} authenticated")
175
+
176
+ req = @socket.read(4)
177
+ if req != "\x05\x01\x00\x03"
178
+ # Unknown version, command, reserved, address-type
179
+ @socket.close
180
+ return
181
+ end
182
+ req_addrlen = @socket.getbyte
183
+ req_addr = @socket.read(req_addrlen)
184
+ req_port = @socket.read(2)
185
+ if req_port != "\x00\x00"
186
+ # Port is not 0
187
+ @socket.write("\x05\x01")
188
+ @socket.close
189
+ return
190
+ end
191
+ @socket.write("\x05\x00\x00\x03#{req_addrlen.chr}#{req_addr}\x00\x00")
192
+ Jabber::debuglog("SOCKS5 BytestreamsServer: peer #{@socket.peeraddr[2]}:#{@socket.peeraddr[1]} connected for #{req_addr}")
193
+
194
+ @address = req_addr
195
+ end
196
+ end
197
+ end
198
+ end
@@ -0,0 +1,65 @@
1
+ # =XMPP4R - XMPP Library for Ruby
2
+ # License:: Ruby's license (see the LICENSE file) or GNU GPL, at your option.
3
+ # Website::http://home.gna.org/xmpp4r/
4
+
5
+ require 'socket'
6
+
7
+ module Jabber
8
+ module Bytestreams
9
+
10
+ ##
11
+ # A SOCKS5 client implementation
12
+ #
13
+ # ==Usage:
14
+ # * Initialize with proxy's address and port
15
+ # * Authenticate
16
+ # * Connect to target host
17
+ class SOCKS5Socket < TCPSocket
18
+ ##
19
+ # Connect to SOCKS5 proxy
20
+ def initialize(socks_host, socks_port)
21
+ super(socks_host, socks_port)
22
+ end
23
+
24
+ ##
25
+ # Authenticate for SOCKS5 proxy
26
+ #
27
+ # Currently supports only 'no authentication required'
28
+ def auth
29
+ write("\x05\x01\x00")
30
+ buf = read(2)
31
+ if buf.nil? or buf != "\x05\x00"
32
+ close
33
+ raise SOCKS5Error.new("Invalid SOCKS5 authentication: #{buf.inspect}")
34
+ end
35
+
36
+ self
37
+ end
38
+
39
+ ##
40
+ # Issue a CONNECT request to a host name
41
+ # which is to be resolved by the proxy.
42
+ # domain:: [String] Host name
43
+ # port:: [Fixnum] Port number
44
+ def connect_domain(domain, port)
45
+ write("\x05\x01\x00\x03#{domain.size.chr}#{domain}#{[port].pack("n")}")
46
+ buf = read(4)
47
+ if buf.nil? or buf[0..1] != "\005\000"
48
+ close
49
+ raise SOCKS5Error.new("Invalid SOCKS5 connect: #{buf.inspect}")
50
+ end
51
+
52
+ case buf.respond_to?(:bytes) ? buf.bytes.to_a[3] : buf[3]
53
+ when 1 then read(6) # IPv4 addr
54
+ when 3 then read(3 + domain.size) # Domain
55
+ when 4 then read(18) # IPv6 addr
56
+ else
57
+ close
58
+ raise SOCKS5Error.new("Invalid SOCKS5 address type #{buf[3].to_s}")
59
+ end
60
+
61
+ self
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,79 @@
1
+ # =XMPP4R - XMPP Library for Ruby
2
+ # License:: Ruby's license (see the LICENSE file) or GNU GPL, at your option.
3
+ # Website::http://home.gna.org/xmpp4r/
4
+
5
+ module Jabber
6
+ module Bytestreams
7
+ ##
8
+ # SOCKS5 Bytestreams implementation of the target site
9
+ class SOCKS5BytestreamsTarget < SOCKS5Bytestreams
10
+ ##
11
+ # See SOCKS5Bytestreams#initialize
12
+ def initialize(stream, session_id, initiator_jid, target_jid)
13
+ @connect_timeout = 60
14
+ @accept_ready = Semaphore::new
15
+ super
16
+ end
17
+
18
+ def accept_wait
19
+ @accept_ready.wait
20
+ end
21
+
22
+ ##
23
+ # Wait until the stream has been established
24
+ #
25
+ # May raise various exceptions
26
+ def accept
27
+ error = nil
28
+ connect_sem = Semaphore.new
29
+
30
+ @stream.add_iq_callback(200, self) { |iq|
31
+ if iq.type == :set and iq.from == @initiator_jid and iq.to == @target_jid and iq.query.kind_of?(IqQueryBytestreams)
32
+ begin
33
+ @stream.delete_iq_callback(self)
34
+
35
+ iq.query.each_element('streamhost') { |streamhost|
36
+ if streamhost.host and streamhost.port and not @socks
37
+ begin
38
+ @socks = connect_socks(streamhost)
39
+ @streamhost_used = streamhost
40
+ rescue Exception => e
41
+ Jabber::debuglog("SOCKS5 Bytestreams: #{e.class}: #{e}\n#{e.backtrace.join("\n")}")
42
+ @streamhost_cbs.process(streamhost, :failure, e)
43
+ end
44
+ end
45
+ }
46
+
47
+ reply = iq.answer(false)
48
+ if @streamhost_used
49
+ reply.type = :result
50
+ reply.add(IqQueryBytestreams.new)
51
+ reply.query.add(StreamHostUsed.new(@streamhost_used.jid))
52
+ else
53
+ reply.type = :error
54
+ reply.add(ErrorResponse.new('item-not-found'))
55
+ end
56
+ @stream.send(reply)
57
+ rescue Exception => e
58
+ error = e
59
+ end
60
+
61
+ connect_sem.run
62
+ true
63
+ else
64
+ false
65
+ end
66
+ }
67
+ @accept_ready.run
68
+ begin
69
+ Timeout::timeout(@connect_timeout) { connect_sem.wait }
70
+ rescue Timeout::Error
71
+ @stream.delete_iq_callback(self)
72
+ end
73
+
74
+ raise error if error
75
+ (@socks != nil)
76
+ end
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,170 @@
1
+ # =XMPP4R - XMPP Library for Ruby
2
+ # License:: Ruby's license (see the LICENSE file) or GNU GPL, at your option.
3
+ # Website::http://home.gna.org/xmpp4r/
4
+
5
+ module Jabber
6
+ module Bytestreams
7
+ NS_BYTESTREAMS = 'http://jabber.org/protocol/bytestreams'
8
+
9
+ ##
10
+ # Class for accessing <query/> elements with
11
+ # xmlns='http://jabber.org/protocol/bytestreams'
12
+ # in <iq/> stanzas.
13
+ class IqQueryBytestreams < IqQuery
14
+ name_xmlns 'query', NS_BYTESTREAMS
15
+
16
+ ##
17
+ # Initialize such a <query/>
18
+ # sid:: [String] Session-ID
19
+ # mode:: [Symbol] :tcp or :udp
20
+ def initialize(sid=nil, mode=nil)
21
+ super()
22
+ self.sid = sid
23
+ self.mode = mode
24
+ end
25
+
26
+ ##
27
+ # Session-ID
28
+ def sid
29
+ attributes['sid']
30
+ end
31
+
32
+ ##
33
+ # Set Session-ID
34
+ def sid=(s)
35
+ attributes['sid'] = s
36
+ end
37
+
38
+ ##
39
+ # Transfer mode
40
+ # result:: :tcp or :udp
41
+ def mode
42
+ case attributes['mode']
43
+ when 'udp' then :udp
44
+ else :tcp
45
+ end
46
+ end
47
+
48
+ ##
49
+ # Set the transfer mode
50
+ # m:: :tcp or :udp
51
+ def mode=(m)
52
+ case m
53
+ when :udp then attributes['mode'] = 'udp'
54
+ else attributes['mode'] = 'tcp'
55
+ end
56
+ end
57
+
58
+ ##
59
+ # Get the <streamhost-used/> child
60
+ # result:: [StreamHostUsed]
61
+ def streamhost_used
62
+ first_element('streamhost-used')
63
+ end
64
+
65
+ ##
66
+ # Get the text of the <activate/> child
67
+ # result:: [JID] or [nil]
68
+ def activate
69
+ j = first_element_text('activate')
70
+ j ? JID.new(j) : nil
71
+ end
72
+
73
+ ##
74
+ # Set the text of the <activate/> child
75
+ # s:: [JID]
76
+ def activate=(s)
77
+ replace_element_text('activate', s ? s.to_s : nil)
78
+ end
79
+ end
80
+
81
+
82
+ ##
83
+ # <streamhost/> element, normally appear
84
+ # as children of IqQueryBytestreams
85
+ class StreamHost < XMPPElement
86
+ name_xmlns 'streamhost', NS_BYTESTREAMS
87
+
88
+ ##
89
+ # Initialize a <streamhost/> element
90
+ # jid:: [JID]
91
+ # host:: [String] Hostname or IP address
92
+ # port:: [Fixnum] Port number
93
+ def initialize(jid=nil, host=nil, port=nil)
94
+ super()
95
+ self.jid = jid
96
+ self.host = host
97
+ self.port = port
98
+ end
99
+
100
+ ##
101
+ # Get the JID of the streamhost
102
+ def jid
103
+ (a = attributes['jid']) ? JID.new(a) : nil
104
+ end
105
+
106
+ ##
107
+ # Set the JID of the streamhost
108
+ def jid=(j)
109
+ attributes['jid'] = (j ? j.to_s : nil)
110
+ end
111
+
112
+ ##
113
+ # Get the host address of the streamhost
114
+ def host
115
+ attributes['host']
116
+ end
117
+
118
+ ##
119
+ # Set the host address of the streamhost
120
+ def host=(h)
121
+ attributes['host'] = h
122
+ end
123
+
124
+ ##
125
+ # Get the zeroconf attribute of the streamhost
126
+ def zeroconf
127
+ attributes['zeroconf']
128
+ end
129
+
130
+ ##
131
+ # Set the zeroconf attribute of the streamhost
132
+ def zeroconf=(s)
133
+ attributes['zeroconf'] = s
134
+ end
135
+
136
+ ##
137
+ # Get the port number of the streamhost
138
+ def port
139
+ p = attributes['port'].to_i
140
+ (p == 0 ? nil : p)
141
+ end
142
+
143
+ ##
144
+ # Set the port number of the streamhost
145
+ def port=(p)
146
+ attributes['port'] = p.to_s
147
+ end
148
+ end
149
+
150
+ ##
151
+ # <streamhost-used/> element, normally appears
152
+ # as child of IqQueryBytestreams
153
+ class StreamHostUsed < XMPPElement
154
+ name_xmlns 'streamhost-used', NS_BYTESTREAMS
155
+
156
+ def initialize(jid=nil)
157
+ super()
158
+ self.jid = jid
159
+ end
160
+
161
+ def jid
162
+ (a = attributes['jid']) ? JID.new(a) : nil
163
+ end
164
+
165
+ def jid=(j)
166
+ attributes['jid'] = (j ? j.to_s : nil)
167
+ end
168
+ end
169
+ end
170
+ end