示例#1
0
    def assert_contact_is_in_roster(self, jid, account):
        contacts = gajim.contacts.get_contacts(account, jid)
        # check for all resources
        for contact in contacts:
            iters = self.roster._get_contact_iter(jid, account,
                    model=self.roster.model)

            if jid != gajim.get_jid_from_account(account):
                # We don't care for groups of SelfContact
                self.assertTrue(len(iters) == len(contact.get_shown_groups()),
                        msg='Contact is not in all his groups')

            # Are we big brother?
            bb_jid = None
            bb_account = None
            family = gajim.contacts.get_metacontacts_family(account, jid)
            if family:
                nearby_family, bb_jid, bb_account = \
                        self.roster._get_nearby_family_and_big_brother(family, account)

                is_in_nearby_family = (jid, account) in (
                        (data['jid'], data['account']) for data in nearby_family)
                self.assertTrue(is_in_nearby_family,
                        msg='Contact not in his own nearby family')

            is_big_brother = (bb_jid, bb_account) == (jid, account)

            # check for each group tag
            for titerC in iters:
                self.assertTrue(self.roster.model.iter_is_valid(titerC),
                        msg='Contact iter invalid')

                c_model = self.roster.model[titerC]
                # name can be stricked if contact or group is blocked
#                self.assertEquals(contact.get_shown_name(), c_model[self.C_NAME],
#                        msg='Contact name missmatch')
                self.assertEquals(contact.jid, c_model[self.C_JID],
                        msg='Jid missmatch')

                if not self.roster.regroup:
                    self.assertEquals(account, c_model[self.C_ACCOUNT],
                            msg='Account missmatch')

                # Check for correct nesting
                parent_iter = self.roster.model.iter_parent(titerC)
                p_model = self.roster.model[parent_iter]
                if family:
                    if is_big_brother:
                        self.assertTrue(p_model[self.C_TYPE] == 'group',
                                msg='Big Brother is not on top')
                    else:
                        self.assertTrue(p_model[self.C_TYPE] == 'contact',
                                msg='Little Brother brother has no BigB')
                else:
                    if jid == gajim.get_jid_from_account(account):
                        self.assertTrue(p_model[self.C_TYPE] == 'account',
                                msg='SelfContact is not on top')
                    else:
                        self.assertTrue(p_model[self.C_TYPE] == 'group',
                                msg='Contact not found in a group')
示例#2
0
文件: pep.py 项目: kevin-teddy/gajim
def delete_pep(jid, name):
	(user, resource) = gajim.get_room_and_nick_from_fjid(jid)

	if jid == gajim.get_jid_from_account(name):
		acc = gajim.connections[name]
		del acc.activity
		acc.activity = {}
		del acc.tune
		acc.tune = {}
		del acc.mood
		acc.mood = {}

	for contact in gajim.contacts.get_contacts(name, user):
		del contact.activity
		contact.activity = {}
		del contact.tune
		contact.tune = {}
		del contact.mood
		contact.mood = {}

	if jid == gajim.get_jid_from_account(name):
		gajim.interface.roster.draw_account(name)

	gajim.interface.roster.draw_activity(user, name)
	gajim.interface.roster.draw_tune(user, name)
	gajim.interface.roster.draw_mood(user, name)
	ctrl = gajim.interface.msg_win_mgr.get_control(user, name)
	if ctrl:
		ctrl.update_activity()
		ctrl.update_tune()
		ctrl.update_mood()
示例#3
0
文件: pep.py 项目: kevin-teddy/gajim
def user_mood(items, name, jid):
	has_child = False
	retract = False
	mood = None
	text = None
	for item in items.getTags('item'):
		child = item.getTag('mood')
		if child is not None:
			has_child = True
			for ch in child.getChildren():
				if ch.getName() != 'text':
					mood = ch.getName()
				else:
					text = ch.getData()
	if items.getTag('retract') is not None:
		retract = True

	if jid == gajim.get_jid_from_account(name):
		acc = gajim.connections[name]
		if has_child:
			if 'mood' in acc.mood:
				del acc.mood['mood']
			if 'text' in acc.mood:
				del acc.mood['text']
			if mood is not None:
				acc.mood['mood'] = mood
			if text is not None:
				acc.mood['text'] = text
		elif retract:
			if 'mood' in acc.mood:
				del acc.mood['mood']
			if 'text' in acc.mood:
				del acc.mood['text']

	(user, resource) = gajim.get_room_and_nick_from_fjid(jid)
	for contact in gajim.contacts.get_contacts(name, user):
		if has_child:
			if 'mood' in contact.mood:
				del contact.mood['mood']
			if 'text' in contact.mood:
				del contact.mood['text']
			if mood is not None:
				contact.mood['mood'] = mood
			if text is not None:
				contact.mood['text'] = text
		elif retract:
			if 'mood' in contact.mood:
				del contact.mood['mood']
			if 'text' in contact.mood:
				del contact.mood['text']

	if jid == gajim.get_jid_from_account(name):
		gajim.interface.roster.draw_account(name)
	gajim.interface.roster.draw_mood(user, name)
	ctrl = gajim.interface.msg_win_mgr.get_control(user, name)
	if ctrl:
		ctrl.update_mood()
示例#4
0
    def handle_devicelist_result(self, account, stanza):
        """ If query was successful add own device to the list.

            Parameters
            ----------
            account : str
                the account name
            stanza
                The stanza object received from callback
        """

        my_jid = gajim.get_jid_from_account(account)
        state = self.get_omemo_state(account)

        if successful(stanza):
            log.info(account + ' => Devicelistquery was successful')
            devices_list = unpack_device_list_update(stanza, account)
            if len(devices_list) == 0:
                return False
            contact_jid = stanza.getAttr('from')
            if contact_jid == my_jid:
                state.set_own_devices(devices_list)
                state.store.sessionStore.setActiveState(devices_list, my_jid)

                if not state.own_device_id_published() or anydup(
                        state.own_devices):
                    # Our own device_id is not in the list, it could be
                    # overwritten by some other client?
                    # Is a Device ID duplicated?
                    self.publish_own_devices_list(account, state)
        else:
            log.error(account + ' => Devicelistquery was NOT successful')
            self.publish_own_devices_list(account, state)
示例#5
0
    def handle_outgoing_stanza(self, event):
        if not event.msg_iq.getTag('body'):
            return
        plaintext = event.msg_iq.getBody().encode('utf8')
        account = event.conn.name
        state = self.get_omemo_state(account)
        full_jid = str(event.msg_iq.getAttr('to'))
        to_jid = gajim.get_jid_without_resource(full_jid)
        if not state.encryption.is_active(to_jid):
            return False

        if not state.store.identityKeyStore.getTrustedFingerprints(to_jid):
                msg = "To send an encrypted message, you have to " \
                      "first trust the fingerprint of your contact!"
                if account in self.ui_list and \
                        to_jid in self.ui_list[account]:
                    self.ui_list[account][to_jid].chat_control. \
                        print_conversation_line(msg, 'status', '', None)

                return True

        try:
            msg_dict = state.create_msg(
                gajim.get_jid_from_account(account), to_jid, plaintext)
            if not msg_dict:
                return True

            encrypted_node = OmemoMessage(msg_dict)
            event.msg_iq.delChild('body')
            event.msg_iq.addChild(node=encrypted_node)
            store = Node('store', attrs={'xmlns': NS_HINTS})
            event.msg_iq.addChild(node=store)
            log.debug(account + ' => ' + str(event.msg_iq))
        except:
            return True
示例#6
0
 def __init__(self, plugin, accountname):
     global PROTOCOL, MMS
     self.plugin = plugin
     self.accountname = accountname
     name = gajim.get_jid_from_account(accountname)
     super(GajimOtrAccount, self).__init__(name, PROTOCOL, MMS)
     self.keyFilePath = os.path.join(gajim.gajimpaths.data_root, accountname)
示例#7
0
    def get_omemo_state(self, account):
        """ Returns the the OmemoState for the specified account.
            Creates the OmemoState if it does not exist yet.

            Parameters
            ----------
            account : str
                the account name

            Returns
            -------
            OmemoState
        """
        if account in self.disabled_accounts:
            return
        if account not in self.omemo_states:
            self.deactivate_gajim_e2e(account)
            my_jid = gajim.get_jid_from_account(account)
            db_path = self.migrate_dbpath(account, my_jid)

            conn = sqlite3.connect(db_path, check_same_thread=False)
            self.omemo_states[account] = OmemoState(my_jid, conn, account,
                                                    self.plugin)

        return self.omemo_states[account]
