"""
Plan of action for this class:
* Determine the FT support of the Jabber client.
- * If we support a common protocol with them, create an
- FTReceive_Invite object of that type. Either OOB (JEP0066) or SI(JEP0095)
- * Call doInvite() and wait on the Deferred to send an affirmative or
- negative to the MSN contact.
- * The InvitationReceive sends IQ packets to the Jabber user to see if they
- accept. If they do it creates an appropriate FTReceive_Transport to send
- the file. Returning a Deferred for success or failure.
+ * If we find a common protocol, then send the invitation.
+ * Tell the legacyftp object the result of the invitation.
+ * If it was accepted, then start the transfer.
"""
def checkSupport(self):
def discoDone(features):
- enabledS5 = hasattr(self.session.pytrans, "ftSOCKS5")
+ LogEvent(INFO, self.ident)
+ enabledS5B = hasattr(self.session.pytrans, "ftSOCKS5")
enabledOOB = hasattr(self.session.pytrans, "ftOOB")
hasFT = features.count(disco.FT)
- hasS5 = features.count(disco.S5)
- #hasIBB = features.count(disco.IBB)
+ hasS5B = features.count(disco.S5B)
hasOOB = features.count(disco.IQOOB)
- if hasFT > 0 and hasS5 > 0 and enabledS5:
+ LogEvent(INFO, self.ident, "Choosing transfer mode.")
+ if hasFT > 0 and hasS5B > 0 and enabledS5B:
self.socksMode()
elif hasOOB > 0 and enabledOOB:
self.oobMode()
self.legacyftp.reject()
del self.legacyftp
- def discoFail(ignored=None):
+ def discoFail(err=None):
+ LogEvent(INFO, self.ident, str(err))
self.messageOobMode()
d = disco.DiscoRequest(self.session.pytrans, self.toJID).doDisco()
- d.addCallback(discoDone)
- d.addErrback(discoFail)
+ d.addCallbacks(discoDone, discoFail)
def socksMode(self):
def ftReply(el):
if el.getAttribute("type") != "result":
ftDeclined()
return
- # FIXME, some kind of mixin
self.session.pytrans.ftSOCKS5.addConnection(utils.socks5Hash(self.sid, self.senderJID, self.toJID), self.legacyftp)
- self.legacyftp.accept(self)
+ LogEvent(INFO, self.ident)
+ iq = Element((None, "iq"))
+ iq.attributes["type"] = "set"
+ iq.attributes["to"] = self.toJID
+ iq.attributes["from"] = self.senderJID
+ query = iq.addElement("query")
+ query.attributes["xmlns"] = disco.S5B
+ query.attributes["sid"] = self.sid
+ query.attributes["mode"] = "tcp"
+ streamhost = query.addElement("streamhost")
+ streamhost.attributes["jid"] = self.senderJID
+ streamhost.attributes["host"] = config.ip
+ streamhost.attributes["port"] = config.ftJabberPort
+ d = self.session.pytrans.discovery.sendIq(iq)
+ d.addErrback(ftDeclined) # Timeout
def ftDeclined(el):
self.legacyftp.reject()
del self.legacyftp
LogEvent(INFO, self.ident)
- self.sid = random.randint(1000, sys.maxint)
+ self.sid = str(random.randint(1000, sys.maxint))
iq = Element((None, "iq"))
iq.attributes["type"] = "set"
iq.attributes["to"] = self.toJID
si.attributes["id"] = self.sid
file = si.addElement("file")
file.attributes["profile"] = disco.FT
- file.attributes["size"] = self.legacyftp.filesize
+ file.attributes["size"] = str(self.legacyftp.filesize)
file.attributes["name"] = self.legacyftp.filename
# Feature negotiation
feature = si.addElement("feature")
option = field.addElement("option")
value = option.addElement("value")
value.addContent(disco.S5B)
- d = self.pytrans.discovery.sendIq(iq, 60*3)
+ d = self.session.pytrans.discovery.sendIq(iq, 60*3)
d.addCallback(ftReply)
d.addErrback(ftDeclined)
self.addr = ""
def connectRequested(self, addr, port):
+ # So that the legacyftp can close the connection
+ self.transport.close = self.transport.disconnect
+
# Check for special connect to the namespace -- this signifies that
# the client is just checking that it can connect to the streamhost
if addr == disco.S5B:
class Proxy65(protocol.Factory):
def __init__(self, port):
- internet.TCPServer(port, self)
+ LogEvent(INFO)
+ reactor.listenTCP(port, self)
self.pendingConns = {}
self.activeConns = {}
assert address not in self.activeConns
self.activeConns[address] = None
- olist[0].peersock = olist[1]
- olist[1].peersock = olist[0]
- olist[0].transport.registerProducer(olist[1], 0)
- olist[1].transport.registerProducer(olist[0], 0)
+ if not isinstance(olist[0], JEP65Connection):
+ legacyftp = olist[0]
+ connection = olist[1]
+ elif not isinstance(olist[1], JEP65Connection):
+ legacyftp = olist[1]
+ connection = olist[0]
+ else:
+ LogEvent(WARN, '', "No legacyftp")
+ return
+
+ legacyftp.accept(connection.transport)
else:
LogEvent(WARN, '', "No pending connection.")
class FileTransferOOB(resource.Resource):
def __init__(self, port):
+ LogEvent(INFO)
self.isLeaf = True
self.files = {}
self.oobSite = server.Site(self)