gmcmillan-xmpp4r 0.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (215) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG +91 -0
  3. data/COPYING +340 -0
  4. data/LICENSE +59 -0
  5. data/README.rdoc +122 -0
  6. data/README_ruby19.txt +43 -0
  7. data/Rakefile +258 -0
  8. data/data/doc/xmpp4r/examples/advanced/adventure/README +56 -0
  9. data/data/doc/xmpp4r/examples/advanced/adventure/adventure.rb +23 -0
  10. data/data/doc/xmpp4r/examples/advanced/adventure/adventuremuc.rb +136 -0
  11. data/data/doc/xmpp4r/examples/advanced/adventure/cube.xml +15 -0
  12. data/data/doc/xmpp4r/examples/advanced/adventure/tower.xml +69 -0
  13. data/data/doc/xmpp4r/examples/advanced/adventure/world.rb +424 -0
  14. data/data/doc/xmpp4r/examples/advanced/fileserve.conf +11 -0
  15. data/data/doc/xmpp4r/examples/advanced/fileserve.rb +346 -0
  16. data/data/doc/xmpp4r/examples/advanced/getonline.rb +56 -0
  17. data/data/doc/xmpp4r/examples/advanced/gtkmucclient.rb +315 -0
  18. data/data/doc/xmpp4r/examples/advanced/migrate.rb +88 -0
  19. data/data/doc/xmpp4r/examples/advanced/minimuc.rb +266 -0
  20. data/data/doc/xmpp4r/examples/advanced/pep-aggregator/index.xsl +235 -0
  21. data/data/doc/xmpp4r/examples/advanced/pep-aggregator/pep-aggregator.rb +147 -0
  22. data/data/doc/xmpp4r/examples/advanced/recvfile.rb +85 -0
  23. data/data/doc/xmpp4r/examples/advanced/rosterdiscovery.rb +129 -0
  24. data/data/doc/xmpp4r/examples/advanced/sendfile.conf +10 -0
  25. data/data/doc/xmpp4r/examples/advanced/sendfile.rb +72 -0
  26. data/data/doc/xmpp4r/examples/advanced/shellmgr/shellmgr.rb +51 -0
  27. data/data/doc/xmpp4r/examples/advanced/shellmgr/shellmgr_jabber.rb +43 -0
  28. data/data/doc/xmpp4r/examples/advanced/shellmgr/shellmgr_test.rb +10 -0
  29. data/data/doc/xmpp4r/examples/advanced/versionpoll.rb +109 -0
  30. data/data/doc/xmpp4r/examples/advanced/xmpping.rb +146 -0
  31. data/data/doc/xmpp4r/examples/advanced/xmppingrc.sample +14 -0
  32. data/data/doc/xmpp4r/examples/basic/change_password.rb +41 -0
  33. data/data/doc/xmpp4r/examples/basic/client.rb +70 -0
  34. data/data/doc/xmpp4r/examples/basic/component.rb +11 -0
  35. data/data/doc/xmpp4r/examples/basic/echo.rb +37 -0
  36. data/data/doc/xmpp4r/examples/basic/jabbersend.rb +41 -0
  37. data/data/doc/xmpp4r/examples/basic/mass_sender.rb +68 -0
  38. data/data/doc/xmpp4r/examples/basic/muc_owner_config.rb +12 -0
  39. data/data/doc/xmpp4r/examples/basic/mucinfo.rb +41 -0
  40. data/data/doc/xmpp4r/examples/basic/mucsimplebot.rb +82 -0
  41. data/data/doc/xmpp4r/examples/basic/register.rb +42 -0
  42. data/data/doc/xmpp4r/examples/basic/remove_registration.rb +18 -0
  43. data/data/doc/xmpp4r/examples/basic/roster.rb +44 -0
  44. data/data/doc/xmpp4r/examples/basic/rosterprint.rb +50 -0
  45. data/data/doc/xmpp4r/examples/basic/rosterrename.rb +34 -0
  46. data/data/doc/xmpp4r/examples/basic/rosterwatch.rb +171 -0
  47. data/data/doc/xmpp4r/examples/basic/send_vcard.rb +67 -0
  48. data/data/doc/xmpp4r/examples/basic/tune_client.rb +56 -0
  49. data/data/doc/xmpp4r/examples/basic/tune_server.rb +58 -0
  50. data/data/doc/xmpp4r/examples/basic/versionbot.rb +75 -0
  51. data/lib/xmpp4r.rb +118 -0
  52. data/lib/xmpp4r/base64.rb +32 -0
  53. data/lib/xmpp4r/bytestreams.rb +15 -0
  54. data/lib/xmpp4r/bytestreams/helper/filetransfer.rb +321 -0
  55. data/lib/xmpp4r/bytestreams/helper/ibb/base.rb +257 -0
  56. data/lib/xmpp4r/bytestreams/helper/ibb/initiator.rb +31 -0
  57. data/lib/xmpp4r/bytestreams/helper/ibb/target.rb +54 -0
  58. data/lib/xmpp4r/bytestreams/helper/socks5bytestreams/base.rb +153 -0
  59. data/lib/xmpp4r/bytestreams/helper/socks5bytestreams/initiator.rb +86 -0
  60. data/lib/xmpp4r/bytestreams/helper/socks5bytestreams/server.rb +198 -0
  61. data/lib/xmpp4r/bytestreams/helper/socks5bytestreams/socks5.rb +65 -0
  62. data/lib/xmpp4r/bytestreams/helper/socks5bytestreams/target.rb +82 -0
  63. data/lib/xmpp4r/bytestreams/iq/bytestreams.rb +170 -0
  64. data/lib/xmpp4r/bytestreams/iq/si.rb +206 -0
  65. data/lib/xmpp4r/callbacks.rb +133 -0
  66. data/lib/xmpp4r/caps.rb +1 -0
  67. data/lib/xmpp4r/caps/c.rb +67 -0
  68. data/lib/xmpp4r/caps/helper/generator.rb +160 -0
  69. data/lib/xmpp4r/caps/helper/helper.rb +84 -0
  70. data/lib/xmpp4r/client.rb +345 -0
  71. data/lib/xmpp4r/command/helper/responder.rb +53 -0
  72. data/lib/xmpp4r/command/iq/command.rb +154 -0
  73. data/lib/xmpp4r/component.rb +103 -0
  74. data/lib/xmpp4r/connection.rb +231 -0
  75. data/lib/xmpp4r/dataforms.rb +5 -0
  76. data/lib/xmpp4r/dataforms/x/data.rb +297 -0
  77. data/lib/xmpp4r/debuglog.rb +63 -0
  78. data/lib/xmpp4r/delay.rb +5 -0
  79. data/lib/xmpp4r/delay/x/delay.rb +99 -0
  80. data/lib/xmpp4r/discovery.rb +8 -0
  81. data/lib/xmpp4r/discovery/helper/helper.rb +58 -0
  82. data/lib/xmpp4r/discovery/helper/responder.rb +165 -0
  83. data/lib/xmpp4r/discovery/iq/discoinfo.rb +211 -0
  84. data/lib/xmpp4r/discovery/iq/discoitems.rb +147 -0
  85. data/lib/xmpp4r/entity_time.rb +6 -0
  86. data/lib/xmpp4r/entity_time/iq.rb +45 -0
  87. data/lib/xmpp4r/entity_time/responder.rb +57 -0
  88. data/lib/xmpp4r/errors.rb +284 -0
  89. data/lib/xmpp4r/feature_negotiation.rb +5 -0
  90. data/lib/xmpp4r/feature_negotiation/iq/feature.rb +28 -0
  91. data/lib/xmpp4r/framework/base.rb +55 -0
  92. data/lib/xmpp4r/framework/bot.rb +148 -0
  93. data/lib/xmpp4r/httpbinding.rb +5 -0
  94. data/lib/xmpp4r/httpbinding/client.rb +275 -0
  95. data/lib/xmpp4r/idgenerator.rb +37 -0
  96. data/lib/xmpp4r/iq.rb +221 -0
  97. data/lib/xmpp4r/jid.rb +167 -0
  98. data/lib/xmpp4r/last.rb +2 -0
  99. data/lib/xmpp4r/last/helper/helper.rb +37 -0
  100. data/lib/xmpp4r/last/iq/last.rb +67 -0
  101. data/lib/xmpp4r/location.rb +2 -0
  102. data/lib/xmpp4r/location/helper/helper.rb +56 -0
  103. data/lib/xmpp4r/location/location.rb +179 -0
  104. data/lib/xmpp4r/message.rb +226 -0
  105. data/lib/xmpp4r/muc.rb +14 -0
  106. data/lib/xmpp4r/muc/helper/mucbrowser.rb +92 -0
  107. data/lib/xmpp4r/muc/helper/mucclient.rb +469 -0
  108. data/lib/xmpp4r/muc/helper/simplemucclient.rb +332 -0
  109. data/lib/xmpp4r/muc/iq/mucadmin.rb +23 -0
  110. data/lib/xmpp4r/muc/iq/mucadminitem.rb +20 -0
  111. data/lib/xmpp4r/muc/iq/mucowner.rb +15 -0
  112. data/lib/xmpp4r/muc/item.rb +143 -0
  113. data/lib/xmpp4r/muc/x/muc.rb +70 -0
  114. data/lib/xmpp4r/muc/x/mucuserinvite.rb +60 -0
  115. data/lib/xmpp4r/muc/x/mucuseritem.rb +36 -0
  116. data/lib/xmpp4r/presence.rb +232 -0
  117. data/lib/xmpp4r/pubsub.rb +8 -0
  118. data/lib/xmpp4r/pubsub/children/configuration.rb +86 -0
  119. data/lib/xmpp4r/pubsub/children/event.rb +49 -0
  120. data/lib/xmpp4r/pubsub/children/item.rb +35 -0
  121. data/lib/xmpp4r/pubsub/children/items.rb +53 -0
  122. data/lib/xmpp4r/pubsub/children/node_config.rb +48 -0
  123. data/lib/xmpp4r/pubsub/children/publish.rb +38 -0
  124. data/lib/xmpp4r/pubsub/children/retract.rb +41 -0
  125. data/lib/xmpp4r/pubsub/children/subscription.rb +62 -0
  126. data/lib/xmpp4r/pubsub/children/subscription_config.rb +67 -0
  127. data/lib/xmpp4r/pubsub/children/unsubscribe.rb +63 -0
  128. data/lib/xmpp4r/pubsub/helper/nodebrowser.rb +129 -0
  129. data/lib/xmpp4r/pubsub/helper/nodehelper.rb +156 -0
  130. data/lib/xmpp4r/pubsub/helper/oauth_service_helper.rb +90 -0
  131. data/lib/xmpp4r/pubsub/helper/servicehelper.rb +490 -0
  132. data/lib/xmpp4r/pubsub/iq/pubsub.rb +19 -0
  133. data/lib/xmpp4r/query.rb +15 -0
  134. data/lib/xmpp4r/reliable.rb +168 -0
  135. data/lib/xmpp4r/rexmladdons.rb +197 -0
  136. data/lib/xmpp4r/roster.rb +7 -0
  137. data/lib/xmpp4r/roster/helper/roster.rb +532 -0
  138. data/lib/xmpp4r/roster/iq/roster.rb +215 -0
  139. data/lib/xmpp4r/roster/x/roster.rb +138 -0
  140. data/lib/xmpp4r/rpc.rb +2 -0
  141. data/lib/xmpp4r/rpc/helper/client.rb +123 -0
  142. data/lib/xmpp4r/rpc/helper/server.rb +74 -0
  143. data/lib/xmpp4r/rpc/helper/xmlrpcaddons.rb +67 -0
  144. data/lib/xmpp4r/rpc/iq/rpc.rb +23 -0
  145. data/lib/xmpp4r/sasl.rb +259 -0
  146. data/lib/xmpp4r/semaphore.rb +38 -0
  147. data/lib/xmpp4r/stream.rb +611 -0
  148. data/lib/xmpp4r/streamparser.rb +66 -0
  149. data/lib/xmpp4r/test/listener_mocker.rb +118 -0
  150. data/lib/xmpp4r/tune.rb +2 -0
  151. data/lib/xmpp4r/tune/helper/helper.rb +58 -0
  152. data/lib/xmpp4r/tune/tune.rb +113 -0
  153. data/lib/xmpp4r/vcard.rb +6 -0
  154. data/lib/xmpp4r/vcard/helper/vcard.rb +84 -0
  155. data/lib/xmpp4r/vcard/iq/vcard.rb +109 -0
  156. data/lib/xmpp4r/version.rb +7 -0
  157. data/lib/xmpp4r/version/helper/responder.rb +72 -0
  158. data/lib/xmpp4r/version/helper/simpleresponder.rb +44 -0
  159. data/lib/xmpp4r/version/iq/version.rb +105 -0
  160. data/lib/xmpp4r/x.rb +37 -0
  161. data/lib/xmpp4r/xhtml.rb +1 -0
  162. data/lib/xmpp4r/xhtml/html.rb +115 -0
  163. data/lib/xmpp4r/xmpp4r.rb +20 -0
  164. data/lib/xmpp4r/xmppelement.rb +168 -0
  165. data/lib/xmpp4r/xmppstanza.rb +162 -0
  166. data/setup.rb +1586 -0
  167. data/test/bytestreams/tc_ibb.rb +188 -0
  168. data/test/bytestreams/tc_socks5bytestreams.rb +114 -0
  169. data/test/caps/tc_helper.rb +158 -0
  170. data/test/dataforms/tc_data.rb +81 -0
  171. data/test/delay/tc_xdelay.rb +51 -0
  172. data/test/discovery/tc_responder.rb +91 -0
  173. data/test/entity_time/tc_responder.rb +65 -0
  174. data/test/last/tc_helper.rb +75 -0
  175. data/test/lib/assert_equal_xml.rb +14 -0
  176. data/test/lib/clienttester.rb +149 -0
  177. data/test/muc/tc_muc_mucclient.rb +834 -0
  178. data/test/muc/tc_muc_simplemucclient.rb +114 -0
  179. data/test/muc/tc_mucowner.rb +50 -0
  180. data/test/pubsub/tc_helper.rb +785 -0
  181. data/test/pubsub/tc_nodeconfig.rb +61 -0
  182. data/test/pubsub/tc_subscriptionconfig.rb +41 -0
  183. data/test/roster/tc_helper.rb +523 -0
  184. data/test/roster/tc_iqqueryroster.rb +173 -0
  185. data/test/roster/tc_xroster.rb +73 -0
  186. data/test/rpc/tc_helper.rb +96 -0
  187. data/test/tc_callbacks.rb +129 -0
  188. data/test/tc_class_names.rb +146 -0
  189. data/test/tc_client.rb +30 -0
  190. data/test/tc_errors.rb +146 -0
  191. data/test/tc_idgenerator.rb +30 -0
  192. data/test/tc_iq.rb +113 -0
  193. data/test/tc_iqquery.rb +31 -0
  194. data/test/tc_jid.rb +204 -0
  195. data/test/tc_presence.rb +150 -0
  196. data/test/tc_rexml.rb +139 -0
  197. data/test/tc_stream.rb +193 -0
  198. data/test/tc_streamComponent.rb +105 -0
  199. data/test/tc_streamError.rb +129 -0
  200. data/test/tc_streamSend.rb +59 -0
  201. data/test/tc_streamparser.rb +137 -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 +249 -0
  215. metadata +299 -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 "Unknown 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,82 @@
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
+ iq_received_sem = Semaphore.new
30
+
31
+ @stream.add_iq_callback(200, self) { |iq|
32
+ if iq.type == :set and iq.from == @initiator_jid and iq.to == @target_jid and iq.query.kind_of?(IqQueryBytestreams)
33
+ begin
34
+ iq_received_sem.run
35
+ @stream.delete_iq_callback(self)
36
+
37
+ iq.query.each_element('streamhost') { |streamhost|
38
+ if streamhost.host and streamhost.port and not @socks
39
+ begin
40
+ @socks = connect_socks(streamhost)
41
+ @streamhost_used = streamhost
42
+ rescue Exception => e
43
+ Jabber::debuglog("SOCKS5 Bytestreams: #{e.class}: #{e}\n#{e.backtrace.join("\n")}")
44
+ @streamhost_cbs.process(streamhost, :failure, e)
45
+ end
46
+ end
47
+ }
48
+
49
+ reply = iq.answer(false)
50
+ if @streamhost_used
51
+ reply.type = :result
52
+ reply.add(IqQueryBytestreams.new)
53
+ reply.query.add(StreamHostUsed.new(@streamhost_used.jid))
54
+ else
55
+ reply.type = :error
56
+ reply.add(ErrorResponse.new('item-not-found'))
57
+ end
58
+ @stream.send(reply)
59
+ rescue Exception => e
60
+ error = e
61
+ end
62
+
63
+ connect_sem.run
64
+ true
65
+ else
66
+ false
67
+ end
68
+ }
69
+ @accept_ready.run
70
+ begin
71
+ Timeout::timeout(@connect_timeout) { iq_received_sem.wait }
72
+ connect_sem.wait
73
+ rescue Timeout::Error
74
+ @stream.delete_iq_callback(self)
75
+ end
76
+
77
+ raise error if error
78
+ (@socks != nil)
79
+ end
80
+ end
81
+ end
82
+ 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