示例#8
0
 def omemo_send_gc_message(message, xhtml=None, process_commands=True):
     self.new_fingerprints_available()
     if self.encryption_active():
         missing = True
         own_jid = gajim.get_jid_from_account(self.account)
         for nick in self.plugin.groupchat[self.room]:
             real_jid = self.plugin.groupchat[self.room][nick]
             if real_jid == own_jid:
                 continue
             if not self.plugin.are_keys_missing(self.account,
                                                 real_jid):
                 missing = False
         if missing:
             log.debug(self.account +
                       ' => No Trusted Fingerprints for ' +
                       self.room)
             self.no_trusted_fingerprints_warning()
         else:
             self.chat_control.orig_send_message(message, xhtml,
                                                 process_commands)
             log.debug(self.account + ' => Sending Message to ' +
                       self.room)
     else:
         self.chat_control.orig_send_message(message, xhtml,
                                             process_commands)
         log.debug(self.account + ' => Sending Message to ' +
                   self.room)
示例#9
0
文件: logger.py 项目: gajim/gajim
    def replace_roster(self, account_name, roster_version, roster):
        """
        Replace current roster in DB by a new one

        accout_name is the name of the account to change.
        roster_version is the version of the new roster.
        roster is the new version.
        """
        # First we must reset roster_version value to ensure that the server
        # sends back all the roster at the next connexion if the replacement
        # didn't work properly.
        gajim.config.set_per('accounts', account_name, 'roster_version', '')

        account_jid = gajim.get_jid_from_account(account_name)
        account_jid_id = self.get_jid_id(account_jid)

        # Delete old roster
        self.remove_roster(account_jid)

        # Fill roster tables with the new roster
        for jid in roster:
            self.add_or_update_contact(account_jid, jid, roster[jid]['name'],
                roster[jid]['subscription'], roster[jid]['ask'],
                roster[jid]['groups'], commit=False)
        self._timeout_commit()

        # At this point, we are sure the replacement works properly so we can
        # set the new roster_version value.
        gajim.config.set_per('accounts', account_name, 'roster_version',
            roster_version)
示例#10
0
    def connect_ui(self, chat_control):
        """ Method called from Gajim when a Chat Window is opened

            Parameters
            ----------
            chat_control : ChatControl
                Gajim ChatControl object
        """
        account = chat_control.contact.account.name
        if account in self.disabled_accounts:
            return
        contact_jid = chat_control.contact.jid
        if account not in self.ui_list:
            self.ui_list[account] = {}
        state = self.get_omemo_state(account)
        my_jid = gajim.get_jid_from_account(account)
        omemo_enabled = state.encryption.is_active(contact_jid)
        if omemo_enabled:
            log.debug(account + " => Adding OMEMO ui for " + contact_jid)
            self.ui_list[account][contact_jid] = Ui(self, chat_control,
                                                    omemo_enabled, state)
            self.ui_list[account][contact_jid].new_fingerprints_available()
            return
        if contact_jid in state.device_ids or contact_jid == my_jid:
            log.debug(account + " => Adding OMEMO ui for " + contact_jid)
            self.ui_list[account][contact_jid] = Ui(self, chat_control,
                                                    omemo_enabled, state)
            self.ui_list[account][contact_jid].new_fingerprints_available()
        else:
            log.warning(account + " => No devices for " + contact_jid)

        if chat_control.type_id == message_control.TYPE_GC:
            self.ui_list[account][contact_jid] = Ui(self, chat_control,
                                                    omemo_enabled, state)
            self.ui_list[account][contact_jid].sensitive(False)
示例#11
0
    def __init__(self, account, transient_for=None):
        self.xml = gtkgui_helpers.get_gtk_builder('profile_window.ui')
        self.window = self.xml.get_object('profile_window')
        self.window.set_transient_for(transient_for)
        self.progressbar = self.xml.get_object('progressbar')
        self.statusbar = self.xml.get_object('statusbar')
        self.context_id = self.statusbar.get_context_id('profile')

        self.account = account
        self.jid = gajim.get_jid_from_account(account)

        self.dialog = None
        self.avatar_mime_type = None
        self.avatar_encoded = None
        self.message_id = self.statusbar.push(self.context_id,
            _('Retrieving profile...'))
        self.update_progressbar_timeout_id = GLib.timeout_add(100,
            self.update_progressbar)
        self.remove_statusbar_timeout_id = None

        # Create Image for avatar button
        image = Gtk.Image()
        self.xml.get_object('PHOTO_button').set_image(image)
        self.xml.connect_signals(self)
        gajim.ged.register_event_handler('vcard-published', ged.GUI1,
            self._nec_vcard_published)
        gajim.ged.register_event_handler('vcard-not-published', ged.GUI1,
            self._nec_vcard_not_published)
        gajim.ged.register_event_handler('vcard-received', ged.GUI1,
            self._nec_vcard_received)
        self.window.show_all()
        self.xml.get_object('ok_button').grab_focus()
示例#12
0
    def handle_device_list_update(self, event):
        """ Check if the passed event is a device list update and store the new
            device ids.

            Parameters
            ----------
            event : MessageReceivedEvent

            Returns
            -------
            bool
                True if the given event was a valid device list update event


            See also
            --------
            4.2 Discovering peer support
                http://conversations.im/xeps/multi-end.html#usecases-discovering
        """
        if event.pep_type != 'headline':
            return False

        devices_list = unpack_device_list_update(event.stanza, event.conn.name)
        if len(devices_list) == 0:
            return False
        account_name = event.conn.name
        contact_jid = gajim.get_jid_without_resource(event.fjid)
        state = self.get_omemo_state(account_name)
        my_jid = gajim.get_jid_from_account(account_name)

        if contact_jid == my_jid:
            log.info(account_name + ' => Received own device list:' + str(
                devices_list))
            state.set_own_devices(devices_list)
            state.store.sessionStore.setActiveState(devices_list, my_jid)

            if not state.own_device_id_published() or anydup(
                    state.own_devices):
                # Our own device_id is not in the list, it could be
                # overwritten by some other client?
                # Is a Device ID duplicated?
                self.publish_own_devices_list(account_name, state)
        else:
            log.info(account_name + ' => Received device list for ' +
                     contact_jid + ':' + str(devices_list))
            state.set_devices(contact_jid, set(devices_list))
            state.store.sessionStore.setActiveState(devices_list, contact_jid)
            if (account_name in self.ui_list and
                    contact_jid not in self.ui_list[account_name]):

                chat_control = gajim.interface.msg_win_mgr.get_control(
                    contact_jid, account_name)

                if chat_control is not None:
                    self.connect_ui(chat_control)

        # Look if Device Keys are missing and fetch them
        self.are_keys_missing(account_name, contact_jid)

        return True
示例#13
0
    def forget_button_clicked_cb(self, button, *args):
        accounts = {}
        for acc in gajim.connections.iterkeys():
            accounts[gajim.get_jid_from_account(acc)] = acc

        tw = self.B.get_object('fingerprint_view')

        mod, paths = tw.get_selection().get_selected_rows()

        for path in paths:
            it = mod.get_iter(path)
            user, human_fpr, a, fpr = mod.get(it, 0, 3, 4, 6)

            dlg = gtk.Dialog('Confirm removal of fingerprint', self,
                    gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
                        (gtk.STOCK_YES, gtk.RESPONSE_YES,
                        gtk.STOCK_NO, gtk.RESPONSE_NO)
                    )
            l = gtk.Label()
            l.set_markup('Are you sure you want remove the following '
                    'fingerprint for the contact %s on the account %s?'
                    '\n\n%s' % (user, a, human_fpr))
            l.set_line_wrap(True)
            dlg.vbox.pack_start(l)
            dlg.show_all()

            if dlg.run() == gtk.RESPONSE_YES:
                ctx = self.plugin.us[accounts[a]].getContext(user)
                ctx.removeFingerprint(fpr)
            dlg.destroy()
            self.plugin.us[accounts[a]].saveTrusts()

        self.plugin.update_context_list()
