diff --git a/src/common/connection_handlers.py b/src/common/connection_handlers.py index 8bcf9b51c6e1039e5be1a75ee428bf6680ac7ea3..089fbd69bf548028b202a0f1ce2f07e6f2543cca 100644 --- a/src/common/connection_handlers.py +++ b/src/common/connection_handlers.py @@ -317,15 +317,20 @@ class ConnectionBytestream: field.setValue(common.xmpp.NS_BYTESTREAM) self.connection.send(iq) + def _ft_get_our_jid(self): + our_jid = gajim.get_jid_from_account(self.name) + resource = self.server_resource + return our_jid + '/' + resource + + def _ft_get_receiver_jid(self, file_props): + return file_props['receiver'].jid + '/' + file_props['receiver'].resource + def send_file_request(self, file_props): ''' send iq for new FT request ''' if not self.connection or self.connected < 2: return - our_jid = gajim.get_jid_from_account(self.name) - resource = self.server_resource - frm = our_jid + '/' + resource - file_props['sender'] = frm - fjid = file_props['receiver'].jid + '/' + file_props['receiver'].resource + file_props['sender'] = self._ft_get_our_jid() + fjid = self._ft_get_receiver_jid(file_props) iq = common.xmpp.Protocol(name = 'iq', to = fjid, typ = 'set') iq.setID(file_props['sid']) @@ -418,6 +423,9 @@ class ConnectionBytestream: self.dispatch('FILE_REQUEST_ERROR', (jid, file_props, '')) raise common.xmpp.NodeProcessed + def _ft_get_from(self, iq_obj): + return helpers.get_full_jid_from_iq(iq_obj) + def _bytestreamSetCB(self, con, iq_obj): log.debug('_bytestreamSetCB') target = unicode(iq_obj.getAttr('to')) @@ -434,7 +442,7 @@ class ConnectionBytestream: 'target': target, 'id': id_, 'sid': sid, - 'initiator': helpers.get_full_jid_from_iq(iq_obj) + 'initiator': self._ft_get_from(iq_obj) } for attr in item.getAttrs(): host_dict[attr] = item.getAttr(attr) @@ -472,7 +480,7 @@ class ConnectionBytestream: return if not real_id.startswith('au_'): return - frm = helpers.get_full_jid_from_iq(iq_obj) + frm = self._ft_get_from(iq_obj) id_ = real_id[3:] if id_ in self.files_props: file_props = self.files_props[id_] @@ -482,9 +490,12 @@ class ConnectionBytestream: gajim.socks5queue.activate_proxy(host['idx']) raise common.xmpp.NodeProcessed + def _ft_get_streamhost_jid_attr(self, streamhost): + return helpers.parse_jid(streamhost.getAttr('jid')) + def _bytestreamResultCB(self, con, iq_obj): log.debug('_bytestreamResultCB') - frm = helpers.get_full_jid_from_iq(iq_obj) + frm = self._ft_get_from(iq_obj) real_id = unicode(iq_obj.getAttr('id')) query = iq_obj.getTag('query') gajim.proxy65_manager.resolve_result(frm, query) @@ -512,7 +523,7 @@ class ConnectionBytestream: gajim.socks5queue.activate_proxy(host['idx']) break raise common.xmpp.NodeProcessed - jid = helpers.parse_jid(streamhost.getAttr('jid')) + jid = self._ft_get_streamhost_jid_attr(streamhost) if 'streamhost-used' in file_props and \ file_props['streamhost-used'] is True: raise common.xmpp.NodeProcessed @@ -569,7 +580,7 @@ class ConnectionBytestream: if 'request-id' in file_props: # we have already sent streamhosts info return - file_props['receiver'] = helpers.get_full_jid_from_iq(iq_obj) + file_props['receiver'] = self._ft_get_from(iq_obj) si = iq_obj.getTag('si') file_tag = si.getTag('file') range_tag = None @@ -595,9 +606,9 @@ class ConnectionBytestream: def _siSetCB(self, con, iq_obj): log.debug('_siSetCB') - jid = helpers.get_jid_from_iq(iq_obj) + jid = self._ft_get_from(iq_obj) file_props = {'type': 'r'} - file_props['sender'] = helpers.get_full_jid_from_iq(iq_obj) + file_props['sender'] = jid file_props['request-id'] = unicode(iq_obj.getAttr('id')) si = iq_obj.getTag('si') profile = si.getAttr('profile') @@ -635,7 +646,7 @@ class ConnectionBytestream: file_props['mime-type'] = mime_type our_jid = gajim.get_jid_from_account(self.name) resource = self.server_resource - file_props['receiver'] = our_jid + '/' + resource + file_props['receiver'] = self._ft_get_our_jid() file_props['sid'] = unicode(si.getAttr('id')) file_props['transfered_size'] = [] gajim.socks5queue.add_file_props(self.name, file_props) @@ -656,7 +667,7 @@ class ConnectionBytestream: if file_props is None: # file properties for jid is none return - jid = helpers.get_jid_from_iq(iq_obj) + jid = self._ft_get_from(iq_obj) file_props['error'] = -3 self.dispatch('FILE_REQUEST_ERROR', (jid, file_props, '')) raise common.xmpp.NodeProcessed diff --git a/src/common/zeroconf/client_zeroconf.py b/src/common/zeroconf/client_zeroconf.py index 6b50a9feae63ff833dfbb23f8546ce5d382337a0..23834be28924d3fb999ddabe69d688e19eb1ccf9 100644 --- a/src/common/zeroconf/client_zeroconf.py +++ b/src/common/zeroconf/client_zeroconf.py @@ -288,6 +288,7 @@ class P2PClient(IdleObject): pass def _register_handlers(self): + self._caller.peerhost = self.Connection._sock.getsockname() self.RegisterHandler('message', lambda conn, data:self._caller._messageCB( self.Server, conn, data)) self.RegisterHandler('iq', self._caller._siSetCB, 'set', @@ -709,6 +710,8 @@ class ClientZeroconf: try: item = self.roster[to] except KeyError: + raise KeyError + print 'ret', to, self.roster.keys() # Contact offline return -1 diff --git a/src/common/zeroconf/connection_handlers_zeroconf.py b/src/common/zeroconf/connection_handlers_zeroconf.py index 4ea0e65bb8b1b0671a00e2fa29c7d56aa8df938d..60dbb0c1bd931fb54bab60498e668be63ef384c5 100644 --- a/src/common/zeroconf/connection_handlers_zeroconf.py +++ b/src/common/zeroconf/connection_handlers_zeroconf.py @@ -70,311 +70,18 @@ class ConnectionVcard(connection_handlers.ConnectionVcard): pass class ConnectionBytestream(connection_handlers.ConnectionBytestream): - def send_socks5_info(self, file_props, fast = True, receiver = None, - sender = None): - ''' send iq for the present streamhosts and proxies ''' - if not isinstance(self.peerhost, tuple): - return - port = gajim.config.get('file_transfers_port') - ft_add_hosts_to_send = gajim.config.get('ft_add_hosts_to_send') - if receiver is None: - receiver = file_props['receiver'] - if sender is None: - sender = file_props['sender'] - sha_str = helpers.get_auth_sha(file_props['sid'], sender, - receiver) - file_props['sha_str'] = sha_str - ft_add_hosts = [] - if ft_add_hosts_to_send: - ft_add_hosts_to_send = [e.strip() for e in ft_add_hosts_to_send.split(',')] - for ft_host in ft_add_hosts_to_send: - try: - ft_host = socket.gethostbyname(ft_host) - ft_add_hosts.append(ft_host) - except socket.gaierror: - self.dispatch('ERROR', (_('Wrong host'), _('The host %s you configured as the ft_add_hosts_to_send advanced option is not valid, so ignored.') % ft_host)) - listener = gajim.socks5queue.start_listener(port, - sha_str, self._result_socks5_sid, file_props['sid']) - if listener is None: - file_props['error'] = -5 - self.dispatch('FILE_REQUEST_ERROR', (unicode(receiver), file_props, - '')) - self._connect_error(unicode(receiver), file_props['sid'], - file_props['sid'], code = 406) - return + def _ft_get_from(self, iq_obj): + return unicode(iq_obj.getFrom()) - iq = common.xmpp.Protocol(name = 'iq', to = unicode(receiver), - typ = 'set') - file_props['request-id'] = 'id_' + file_props['sid'] - iq.setID(file_props['request-id']) - query = iq.setTag('query') - query.setNamespace(common.xmpp.NS_BYTESTREAM) - query.setAttr('mode', 'tcp') - query.setAttr('sid', file_props['sid']) - for ft_host in ft_add_hosts: - # The streamhost, if set - ostreamhost = common.xmpp.Node(tag = 'streamhost') - query.addChild(node = ostreamhost) - ostreamhost.setAttr('port', unicode(port)) - ostreamhost.setAttr('host', ft_host) - ostreamhost.setAttr('jid', sender) - for thehost in self.peerhost: - thehost = self.peerhost[0] - streamhost = common.xmpp.Node(tag = 'streamhost') # My IP - query.addChild(node = streamhost) - streamhost.setAttr('port', unicode(port)) - streamhost.setAttr('host', thehost) - streamhost.setAttr('jid', sender) - self.connection.send(iq) - - def send_file_request(self, file_props): - ''' send iq for new FT request ''' - if not self.connection or self.connected < 2: - return - our_jid = gajim.get_jid_from_account(self.name) - frm = our_jid - file_props['sender'] = frm - fjid = file_props['receiver'].jid - iq = common.xmpp.Protocol(name = 'iq', to = fjid, - typ = 'set') - iq.setID(file_props['sid']) - self.files_props[file_props['sid']] = file_props - si = iq.setTag('si') - si.setNamespace(common.xmpp.NS_SI) - si.setAttr('profile', common.xmpp.NS_FILE) - si.setAttr('id', file_props['sid']) - file_tag = si.setTag('file') - file_tag.setNamespace(common.xmpp.NS_FILE) - file_tag.setAttr('name', file_props['name']) - file_tag.setAttr('size', file_props['size']) - desc = file_tag.setTag('desc') - if 'desc' in file_props: - desc.setData(file_props['desc']) - file_tag.setTag('range') - feature = si.setTag('feature') - feature.setNamespace(common.xmpp.NS_FEATURE) - _feature = common.xmpp.DataForm(typ='form') - feature.addChild(node=_feature) - field = _feature.setField('stream-method') - field.setAttr('type', 'list-single') - field.addOption(common.xmpp.NS_BYTESTREAM) - self.connection.send(iq) - - def _bytestreamSetCB(self, con, iq_obj): - log.debug('_bytestreamSetCB') - target = unicode(iq_obj.getAttr('to')) - id_ = unicode(iq_obj.getAttr('id')) - query = iq_obj.getTag('query') - sid = unicode(query.getAttr('sid')) - file_props = gajim.socks5queue.get_file_props( - self.name, sid) - streamhosts=[] - for item in query.getChildren(): - if item.getName() == 'streamhost': - host_dict={ - 'state': 0, - 'target': target, - 'id': id_, - 'sid': sid, - 'initiator': unicode(iq_obj.getFrom()) - } - for attr in item.getAttrs(): - host_dict[attr] = item.getAttr(attr) - streamhosts.append(host_dict) - if file_props is None: - if sid in self.files_props: - file_props = self.files_props[sid] - file_props['fast'] = streamhosts - if file_props['type'] == 's': - if 'streamhosts' in file_props: - file_props['streamhosts'].extend(streamhosts) - else: - file_props['streamhosts'] = streamhosts - if not gajim.socks5queue.get_file_props(self.name, sid): - gajim.socks5queue.add_file_props(self.name, file_props) - gajim.socks5queue.connect_to_hosts(self.name, sid, - self.send_success_connect_reply, None) - raise common.xmpp.NodeProcessed - - file_props['streamhosts'] = streamhosts - if file_props['type'] == 'r': - gajim.socks5queue.connect_to_hosts(self.name, sid, - self.send_success_connect_reply, self._connect_error) - raise common.xmpp.NodeProcessed - - def _ResultCB(self, con, iq_obj): - log.debug('_ResultCB') - # if we want to respect jep-0065 we have to check for proxy - # activation result in any result iq - real_id = unicode(iq_obj.getAttr('id')) - if not real_id.startswith('au_'): - return - frm = unicode(iq_obj.getFrom()) - id_ = real_id[3:] - if id_ in self.files_props: - file_props = self.files_props[id_] - if file_props['streamhost-used']: - for host in file_props['proxyhosts']: - if host['initiator'] == frm and 'idx' in host: - gajim.socks5queue.activate_proxy(host['idx']) - raise common.xmpp.NodeProcessed - - def _bytestreamResultCB(self, con, iq_obj): - log.debug('_bytestreamResultCB') - frm = unicode(iq_obj.getFrom()) - real_id = unicode(iq_obj.getAttr('id')) - query = iq_obj.getTag('query') - gajim.proxy65_manager.resolve_result(frm, query) + def _ft_get_our_jid(self): + return gajim.get_jid_from_account(self.name) - try: - streamhost = query.getTag('streamhost-used') - except Exception: # this bytestream result is not what we need - pass - id_ = real_id[3:] - if id_ in self.files_props: - file_props = self.files_props[id_] - else: - raise common.xmpp.NodeProcessed - if streamhost is None: - # proxy approves the activate query - if real_id.startswith('au_'): - id_ = real_id[3:] - if 'streamhost-used' not in file_props or \ - file_props['streamhost-used'] is False: - raise common.xmpp.NodeProcessed - if 'proxyhosts' not in file_props: - raise common.xmpp.NodeProcessed - for host in file_props['proxyhosts']: - if host['initiator'] == frm and \ - unicode(query.getAttr('sid')) == file_props['sid']: - gajim.socks5queue.activate_proxy(host['idx']) - break - raise common.xmpp.NodeProcessed - jid = streamhost.getAttr('jid') - if 'streamhost-used' in file_props and \ - file_props['streamhost-used'] is True: - raise common.xmpp.NodeProcessed + def _ft_get_receiver_jid(self, file_props): + return file_props['receiver'].jid - if real_id.startswith('au_'): - gajim.socks5queue.send_file(file_props, self.name) - raise common.xmpp.NodeProcessed + def _ft_get_streamhost_jid_attr(self, streamhost): + return streamhost.getAttr('jid') - proxy = None - if 'proxyhosts' in file_props: - for proxyhost in file_props['proxyhosts']: - if proxyhost['jid'] == jid: - proxy = proxyhost - - if proxy is not None: - file_props['streamhost-used'] = True - if 'streamhosts' not in file_props: - file_props['streamhosts'] = [] - file_props['streamhosts'].append(proxy) - file_props['is_a_proxy'] = True - receiver = socks5.Socks5Receiver(gajim.idlequeue, proxy, file_props['sid'], file_props) - gajim.socks5queue.add_receiver(self.name, receiver) - proxy['idx'] = receiver.queue_idx - gajim.socks5queue.on_success = self._proxy_auth_ok - raise common.xmpp.NodeProcessed - - else: - gajim.socks5queue.send_file(file_props, self.name) - if 'fast' in file_props: - fasts = file_props['fast'] - if len(fasts) > 0: - self._connect_error(frm, fasts[0]['id'], file_props['sid'], - code = 406) - - raise common.xmpp.NodeProcessed - - def _siResultCB(self, con, iq_obj): - log.debug('_siResultCB') - self.peerhost = con._owner.Connection._sock.getsockname() - id_ = iq_obj.getAttr('id') - if id_ not in self.files_props: - # no such jid - return - file_props = self.files_props[id_] - if file_props is None: - # file properties for jid is none - return - if 'request-id' in file_props: - # we have already sent streamhosts info - return - file_props['receiver'] = unicode(iq_obj.getFrom()) - si = iq_obj.getTag('si') - file_tag = si.getTag('file') - range_tag = None - if file_tag: - range_tag = file_tag.getTag('range') - if range_tag: - offset = range_tag.getAttr('offset') - if offset: - file_props['offset'] = int(offset) - length = range_tag.getAttr('length') - if length: - file_props['length'] = int(length) - feature = si.setTag('feature') - if feature.getNamespace() != common.xmpp.NS_FEATURE: - return - form_tag = feature.getTag('x') - form = common.xmpp.DataForm(node=form_tag) - field = form.getField('stream-method') - if field.getValue() != common.xmpp.NS_BYTESTREAM: - return - self.send_socks5_info(file_props, fast = True) - raise common.xmpp.NodeProcessed - - def _siSetCB(self, con, iq_obj): - log.debug('_siSetCB') - jid = unicode(iq_obj.getFrom()) - si = iq_obj.getTag('si') - profile = si.getAttr('profile') - mime_type = si.getAttr('mime-type') - if profile != common.xmpp.NS_FILE: - return - file_tag = si.getTag('file') - file_props = {'type': 'r'} - for attribute in file_tag.getAttrs(): - if attribute in ('name', 'size', 'hash', 'date'): - val = file_tag.getAttr(attribute) - if val is None: - continue - file_props[attribute] = val - file_desc_tag = file_tag.getTag('desc') - if file_desc_tag is not None: - file_props['desc'] = file_desc_tag.getData() - - if mime_type is not None: - file_props['mime-type'] = mime_type - our_jid = gajim.get_jid_from_account(self.name) - file_props['receiver'] = our_jid - file_props['sender'] = unicode(iq_obj.getFrom()) - file_props['request-id'] = unicode(iq_obj.getAttr('id')) - file_props['sid'] = unicode(si.getAttr('id')) - file_props['transfered_size'] = [] - gajim.socks5queue.add_file_props(self.name, file_props) - self.dispatch('FILE_REQUEST', (jid, file_props)) - raise common.xmpp.NodeProcessed - - def _siErrorCB(self, con, iq_obj): - log.debug('_siErrorCB') - si = iq_obj.getTag('si') - profile = si.getAttr('profile') - if profile != common.xmpp.NS_FILE: - return - id_ = iq_obj.getAttr('id') - if id_ not in self.files_props: - # no such jid - return - file_props = self.files_props[id_] - if file_props is None: - # file properties for jid is none - return - jid = unicode(iq_obj.getFrom()) - file_props['error'] = -3 - self.dispatch('FILE_REQUEST_ERROR', (jid, file_props, '')) - raise common.xmpp.NodeProcessed class ConnectionHandlersZeroconf(ConnectionVcard, ConnectionBytestream, ConnectionCommands, ConnectionPEP, connection_handlers.ConnectionHandlersBase): diff --git a/src/common/zeroconf/connection_zeroconf.py b/src/common/zeroconf/connection_zeroconf.py index e1cc30971ff106b674ca424e2bb7af38bb2151da..dff41e39bca7100adf595a14b0598d9364e7f424 100644 --- a/src/common/zeroconf/connection_zeroconf.py +++ b/src/common/zeroconf/connection_zeroconf.py @@ -85,6 +85,8 @@ class ConnectionZeroconf(CommonConnection, ConnectionHandlersZeroconf): 'custom_port', 5298) gajim.config.set_per('accounts', gajim.ZEROCONF_ACC_NAME, 'is_zeroconf', True) + gajim.config.set_per('accounts', gajim.ZEROCONF_ACC_NAME, + 'use_ft_proxies', False) #XXX make sure host is US-ASCII self.host = unicode(socket.gethostname()) gajim.config.set_per('accounts', gajim.ZEROCONF_ACC_NAME, 'hostname', diff --git a/src/gui_interface.py b/src/gui_interface.py index 7c7825100f5aed4b967b4e6c30bb4f3dddc24268..7a948d5c1ae19d75d4f3c1fe641acfd7ed8b3981 100644 --- a/src/gui_interface.py +++ b/src/gui_interface.py @@ -1324,6 +1324,7 @@ class Interface: def handle_event_file_request_error(self, account, array): # ('FILE_REQUEST_ERROR', account, (jid, file_props, error_msg)) jid, file_props, errmsg = array + jid = gajim.get_jid_without_resource(jid) ft = self.instances['file_transfers'] ft.set_status(file_props['type'], file_props['sid'], 'stop') errno = file_props['error'] @@ -1353,6 +1354,7 @@ class Interface: def handle_event_file_request(self, account, array): jid = array[0] + jid = gajim.get_jid_without_resource(jid) if jid not in gajim.contacts.get_jid_list(account): keyID = '' attached_keys = gajim.config.get_per('accounts', account,