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,154 @@
1
+ require 'xmpp4r/iq'
2
+
3
+ module Jabber
4
+
5
+ module Command
6
+
7
+ ##
8
+ # Class for handling ad-hoc commands
9
+ # (JEP 0050)
10
+ #
11
+ # A command is uniquely identified by its node attribute.
12
+ class IqCommand < Iq
13
+ name_xmlns 'command', 'http://jabber.org/protocol/commands'
14
+
15
+ def initialize(node=nil, action=nil)
16
+ super()
17
+ set_node(node)
18
+ set_action(action)
19
+ end
20
+
21
+ ##
22
+ # Get the node of the Command stanza
23
+ # result:: [String] or nil
24
+ def node
25
+ attributes['node']
26
+ end
27
+
28
+ ##
29
+ # Set the node of the Command stanza
30
+ # v:: [String] or nil
31
+ def node=(v)
32
+ attributes['node'] = v
33
+ end
34
+
35
+ ##
36
+ # Set the node of the Command stanza (chaining-friendly)
37
+ # v:: [String] or nil
38
+ def set_node(v)
39
+ self.node = v
40
+ self
41
+ end
42
+
43
+ ##
44
+ # Get the sessionid of the Command stanza
45
+ # result:: [String] or nil
46
+ def sessionid
47
+ attributes['sessionid']
48
+ end
49
+
50
+ ##
51
+ # Set the sessionid of the Command stanza
52
+ # v:: [String] or nil
53
+ def sessionid=(v)
54
+ attributes['sessionid'] = v
55
+ end
56
+
57
+ ##
58
+ # Set the sessionid of the Command stanza (chaining-friendly)
59
+ # v:: [String] or nil
60
+ def set_sessionid(v)
61
+ self.sessionid = v
62
+ self
63
+ end
64
+
65
+ ##
66
+ # Get the action of the Command stanza
67
+ #
68
+ # The following Symbols are allowed:
69
+ # * :execute
70
+ # * :cancel
71
+ # * :prev
72
+ # * :next
73
+ # * :complete
74
+ # return:: [Symbol] or nil
75
+ def action
76
+ case attributes['action']
77
+ when 'execute' then :execute
78
+ when 'cancel' then :cancel
79
+ when 'prev' then :prev
80
+ when 'next' then :next
81
+ when 'complete' then :complete
82
+ else nil
83
+ end
84
+ end
85
+
86
+ ##
87
+ # Set the action of the Command stanza (see IqCommand#action for details)
88
+ # v:: [Symbol] or nil
89
+ def action=(v)
90
+ attributes['action'] = case v
91
+ when :execute then 'execute'
92
+ when :cancel then 'cancel'
93
+ when :prev then 'prev'
94
+ when :next then 'next'
95
+ when :complete then 'complete'
96
+ else nil
97
+ end
98
+ end
99
+
100
+ ##
101
+ # Set the action of the Command stanza (chaining-friendly)
102
+ # v:: [Symbol] or nil
103
+ def set_action(v)
104
+ self.action = v
105
+ self
106
+ end
107
+
108
+ ##
109
+ # Get the status of the Command stanza
110
+ #
111
+ # The following Symbols are allowed:
112
+ # * :executing
113
+ # * :completed
114
+ # * :canceled
115
+ # return:: [Symbol] or nil
116
+ def status
117
+ case attributes['status']
118
+ when 'executing' then :executing
119
+ when 'completed' then :completed
120
+ when 'canceled' then :canceled
121
+ else nil
122
+ end
123
+ end
124
+
125
+ ##
126
+ # Set the status of the Command stanza (see IqCommand#status for details)
127
+ # v:: [Symbol] or nil
128
+ def status=(v)
129
+ attributes['status'] = case v
130
+ when :executing then 'executing'
131
+ when :completed then 'completed'
132
+ when :canceled then 'canceled'
133
+ else nil
134
+ end
135
+ end
136
+
137
+ ##
138
+ # Set the status of the Command stanza (chaining-friendly)
139
+ # v:: [Symbol] or nil
140
+ def set_status(v)
141
+ self.status = v
142
+ self
143
+ end
144
+
145
+ ##
146
+ # Get the actions allowed
147
+ # return:: [REXML::Element] or nil
148
+ def actions
149
+ first_element('actions')
150
+ end
151
+
152
+ end
153
+ end
154
+ end
@@ -0,0 +1,103 @@
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 'xmpp4r/connection'
6
+
7
+ module Jabber
8
+ ##
9
+ # The component class provides everything needed to build a XMPP Component.
10
+ #
11
+ # Components are more flexible as they are only restricted in the use of a
12
+ # fixed domain. node and resource of JIDs are freely choosable for all stanzas.
13
+ class Component < Connection
14
+
15
+ # The component's JID
16
+ attr_reader :jid
17
+
18
+ # The server's address
19
+ attr_reader :server_address
20
+
21
+ # The server's port
22
+ attr_reader :server_port
23
+
24
+ # Create a new Component
25
+ # jid:: [JID]
26
+ def initialize(jid, server_address=nil, server_port=5347)
27
+ super()
28
+ @jid = (jid.kind_of?(JID) ? jid : JID.new(jid.to_s))
29
+
30
+ if server_address
31
+ $stderr.puts "Passing server and port to Jabber::Component.new is " +
32
+ "obsolete and will vanish in some later XMPP4R release. " +
33
+ "Please use these arguments when calling " +
34
+ "Jabber::Client#connect"
35
+ @server_address = server_address
36
+ @server_port = server_port
37
+ end
38
+ end
39
+
40
+ # Connect to the server
41
+ # (chaining-friendly)
42
+ # server:: [String] Hostname
43
+ # port:: [Integer] TCP port (5347)
44
+ # return:: self
45
+ def connect(server=nil, port=5347)
46
+ if server
47
+ super(server, port)
48
+ else
49
+ super(@server_address, @server_port)
50
+ end
51
+ self
52
+ end
53
+
54
+ ##
55
+ # Close the connection,
56
+ # sends <tt></stream:stream></tt> tag first
57
+ def close
58
+ send("</stream:stream>")
59
+ super
60
+ end
61
+
62
+ def generate_stream_start(to=nil, from=nil, id=nil, xml_lang="en", xmlns="jabber:component:accept", version="1.0")
63
+ super
64
+ end
65
+ private :generate_stream_start
66
+
67
+ ##
68
+ # Start the stream-parser and send the component-specific stream opening element
69
+ def start
70
+ super
71
+ send(generate_stream_start(@jid)) { |e|
72
+ if e.name == 'stream'
73
+ true
74
+ else
75
+ false
76
+ end
77
+ }
78
+ end
79
+
80
+ ##
81
+ # Send auth with given secret and wait for result
82
+ #
83
+ # Throws ComponentAuthenticationFailure
84
+ # secret:: [String] the shared secret
85
+ def auth(secret)
86
+ hash = Digest::SHA1::hexdigest(@streamid.to_s + secret)
87
+ authenticated = false
88
+ send("<handshake>#{hash}</handshake>") { |r|
89
+ if r.prefix == 'stream' and r.name == 'error'
90
+ true
91
+ elsif r.name == 'handshake'
92
+ authenticated = true
93
+ true
94
+ else
95
+ false
96
+ end
97
+ }
98
+ unless authenticated
99
+ raise ComponentAuthenticationFailure.new, "Component authentication failed"
100
+ end
101
+ end
102
+ end
103
+ end
@@ -0,0 +1,223 @@
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
+ begin
6
+ require 'openssl'
7
+ rescue LoadError
8
+ end
9
+ require 'xmpp4r/stream'
10
+
11
+ module Jabber
12
+ ##
13
+ # The connection class manages the TCP connection to the Jabber server
14
+ #
15
+ class Connection < Stream
16
+ attr_reader :host, :port
17
+
18
+ # How many seconds to wait for <stream:features/>
19
+ # before proceeding
20
+ attr_accessor :features_timeout
21
+
22
+ # Keep-alive interval in seconds, defaults to 60
23
+ # (see private method keepalive_loop for implementation details)
24
+ attr_accessor :keepalive_interval
25
+
26
+ # Allow TLS negotiation? Defaults to true
27
+ attr_accessor :allow_tls
28
+
29
+ # Optional CA-Path for TLS-handshake
30
+ attr_accessor :ssl_capath
31
+
32
+ # Optional callback for verification of SSL peer
33
+ attr_accessor :ssl_verifycb
34
+
35
+ #whether to use the old and deprecated SSL protocol
36
+ #Defaults to false
37
+ attr_accessor :use_ssl
38
+
39
+ ##
40
+ # Create a new connection to the given host and port
41
+ def initialize
42
+ super()
43
+ @host = nil
44
+ @port = nil
45
+ @allow_tls = defined? OpenSSL
46
+ @tls = false
47
+ @ssl_capath = nil
48
+ @ssl_verifycb = nil
49
+ @features_timeout = 10
50
+ @keepalive_interval = 60
51
+ @use_ssl = false
52
+ end
53
+
54
+ ##
55
+ # Connect to the Jabber server through a TCP Socket,
56
+ # start the Jabber parser,
57
+ # invoke to accept_features to wait for TLS,
58
+ # start the keep-alive thread
59
+ def connect(host, port)
60
+ @host = host
61
+ @port = port
62
+ # Reset is_tls?, so that it works when reconnecting
63
+ @tls = false
64
+
65
+ Jabber::debuglog("CONNECTING:\n#{@host}:#{@port}")
66
+ @socket = TCPSocket.new(@host, @port)
67
+
68
+ # We want to use the old and deprecated SSL protocol (usually on port 5223)
69
+ if @use_ssl
70
+ ssl = OpenSSL::SSL::SSLSocket.new(@socket)
71
+ ssl.connect # start SSL session
72
+ ssl.sync_close = true
73
+ Jabber::debuglog("SSL connection established.")
74
+ @socket = ssl
75
+ end
76
+
77
+ start
78
+
79
+ accept_features
80
+
81
+ @keepaliveThread = Thread.new do
82
+ Thread.current.abort_on_exception = true
83
+ keepalive_loop
84
+ end
85
+ end
86
+
87
+ ##
88
+ # Closing connection:
89
+ # first kill keepaliveThread (but only if it's not me), then call Stream#close!
90
+ def close!
91
+ @keepaliveThread.kill if @keepaliveThread and @keepaliveThread.alive? and @keepaliveThread != Thread.current
92
+ super
93
+ @keepaliveThread.kill if @keepaliveThread and @keepaliveThread.alive?
94
+ end
95
+
96
+ def accept_features
97
+ begin
98
+ Timeout::timeout(@features_timeout) {
99
+ Jabber::debuglog("FEATURES: waiting...")
100
+ @features_sem.wait
101
+ Jabber::debuglog("FEATURES: waiting finished")
102
+ }
103
+ rescue Timeout::Error
104
+ Jabber::debuglog("FEATURES: timed out when waiting, stream peer seems not XMPP compliant")
105
+ end
106
+
107
+ if @allow_tls and not is_tls? and @stream_features['starttls'] == 'urn:ietf:params:xml:ns:xmpp-tls'
108
+ begin
109
+ starttls
110
+ rescue
111
+ Jabber::debuglog("STARTTLS:\nFailure: #{$!}")
112
+ end
113
+ end
114
+ end
115
+
116
+ ##
117
+ # Start the parser on the previously connected socket
118
+ def start
119
+ super(@socket)
120
+ end
121
+
122
+ ##
123
+ # Do a <starttls/>
124
+ # (will be automatically done by connect if stream peer supports this)
125
+ def starttls
126
+ stls = REXML::Element.new('starttls')
127
+ stls.add_namespace('urn:ietf:params:xml:ns:xmpp-tls')
128
+
129
+ reply = nil
130
+ send(stls) { |r|
131
+ reply = r
132
+ true
133
+ }
134
+ if reply.name != 'proceed'
135
+ raise ServerError.new(reply.first_element('error'))
136
+ end
137
+ # Don't be interrupted
138
+ stop
139
+
140
+ begin
141
+ error = nil
142
+
143
+ # Context/user set-able stuff
144
+ ctx = OpenSSL::SSL::SSLContext.new
145
+ if @ssl_capath
146
+ ctx.verify_mode = OpenSSL::SSL::VERIFY_PEER
147
+ ctx.ca_path = @ssl_capath
148
+ else
149
+ ctx.verify_mode = OpenSSL::SSL::VERIFY_NONE
150
+ end
151
+ ctx.verify_callback = @ssl_verifycb
152
+
153
+ # SSL connection establishing
154
+ sslsocket = OpenSSL::SSL::SSLSocket.new(@socket, ctx)
155
+ sslsocket.sync_close = true
156
+ Jabber::debuglog("TLSv1: OpenSSL handshake in progress")
157
+ sslsocket.connect
158
+
159
+ # Make REXML believe it's a real socket
160
+ class << sslsocket
161
+ def kind_of?(o)
162
+ o == IO ? true : super
163
+ end
164
+ end
165
+
166
+ # We're done and will use it
167
+ @tls = true
168
+ @socket = sslsocket
169
+ rescue
170
+ error = $!
171
+ ensure
172
+ Jabber::debuglog("TLSv1: restarting parser")
173
+ start
174
+ accept_features
175
+ raise error if error
176
+ end
177
+ end
178
+
179
+ ##
180
+ # Have we gone to TLS mode?
181
+ # result:: [true] or [false]
182
+ def is_tls?
183
+ @tls
184
+ end
185
+
186
+ def generate_stream_start(to=nil, from=nil, id=nil, xml_lang="en", xmlns="jabber:client", version="1.0")
187
+ stream_start_string = "<stream:stream xmlns:stream='http://etherx.jabber.org/streams' "
188
+ stream_start_string += "xmlns='#{xmlns}' " unless xmlns.nil?
189
+ stream_start_string += "to='#{to}' " unless to.nil?
190
+ stream_start_string += "from='#{from}' " unless from.nil?
191
+ stream_start_string += "id='#{id}' " unless id.nil?
192
+ stream_start_string += "xml:lang='#{xml_lang}' " unless xml_lang.nil?
193
+ stream_start_string += "version='#{version}' " unless version.nil?
194
+ stream_start_string += ">"
195
+ stream_start_string
196
+ end
197
+ private :generate_stream_start
198
+
199
+ ##
200
+ # A loop to send "keep alive" data to prevent
201
+ # the Jabber connection from closing for inactivity.
202
+ #
203
+ # This loop sends a single white-space character if
204
+ # no other data has been sent in the last @keepalive_interval
205
+ # seconds.
206
+ def keepalive_loop
207
+ loop do
208
+ unless is_connected?
209
+ Thread.current.kill
210
+ end
211
+ difference = @last_send + @keepalive_interval - Time.now
212
+ if difference <= 0
213
+ send(' ')
214
+ sleep @keepalive_interval
215
+ else
216
+ sleep(difference)
217
+ end
218
+ end
219
+ end
220
+ private :keepalive_loop
221
+
222
+ end
223
+ end