示例#14
0
 def query_own_devicelist(self, account):
     my_jid = gajim.get_jid_from_account(account)
     iq = DevicelistQuery(my_jid)
     gajim.connections[account].connection.send(iq)
     log.info(account + ' => Querry own devicelist ...')
     id_ = str(iq.getAttr("id"))
     iq_ids_to_callbacks[id_] = lambda stanza: \
         self.handle_devicelist_result(account, stanza)
示例#15
0
 def __init__(self, account, plugin):
     self.account = account
     self.plugin = plugin
     self.conn = gajim.connections[self.account]
     # get our jid with resource
     ourjid = gajim.get_jid_from_account(self.account)
     Protocol.__init__(self, ourjid)
     self.fsw = None
示例#16
0
 def are_keys_missing(self, contact):
     """ Used by the ui to set the state of the PreKeyButton. """
     account = contact.account.name
     my_jid = gajim.get_jid_from_account(account)
     state = self.get_omemo_state(account)
     result = 0
     result += len(state.devices_without_sessions(str(contact.jid)))
     result += len(state.own_devices_without_sessions(my_jid))
     return result
示例#17
0
    def fill_treeview(self):
        # Account-JID, RoomName, Room-JID, Autojoin, Minimize, Passowrd, Nick,
        # Show_Status
        self.treestore = gtk.TreeStore(str, str, str, bool, bool, str, str, str)
        self.treestore.set_sort_column_id(1, gtk.SORT_ASCENDING)
        self.accounts = []
        self.jids = []

        # Store bookmarks in treeview.
        for account in gajim.connections:
            if gajim.connections[account].connected <= 1:
                continue
            if gajim.connections[account].is_zeroconf:
                continue

            self.accounts.append(account)
            self.jids.append(gajim.get_jid_from_account(account))
            iter_ = self.treestore.append(None, [None, account, None, None,
                    None, None, None, None])

            for bookmark in gajim.connections[account].bookmarks:
                if bookmark['name'] == '':
                    # No name was given for this bookmark.
                    # Use the first part of JID instead...
                    name = bookmark['jid'].split("@")[0]
                    bookmark['name'] = name
                from common import helpers
                # make '1', '0', 'true', 'false' (or other) to True/False
                autojoin = helpers.from_xs_boolean_to_python_boolean(
                        bookmark['autojoin'])

                minimize = helpers.from_xs_boolean_to_python_boolean(
                        bookmark['minimize'])

                print_status = bookmark.get('print_status', '')
                if print_status not in ('', 'all', 'in_and_out', 'none'):
                    print_status = ''
                self.treestore.append(iter_, [
                                account,
                                bookmark['name'],
                                bookmark['jid'],
                                autojoin,
                                minimize,
                                bookmark['password'],
                                bookmark['nick'],
                                print_status ])

        self.view = self.xml.get_object('bookmarks_treeview')
        self.view.set_model(self.treestore)
        self.view.expand_all()

        renderer = gtk.CellRendererText()
        column = gtk.TreeViewColumn('Bookmarks', renderer, text=1)
        if self.view.get_column(0):
            self.view.remove_column(self.view.get_column(0))
        self.view.append_column(column)
示例#18
0
    def query_prekey(self, contact):
        account = contact.account.name
        state = self.get_omemo_state(account)
        to_jid = contact.jid
        my_jid = gajim.get_jid_from_account(account)
        for device_id in state.devices_without_sessions(to_jid):
            self.fetch_device_bundle_information(state, to_jid, device_id)

        for device_id in state.own_devices_without_sessions(my_jid):
            self.fetch_device_bundle_information(state, my_jid, device_id)
示例#19
0
    def handle_device_list_update(self, event):
        """ Check if the passed event is a device list update and store the new
            device ids.

            Parameters
            ----------
            event : MessageReceivedEvent

            Returns
            -------
            bool
                True if the given event was a valid device list update event


            See also
            --------
            4.2 Discovering peer support
                http://conversations.im/xeps/multi-end.html#usecases-discovering
        """
        if event.pep_type != 'headline':
            return False

        devices_list = unpack_device_list_update(event)
        if len(devices_list) == 0:
            return False
        account = event.conn.name
        contact_jid = gajim.get_jid_without_resource(event.fjid)
        state = self.get_omemo_state(account)
        my_jid = gajim.get_jid_from_account(account)

        log.debug(account + ' ⇒ Received OMEMO pep for jid ' + contact_jid)

        if contact_jid == my_jid:
            log.debug(state.name + ' ⇒ Received own device_list ' + str(
                devices_list))
            state.add_own_devices(devices_list)

            if not state.own_device_id_published() or anydup(
                    state.own_devices):
                # Our own device_id is not in the list, it could be
                # overwritten by some other client?
                # also remove duplicates
                devices_list = list(set(state.own_devices))
                devices_list.append(state.own_device_id)
                self.publish_own_devices_list(state)
        else:
            state.add_devices(contact_jid, devices_list)
            if account in self.ui_list and contact_jid in self.ui_list[
                    account]:
                self.ui_list[account][contact_jid].toggle_omemo(True)

        self.update_prekeys(account, contact_jid)

        return True
示例#20
0
文件: pubsub.py 项目: gajim/gajim
    def send_pb_unsubscribe(self, jid, node, cb, *args, **kwargs):
        if not self.connection or self.connected < 2:
            return
        our_jid = gajim.get_jid_from_account(self.name)
        query = nbxmpp.Iq('set', to=jid)
        pb = query.addChild('pubsub', namespace=nbxmpp.NS_PUBSUB)
        pb.addChild('unsubscribe', {'node': node, 'jid': our_jid})

        id_ = self.connection.send(query)

        self.__callbacks[id_] = (cb, args, kwargs)
示例#21
0
    def get_omemo_state(self, account):
        """ Returns the the OmemoState for specified account. Creates the
            OmemoState if it does not exist yet.
        """
        if account not in self.omemo_states:
            self.deactivate_gajim_e2e(account)
            db_path = os.path.join(DB_DIR, 'omemo_' + account + '.db')
            conn = sqlite3.connect(db_path, check_same_thread=False)

            my_jid = gajim.get_jid_from_account(account)

            self.omemo_states[account] = OmemoState(my_jid, conn, account)
        return self.omemo_states[account]
示例#22
0
    def are_keys_missing(self, account, contact_jid):
        """ Checks if devicekeys are missing and querys the
            bundles

            Parameters
            ----------
            account : str
                the account name
            contact_jid : str
                bare jid of the contact

            Returns
            -------
            bool
                Returns True if there are no trusted Fingerprints
        """
        state = self.get_omemo_state(account)
        my_jid = gajim.get_jid_from_account(account)

        # Fetch Bundles of own other Devices
        if my_jid not in self.query_for_bundles:

            devices_without_session = state \
                .devices_without_sessions(my_jid)

            self.query_for_bundles.append(my_jid)

            if devices_without_session:
                for device_id in devices_without_session:
                    self.fetch_device_bundle_information(account, my_jid,
                                                         device_id)

        # Fetch Bundles of contacts devices
        if contact_jid not in self.query_for_bundles:

            devices_without_session = state \
                .devices_without_sessions(contact_jid)

            self.query_for_bundles.append(contact_jid)

            if devices_without_session:
                for device_id in devices_without_session:
                    self.fetch_device_bundle_information(account, contact_jid,
                                                         device_id)

        if state.getTrustedFingerprints(contact_jid):
            return False
        else:
            return True
示例#23
0
	def account_info(self, account):
		'''show info on account: resource, jid, nick, prio, message'''
		result = DBUS_DICT_SS()
		if account in gajim.connections:
			# account is valid
			con = gajim.connections[account]
			index = con.connected
			result['status'] = DBUS_STRING(gajim.SHOW_LIST[index])
			result['name'] = DBUS_STRING(con.name)
			result['jid'] = DBUS_STRING(gajim.get_jid_from_account(con.name))
			result['message'] = DBUS_STRING(con.status)
			result['priority'] = DBUS_STRING(unicode(con.priority))
			result['resource'] = DBUS_STRING(unicode(gajim.config.get_per(
				'accounts', con.name, 'resource')))
		return result
