changeset 77bf2919b7ed in /home/hg/repos/gajim
details:http://hg.gajim.org/gajim?cmd=changeset;node=77bf2919b7ed
description: merge jingleFT branch! Thanks to Zhenchao Li and Jefry Lagrange
for their work.
diffstat:
src/chat_control.py | 6 +-
src/common/caps_cache.py | 4 +-
src/common/check_paths.py | 14 +
src/common/configpaths.py | 3 +-
src/common/connection_handlers.py | 47 +-
src/common/connection_handlers_events.py | 101 +-
src/common/gajim.py | 6 +-
src/common/helpers.py | 4 +
src/common/jingle.py | 80 +-
src/common/jingle_content.py | 21 +-
src/common/jingle_ft.py | 375 ++++++++
src/common/jingle_ftstates.py | 244 +++++
src/common/jingle_rtp.py | 2 +-
src/common/jingle_session.py | 211 +++-
src/common/jingle_transport.py | 262 ++++++-
src/common/jingle_xtls.py | 239 +++++
src/common/protocol/bytestream.py | 66 +-
src/common/socks5.py | 1258 +++++++++++++++++++----------
src/common/xmpp/protocol.py | 91 ++-
src/dialogs.py | 7 +-
src/filetransfers_window.py | 80 +-
src/gui_interface.py | 104 ++-
src/gui_menu_builder.py | 4 +-
src/roster_window.py | 3 +
test/unit/test_jingle.py | 157 +++
test/unit/test_socks5.py | 177 ++++
26 files changed, 2971 insertions(+), 595 deletions(-)
diffs (truncated from 4863 to 300 lines):
diff -r f6f78f3802c0 -r 77bf2919b7ed src/chat_control.py
--- a/src/chat_control.py Thu Apr 12 07:17:50 2012 +0200
+++ b/src/chat_control.py Sat Apr 14 13:40:55 2012 +0200
@@ -53,7 +53,7 @@
from common.pep import MOODS, ACTIVITIES
from common.xmpp.protocol import NS_XHTML, NS_XHTML_IM, NS_FILE, NS_MUC
from common.xmpp.protocol import NS_RECEIPTS, NS_ESESSION
-from common.xmpp.protocol import NS_JINGLE_RTP_AUDIO, NS_JINGLE_RTP_VIDEO,
NS_JINGLE_ICE_UDP
+from common.xmpp.protocol import NS_JINGLE_RTP_AUDIO, NS_JINGLE_RTP_VIDEO,
NS_JINGLE_ICE_UDP, NS_JINGLE_FILE_TRANSFER
from common.xmpp.protocol import NS_CHATSTATES
from common.connection_handlers_events import MessageOutgoingEvent
from common.exceptions import GajimGeneralException
@@ -1722,13 +1722,13 @@
self._video_button.set_sensitive(self.video_available)
# Send file
- if self.contact.supports(NS_FILE) and (self.type_id == 'chat' or \
+ if (self.contact.supports(NS_FILE) or
self.contact.supports(NS_JINGLE_FILE_TRANSFER)) and (self.type_id == 'chat' or \
self.gc_contact.resource):
self._send_file_button.set_sensitive(True)
self._send_file_button.set_tooltip_text('')
else:
self._send_file_button.set_sensitive(False)
- if not self.contact.supports(NS_FILE):
+ if not (self.contact.supports(NS_FILE) or
self.contact.supports(NS_JINGLE_FILE_TRANSFER)):
self._send_file_button.set_tooltip_text(_(
"This contact does not support file transfer."))
else:
diff -r f6f78f3802c0 -r 77bf2919b7ed src/common/caps_cache.py
--- a/src/common/caps_cache.py Thu Apr 12 07:17:50 2012 +0200
+++ b/src/common/caps_cache.py Sat Apr 14 13:40:55 2012 +0200
@@ -38,10 +38,10 @@
log = logging.getLogger('gajim.c.caps_cache')
from common.xmpp import (NS_XHTML_IM, NS_RECEIPTS, NS_ESESSION, NS_CHATSTATES,
- NS_JINGLE_ICE_UDP, NS_JINGLE_RTP_AUDIO, NS_JINGLE_RTP_VIDEO, NS_CAPS)
+ NS_JINGLE_ICE_UDP, NS_JINGLE_RTP_AUDIO, NS_JINGLE_RTP_VIDEO, NS_CAPS,
NS_JINGLE_FILE_TRANSFER)
# Features where we cannot safely assume that the other side supports them
FEATURE_BLACKLIST = [NS_CHATSTATES, NS_XHTML_IM, NS_RECEIPTS, NS_ESESSION,
- NS_JINGLE_ICE_UDP, NS_JINGLE_RTP_AUDIO, NS_JINGLE_RTP_VIDEO]
+ NS_JINGLE_ICE_UDP, NS_JINGLE_RTP_AUDIO, NS_JINGLE_RTP_VIDEO,
NS_JINGLE_FILE_TRANSFER]
# Query entry status codes
NEW = 0
diff -r f6f78f3802c0 -r 77bf2919b7ed src/common/check_paths.py
--- a/src/common/check_paths.py Thu Apr 12 07:17:50 2012 +0200
+++ b/src/common/check_paths.py Sat Apr 14 13:40:55 2012 +0200
@@ -30,6 +30,7 @@
from common import gajim
import logger
+from common import jingle_xtls
# DO NOT MOVE ABOVE OF import gajim
import sqlite3 as sqlite
@@ -266,6 +267,8 @@
MY_DATA = configpaths.gajimpaths['MY_DATA']
MY_CONFIG = configpaths.gajimpaths['MY_CONFIG']
MY_CACHE = configpaths.gajimpaths['MY_CACHE']
+ XTLS_CERTS = configpaths.gajimpaths['MY_PEER_CERTS']
+ LOCAL_XTLS_CERTS = configpaths.gajimpaths['MY_CERT']
PLUGINS_CONFIG_PATH = gajim.PLUGINS_CONFIG_DIR
@@ -342,6 +345,17 @@
print _('%s is a directory but should be a file') % CACHE_DB_PATH
print _('Gajim will now exit')
sys.exit()
+
+ if not os.path.exists(XTLS_CERTS):
+ create_path(XTLS_CERTS)
+ if not os.path.exists(LOCAL_XTLS_CERTS):
+ create_path(LOCAL_XTLS_CERTS)
+ cert_name = os.path.join(LOCAL_XTLS_CERTS,
+ jingle_xtls.SELF_SIGNED_CERTIFICATE)
+ if not (os.path.exists(cert_name + '.cert') and os.path.exists(
+ cert_name + '.pkey')):
+ jingle_xtls.make_certs(cert_name, 'gajim')
+
def create_path(directory):
head, tail = os.path.split(directory)
diff -r f6f78f3802c0 -r 77bf2919b7ed src/common/configpaths.py
--- a/src/common/configpaths.py Thu Apr 12 07:17:50 2012 +0200
+++ b/src/common/configpaths.py Sat Apr 14 13:40:55 2012 +0200
@@ -141,7 +141,7 @@
d = {'MY_DATA': '', 'LOG_DB': u'logs.db', 'MY_CACERTS': u'cacerts.pem',
'MY_EMOTS': u'emoticons', 'MY_ICONSETS': u'iconsets',
'MY_MOOD_ICONSETS': u'moods', 'MY_ACTIVITY_ICONSETS':
u'activities',
- 'PLUGINS_USER': u'plugins'}
+ 'PLUGINS_USER': u'plugins', 'MY_PEER_CERTS': u'certs'}
for name in d:
self.add(name, TYPE_DATA, windowsify(d[name]))
@@ -151,6 +151,7 @@
self.add(name, TYPE_CACHE, windowsify(d[name]))
self.add('MY_CONFIG', TYPE_CONFIG, '')
+ self.add('MY_CERT', TYPE_CONFIG, '')
basedir = fse(os.environ.get(u'GAJIM_BASEDIR', defs.basedir))
self.add('DATA', None, os.path.join(basedir, windowsify(u'data')))
diff -r f6f78f3802c0 -r 77bf2919b7ed src/common/connection_handlers.py
--- a/src/common/connection_handlers.py Thu Apr 12 07:17:50 2012 +0200
+++ b/src/common/connection_handlers.py Sat Apr 14 13:40:55 2012 +0200
@@ -45,6 +45,7 @@
from common import gajim
from common import exceptions
from common import dataforms
+from common import jingle_xtls
from common.commands import ConnectionCommands
from common.pubsub import ConnectionPubSub
from common.pep import ConnectionPEP
@@ -189,7 +190,10 @@
query.setAttr('node', 'http://gajim.org#' + gajim.version.split('-',
1)[
0])
for f in (common.xmpp.NS_BYTESTREAM, common.xmpp.NS_SI,
- common.xmpp.NS_FILE, common.xmpp.NS_COMMANDS):
+ common.xmpp.NS_FILE, common.xmpp.NS_COMMANDS,
+ common.xmpp.NS_JINGLE_FILE_TRANSFER, common.xmpp.NS_JINGLE_XTLS,
+ common.xmpp.NS_PUBKEY_PUBKEY, common.xmpp.NS_PUBKEY_REVOKE,
+ common.xmpp.NS_PUBKEY_ATTEST):
feature = common.xmpp.Node('feature')
feature.setAttr('var', f)
query.addChild(node=feature)
@@ -1979,10 +1983,37 @@
gajim.nec.push_incoming_event(SearchFormReceivedEvent(None,
conn=self, stanza=iq_obj))
- def _StreamCB(self, con, iq_obj):
- log.debug('StreamCB')
- gajim.nec.push_incoming_event(StreamReceivedEvent(None,
- conn=self, stanza=iq_obj))
+ def _search_fields_received(self, con, iq_obj):
+ jid = jid = helpers.get_jid_from_iq(iq_obj)
+ tag = iq_obj.getTag('query', namespace = common.xmpp.NS_SEARCH)
+ if not tag:
+ self.dispatch('SEARCH_FORM', (jid, None, False))
+ return
+ df = tag.getTag('x', namespace = common.xmpp.NS_DATA)
+ if df:
+ self.dispatch('SEARCH_FORM', (jid, df, True))
+ return
+ df = {}
+ for i in iq_obj.getQueryPayload():
+ df[i.getName()] = i.getData()
+ self.dispatch('SEARCH_FORM', (jid, df, False))
+
+ def _PubkeyGetCB(self, con, iq_obj):
+ log.info('PubkeyGetCB')
+ jid_from = helpers.get_full_jid_from_iq(iq_obj)
+ sid = iq_obj.getAttr('id')
+ jingle_xtls.send_cert(con, jid_from, sid)
+ raise common.xmpp.NodeProcessed
+
+ def _PubkeyResultCB(self, con, iq_obj):
+ log.info('PubkeyResultCB')
+ jid_from = helpers.get_full_jid_from_iq(iq_obj)
+ jingle_xtls.handle_new_cert(con, iq_obj, jid_from)
+
+ def _StreamCB(self, con, obj):
+ if obj.getTag('conflict'):
+ # disconnected because of a resource conflict
+ self.dispatch('RESOURCE_CONFLICT', ())
def _register_handlers(self, con, con_type):
# try to find another way to register handlers in each class
@@ -2070,5 +2101,7 @@
con.RegisterHandler('iq', self._ResultCB, 'result')
con.RegisterHandler('presence', self._StanzaArrivedCB)
con.RegisterHandler('message', self._StanzaArrivedCB)
- con.RegisterHandler('unknown', self._StreamCB,
- common.xmpp.NS_XMPP_STREAMS, xmlns=common.xmpp.NS_STREAMS)
+ con.RegisterHandler('unknown', self._StreamCB,
'urn:ietf:params:xml:ns:xmpp-streams', xmlns='http://etherx.jabber.org/streams')
+ con.RegisterHandler('iq', self._PubkeyGetCB, 'get',
common.xmpp.NS_PUBKEY_PUBKEY)
+ con.RegisterHandler('iq', self._PubkeyResultCB, 'result',
common.xmpp.NS_PUBKEY_PUBKEY)
+
diff -r f6f78f3802c0 -r 77bf2919b7ed src/common/connection_handlers_events.py
--- a/src/common/connection_handlers_events.py Thu Apr 12 07:17:50 2012 +0200
+++ b/src/common/connection_handlers_events.py Sat Apr 14 13:40:55 2012 +0200
@@ -36,6 +36,7 @@
from common.logger import LOG_DB_PATH
from common.pep import SUPPORTED_PERSONAL_USER_EVENTS
from common.xmpp.protocol import NS_CHATSTATES
+from common.jingle_transport import JingleTransportSocks5
import gtkgui_helpers
@@ -1392,6 +1393,16 @@
self.jid, self.resource = gajim.get_room_and_nick_from_fjid(self.fjid)
self.sid = self.jingle_session.sid
return True
+
+class JingleTransferCancelledEvent(nec.NetworkIncomingEvent):
+ name = 'jingleFT-cancelled-received'
+ base_network_events = []
+
+ def generate(self):
+ self.fjid = self.jingle_session.peerjid
+ self.jid, self.resource = gajim.get_room_and_nick_from_fjid(self.fjid)
+ self.sid = self.jingle_session.sid
+ return True
class JingleErrorReceivedEvent(nec.NetworkIncomingEvent):
name = 'jingle-error-received'
@@ -1901,6 +1912,10 @@
name = 'file-request-received'
base_network_events = []
+ def init(self):
+ self.jingle_content = None
+ self.FT_content = None
+
def generate(self):
self.get_id()
self.fjid = self.conn._ft_get_from(self.stanza)
@@ -1908,28 +1923,36 @@
self.file_props = {'type': 'r'}
self.file_props['sender'] = self.fjid
self.file_props['request-id'] = self.id_
- si = self.stanza.getTag('si')
- profile = si.getAttr('profile')
- if profile != xmpp.NS_FILE:
- self.conn.send_file_rejection(self.file_props, code='400',
typ='profile')
- raise xmpp.NodeProcessed
- feature_tag = si.getTag('feature', namespace=xmpp.NS_FEATURE)
- if not feature_tag:
- return
- form_tag = feature_tag.getTag('x', namespace=xmpp.NS_DATA)
- if not form_tag:
- return
- self.dataform = dataforms.ExtendForm(node=form_tag)
- for f in self.dataform.iter_fields():
- if f.var == 'stream-method' and f.type == 'list-single':
- values = [o[1] for o in f.options]
- self.file_props['stream-methods'] = ' '.join(values)
- if xmpp.NS_BYTESTREAM in values or xmpp.NS_IBB in values:
- break
+ if self.jingle_content:
+ self.file_props['session-type'] = 'jingle'
+ self.file_props['stream-methods'] = xmpp.NS_BYTESTREAM
+ file_tag = self.jingle_content.getTag('description').getTag(
+ 'offer').getTag('file')
else:
- self.conn.send_file_rejection(self.file_props, code='400',
typ='stream')
- raise xmpp.NodeProcessed
- file_tag = si.getTag('file')
+ si = self.stanza.getTag('si')
+ profile = si.getAttr('profile')
+ if profile != xmpp.NS_FILE:
+ self.conn.send_file_rejection(self.file_props, code='400',
+ typ='profile')
+ raise xmpp.NodeProcessed
+ feature_tag = si.getTag('feature', namespace=xmpp.NS_FEATURE)
+ if not feature_tag:
+ return
+ form_tag = feature_tag.getTag('x', namespace=xmpp.NS_DATA)
+ if not form_tag:
+ return
+ self.dataform = dataforms.ExtendForm(node=form_tag)
+ for f in self.dataform.iter_fields():
+ if f.var == 'stream-method' and f.type == 'list-single':
+ values = [o[1] for o in f.options]
+ self.file_props['stream-methods'] = ' '.join(values)
+ if xmpp.NS_BYTESTREAM in values or xmpp.NS_IBB in values:
+ break
+ else:
+ self.conn.send_file_rejection(self.file_props, code='400',
+ typ='stream')
+ raise xmpp.NodeProcessed
+ file_tag = si.getTag('file')
for attribute in file_tag.getAttrs():
if attribute in ('name', 'size', 'hash', 'date'):
val = file_tag.getAttr(attribute)
@@ -1940,13 +1963,41 @@
if file_desc_tag is not None:
self.file_props['desc'] = file_desc_tag.getData()
- mime_type = si.getAttr('mime-type')
- if mime_type is not None:
- self.file_props['mime-type'] = mime_type
+ if not self.jingle_content:
+ mime_type = si.getAttr('mime-type')
+ if mime_type is not None:
+ self.file_props['mime-type'] = mime_type
self.file_props['receiver'] = self.conn._ft_get_our_jid()
- self.file_props['sid'] = unicode(si.getAttr('id'))
self.file_props['transfered_size'] = []
+ if self.jingle_content:
+ self.FT_content.use_security = bool(self.jingle_content.getTag(
+ 'security'))
+ self.file_props['session-sid'] = unicode(self.stanza.getTag(
+ 'jingle').getAttr('sid'))
+
+ self.FT_content.file_props = self.file_props
+ if not self.FT_content.transport:
+ self.FT_content.transport = JingleTransportSocks5()
+ self.FT_content.transport.set_our_jid(
+ self.FT_content.session.ourjid)
_______________________________________________
Commits mailing list
[email protected]
http://lists.gajim.org/cgi-bin/listinfo/commits