annotate src/plugins/plugin_xep_0065.py @ 297:c5554e2939dd

plugin XEP 0277: author for in request + author, updated management for out request - a workaround is now used to parse "nick" tag (Jappix behaviour) - author and updated can now be used in data when sendind microblog. Is no author is given, user jid is used, if no updated is given, current timestamp is used
author Goffi <goffi@goffi.org>
date Fri, 18 Feb 2011 22:32:02 +0100
parents 7c79d4a8c9e6
children 8f3551ceee17
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
goffi@necton2
parents:
diff changeset
1 #!/usr/bin/python
goffi@necton2
parents:
diff changeset
2 #-*- coding: utf-8 -*-
goffi@necton2
parents:
diff changeset
3 """
goffi@necton2
parents:
diff changeset
4 SAT plugin for managing xep-0065
goffi@necton2
parents:
diff changeset
5
goffi@necton2
parents:
diff changeset
6 Copyright (C)
251
dbe1803eca7c minor copyright update, date format harmonisation
Goffi <goffi@goffi.org>
parents: 228
diff changeset
7 2002, 2003, 2004 Dave Smith (dizzyd@jabber.org)
dbe1803eca7c minor copyright update, date format harmonisation
Goffi <goffi@goffi.org>
parents: 228
diff changeset
8 2007, 2008 Fabio Forno (xmpp:ff@jabber.bluendo.com)
dbe1803eca7c minor copyright update, date format harmonisation
Goffi <goffi@goffi.org>
parents: 228
diff changeset
9 2009, 2010, 2011 Jérôme Poisson (goffi@goffi.org)
0
goffi@necton2
parents:
diff changeset
10
goffi@necton2
parents:
diff changeset
11 This program is free software: you can redistribute it and/or modify
goffi@necton2
parents:
diff changeset
12 it under the terms of the GNU General Public License as published by
goffi@necton2
parents:
diff changeset
13 the Free Software Foundation, either version 3 of the License, or
goffi@necton2
parents:
diff changeset
14 (at your option) any later version.
goffi@necton2
parents:
diff changeset
15
goffi@necton2
parents:
diff changeset
16 This program is distributed in the hope that it will be useful,
goffi@necton2
parents:
diff changeset
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
goffi@necton2
parents:
diff changeset
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
goffi@necton2
parents:
diff changeset
19 GNU General Public License for more details.
goffi@necton2
parents:
diff changeset
20
goffi@necton2
parents:
diff changeset
21 You should have received a copy of the GNU General Public License
goffi@necton2
parents:
diff changeset
22 along with this program. If not, see <http://www.gnu.org/licenses/>.
goffi@necton2
parents:
diff changeset
23
goffi@necton2
parents:
diff changeset
24 --
goffi@necton2
parents:
diff changeset
25
goffi@necton2
parents:
diff changeset
26 This program is based on proxy65 (http://code.google.com/p/proxy65),
goffi@necton2
parents:
diff changeset
27 originaly written by David Smith and modified by Fabio Forno.
goffi@necton2
parents:
diff changeset
28 It is sublicensed under GPL v3 (or any later version) as allowed by the original
goffi@necton2
parents:
diff changeset
29 license.
goffi@necton2
parents:
diff changeset
30
goffi@necton2
parents:
diff changeset
31 --
goffi@necton2
parents:
diff changeset
32
goffi@necton2
parents:
diff changeset
33 Here is a copy of the original license:
goffi@necton2
parents:
diff changeset
34
goffi@necton2
parents:
diff changeset
35 Copyright (C)
goffi@necton2
parents:
diff changeset
36 2002-2004 Dave Smith (dizzyd@jabber.org)
goffi@necton2
parents:
diff changeset
37 2007-2008 Fabio Forno (xmpp:ff@jabber.bluendo.com)
goffi@necton2
parents:
diff changeset
38
goffi@necton2
parents:
diff changeset
39 Permission is hereby granted, free of charge, to any person obtaining a copy
goffi@necton2
parents:
diff changeset
40 of this software and associated documentation files (the "Software"), to deal
goffi@necton2
parents:
diff changeset
41 in the Software without restriction, including without limitation the rights
goffi@necton2
parents:
diff changeset
42 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
goffi@necton2
parents:
diff changeset
43 copies of the Software, and to permit persons to whom the Software is
goffi@necton2
parents:
diff changeset
44 furnished to do so, subject to the following conditions:
goffi@necton2
parents:
diff changeset
45
goffi@necton2
parents:
diff changeset
46 The above copyright notice and this permission notice shall be included in
goffi@necton2
parents:
diff changeset
47 all copies or substantial portions of the Software.
goffi@necton2
parents:
diff changeset
48
goffi@necton2
parents:
diff changeset
49 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
goffi@necton2
parents:
diff changeset
50 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
goffi@necton2
parents:
diff changeset
51 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
goffi@necton2
parents:
diff changeset
52 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
goffi@necton2
parents:
diff changeset
53 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
goffi@necton2
parents:
diff changeset
54 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
goffi@necton2
parents:
diff changeset
55 THE SOFTWARE.
goffi@necton2
parents:
diff changeset
56 """
goffi@necton2
parents:
diff changeset
57
goffi@necton2
parents:
diff changeset
58 from logging import debug, info, error
goffi@necton2
parents:
diff changeset
59 from twisted.internet import protocol, reactor
goffi@necton2
parents:
diff changeset
60 from twisted.protocols.basic import FileSender
goffi@necton2
parents:
diff changeset
61 from twisted.words.xish import domish
20
fc8c202cda87 refactoring: using xml params part IV (default values)
Goffi <goffi@goffi.org>
parents: 19
diff changeset
62 from twisted.web.client import getPage
0
goffi@necton2
parents:
diff changeset
63 import struct
20
fc8c202cda87 refactoring: using xml params part IV (default values)
Goffi <goffi@goffi.org>
parents: 19
diff changeset
64 import urllib
0
goffi@necton2
parents:
diff changeset
65 import hashlib, pdb
goffi@necton2
parents:
diff changeset
66
15
218ec9984fa5 wokkel integration part III + memory saved again
Goffi <goffi@goffi.org>
parents: 9
diff changeset
67 from zope.interface import implements
218ec9984fa5 wokkel integration part III + memory saved again
Goffi <goffi@goffi.org>
parents: 9
diff changeset
68
218ec9984fa5 wokkel integration part III + memory saved again
Goffi <goffi@goffi.org>
parents: 9
diff changeset
69 try:
218ec9984fa5 wokkel integration part III + memory saved again
Goffi <goffi@goffi.org>
parents: 9
diff changeset
70 from twisted.words.protocols.xmlstream import XMPPHandler
218ec9984fa5 wokkel integration part III + memory saved again
Goffi <goffi@goffi.org>
parents: 9
diff changeset
71 except ImportError:
218ec9984fa5 wokkel integration part III + memory saved again
Goffi <goffi@goffi.org>
parents: 9
diff changeset
72 from wokkel.subprotocols import XMPPHandler
218ec9984fa5 wokkel integration part III + memory saved again
Goffi <goffi@goffi.org>
parents: 9
diff changeset
73
218ec9984fa5 wokkel integration part III + memory saved again
Goffi <goffi@goffi.org>
parents: 9
diff changeset
74 from wokkel import disco, iwokkel
218ec9984fa5 wokkel integration part III + memory saved again
Goffi <goffi@goffi.org>
parents: 9
diff changeset
75
218ec9984fa5 wokkel integration part III + memory saved again
Goffi <goffi@goffi.org>
parents: 9
diff changeset
76 IQ_SET = '/iq[@type="set"]'
218ec9984fa5 wokkel integration part III + memory saved again
Goffi <goffi@goffi.org>
parents: 9
diff changeset
77 NS_BS = 'http://jabber.org/protocol/bytestreams'
218ec9984fa5 wokkel integration part III + memory saved again
Goffi <goffi@goffi.org>
parents: 9
diff changeset
78 BS_REQUEST = IQ_SET + '/query[@xmlns="' + NS_BS + '"]'
218ec9984fa5 wokkel integration part III + memory saved again
Goffi <goffi@goffi.org>
parents: 9
diff changeset
79
218ec9984fa5 wokkel integration part III + memory saved again
Goffi <goffi@goffi.org>
parents: 9
diff changeset
80
0
goffi@necton2
parents:
diff changeset
81
goffi@necton2
parents:
diff changeset
82 PLUGIN_INFO = {
goffi@necton2
parents:
diff changeset
83 "name": "XEP 0065 Plugin",
291
7c79d4a8c9e6 plugins: fixed bad import names
Goffi <goffi@goffi.org>
parents: 251
diff changeset
84 "import_name": "XEP-0065",
0
goffi@necton2
parents:
diff changeset
85 "type": "XEP",
48
4392f1fdb064 plugins improvement
Goffi <goffi@goffi.org>
parents: 38
diff changeset
86 "protocols": ["XEP-0065"],
0
goffi@necton2
parents:
diff changeset
87 "main": "XEP_0065",
64
d46f849664aa SàT: multi-profile, plugins updated
Goffi <goffi@goffi.org>
parents: 60
diff changeset
88 "handler": "yes",
69
86f1f7f6d332 i18n first draft
Goffi <goffi@goffi.org>
parents: 64
diff changeset
89 "description": _("""Implementation of SOCKS5 Bytestreams""")
0
goffi@necton2
parents:
diff changeset
90 }
goffi@necton2
parents:
diff changeset
91
goffi@necton2
parents:
diff changeset
92 STATE_INITIAL = 0
goffi@necton2
parents:
diff changeset
93 STATE_AUTH = 1
goffi@necton2
parents:
diff changeset
94 STATE_REQUEST = 2
goffi@necton2
parents:
diff changeset
95 STATE_READY = 3
goffi@necton2
parents:
diff changeset
96 STATE_AUTH_USERPASS = 4
goffi@necton2
parents:
diff changeset
97 STATE_TARGET_INITIAL = 5
goffi@necton2
parents:
diff changeset
98 STATE_TARGET_AUTH = 6
goffi@necton2
parents:
diff changeset
99 STATE_TARGET_REQUEST = 7
goffi@necton2
parents:
diff changeset
100 STATE_TARGET_READY = 8
goffi@necton2
parents:
diff changeset
101 STATE_LAST = 9
goffi@necton2
parents:
diff changeset
102
goffi@necton2
parents:
diff changeset
103 STATE_CONNECT_PENDING = STATE_LAST + 1
goffi@necton2
parents:
diff changeset
104
goffi@necton2
parents:
diff changeset
105 SOCKS5_VER = 0x05
goffi@necton2
parents:
diff changeset
106
goffi@necton2
parents:
diff changeset
107 ADDR_IPV4 = 0x01
goffi@necton2
parents:
diff changeset
108 ADDR_DOMAINNAME = 0x03
goffi@necton2
parents:
diff changeset
109 ADDR_IPV6 = 0x04
goffi@necton2
parents:
diff changeset
110
goffi@necton2
parents:
diff changeset
111 CMD_CONNECT = 0x01
goffi@necton2
parents:
diff changeset
112 CMD_BIND = 0x02
goffi@necton2
parents:
diff changeset
113 CMD_UDPASSOC = 0x03
goffi@necton2
parents:
diff changeset
114
goffi@necton2
parents:
diff changeset
115 AUTHMECH_ANON = 0x00
goffi@necton2
parents:
diff changeset
116 AUTHMECH_USERPASS = 0x02
goffi@necton2
parents:
diff changeset
117 AUTHMECH_INVALID = 0xFF
goffi@necton2
parents:
diff changeset
118
goffi@necton2
parents:
diff changeset
119 REPLY_SUCCESS = 0x00
goffi@necton2
parents:
diff changeset
120 REPLY_GENERAL_FAILUR = 0x01
goffi@necton2
parents:
diff changeset
121 REPLY_CONN_NOT_ALLOWED = 0x02
goffi@necton2
parents:
diff changeset
122 REPLY_NETWORK_UNREACHABLE = 0x03
goffi@necton2
parents:
diff changeset
123 REPLY_HOST_UNREACHABLE = 0x04
goffi@necton2
parents:
diff changeset
124 REPLY_CONN_REFUSED = 0x05
goffi@necton2
parents:
diff changeset
125 REPLY_TTL_EXPIRED = 0x06
goffi@necton2
parents:
diff changeset
126 REPLY_CMD_NOT_SUPPORTED = 0x07
goffi@necton2
parents:
diff changeset
127 REPLY_ADDR_NOT_SUPPORTED = 0x08
goffi@necton2
parents:
diff changeset
128
goffi@necton2
parents:
diff changeset
129
goffi@necton2
parents:
diff changeset
130
goffi@necton2
parents:
diff changeset
131
goffi@necton2
parents:
diff changeset
132
goffi@necton2
parents:
diff changeset
133 class SOCKSv5(protocol.Protocol, FileSender):
goffi@necton2
parents:
diff changeset
134 def __init__(self):
69
86f1f7f6d332 i18n first draft
Goffi <goffi@goffi.org>
parents: 64
diff changeset
135 debug(_("Protocol init"))
0
goffi@necton2
parents:
diff changeset
136 self.state = STATE_INITIAL
goffi@necton2
parents:
diff changeset
137 self.buf = ""
goffi@necton2
parents:
diff changeset
138 self.supportedAuthMechs = [ AUTHMECH_ANON ]
goffi@necton2
parents:
diff changeset
139 self.supportedAddrs = [ ADDR_DOMAINNAME ]
goffi@necton2
parents:
diff changeset
140 self.enabledCommands = [ CMD_CONNECT ]
goffi@necton2
parents:
diff changeset
141 self.peersock = None
goffi@necton2
parents:
diff changeset
142 self.addressType = 0
goffi@necton2
parents:
diff changeset
143 self.requestType = 0
goffi@necton2
parents:
diff changeset
144 self.activeConns = {}
goffi@necton2
parents:
diff changeset
145 self.pendingConns = {}
goffi@necton2
parents:
diff changeset
146 self.transfered = 0 #nb of bytes already copied
goffi@necton2
parents:
diff changeset
147
goffi@necton2
parents:
diff changeset
148 def _startNegotiation(self):
goffi@necton2
parents:
diff changeset
149 debug("_startNegotiation")
goffi@necton2
parents:
diff changeset
150 self.state = STATE_TARGET_AUTH
goffi@necton2
parents:
diff changeset
151 self.transport.write(struct.pack('!3B', SOCKS5_VER, 1, AUTHMECH_ANON))
goffi@necton2
parents:
diff changeset
152
goffi@necton2
parents:
diff changeset
153 def _parseNegotiation(self):
goffi@necton2
parents:
diff changeset
154 debug("_parseNegotiation")
goffi@necton2
parents:
diff changeset
155 try:
goffi@necton2
parents:
diff changeset
156 # Parse out data
goffi@necton2
parents:
diff changeset
157 ver, nmethod = struct.unpack('!BB', self.buf[:2])
goffi@necton2
parents:
diff changeset
158 methods = struct.unpack('%dB' % nmethod, self.buf[2:nmethod+2])
goffi@necton2
parents:
diff changeset
159
goffi@necton2
parents:
diff changeset
160 # Ensure version is correct
goffi@necton2
parents:
diff changeset
161 if ver != 5:
goffi@necton2
parents:
diff changeset
162 self.transport.write(struct.pack('!BB', SOCKS5_VER, AUTHMECH_INVALID))
goffi@necton2
parents:
diff changeset
163 self.transport.loseConnection()
goffi@necton2
parents:
diff changeset
164 return
goffi@necton2
parents:
diff changeset
165
goffi@necton2
parents:
diff changeset
166 # Trim off front of the buffer
goffi@necton2
parents:
diff changeset
167 self.buf = self.buf[nmethod+2:]
goffi@necton2
parents:
diff changeset
168
goffi@necton2
parents:
diff changeset
169 # Check for supported auth mechs
goffi@necton2
parents:
diff changeset
170 for m in self.supportedAuthMechs:
goffi@necton2
parents:
diff changeset
171 if m in methods:
goffi@necton2
parents:
diff changeset
172 # Update internal state, according to selected method
goffi@necton2
parents:
diff changeset
173 if m == AUTHMECH_ANON:
goffi@necton2
parents:
diff changeset
174 self.state = STATE_REQUEST
goffi@necton2
parents:
diff changeset
175 elif m == AUTHMECH_USERPASS:
goffi@necton2
parents:
diff changeset
176 self.state = STATE_AUTH_USERPASS
goffi@necton2
parents:
diff changeset
177 # Complete negotiation w/ this method
goffi@necton2
parents:
diff changeset
178 self.transport.write(struct.pack('!BB', SOCKS5_VER, m))
goffi@necton2
parents:
diff changeset
179 return
goffi@necton2
parents:
diff changeset
180
goffi@necton2
parents:
diff changeset
181 # No supported mechs found, notify client and close the connection
goffi@necton2
parents:
diff changeset
182 self.transport.write(struct.pack('!BB', SOCKS5_VER, AUTHMECH_INVALID))
goffi@necton2
parents:
diff changeset
183 self.transport.loseConnection()
goffi@necton2
parents:
diff changeset
184 except struct.error:
goffi@necton2
parents:
diff changeset
185 pass
goffi@necton2
parents:
diff changeset
186
goffi@necton2
parents:
diff changeset
187 def _parseUserPass(self):
goffi@necton2
parents:
diff changeset
188 debug("_parseUserPass")
goffi@necton2
parents:
diff changeset
189 try:
goffi@necton2
parents:
diff changeset
190 # Parse out data
goffi@necton2
parents:
diff changeset
191 ver, ulen = struct.unpack('BB', self.buf[:2])
goffi@necton2
parents:
diff changeset
192 uname, = struct.unpack('%ds' % ulen, self.buf[2:ulen + 2])
goffi@necton2
parents:
diff changeset
193 plen, = struct.unpack('B', self.buf[ulen + 2])
goffi@necton2
parents:
diff changeset
194 password, = struct.unpack('%ds' % plen, self.buf[ulen + 3:ulen + 3 + plen])
goffi@necton2
parents:
diff changeset
195 # Trim off fron of the buffer
goffi@necton2
parents:
diff changeset
196 self.buf = self.buf[3 + ulen + plen:]
goffi@necton2
parents:
diff changeset
197 # Fire event to authenticate user
goffi@necton2
parents:
diff changeset
198 if self.authenticateUserPass(uname, password):
goffi@necton2
parents:
diff changeset
199 # Signal success
goffi@necton2
parents:
diff changeset
200 self.state = STATE_REQUEST
goffi@necton2
parents:
diff changeset
201 self.transport.write(struct.pack('!BB', SOCKS5_VER, 0x00))
goffi@necton2
parents:
diff changeset
202 else:
goffi@necton2
parents:
diff changeset
203 # Signal failure
goffi@necton2
parents:
diff changeset
204 self.transport.write(struct.pack('!BB', SOCKS5_VER, 0x01))
goffi@necton2
parents:
diff changeset
205 self.transport.loseConnection()
goffi@necton2
parents:
diff changeset
206 except struct.error:
goffi@necton2
parents:
diff changeset
207 pass
goffi@necton2
parents:
diff changeset
208
goffi@necton2
parents:
diff changeset
209 def sendErrorReply(self, errorcode):
goffi@necton2
parents:
diff changeset
210 debug("sendErrorReply")
goffi@necton2
parents:
diff changeset
211 # Any other address types are not supported
goffi@necton2
parents:
diff changeset
212 result = struct.pack('!BBBBIH', SOCKS5_VER, errorcode, 0, 1, 0, 0)
goffi@necton2
parents:
diff changeset
213 self.transport.write(result)
goffi@necton2
parents:
diff changeset
214 self.transport.loseConnection()
goffi@necton2
parents:
diff changeset
215
goffi@necton2
parents:
diff changeset
216 def addConnection(self, address, connection):
69
86f1f7f6d332 i18n first draft
Goffi <goffi@goffi.org>
parents: 64
diff changeset
217 info(_("Adding connection: %(address)s, %(connection)s") % {'address':address, 'connection':connection})
0
goffi@necton2
parents:
diff changeset
218 olist = self.pendingConns.get(address, [])
goffi@necton2
parents:
diff changeset
219 if len(olist) <= 1:
goffi@necton2
parents:
diff changeset
220 olist.append(connection)
goffi@necton2
parents:
diff changeset
221 self.pendingConns[address] = olist
goffi@necton2
parents:
diff changeset
222 return True
goffi@necton2
parents:
diff changeset
223 else:
goffi@necton2
parents:
diff changeset
224 return False
goffi@necton2
parents:
diff changeset
225
goffi@necton2
parents:
diff changeset
226 def removePendingConnection(self, address, connection):
goffi@necton2
parents:
diff changeset
227 olist = self.pendingConns[address]
goffi@necton2
parents:
diff changeset
228 if len(olist) == 1:
goffi@necton2
parents:
diff changeset
229 del self.pendingConns[address]
goffi@necton2
parents:
diff changeset
230 else:
goffi@necton2
parents:
diff changeset
231 olist.remove(connection)
goffi@necton2
parents:
diff changeset
232 self.pendingConns[address] = olist
goffi@necton2
parents:
diff changeset
233
goffi@necton2
parents:
diff changeset
234 def removeActiveConnection(self, address):
goffi@necton2
parents:
diff changeset
235 del self.activeConns[address]
goffi@necton2
parents:
diff changeset
236
goffi@necton2
parents:
diff changeset
237 def _parseRequest(self):
goffi@necton2
parents:
diff changeset
238 debug("_parseRequest")
goffi@necton2
parents:
diff changeset
239 try:
goffi@necton2
parents:
diff changeset
240 # Parse out data and trim buffer accordingly
goffi@necton2
parents:
diff changeset
241 ver, cmd, rsvd, self.addressType = struct.unpack('!BBBB', self.buf[:4])
goffi@necton2
parents:
diff changeset
242
goffi@necton2
parents:
diff changeset
243 # Ensure we actually support the requested address type
goffi@necton2
parents:
diff changeset
244 if self.addressType not in self.supportedAddrs:
goffi@necton2
parents:
diff changeset
245 self.sendErrorReply(REPLY_ADDR_NOT_SUPPORTED)
goffi@necton2
parents:
diff changeset
246 return
goffi@necton2
parents:
diff changeset
247
goffi@necton2
parents:
diff changeset
248 # Deal with addresses
goffi@necton2
parents:
diff changeset
249 if self.addressType == ADDR_IPV4:
goffi@necton2
parents:
diff changeset
250 addr, port = struct.unpack('!IH', self.buf[4:10])
goffi@necton2
parents:
diff changeset
251 self.buf = self.buf[10:]
goffi@necton2
parents:
diff changeset
252 elif self.addressType == ADDR_DOMAINNAME:
goffi@necton2
parents:
diff changeset
253 nlen = ord(self.buf[4])
goffi@necton2
parents:
diff changeset
254 addr, port = struct.unpack('!%dsH' % nlen, self.buf[5:])
goffi@necton2
parents:
diff changeset
255 self.buf = self.buf[7 + len(addr):]
goffi@necton2
parents:
diff changeset
256 else:
goffi@necton2
parents:
diff changeset
257 # Any other address types are not supported
goffi@necton2
parents:
diff changeset
258 self.sendErrorReply(REPLY_ADDR_NOT_SUPPORTED)
goffi@necton2
parents:
diff changeset
259 return
goffi@necton2
parents:
diff changeset
260
goffi@necton2
parents:
diff changeset
261 # Ensure command is supported
goffi@necton2
parents:
diff changeset
262 if cmd not in self.enabledCommands:
goffi@necton2
parents:
diff changeset
263 # Send a not supported error
goffi@necton2
parents:
diff changeset
264 self.sendErrorReply(REPLY_CMD_NOT_SUPPORTED)
goffi@necton2
parents:
diff changeset
265 return
goffi@necton2
parents:
diff changeset
266
goffi@necton2
parents:
diff changeset
267 # Process the command
goffi@necton2
parents:
diff changeset
268 if cmd == CMD_CONNECT:
goffi@necton2
parents:
diff changeset
269 self.connectRequested(addr, port)
goffi@necton2
parents:
diff changeset
270 elif cmd == CMD_BIND:
goffi@necton2
parents:
diff changeset
271 self.bindRequested(addr, port)
goffi@necton2
parents:
diff changeset
272 else:
goffi@necton2
parents:
diff changeset
273 # Any other command is not supported
goffi@necton2
parents:
diff changeset
274 self.sendErrorReply(REPLY_CMD_NOT_SUPPORTED)
goffi@necton2
parents:
diff changeset
275
goffi@necton2
parents:
diff changeset
276 except struct.error, why:
goffi@necton2
parents:
diff changeset
277 return None
goffi@necton2
parents:
diff changeset
278
goffi@necton2
parents:
diff changeset
279 def _makeRequest(self):
goffi@necton2
parents:
diff changeset
280 debug("_makeRequest")
goffi@necton2
parents:
diff changeset
281 self.state = STATE_TARGET_REQUEST
goffi@necton2
parents:
diff changeset
282 sha1 = hashlib.sha1(self.sid + self.initiator_jid + self.target_jid).hexdigest()
goffi@necton2
parents:
diff changeset
283 request = struct.pack('!5B%dsH' % len(sha1), SOCKS5_VER, CMD_CONNECT, 0, ADDR_DOMAINNAME, len(sha1), sha1, 0)
goffi@necton2
parents:
diff changeset
284 self.transport.write(request)
goffi@necton2
parents:
diff changeset
285
goffi@necton2
parents:
diff changeset
286 def _parseRequestReply(self):
goffi@necton2
parents:
diff changeset
287 debug("_parseRequestReply")
goffi@necton2
parents:
diff changeset
288 try:
goffi@necton2
parents:
diff changeset
289 ver, rep, rsvd, self.addressType = struct.unpack('!BBBB', self.buf[:4])
goffi@necton2
parents:
diff changeset
290 # Ensure we actually support the requested address type
goffi@necton2
parents:
diff changeset
291 if self.addressType not in self.supportedAddrs:
goffi@necton2
parents:
diff changeset
292 self.sendErrorReply(REPLY_ADDR_NOT_SUPPORTED)
goffi@necton2
parents:
diff changeset
293 return
goffi@necton2
parents:
diff changeset
294
goffi@necton2
parents:
diff changeset
295 # Deal with addresses
goffi@necton2
parents:
diff changeset
296 if self.addressType == ADDR_IPV4:
goffi@necton2
parents:
diff changeset
297 addr, port = struct.unpack('!IH', self.buf[4:10])
goffi@necton2
parents:
diff changeset
298 self.buf = self.buf[10:]
goffi@necton2
parents:
diff changeset
299 elif self.addressType == ADDR_DOMAINNAME:
goffi@necton2
parents:
diff changeset
300 nlen = ord(self.buf[4])
goffi@necton2
parents:
diff changeset
301 addr, port = struct.unpack('!%dsH' % nlen, self.buf[5:])
goffi@necton2
parents:
diff changeset
302 self.buf = self.buf[7 + len(addr):]
goffi@necton2
parents:
diff changeset
303 else:
goffi@necton2
parents:
diff changeset
304 # Any other address types are not supported
goffi@necton2
parents:
diff changeset
305 self.sendErrorReply(REPLY_ADDR_NOT_SUPPORTED)
goffi@necton2
parents:
diff changeset
306 return
goffi@necton2
parents:
diff changeset
307
goffi@necton2
parents:
diff changeset
308 # Ensure reply is OK
goffi@necton2
parents:
diff changeset
309 if rep != REPLY_SUCCESS:
goffi@necton2
parents:
diff changeset
310 self.loseConnection()
goffi@necton2
parents:
diff changeset
311 return
goffi@necton2
parents:
diff changeset
312
69
86f1f7f6d332 i18n first draft
Goffi <goffi@goffi.org>
parents: 64
diff changeset
313 debug(_("Saving file in %s."), self.data["dest_path"])
0
goffi@necton2
parents:
diff changeset
314 self.dest_file = open(self.data["dest_path"], 'w')
goffi@necton2
parents:
diff changeset
315 self.state = STATE_TARGET_READY
64
d46f849664aa SàT: multi-profile, plugins updated
Goffi <goffi@goffi.org>
parents: 60
diff changeset
316 self.activateCB(self.target_jid, self.initiator_jid, self.sid, self.IQ_id, self.xmlstream)
0
goffi@necton2
parents:
diff changeset
317
goffi@necton2
parents:
diff changeset
318
goffi@necton2
parents:
diff changeset
319 except struct.error, why:
goffi@necton2
parents:
diff changeset
320 return None
goffi@necton2
parents:
diff changeset
321
goffi@necton2
parents:
diff changeset
322 def connectionMade(self):
goffi@necton2
parents:
diff changeset
323 debug("connectionMade (mode = %s)" % self.mode)
goffi@necton2
parents:
diff changeset
324 self.host.registerProgressCB(self.transfert_id, self.getProgress)
goffi@necton2
parents:
diff changeset
325
goffi@necton2
parents:
diff changeset
326 if self.mode == "target":
goffi@necton2
parents:
diff changeset
327 self.state = STATE_TARGET_INITIAL
goffi@necton2
parents:
diff changeset
328 self._startNegotiation()
goffi@necton2
parents:
diff changeset
329
goffi@necton2
parents:
diff changeset
330 def connectRequested(self, addr, port):
69
86f1f7f6d332 i18n first draft
Goffi <goffi@goffi.org>
parents: 64
diff changeset
331 debug("connectRequested")
0
goffi@necton2
parents:
diff changeset
332 # Check for special connect to the namespace -- this signifies that the client
goffi@necton2
parents:
diff changeset
333 # is just checking to ensure it can connect to the streamhost
goffi@necton2
parents:
diff changeset
334 if addr == "http://jabber.org/protocol/bytestreams":
goffi@necton2
parents:
diff changeset
335 self.connectCompleted(addr, 0)
goffi@necton2
parents:
diff changeset
336 self.transport.loseConnection()
goffi@necton2
parents:
diff changeset
337 return
goffi@necton2
parents:
diff changeset
338
goffi@necton2
parents:
diff changeset
339 # Save addr, for cleanup
goffi@necton2
parents:
diff changeset
340 self.addr = addr
goffi@necton2
parents:
diff changeset
341
goffi@necton2
parents:
diff changeset
342 # Check to see if the requested address is already
goffi@necton2
parents:
diff changeset
343 # activated -- send an error if so
goffi@necton2
parents:
diff changeset
344 if addr in self.activeConns:
goffi@necton2
parents:
diff changeset
345 self.sendErrorReply(socks5.REPLY_CONN_NOT_ALLOWED)
goffi@necton2
parents:
diff changeset
346 return
goffi@necton2
parents:
diff changeset
347
goffi@necton2
parents:
diff changeset
348 # Add this address to the pending connections
goffi@necton2
parents:
diff changeset
349 if self.addConnection(addr, self):
goffi@necton2
parents:
diff changeset
350 self.connectCompleted(addr, 0)
goffi@necton2
parents:
diff changeset
351 self.transport.stopReading()
goffi@necton2
parents:
diff changeset
352 else:
goffi@necton2
parents:
diff changeset
353 self.sendErrorReply(socks5.REPLY_CONN_REFUSED)
goffi@necton2
parents:
diff changeset
354
goffi@necton2
parents:
diff changeset
355 def getProgress(self, data):
goffi@necton2
parents:
diff changeset
356 """Fill data with position of current transfert"""
goffi@necton2
parents:
diff changeset
357 try:
goffi@necton2
parents:
diff changeset
358 data["position"] = str(self.dest_file.tell())
178
bd24f2aed80c Plugin XEP-0065: dest_file is now propertly closed after copy, and data dict in getProgress is not filled in case of file access error (file closed)
Goffi <goffi@goffi.org>
parents: 127
diff changeset
359 data["size"] = self.filesize
0
goffi@necton2
parents:
diff changeset
360 except (ValueError, AttributeError):
178
bd24f2aed80c Plugin XEP-0065: dest_file is now propertly closed after copy, and data dict in getProgress is not filled in case of file access error (file closed)
Goffi <goffi@goffi.org>
parents: 127
diff changeset
361 pass
0
goffi@necton2
parents:
diff changeset
362
goffi@necton2
parents:
diff changeset
363 def fileTransfered(self, d):
69
86f1f7f6d332 i18n first draft
Goffi <goffi@goffi.org>
parents: 64
diff changeset
364 info(_("File transfer completed, closing connection"))
0
goffi@necton2
parents:
diff changeset
365 self.transport.loseConnection()
178
bd24f2aed80c Plugin XEP-0065: dest_file is now propertly closed after copy, and data dict in getProgress is not filled in case of file access error (file closed)
Goffi <goffi@goffi.org>
parents: 127
diff changeset
366 try:
bd24f2aed80c Plugin XEP-0065: dest_file is now propertly closed after copy, and data dict in getProgress is not filled in case of file access error (file closed)
Goffi <goffi@goffi.org>
parents: 127
diff changeset
367 self.dest_file.close()
bd24f2aed80c Plugin XEP-0065: dest_file is now propertly closed after copy, and data dict in getProgress is not filled in case of file access error (file closed)
Goffi <goffi@goffi.org>
parents: 127
diff changeset
368 except:
bd24f2aed80c Plugin XEP-0065: dest_file is now propertly closed after copy, and data dict in getProgress is not filled in case of file access error (file closed)
Goffi <goffi@goffi.org>
parents: 127
diff changeset
369 pass
0
goffi@necton2
parents:
diff changeset
370
goffi@necton2
parents:
diff changeset
371 def updateTransfered(self, data):
goffi@necton2
parents:
diff changeset
372 self.transfered+=len(data)
goffi@necton2
parents:
diff changeset
373 return data
goffi@necton2
parents:
diff changeset
374
goffi@necton2
parents:
diff changeset
375 def connectCompleted(self, remotehost, remoteport):
goffi@necton2
parents:
diff changeset
376 debug("connectCompleted")
goffi@necton2
parents:
diff changeset
377 if self.addressType == ADDR_IPV4:
goffi@necton2
parents:
diff changeset
378 result = struct.pack('!BBBBIH', SOCKS5_VER, REPLY_SUCCESS, 0, 1, remotehost, remoteport)
goffi@necton2
parents:
diff changeset
379 elif self.addressType == ADDR_DOMAINNAME:
goffi@necton2
parents:
diff changeset
380 result = struct.pack('!BBBBB%dsH' % len(remotehost), SOCKS5_VER, REPLY_SUCCESS, 0,
goffi@necton2
parents:
diff changeset
381 ADDR_DOMAINNAME, len(remotehost), remotehost, remoteport)
goffi@necton2
parents:
diff changeset
382 self.transport.write(result)
goffi@necton2
parents:
diff changeset
383 self.state = STATE_READY
goffi@necton2
parents:
diff changeset
384 self.dest_file=open(self.filepath)
goffi@necton2
parents:
diff changeset
385 d=self.beginFileTransfer(self.dest_file, self.transport, self.updateTransfered)
goffi@necton2
parents:
diff changeset
386 d.addCallback(self.fileTransfered)
goffi@necton2
parents:
diff changeset
387
goffi@necton2
parents:
diff changeset
388 def bindRequested(self, addr, port):
goffi@necton2
parents:
diff changeset
389 pass
goffi@necton2
parents:
diff changeset
390
goffi@necton2
parents:
diff changeset
391 def authenticateUserPass(self, user, passwd):
goffi@necton2
parents:
diff changeset
392 debug("User/pass: %s/%s", user, passwd)
goffi@necton2
parents:
diff changeset
393 return True
goffi@necton2
parents:
diff changeset
394
goffi@necton2
parents:
diff changeset
395 def dataReceived(self, buf):
goffi@necton2
parents:
diff changeset
396 if self.state == STATE_TARGET_READY:
goffi@necton2
parents:
diff changeset
397 self.dest_file.write(buf)
goffi@necton2
parents:
diff changeset
398 self.transfered+=len(buf)
goffi@necton2
parents:
diff changeset
399 return
goffi@necton2
parents:
diff changeset
400
goffi@necton2
parents:
diff changeset
401 self.buf = self.buf + buf
goffi@necton2
parents:
diff changeset
402 if self.state == STATE_INITIAL:
goffi@necton2
parents:
diff changeset
403 self._parseNegotiation()
goffi@necton2
parents:
diff changeset
404 if self.state == STATE_AUTH_USERPASS:
goffi@necton2
parents:
diff changeset
405 self._parseUserPass()
goffi@necton2
parents:
diff changeset
406 if self.state == STATE_REQUEST:
goffi@necton2
parents:
diff changeset
407 self._parseRequest()
goffi@necton2
parents:
diff changeset
408 if self.state == STATE_TARGET_AUTH:
goffi@necton2
parents:
diff changeset
409 ver, method = struct.unpack('!BB', buf)
goffi@necton2
parents:
diff changeset
410 self.buf = self.buf[2:]
goffi@necton2
parents:
diff changeset
411 if ver!=SOCKS5_VER or method!=AUTHMECH_ANON:
goffi@necton2
parents:
diff changeset
412 self.transport.loseConnection()
goffi@necton2
parents:
diff changeset
413 else:
goffi@necton2
parents:
diff changeset
414 self._makeRequest()
goffi@necton2
parents:
diff changeset
415 if self.state == STATE_TARGET_REQUEST:
goffi@necton2
parents:
diff changeset
416 self._parseRequestReply()
goffi@necton2
parents:
diff changeset
417
goffi@necton2
parents:
diff changeset
418
goffi@necton2
parents:
diff changeset
419 def clientConnectionLost(self, reason):
goffi@necton2
parents:
diff changeset
420 debug("clientConnectionLost")
goffi@necton2
parents:
diff changeset
421 self.transport.loseConnection()
goffi@necton2
parents:
diff changeset
422
goffi@necton2
parents:
diff changeset
423 def connectionLost(self, reason):
goffi@necton2
parents:
diff changeset
424 debug("connectionLost")
goffi@necton2
parents:
diff changeset
425 self.host.removeProgressCB(self.transfert_id)
goffi@necton2
parents:
diff changeset
426 if self.state == STATE_CONNECT_PENDING:
goffi@necton2
parents:
diff changeset
427 self.removePendingConnection(self.addr, self)
goffi@necton2
parents:
diff changeset
428 else:
goffi@necton2
parents:
diff changeset
429 self.transport.unregisterProducer()
goffi@necton2
parents:
diff changeset
430 if self.peersock != None:
goffi@necton2
parents:
diff changeset
431 self.peersock.peersock = None
goffi@necton2
parents:
diff changeset
432 self.peersock.transport.unregisterProducer()
goffi@necton2
parents:
diff changeset
433 self.peersock = None
goffi@necton2
parents:
diff changeset
434 self.removeActiveConnection(self.addr)
goffi@necton2
parents:
diff changeset
435
goffi@necton2
parents:
diff changeset
436 class Socks5ServerFactory(protocol.ServerFactory):
goffi@necton2
parents:
diff changeset
437 protocol = SOCKSv5
goffi@necton2
parents:
diff changeset
438 protocol.mode = "initiator" #FIXME: Q&D way, fix it
goffi@necton2
parents:
diff changeset
439
goffi@necton2
parents:
diff changeset
440
goffi@necton2
parents:
diff changeset
441 def startedConnecting(self, connector):
69
86f1f7f6d332 i18n first draft
Goffi <goffi@goffi.org>
parents: 64
diff changeset
442 debug (_("Socks 5 server connection started"))
0
goffi@necton2
parents:
diff changeset
443
goffi@necton2
parents:
diff changeset
444 def clientConnectionLost(self, connector, reason):
69
86f1f7f6d332 i18n first draft
Goffi <goffi@goffi.org>
parents: 64
diff changeset
445 debug (_("Socks 5 server connection lost (reason: %s)"), reason)
0
goffi@necton2
parents:
diff changeset
446
goffi@necton2
parents:
diff changeset
447 class Socks5ClientFactory(protocol.ClientFactory):
goffi@necton2
parents:
diff changeset
448 protocol = SOCKSv5
goffi@necton2
parents:
diff changeset
449 protocol.mode = "target" #FIXME: Q&D way, fix it
goffi@necton2
parents:
diff changeset
450
goffi@necton2
parents:
diff changeset
451 def startedConnecting(self, connector):
69
86f1f7f6d332 i18n first draft
Goffi <goffi@goffi.org>
parents: 64
diff changeset
452 debug (_("Socks 5 client connection started"))
0
goffi@necton2
parents:
diff changeset
453
goffi@necton2
parents:
diff changeset
454 def clientConnectionLost(self, connector, reason):
69
86f1f7f6d332 i18n first draft
Goffi <goffi@goffi.org>
parents: 64
diff changeset
455 debug (_("Socks 5 client connection lost (reason: %s)"), reason)
0
goffi@necton2
parents:
diff changeset
456
goffi@necton2
parents:
diff changeset
457
64
d46f849664aa SàT: multi-profile, plugins updated
Goffi <goffi@goffi.org>
parents: 60
diff changeset
458 class XEP_0065():
15
218ec9984fa5 wokkel integration part III + memory saved again
Goffi <goffi@goffi.org>
parents: 9
diff changeset
459
19
f2a745ca0fbc refactoring: using xml params part III (parameters import)
Goffi <goffi@goffi.org>
parents: 15
diff changeset
460 params = """
f2a745ca0fbc refactoring: using xml params part III (parameters import)
Goffi <goffi@goffi.org>
parents: 15
diff changeset
461 <params>
60
9764e027ecc0 SàT: multi-profile parameters, first draft
Goffi <goffi@goffi.org>
parents: 57
diff changeset
462 <general>
19
f2a745ca0fbc refactoring: using xml params part III (parameters import)
Goffi <goffi@goffi.org>
parents: 15
diff changeset
463 <category name="File Transfert">
20
fc8c202cda87 refactoring: using xml params part IV (default values)
Goffi <goffi@goffi.org>
parents: 19
diff changeset
464 <param name="IP" value='0.0.0.0' default_cb='yes' type="string" />
19
f2a745ca0fbc refactoring: using xml params part III (parameters import)
Goffi <goffi@goffi.org>
parents: 15
diff changeset
465 <param name="Port" value="28915" type="string" />
f2a745ca0fbc refactoring: using xml params part III (parameters import)
Goffi <goffi@goffi.org>
parents: 15
diff changeset
466 </category>
60
9764e027ecc0 SàT: multi-profile parameters, first draft
Goffi <goffi@goffi.org>
parents: 57
diff changeset
467 </general>
19
f2a745ca0fbc refactoring: using xml params part III (parameters import)
Goffi <goffi@goffi.org>
parents: 15
diff changeset
468 </params>
f2a745ca0fbc refactoring: using xml params part III (parameters import)
Goffi <goffi@goffi.org>
parents: 15
diff changeset
469 """
20
fc8c202cda87 refactoring: using xml params part IV (default values)
Goffi <goffi@goffi.org>
parents: 19
diff changeset
470
0
goffi@necton2
parents:
diff changeset
471 def __init__(self, host):
69
86f1f7f6d332 i18n first draft
Goffi <goffi@goffi.org>
parents: 64
diff changeset
472 info(_("Plugin XEP_0065 initialization"))
0
goffi@necton2
parents:
diff changeset
473 self.host = host
69
86f1f7f6d332 i18n first draft
Goffi <goffi@goffi.org>
parents: 64
diff changeset
474 debug(_("registering"))
0
goffi@necton2
parents:
diff changeset
475 self.server_factory = Socks5ServerFactory()
goffi@necton2
parents:
diff changeset
476 self.server_factory.protocol.host = self.host #needed for progress CB
goffi@necton2
parents:
diff changeset
477 self.client_factory = Socks5ClientFactory()
21
633c5ed65701 parameters: new button type (not finished)
Goffi <goffi@goffi.org>
parents: 20
diff changeset
478
633c5ed65701 parameters: new button type (not finished)
Goffi <goffi@goffi.org>
parents: 20
diff changeset
479 #parameters
38
3e24753b9e0b Fixed parameters loading/saving
Goffi <goffi@goffi.org>
parents: 22
diff changeset
480 host.memory.importParams(XEP_0065.params)
20
fc8c202cda87 refactoring: using xml params part IV (default values)
Goffi <goffi@goffi.org>
parents: 19
diff changeset
481 host.memory.setDefault("IP", "File Transfert", self.getExternalIP)
21
633c5ed65701 parameters: new button type (not finished)
Goffi <goffi@goffi.org>
parents: 20
diff changeset
482
22
bb72c29f3432 added action cb mechanism for buttons. Tested with a temporary new user registration button.
Goffi <goffi@goffi.org>
parents: 21
diff changeset
483 port = int(self.host.memory.getParamA("Port", "File Transfert"))
69
86f1f7f6d332 i18n first draft
Goffi <goffi@goffi.org>
parents: 64
diff changeset
484 info(_("Launching Socks5 Stream server on port %d"), port)
0
goffi@necton2
parents:
diff changeset
485 reactor.listenTCP(port, self.server_factory)
15
218ec9984fa5 wokkel integration part III + memory saved again
Goffi <goffi@goffi.org>
parents: 9
diff changeset
486
72
f271fff3a713 MUC implementation: first draft
Goffi <goffi@goffi.org>
parents: 69
diff changeset
487 def getHandler(self, profile):
64
d46f849664aa SàT: multi-profile, plugins updated
Goffi <goffi@goffi.org>
parents: 60
diff changeset
488 return XEP_0065_handler(self)
d46f849664aa SàT: multi-profile, plugins updated
Goffi <goffi@goffi.org>
parents: 60
diff changeset
489
20
fc8c202cda87 refactoring: using xml params part IV (default values)
Goffi <goffi@goffi.org>
parents: 19
diff changeset
490 def getExternalIP(self):
fc8c202cda87 refactoring: using xml params part IV (default values)
Goffi <goffi@goffi.org>
parents: 19
diff changeset
491 """Return IP visible from outside, by asking to a website"""
fc8c202cda87 refactoring: using xml params part IV (default values)
Goffi <goffi@goffi.org>
parents: 19
diff changeset
492 return getPage("http://www.goffi.org/sat_tools/get_ip.php")
0
goffi@necton2
parents:
diff changeset
493
goffi@necton2
parents:
diff changeset
494 def setData(self, data, id):
goffi@necton2
parents:
diff changeset
495 self.data = data
goffi@necton2
parents:
diff changeset
496 self.transfert_id = id
goffi@necton2
parents:
diff changeset
497
goffi@necton2
parents:
diff changeset
498 def sendFile(self, id, filepath, size):
goffi@necton2
parents:
diff changeset
499 #lauching socks5 initiator
69
86f1f7f6d332 i18n first draft
Goffi <goffi@goffi.org>
parents: 64
diff changeset
500 debug(_("Launching socks5 initiator"))
0
goffi@necton2
parents:
diff changeset
501 self.server_factory.protocol.mode = "initiator"
goffi@necton2
parents:
diff changeset
502 self.server_factory.protocol.filepath = filepath
goffi@necton2
parents:
diff changeset
503 self.server_factory.protocol.filesize = size
goffi@necton2
parents:
diff changeset
504 self.server_factory.protocol.transfert_id = id
goffi@necton2
parents:
diff changeset
505
64
d46f849664aa SàT: multi-profile, plugins updated
Goffi <goffi@goffi.org>
parents: 60
diff changeset
506 def getFile(self, iq, profile_key='@DEFAULT@'):
0
goffi@necton2
parents:
diff changeset
507 """Get file using byte stream"""
64
d46f849664aa SàT: multi-profile, plugins updated
Goffi <goffi@goffi.org>
parents: 60
diff changeset
508 client = self.host.getClient(profile_key)
d46f849664aa SàT: multi-profile, plugins updated
Goffi <goffi@goffi.org>
parents: 60
diff changeset
509 assert(client)
15
218ec9984fa5 wokkel integration part III + memory saved again
Goffi <goffi@goffi.org>
parents: 9
diff changeset
510 iq.handled = True
218ec9984fa5 wokkel integration part III + memory saved again
Goffi <goffi@goffi.org>
parents: 9
diff changeset
511 SI_elem = iq.firstChildElement()
218ec9984fa5 wokkel integration part III + memory saved again
Goffi <goffi@goffi.org>
parents: 9
diff changeset
512 IQ_id = iq['id']
0
goffi@necton2
parents:
diff changeset
513 for element in SI_elem.elements():
goffi@necton2
parents:
diff changeset
514 if element.name == "streamhost":
127
55d3ef84f01f Primitivus: mouse wheel changed to 'up' and 'down' key press
Goffi <goffi@goffi.org>
parents: 72
diff changeset
515 info (_("Stream proposed: host=[%(host)s] port=[%(port)s]") % {'host':element['host'], 'port':element['port']})
0
goffi@necton2
parents:
diff changeset
516 factory = self.client_factory
goffi@necton2
parents:
diff changeset
517 self.server_factory.protocol.mode = "target"
goffi@necton2
parents:
diff changeset
518 factory.protocol.host = self.host #needed for progress CB
64
d46f849664aa SàT: multi-profile, plugins updated
Goffi <goffi@goffi.org>
parents: 60
diff changeset
519 factory.protocol.xmlstream = client.xmlstream
0
goffi@necton2
parents:
diff changeset
520 factory.protocol.data = self.data
goffi@necton2
parents:
diff changeset
521 factory.protocol.transfert_id = self.transfert_id
goffi@necton2
parents:
diff changeset
522 factory.protocol.filesize = self.data["size"]
goffi@necton2
parents:
diff changeset
523 factory.protocol.sid = SI_elem['sid']
goffi@necton2
parents:
diff changeset
524 factory.protocol.initiator_jid = element['jid']
64
d46f849664aa SàT: multi-profile, plugins updated
Goffi <goffi@goffi.org>
parents: 60
diff changeset
525 factory.protocol.target_jid = client.jid.full()
0
goffi@necton2
parents:
diff changeset
526 factory.protocol.IQ_id = IQ_id
goffi@necton2
parents:
diff changeset
527 factory.protocol.activateCB = self.activateStream
goffi@necton2
parents:
diff changeset
528 reactor.connectTCP(element['host'], int(element['port']), factory)
goffi@necton2
parents:
diff changeset
529
64
d46f849664aa SàT: multi-profile, plugins updated
Goffi <goffi@goffi.org>
parents: 60
diff changeset
530 def activateStream(self, from_jid, to_jid, sid, IQ_id, xmlstream):
69
86f1f7f6d332 i18n first draft
Goffi <goffi@goffi.org>
parents: 64
diff changeset
531 debug(_("activating stream"))
0
goffi@necton2
parents:
diff changeset
532 result = domish.Element(('', 'iq'))
goffi@necton2
parents:
diff changeset
533 result['type'] = 'result'
goffi@necton2
parents:
diff changeset
534 result['id'] = IQ_id
goffi@necton2
parents:
diff changeset
535 result['from'] = from_jid
goffi@necton2
parents:
diff changeset
536 result['to'] = to_jid
goffi@necton2
parents:
diff changeset
537 query = result.addElement('query', 'http://jabber.org/protocol/bytestreams')
goffi@necton2
parents:
diff changeset
538 query['sid'] = sid
goffi@necton2
parents:
diff changeset
539 streamhost = query.addElement('streamhost-used')
goffi@necton2
parents:
diff changeset
540 streamhost['jid'] = to_jid #FIXME: use real streamhost
64
d46f849664aa SàT: multi-profile, plugins updated
Goffi <goffi@goffi.org>
parents: 60
diff changeset
541 xmlstream.send(result)
0
goffi@necton2
parents:
diff changeset
542
64
d46f849664aa SàT: multi-profile, plugins updated
Goffi <goffi@goffi.org>
parents: 60
diff changeset
543 class XEP_0065_handler(XMPPHandler):
d46f849664aa SàT: multi-profile, plugins updated
Goffi <goffi@goffi.org>
parents: 60
diff changeset
544 implements(iwokkel.IDisco)
d46f849664aa SàT: multi-profile, plugins updated
Goffi <goffi@goffi.org>
parents: 60
diff changeset
545
d46f849664aa SàT: multi-profile, plugins updated
Goffi <goffi@goffi.org>
parents: 60
diff changeset
546 def __init__(self, plugin_parent):
d46f849664aa SàT: multi-profile, plugins updated
Goffi <goffi@goffi.org>
parents: 60
diff changeset
547 self.plugin_parent = plugin_parent
d46f849664aa SàT: multi-profile, plugins updated
Goffi <goffi@goffi.org>
parents: 60
diff changeset
548 self.host = plugin_parent.host
d46f849664aa SàT: multi-profile, plugins updated
Goffi <goffi@goffi.org>
parents: 60
diff changeset
549
d46f849664aa SàT: multi-profile, plugins updated
Goffi <goffi@goffi.org>
parents: 60
diff changeset
550 def connectionInitialized(self):
d46f849664aa SàT: multi-profile, plugins updated
Goffi <goffi@goffi.org>
parents: 60
diff changeset
551 self.xmlstream.addObserver(BS_REQUEST, self.plugin_parent.getFile)
d46f849664aa SàT: multi-profile, plugins updated
Goffi <goffi@goffi.org>
parents: 60
diff changeset
552
d46f849664aa SàT: multi-profile, plugins updated
Goffi <goffi@goffi.org>
parents: 60
diff changeset
553
d46f849664aa SàT: multi-profile, plugins updated
Goffi <goffi@goffi.org>
parents: 60
diff changeset
554 def getDiscoInfo(self, requestor, target, nodeIdentifier=''):
d46f849664aa SàT: multi-profile, plugins updated
Goffi <goffi@goffi.org>
parents: 60
diff changeset
555 return [disco.DiscoFeature(NS_BS)]
d46f849664aa SàT: multi-profile, plugins updated
Goffi <goffi@goffi.org>
parents: 60
diff changeset
556
d46f849664aa SàT: multi-profile, plugins updated
Goffi <goffi@goffi.org>
parents: 60
diff changeset
557 def getDiscoItems(self, requestor, target, nodeIdentifier=''):
d46f849664aa SàT: multi-profile, plugins updated
Goffi <goffi@goffi.org>
parents: 60
diff changeset
558 return []