示例#24
0
    def query_prekey(self, recipient):
        """ Calls OmemoPlugin.fetch_device_bundle_information() for each own or
            recipient device key missing.
        """
        account = recipient.account.name
        state = self.get_omemo_state(account)
        to_jid = recipient.jid
        my_jid = gajim.get_jid_from_account(account)
        for device_id in state.devices_without_sessions(to_jid):
            self.fetch_device_bundle_information(account, state, to_jid,
                                                 device_id)

        for device_id in state.own_devices_without_sessions(my_jid):
            self.fetch_device_bundle_information(account, state, my_jid,
                                                 device_id)
示例#25
0
    def query_own_devicelist(self, account):
        """ Query own devicelist from the server.

            Parameters
            ----------
            account : str
                the account name
        """
        my_jid = gajim.get_jid_from_account(account)
        iq = DevicelistQuery(my_jid)
        gajim.connections[account].connection.send(iq)
        log.info(account + ' => Querry own devicelist ...')
        id_ = str(iq.getAttr("id"))
        IQ_CALLBACK[id_] = lambda stanza: \
            self.handle_devicelist_result(account, stanza)
示例#26
0
    def assert_account_is_in_roster(self, acc):
        titerA = self.roster._get_account_iter(acc, model=self.roster.model)
        self.assertTrue(self.roster.model.iter_is_valid(titerA),
                msg='Account iter is invalid')

        acc_model = self.roster.model[titerA]
        self.assertEquals(acc_model[self.C_TYPE], 'account',
                msg='No account found')

        if not self.roster.regroup:
            self.assertEquals(acc_model[self.C_ACCOUNT], acc,
                    msg='Account not found')

            self_jid = gajim.get_jid_from_account(acc)
            self.assertEquals(acc_model[self.C_JID], self_jid,
                    msg='Account JID not found in account row')
示例#27
0
    def handle_incoming_msg(self, event):
        ctx = None
        account = event.conn.name
        accjid = gajim.get_jid_from_account(account)

        if event.encrypted is not False or not event.stanza.getTag('body') \
        or not isinstance(event.stanza.getBody(), unicode):
            return PASS

        try:
            ctx = self.us[account].getContext(event.fjid)
            msgtxt, tlvs = ctx.receiveMessage(event.msgtxt,
                            appdata={'session':event.session})
        except potr.context.NotOTRMessage, e:
            # received message was not OTR - pass it on
            return PASS
示例#28
0
    def pep_received(self, obj):
        if obj.jid != gajim.get_jid_from_account(obj.conn.name):
            return

        pep_dict = gajim.connections[obj.conn.name].pep
        if  obj.pep_type == 'mood':
            img = self.xml.get_object('mood_image')
            if 'mood' in pep_dict:
                img.set_from_pixbuf(pep_dict['mood'].asPixbufIcon())
            else:
                img.set_from_stock('gtk-stop', gtk.ICON_SIZE_MENU)
        if  obj.pep_type == 'activity':
            img = self.xml.get_object('activity_image')
            if 'activity' in pep_dict:
                img.set_from_pixbuf(pep_dict['activity'].asPixbufIcon())
            else:
                img.set_from_stock('gtk-stop', gtk.ICON_SIZE_MENU)
示例#29
0
文件: ui.py 项目: gsathya/gotr
    def verify_button_clicked_cb(self, button, *args):
        accounts = {}
        for acc in gajim.connections.iterkeys():
            accounts[gajim.get_jid_from_account(acc)] = acc

        mod, paths = self.fpr_view.get_selection().get_selected_rows()

        # open the window for the first selected row
        for path in paths[0:1]:
            it = mod.get_iter(path)
            fjid, fpr, a = mod.get(it, 0, 6, 4)

            ctx = self.plugin.us[accounts[a]].getContext(fjid)

            dlg = ContactOtrWindow(self.plugin, ctx, fpr=fpr, parent=self)
            dlg.run()
            dlg.destroy()
            break
示例#30
0
    def handle_incoming_msg(self, event):
        ctx = None
        account = event.conn.name
        accjid = gajim.get_jid_from_account(account)

        if event.encrypted is not False or not event.stanza.getTag('body') \
        or not isinstance(event.stanza.getBody(), unicode):
            return PASS

        try:
            ctx = self.us[account].getContext(event.fjid)
            msgtxt, tlvs = ctx.receiveMessage(event.msgtxt,
                            appdata={'session':event.session})
        except potr.context.UnencryptedMessage, e:
            tlvs = []
            msgtxt = _('The following message received from %(jid)s was '
                    '*not encrypted*: [%(error)s]') % {'jid': event.fjid,
                    'error': e.args[0]}
示例#31
0
 def __init__(self, con, weinitiate, jid, iq_id=None, sid=None,
             werequest=False):
     """
     con -- connection object,
     weinitiate -- boolean, are we the initiator?
     jid - jid of the other entity
     """
     self.contents = {} # negotiated contents
     self.connection = con # connection to use
     # our full jid
     self.ourjid = gajim.get_jid_from_account(self.connection.name)
     if con.server_resource:
         self.ourjid = self.ourjid + '/' + con.server_resource
     self.peerjid = jid # jid we connect to
     # jid we use as the initiator
     self.initiator = weinitiate and self.ourjid or self.peerjid
     # jid we use as the responder
     self.responder = weinitiate and self.peerjid or self.ourjid
     # are we an initiator?
     self.weinitiate = weinitiate
     # Are we requesting or offering a file?
     self.werequest = werequest
     self.request = False
     # what state is session in? (one from JingleStates)
     self.state = JingleStates.ended
     if not sid:
         sid = con.connection.getAnID()
     self.sid = sid # sessionid
     # iq stanza id, used to determine which sessions to summon callback
     # later on when iq-result stanza arrives
     if iq_id is not None:
         self.iq_ids = [iq_id]
     else:
         self.iq_ids = []
     self.accepted = True # is this session accepted by user
     # Tells whether this session is a file transfer or not
     self.session_type_FT = False
     # callbacks to call on proper contents
     # use .prepend() to add new callbacks, especially when you're going
     # to send error instead of ack
     self.callbacks = {
             'content-accept':       [self.__ack, self.__on_content_accept,
                                      self.__broadcast],
             'content-add':          [self.__ack,
                                     self.__on_content_add, self.__broadcast
                                     ], #TODO
             'content-modify':       [self.__ack], #TODO
             'content-reject':       [self.__ack, self.__on_content_remove],
             'content-remove':       [self.__ack, self.__on_content_remove],
             'description-info':     [self.__ack, self.__broadcast], #TODO
             'security-info':        [self.__ack], #TODO
             'session-accept':       [self.__ack, self.__on_session_accept,
                                      self.__on_content_accept,
                                      self.__broadcast],
             'session-info':         [self.__ack, self.__broadcast,
                                      self.__on_session_info ],
             'session-initiate':     [self.__ack, self.__on_session_initiate,
                                      self.__broadcast],
             'session-terminate':    [self.__ack,self.__on_session_terminate,
                                      self.__broadcast_all],
             'transport-info':       [self.__ack, self.__broadcast],
             'transport-replace':    [self.__ack, self.__broadcast,
                                      self.__on_transport_replace], #TODO
             'transport-accept':     [self.__ack], #TODO
             'transport-reject':     [self.__ack], #TODO
             'iq-result':            [self.__broadcast],
             'iq-error':             [self.__on_error],
     }
示例#32
0
 def _ft_get_our_jid(self):
     our_jid = gajim.get_jid_from_account(self.name)
     resource = self.server_resource
     return our_jid + '/' + resource
示例#33
0
    def update_button_state(self, chat_control):
        global jid_to_servers
        global iq_ids_to_callbacks
        global last_info_query

        if gajim.connections[chat_control.account].connection == None and \
            gajim.get_jid_from_account(chat_control.account) in jid_to_servers:
            # maybe don't delete this and detect vanished upload components when actually trying to upload something
            log.info("Deleting %s from jid_to_servers (disconnected)" %
                     gajim.get_jid_from_account(chat_control.account))
            del jid_to_servers[gajim.get_jid_from_account(
                chat_control.account)]
            #pass

        # query info at most every 60 seconds in case something goes wrong
        if (not chat_control.account in last_info_query or \
            last_info_query[chat_control.account] + 60 < time.time()) and \
            not gajim.get_jid_from_account(chat_control.account) in jid_to_servers and \
            gajim.account_is_connected(chat_control.account):
            log.info(
                "Account %s: Using dicovery to find jid of httpupload component"
                % chat_control.account)
            id_ = gajim.get_an_id()
            iq = nbxmpp.Iq(typ='get',
                           to=gajim.get_server_from_jid(
                               gajim.get_jid_from_account(
                                   chat_control.account)),
                           queryNS="http://jabber.org/protocol/disco#items")
            iq.setID(id_)

            def query_info(stanza):
                global last_info_query
                for item in stanza.getTag("query").getTags("item"):
                    id_ = gajim.get_an_id()
                    iq = nbxmpp.Iq(
                        typ='get',
                        to=item.getAttr("jid"),
                        queryNS="http://jabber.org/protocol/disco#info")
                    iq.setID(id_)
                    last_info_query[chat_control.account] = time.time()
                    gajim.connections[chat_control.account].connection.send(iq)

            iq_ids_to_callbacks[str(id_)] = query_info
            gajim.connections[chat_control.account].connection.send(iq)
            #send disco query to main server jid
            id_ = gajim.get_an_id()
            iq = nbxmpp.Iq(typ='get',
                           to=gajim.get_server_from_jid(
                               gajim.get_jid_from_account(
                                   chat_control.account)),
                           queryNS="http://jabber.org/protocol/disco#info")
            iq.setID(id_)
            last_info_query[chat_control.account] = time.time()
            gajim.connections[chat_control.account].connection.send(iq)

        for base in self.controls:
            if base.chat_control == chat_control:
                is_supported = gajim.get_jid_from_account(chat_control.account) in jid_to_servers and \
                    gajim.connections[chat_control.account].connection != None
                log.info("Account %s: httpupload is_supported: %s" %
                         (str(chat_control.account), str(is_supported)))
                if not is_supported:
                    text = _('Your server does not support http uploads')
                    image_text = text
                else:
                    text = _('Send file via http upload')
                    image_text = _('Send image via http upload')
                base.button.set_sensitive(is_supported)
                base.button.set_tooltip_text(text)
                base.image_button.set_sensitive(is_supported)
                base.image_button.set_tooltip_text(image_text)
示例#34
0
    def on_file_dialog_ok(self, widget, path_to_file=None):
        global jid_to_servers

        try:
            self.encrypted_upload = self.encryption_activated()
        except Exception as e:
            log.debug(e)
            self.encrypted_upload = False

        if not path_to_file:
            path_to_file = self.dlg.get_filename()
            if not path_to_file:
                self.dlg.destroy()
                return
            path_to_file = gtkgui_helpers.decode_filechooser_file_paths(
                (path_to_file, ))[0]
        self.dlg.destroy()
        if not os.path.exists(path_to_file):
            return
        if self.encrypted_upload:
            filesize = os.path.getsize(path_to_file) + TAGSIZE  # in bytes
        else:
            filesize = os.path.getsize(path_to_file)
        invalid_file = False
        msg = ''
        if os.path.isfile(path_to_file):
            stat = os.stat(path_to_file)
            if stat[6] == 0:
                invalid_file = True
                msg = _('File is empty')
        else:
            invalid_file = True
            msg = _('File does not exist')
        if invalid_file:
            ErrorDialog(_('Could not open file'),
                        msg,
                        transient_for=self.chat_control.parent_win.window)
            return

        mime_type = mimetypes.MimeTypes().guess_type(path_to_file)[0]
        if not mime_type:
            mime_type = 'application/octet-stream'  # fallback mime type
        log.info("Detected MIME Type of file: " + str(mime_type))
        progress_messages = Queue(8)
        event = threading.Event()
        progress_window = ProgressWindow(_('Requesting HTTP Upload Slot...'),
                                         progress_messages, self.plugin, event)

        def upload_file(stanza):
            if stanza.getType() == 'error':
                ErrorDialog(_('Could not request upload slot'),
                            stanza.getErrorMsg(),
                            transient_for=self.chat_control.parent_win.window)
                log.error(stanza)
                progress_window.close_dialog()
                return

            slot = stanza.getTag("slot")
            if slot:
                put = slot.getTag("put")
                get = slot.getTag("get")
            else:
                progress_window.close_dialog()
                log.error("got unexpected stanza: " + str(stanza))
                ErrorDialog(_('Could not request upload slot'),
                            _('Got unexpected response from server (see log)'),
                            transient_for=self.chat_control.parent_win.window)
                return

            try:
                if self.encrypted_upload:
                    key = os.urandom(32)
                    iv = os.urandom(16)
                    data = StreamFileWithProgress(
                        path_to_file, "rb", progress_window.update_progress,
                        event, self.encrypted_upload, key, iv)
                else:
                    data = StreamFileWithProgress(
                        path_to_file, "rb", progress_window.update_progress,
                        event)
            except:
                progress_window.close_dialog()
                ErrorDialog(
                    _('Could not open file'),
                    _('Exception raised while opening file (see error log for more information)'
                      ),
                    transient_for=self.chat_control.parent_win.window)
                raise  # fill error log with useful information

            def upload_complete(response_code):
                if isinstance(response_code, str):
                    # We got a error Message
                    ErrorDialog(
                        _('Error'),
                        response_code,
                        transient_for=self.chat_control.parent_win.window)
                    return
                if response_code >= 200 and response_code < 300:
                    log.info("Upload completed successfully")
                    xhtml = None
                    is_image = mime_type.split('/', 1)[0] == 'image'
                    if (not isinstance(self.chat_control, chat_control.ChatControl) or not self.chat_control.gpg_is_active) and \
                        self.dialog_type == 'image' and is_image and not self.encrypted_upload:

                        progress_messages.put(
                            _('Calculating (possible) image thumbnail...'))
                        thumb = None
                        quality_steps = (100, 80, 60, 50, 40, 35, 30, 25, 23,
                                         20, 18, 15, 13, 10, 9, 8, 7, 6, 5, 4,
                                         3, 2, 1)
                        with open(path_to_file, 'rb') as content_file:
                            thumb = urllib2.quote(
                                base64.standard_b64encode(content_file.read()),
                                '')
                        if thumb and len(thumb) < max_thumbnail_size:
                            quality = 100
                            log.info(
                                "Image small enough (%d bytes), not resampling"
                                % len(thumb))
                        elif pil_available:
                            log.info(
                                "PIL available, using it for image downsampling"
                            )
                            try:
                                for quality in quality_steps:
                                    thumb = Image.open(path_to_file)
                                    thumb.thumbnail((max_thumbnail_dimension,
                                                     max_thumbnail_dimension),
                                                    Image.ANTIALIAS)
                                    output = BytesIO()
                                    thumb.save(output,
                                               format='JPEG',
                                               quality=quality,
                                               optimize=True)
                                    thumb = output.getvalue()
                                    output.close()
                                    thumb = urllib2.quote(
                                        base64.standard_b64encode(thumb), '')
                                    log.debug(
                                        "pil thumbnail jpeg quality %d produces an image of size %d..."
                                        % (quality, len(thumb)))
                                    if len(thumb) < max_thumbnail_size:
                                        break
                            except:
                                thumb = None
                        else:
                            thumb = None
                        if not thumb:
                            log.info(
                                "PIL not available, using GTK for image downsampling"
                            )
                            temp_file = None
                            try:
                                with open(path_to_file, 'rb') as content_file:
                                    thumb = content_file.read()
                                loader = gtk.gdk.PixbufLoader()
                                loader.write(thumb)
                                loader.close()
                                pixbuf = loader.get_pixbuf()
                                scaled_pb = self.get_pixbuf_of_size(
                                    pixbuf, max_thumbnail_dimension)
                                handle, temp_file = tempfile.mkstemp(
                                    suffix='.jpeg',
                                    prefix='gajim_httpupload_scaled_tmp',
                                    dir=gajim.TMP)
                                log.debug(
                                    "Saving temporary jpeg image to '%s'..." %
                                    temp_file)
                                os.close(handle)
                                for quality in quality_steps:
                                    scaled_pb.save(temp_file, "jpeg",
                                                   {"quality": str(quality)})
                                    with open(temp_file, 'rb') as content_file:
                                        thumb = content_file.read()
                                    thumb = urllib2.quote(
                                        base64.standard_b64encode(thumb), '')
                                    log.debug(
                                        "gtk thumbnail jpeg quality %d produces an image of size %d..."
                                        % (quality, len(thumb)))
                                    if len(thumb) < max_thumbnail_size:
                                        break
                            except:
                                thumb = None
                            finally:
                                if temp_file:
                                    os.unlink(temp_file)
                        if thumb:
                            if len(thumb) > max_thumbnail_size:
                                log.info(
                                    "Couldn't compress image enough, not sending any thumbnail"
                                )
                            else:
                                log.info(
                                    "Using thumbnail jpeg quality %d (image size: %d bytes)"
                                    % (quality, len(thumb)))
                                xhtml = '<body><br/><a href="%s"> <img alt="%s" src="data:image/png;base64,%s"/> </a></body>' % \
                                    (get.getData(), get.getData(), thumb)
                    progress_window.close_dialog()
                    id_ = gajim.get_an_id()

                    def add_oob_tag():
                        pass

                    if self.encrypted_upload:
                        keyAndIv = '#' + binascii.hexlify(
                            iv) + binascii.hexlify(key)
                        self.chat_control.send_message(message=get.getData() +
                                                       keyAndIv,
                                                       xhtml=None)
                    else:
                        self.chat_control.send_message(message=get.getData(),
                                                       xhtml=xhtml)
                    self.chat_control.msg_textview.grab_focus()
                else:
                    progress_window.close_dialog()
                    log.error("got unexpected http upload response code: " +
                              str(response_code))
                    ErrorDialog(
                        _('Could not upload file'),
                        _('Got unexpected http response code from server: ') +
                        str(response_code),
                        transient_for=self.chat_control.parent_win.window)

            def uploader():
                progress_messages.put(_('Uploading file via HTTP...'))
                try:
                    headers = {
                        'User-Agent': 'Gajim %s' % gajim.version,
                        'Content-Type': mime_type
                    }
                    request = urllib2.Request(put.getData().encode("utf-8"),
                                              data=data,
                                              headers=headers)
                    request.get_method = lambda: 'PUT'
                    log.debug("opening urllib2 upload request...")
                    transfer = urllib2.urlopen(request, timeout=30)
                    log.debug("urllib2 upload request done, response code: " +
                              str(transfer.getcode()))
                    return transfer.getcode()
                except UploadAbortedException as error:
                    log.info('Upload Aborted')
                except Exception as error:
                    gobject.idle_add(progress_window.close_dialog)
                    log.exception('Error')
                return str(error)

            log.info("Uploading file to '%s'..." % str(put.getData()))
            log.info("Please download from '%s' later..." % str(get.getData()))

            gajim.thread_interface(uploader, [], upload_complete)

        is_supported = gajim.get_jid_from_account(self.chat_control.account) in jid_to_servers and \
                    gajim.connections[self.chat_control.account].connection != None
        log.info(
            "jid_to_servers of %s: %s ; connection: %s" %
            (gajim.get_jid_from_account(self.chat_control.account),
             str(jid_to_servers[gajim.get_jid_from_account(
                 self.chat_control.account)]),
             str(gajim.connections[self.chat_control.account].connection)))
        if not is_supported:
            progress_window.close_dialog()
            log.error("upload component vanished, account got disconnected??")
            ErrorDialog(_(
                'Your server does not support http uploads or you just got disconnected.\nPlease try to reconnect or reopen the chat window to fix this.'
            ),
                        transient_for=self.chat_control.parent_win.window)
            return

        # create iq for slot request
        id_ = gajim.get_an_id()
        iq = nbxmpp.Iq(typ='get',
                       to=jid_to_servers[gajim.get_jid_from_account(
                           self.chat_control.account)],
                       queryNS=None)
        iq.setID(id_)
        request = iq.addChild(name="request", namespace=NS_HTTPUPLOAD)
        filename = request.addChild(name="filename", )
        filename.addData(os.path.basename(path_to_file))
        size = request.addChild(name="size", )
        size.addData(filesize)
        content_type = request.addChild(name="content-type", )
        content_type.addData(mime_type)

        # send slot request and register callback
        log.debug("sending httpupload slot request iq...")
        iq_ids_to_callbacks[str(id_)] = upload_file
        gajim.connections[self.chat_control.account].connection.send(iq)

        self.chat_control.msg_textview.grab_focus()
示例#35
0
    def populate(self, contacts, account, typ):
        """
        Populate the Tooltip Grid with data of from the contact
        """
        self.current_row = 0
        self.account = account
        if self.last_widget:
            self.last_widget.set_vexpand(False)

        self.clear_tooltip()

        if account == 'all':
            # Tooltip for merged accounts row
            accounts = helpers.get_notification_icon_tooltip_dict()
            self.spacer_label = ''
            self.fill_table_with_accounts(accounts)
            self.tooltip_grid.attach(self.table, 0, 3, 2, 1)
            self.table.show_all()
            return

        if typ == 'account':
            jid = gajim.get_jid_from_account(account)
            contacts = []
            connection = gajim.connections[account]
            # get our current contact info

            nbr_on, nbr_total = gajim.\
                contacts.get_nb_online_total_contacts(
                accounts=[account])
            account_name = account
            if gajim.account_is_connected(account):
                account_name += ' (%s/%s)' % (repr(nbr_on),
                    repr(nbr_total))
            contact = gajim.contacts.create_self_contact(jid=jid,
                account=account, name=account_name,
                show=connection.get_status(), status=connection.status,
                resource=connection.server_resource,
                priority=connection.priority)
            if gajim.connections[account].gpg:
                contact.keyID = gajim.config.get_per('accounts',
                    connection.name, 'keyid')
            contacts.append(contact)
            # if we're online ...
            if connection.connection:
                roster = connection.connection.getRoster()
                # in threadless connection when no roster stanza is sent
                # 'roster' is None
                if roster and roster.getItem(jid):
                    resources = roster.getResources(jid)
                    # ...get the contact info for our other online
                    # resources
                    for resource in resources:
                        # Check if we already have this resource
                        found = False
                        for contact_ in contacts:
                            if contact_.resource == resource:
                                found = True
                                break
                        if found:
                            continue
                        show = roster.getShow(jid + '/' + resource)
                        if not show:
                            show = 'online'
                        contact = gajim.contacts.create_self_contact(
                            jid=jid, account=account, show=show,
                            status=roster.getStatus(
                            jid + '/' + resource),
                            priority=roster.getPriority(
                            jid + '/' + resource), resource=resource)
                        contacts.append(contact)

        # Username/Account/Groupchat
        self.prim_contact = gajim.contacts.get_highest_prio_contact_from_contacts(
            contacts)
        self.contact_jid = self.prim_contact.jid
        name = GLib.markup_escape_text(self.prim_contact.get_shown_name())
        name_markup = '<b>{}</b>'.format(name)
        if gajim.config.get('mergeaccounts'):
            color = gajim.config.get('tooltip_account_name_color')
            account_name = GLib.markup_escape_text(self.prim_contact.account.name)
            name_markup += " <span foreground='{}'>({})</span>".format(
                color, account_name)

        if account and helpers.jid_is_blocked(account, self.prim_contact.jid):
            name_markup += _(' [blocked]')

        try:
            if self.prim_contact.jid in gajim.interface.minimized_controls[account]:
                name_markup += _(' [minimized]')
        except KeyError:
            pass

        self.name.set_markup(name_markup)
        self.name.show()

        self.num_resources = 0
        # put contacts in dict, where key is priority
        contacts_dict = {}
        for contact in contacts:
            if contact.resource:
                self.num_resources += 1
                priority = int(contact.priority)
                if priority in contacts_dict:
                    contacts_dict[priority].append(contact)
                else:
                    contacts_dict[priority] = [contact]
        if self.num_resources > 1:
            self.status_label.show()
            transport = gajim.get_transport_name_from_jid(self.prim_contact.jid)
            if transport:
                file_path = os.path.join(helpers.get_transport_path(transport),
                    '16x16')
            else:
                iconset = gajim.config.get('iconset')
                if not iconset:
                    iconset = 'dcraven'
                file_path = os.path.join(helpers.get_iconset_path(iconset),
                    '16x16')

            contact_keys = sorted(contacts_dict.keys())
            contact_keys.reverse()
            for priority in contact_keys:
                for acontact in contacts_dict[priority]:
                    icon_name = self._get_icon_name_for_tooltip(acontact)
                    if acontact.status and len(acontact.status) > 25:
                        status = ''
                        add_text = True
                    else:
                        status = acontact.status
                        add_text = False

                    status_line = self.get_status_info(acontact.resource,
                    acontact.priority, acontact.show, status)
                    self.add_status_row(file_path, icon_name, status_line,
                        acontact.last_status_time)
                    if add_text:
                        self.add_text_row(acontact.status, 2)

            self.tooltip_grid.attach(self.table, 0, 3, 2, 1)
            self.table.show_all()

        else:  # only one resource
            if contact.show:
                request_time = False
                try:
                    last_time = self.check_last_time[contact]
                    if isinstance(last_time, float) and last_time < time.time() - 60:
                        request_time = True
                except KeyError:
                    request_time = True

                if request_time:
                    if contact.show == 'offline':
                        gajim.connections[account].\
                            request_last_status_time(contact.jid, '')
                    elif contact.resource:
                        gajim.connections[account].\
                            request_last_status_time(
                            contact.jid, contact.resource)
                    self.check_last_time[contact] = time.time()

                if contact.status:
                    status = contact.status.strip()
                    if status:
                        self.status.set_text(status)
                        self.status.show()
                        self.status_label.show()

        # PEP Info
        self._append_pep_info(contact)

        # JID
        self.jid.set_text(self.prim_contact.jid)
        self.jid.show()
        self.jid_label.show()

        # contact has only one ressource
        if self.num_resources == 1 and contact.resource:
            res = GLib.markup_escape_text(contact.resource)
            prio = str(contact.priority)
            self.resource.set_text("{} ({})".format(res, prio))
            self.resource.show()
            self.resource_label.show()

        if self.prim_contact.jid not in gajim.gc_connected[account]:
            if (account and
                self.prim_contact.sub and
                    self.prim_contact.sub != 'both'):
                # ('both' is the normal sub so we don't show it)
                self.sub.set_text(helpers.get_uf_sub(self.prim_contact.sub))
                self.sub.show()
                self.sub_label.show()

        if self.prim_contact.keyID:
            keyID = None
            if len(self.prim_contact.keyID) == 8:
                keyID = self.prim_contact.keyID
            elif len(self.prim_contact.keyID) == 16:
                keyID = self.prim_contact.keyID[8:]
            if keyID:
                self.pgp.set_text(keyID)
                self.pgp.show()
                self.pgp_label.show()

        self._set_idle_time(contact)

        # Avatar
        puny_jid = helpers.sanitize_filename(self.prim_contact.jid)
        file_ = helpers.get_avatar_path(os.path.join(gajim.AVATAR_PATH,
            puny_jid))
        if file_:
            with open(file_, 'rb') as file_data:
                pix = gtkgui_helpers.get_pixbuf_from_data(file_data.read())
            pix = gtkgui_helpers.get_scaled_pixbuf(pix, 'tooltip')
            self.avatar.set_from_pixbuf(pix)
            self.avatar.show()

            # Sets the Widget that is at the bottom to expand.
            # This is needed in case the Picture takes more Space then the Labels
            i = 1
            while i < 15:
                if self.tooltip_grid.get_child_at(0, i):
                    if self.tooltip_grid.get_child_at(0, i).get_visible():
                        self.last_widget = self.tooltip_grid.get_child_at(0, i)
                i += 1
            self.last_widget.set_vexpand(True)
示例#36
0
 def _ft_get_our_jid(self):
     return gajim.get_jid_from_account(self.name)
示例#37
0
    def update_context_list(self):
        self.fpr_model.clear()
        self.device_model.clear()
        self.qrcode = self.B.get_object('qrcode')
        self.qrinfo = self.B.get_object('qrinfo')
        if len(self.account_store) == 0:
            self.B.get_object('ID').set_markup('')
            self.B.get_object('fingerprint_label').set_markup('')
            self.B.get_object('trust_button').set_sensitive(False)
            self.B.get_object('delfprbutton').set_sensitive(False)
            self.B.get_object('refresh').set_sensitive(False)
            self.B.get_object('cleardevice_button').set_sensitive(False)
            self.B.get_object('qrcode').clear()
            return
        active = self.B.get_object('account_combobox').get_active()
        account = self.account_store[active][0].decode()

        # Set buttons active
        self.B.get_object('trust_button').set_sensitive(True)
        self.B.get_object('delfprbutton').set_sensitive(True)
        self.B.get_object('refresh').set_sensitive(True)
        if account == 'Local':
            self.B.get_object('cleardevice_button').set_sensitive(False)
        else:
            self.B.get_object('cleardevice_button').set_sensitive(True)

        # Set FPR Label and DeviceID
        state = self.plugin.get_omemo_state(account)
        deviceid = state.own_device_id
        self.B.get_object('ID').set_markup('<tt>%s</tt>' % deviceid)

        ownfpr = binascii.hexlify(state.store.getIdentityKeyPair()
                                  .getPublicKey().serialize())
        human_ownfpr = human_hash(ownfpr[2:])
        self.B.get_object('fingerprint_label').set_markup('<tt>%s</tt>'
                                                          % human_ownfpr)

        # Set Fingerprint List
        trust_str = {0: 'False', 1: 'True', 2: 'Undecided'}
        session_db = state.store.getAllSessions()

        for item in session_db:
            color = {0: '#FF0040',  # red
                     1: '#2EFE2E',  # green
                     2: '#FF8000'}  # orange

            _id, jid, deviceid, record, active = item

            active = bool(active)

            identity_key = SessionRecord(serialized=record). \
                getSessionState().getRemoteIdentityKey()
            fpr = binascii.hexlify(identity_key.getPublicKey().serialize())
            fpr = human_hash(fpr[2:])

            trust = state.store.isTrustedIdentity(jid, identity_key)

            if not active:
                color[trust] = '#585858'  # grey

            self.fpr_model.append(
                (_id, jid, trust_str[trust],
                 '<tt><span foreground="{}">{}</span></tt>'.
                 format(color[trust], fpr),
                 deviceid))

        # Set Device ID List
        for item in state.own_devices:
            self.device_model.append([item])

        # Set QR Verification Code
        if PILLOW:
            path = self.get_qrcode(
                gajim.get_jid_from_account(account), deviceid, ownfpr[2:])
            self.qrcode.set_from_pixbuf(gtk.gdk.pixbuf_new_from_file(path))
            self.qrinfo.hide()
        else:
            self.qrinfo.show()
示例#38
0
 def getOurBareJID(self):
     return gajim.get_jid_from_account(self.name)
示例#39
0
    def handle_outgoing_stanza(self, event):
        """ Manipulates the outgoing stanza

            The body is getting encrypted

            Parameters
            ----------
            event : StanzaMessageOutgoingEvent

            Returns
            -------
            Return if encryption is not activated or any other
            exception or error occurs
        """
        account = event.conn.name
        if account in self.disabled_accounts:
            return
        try:
            if not event.msg_iq.getTag('body'):
                return

            state = self.get_omemo_state(account)
            full_jid = str(event.msg_iq.getAttr('to'))
            to_jid = gajim.get_jid_without_resource(full_jid)
            if not state.encryption.is_active(to_jid):
                return

            # Delete previous Message out of Correction Message Stanza
            if event.msg_iq.getTag('replace', namespace=NS_CORRECT):
                event.msg_iq.delChild('encrypted', attrs={'xmlns': NS_OMEMO})

            plaintext = event.msg_iq.getBody().encode('utf8')

            msg_dict = state.create_msg(
                gajim.get_jid_from_account(account), to_jid, plaintext)
            if not msg_dict:
                return True

            encrypted_node = OmemoMessage(msg_dict)

            # Check if non-OMEMO resource is online
            contacts = gajim.contacts.get_contacts(account, to_jid)
            non_omemo_resource_online = False
            for contact in contacts:
                if contact.show == 'offline':
                    continue
                if not contact.supports(NS_NOTIFY):
                    log.debug(contact.get_full_jid() +
                              ' => Contact doesnt support OMEMO, '
                              'adding Info Message to Body')
                    support_msg = 'You received a message encrypted with ' \
                                  'OMEMO but your client doesnt support OMEMO.'
                    event.msg_iq.setBody(support_msg)
                    non_omemo_resource_online = True
            if not non_omemo_resource_online:
                event.msg_iq.delChild('body')

            event.msg_iq.addChild(node=encrypted_node)

            # XEP-xxxx: Explicit Message Encryption
            if not event.msg_iq.getTag('encrypted', attrs={'xmlns': NS_EME}):
                eme_node = Node('encrypted', attrs={'xmlns': NS_EME,
                                                    'name': 'OMEMO',
                                                    'namespace': NS_OMEMO})
                event.msg_iq.addChild(node=eme_node)

            # Store Hint for MAM
            store = Node('store', attrs={'xmlns': NS_HINTS})
            event.msg_iq.addChild(node=store)
            self.print_msg_to_log(event.msg_iq)
        except Exception as e:
            log.debug(e)
            return True
示例#40
0
    def handle_device_list_update(self, event):
        """ Check if the passed event is a device list update and store the new
            device ids.

            Parameters
            ----------
            event : PEPReceivedEvent

            Returns
            -------
            bool
                True if the given event was a valid device list update event


            See also
            --------
            4.2 Discovering peer support
                http://conversations.im/xeps/multi-end.html#usecases-discovering
        """

        account = event.conn.name
        if account in self.disabled_accounts:
            return False

        if event.pep_type != 'headline':
            return False

        devices_list = list(set(unpack_device_list_update(event.stanza,
                                                          event.conn.name)))
        contact_jid = gajim.get_jid_without_resource(event.fjid)
        if len(devices_list) == 0:
            log.error(account +
                      ' => Received empty or invalid Devicelist from: ' +
                      contact_jid)
            return False

        state = self.get_omemo_state(account)
        my_jid = gajim.get_jid_from_account(account)

        if contact_jid == my_jid:
            log.info(account + ' => Received own device list:' + str(
                devices_list))
            state.set_own_devices(devices_list)
            state.store.sessionStore.setActiveState(devices_list, my_jid)

            # remove contact from list, so on send button pressed
            # we query for bundle and build a session
            if contact_jid in self.query_for_bundles:
                self.query_for_bundles.remove(contact_jid)

            if not state.own_device_id_published():
                # Our own device_id is not in the list, it could be
                # overwritten by some other client
                self.publish_own_devices_list(account)
        else:
            log.info(account + ' => Received device list for ' +
                     contact_jid + ':' + str(devices_list))
            state.set_devices(contact_jid, devices_list)
            state.store.sessionStore.setActiveState(devices_list, contact_jid)

            # remove contact from list, so on send button pressed
            # we query for bundle and build a session
            if contact_jid in self.query_for_bundles:
                self.query_for_bundles.remove(contact_jid)

            # Enable Encryption on receiving first Device List
            if not state.encryption.exist(contact_jid):
                if account in self.ui_list and \
                        contact_jid in self.ui_list[account]:
                    log.debug(account +
                              ' => Switch encryption ON automatically ...')
                    self.ui_list[account][contact_jid].activate_omemo()
                else:
                    log.debug(account +
                              ' => Switch encryption ON automatically ...')
                    self.omemo_enable_for(contact_jid, account)

            if account in self.ui_list and \
                    contact_jid not in self.ui_list[account]:

                chat_control = gajim.interface.msg_win_mgr.get_control(
                    contact_jid, account)

                if chat_control:
                    self.connect_ui(chat_control)

        return True
示例#41
0
    def handle_outgoing_gc_stanza(self, event):
        """ Manipulates the outgoing groupchat stanza

            The body is getting encrypted

            Parameters
            ----------
            event : StanzaMessageOutgoingEvent

            Returns
            -------
            Return if encryption is not activated or any other
            exception or error occurs
        """
        account = event.conn.name
        if account in self.disabled_accounts:
            return
        try:
            # If we send a correction msg, the stanza is saved
            # in correction_msg
            if event.correction_msg:
                event.msg_iq = event.correction_msg
            if not event.msg_iq.getTag('body'):
                return
            state = self.get_omemo_state(account)
            full_jid = str(event.msg_iq.getAttr('to'))
            to_jid = gajim.get_jid_without_resource(full_jid)
            if to_jid not in self.groupchat:
                return
            if not state.encryption.is_active(to_jid):
                return

            # Setting the ID here first for the old stanza object, which
            # Gajim uses for message correction later.
            # after cleanup_stanza() we have a new stanza object so we
            # have to set the same ID so the ID we send matches with the
            # ID from the correction stanza that Gajim hands us on a correction

            # This is a nasty workaround, dont remove this or LMC in Groupchat
            # will break for everything <= 0.16.8

            new_id = gajim.connections[account].connection.getAnID()
            event.msg_iq.setID(new_id)
            self.cleanup_stanza(event)
            event.msg_iq.setID(new_id)

            plaintext = event.message
            msg_dict = state.create_gc_msg(gajim.get_jid_from_account(account),
                                           to_jid, plaintext.encode('utf8'))
            if not msg_dict:
                return True

            self.gc_message[msg_dict['payload']] = plaintext
            encrypted_node = OmemoMessage(msg_dict)
            event.msg_iq.addChild(node=encrypted_node)

            # XEP-0380: Explicit Message Encryption
            eme_node = Node('encryption',
                            attrs={
                                'xmlns': NS_EME,
                                'name': 'OMEMO',
                                'namespace': NS_OMEMO
                            })
            event.msg_iq.addChild(node=eme_node)

            # Add Message for devices that dont support OMEMO
            support_msg = 'You received a message encrypted with ' \
                          'OMEMO but your client doesnt support OMEMO.'
            event.msg_iq.setBody(support_msg)

            # Store Hint for MAM
            store = Node('store', attrs={'xmlns': NS_HINTS})
            event.msg_iq.addChild(node=store)
            if event.correction_msg:
                event.correction_msg = event.msg_iq
                event.msg_iq = None
                self.print_msg_to_log(event.correction_msg)
            else:
                self.print_msg_to_log(event.msg_iq)
        except Exception as e:
            log.debug(e)
            return True

        event.xhtml = None
示例#42
0
    def handle_outgoing_gc_stanza(self, event):
        """ Manipulates the outgoing groupchat stanza

            The body is getting encrypted

            Parameters
            ----------
            event : StanzaMessageOutgoingEvent

            Returns
            -------
            Return if encryption is not activated or any other
            exception or error occurs
        """
        account = event.conn.name
        if account in self.disabled_accounts:
            return
        try:
            # If we send a correction msg, the stanza is saved
            # in correction_msg
            if event.correction_msg:
                event.msg_iq = event.correction_msg
            if not event.msg_iq.getTag('body'):
                return
            state = self.get_omemo_state(account)
            full_jid = str(event.msg_iq.getAttr('to'))
            to_jid = gajim.get_jid_without_resource(full_jid)
            if to_jid not in self.groupchat:
                return
            if not state.encryption.is_active(to_jid):
                return
            # Delete previous Message out of Correction Message Stanza
            if event.msg_iq.getTag('replace', namespace=NS_CORRECT):
                event.msg_iq.delChild('encrypted', attrs={'xmlns': NS_OMEMO})

            plaintext = event.msg_iq.getBody()
            msg_dict = state.create_gc_msg(
                gajim.get_jid_from_account(account),
                to_jid,
                plaintext.encode('utf8'))
            if not msg_dict:
                return True

            self.gc_message[msg_dict['payload']] = plaintext
            encrypted_node = OmemoMessage(msg_dict)
            event.msg_iq.delChild('body')
            event.msg_iq.addChild(node=encrypted_node)

            # XEP-xxxx: Explicit Message Encryption
            if not event.msg_iq.getTag('encrypted', attrs={'xmlns': NS_EME}):
                eme_node = Node('encrypted', attrs={'xmlns': NS_EME,
                                                    'name': 'OMEMO',
                                                    'namespace': NS_OMEMO})
                event.msg_iq.addChild(node=eme_node)

            # Add Message for devices that dont support OMEMO
            support_msg = 'You received a message encrypted with ' \
                          'OMEMO but your client doesnt support OMEMO.'
            event.msg_iq.setBody(support_msg)

            # Store Hint for MAM
            store = Node('store', attrs={'xmlns': NS_HINTS})
            event.msg_iq.addChild(node=store)
            if event.correction_msg:
                event.correction_msg = event.msg_iq
                event.msg_iq = None
                self.print_msg_to_log(event.correction_msg)
            else:
                self.print_msg_to_log(event.msg_iq)
        except Exception as e:
            log.debug(e)
            return True