pax_global_header00006660000000000000000000000064131662167230014521gustar00rootroot0000000000000052 comment=7a9684ca4a8481d63d77d211858f7f61cd0e9d23 gajim-antispam/000077500000000000000000000000001316621672300137665ustar00rootroot00000000000000gajim-antispam/CHANGELOG000066400000000000000000000011301316621672300151730ustar00rootroot00000000000000## [Unreleased] ### Added - Sending confirmation message that anti spam check was passed. It can be disabled in plugin gui config. ## [1.4.3] - 2016-12-04 ### Added - Filtering 'normal' type messages ### Changed - User from private conference conversation permanently stored in file - Switched to GTK3 ### Fixed - Messages that was sent before correct answer was marked as received - Chat between the two antispam plugins ## [0.4.2] - 2016-11-28 ### Added - Anti spam question functionality - This CHANGELOG - README with some explanation of functionality ### Changed - homepage in manifest.ini gajim-antispam/README.md000066400000000000000000000017461316621672300152550ustar00rootroot00000000000000# Anti_spam Plugin for Gajim This Plugin allows you to dissociate itself from the spam. ## Installation Use special plugin, that manages automatic download and installation of others plugins, it is called Plugin Installer. ## Options ### Block pubsub Block incoming messages from pubsub ### Message size limit Block incoming messages that have size more than configured. Default value -1 mean that any sized messages are coming. ### Anti spam question Block incoming messages from users not in your roster. In response, the Plugin sends a question that you configured. After correct answer(also configurable) you will receive all new messages from user. **Attention!** All messages before correct answer will be lost. Also you can enable this function, in Plugin config, for conference private messages. In some servers, the question in conference private does not reach your interlocutor. This can lead to the fact that you will not receive any messages from him, and he will not know it.gajim-antispam/__init__.py000066400000000000000000000000461316621672300160770ustar00rootroot00000000000000from .anti_spam import AntiSpamPlugin gajim-antispam/anti_spam.png000066400000000000000000000014651316621672300164550ustar00rootroot00000000000000PNG  IHDRabKGD pHYs  tIME  XLIDAT8mMh\U{޹hBLآ  BQDDBVYi Y骛R.B* Y )1N6jmN2i94]>pα1[.KB>,JX*=}FzVe28󌍍-y>avz_ZMQJEvwtt վurƐ4@Ǐc0E4M=999D9cĀFt(&EzV"8xZ+ J-,6Xo83IF+Rƻ=nQ.<|H(h- Q޳]mx7yvO^J#CL{^08yrl:Uߑ=8L`t. ## ''' Block some incoming messages :author: Yann Leboulanger :since: 16 August 2012 :copyright: Copyright (2012) Yann Leboulanger :license: GPLv3 ''' from gi.repository import Gtk import nbxmpp from gajim.common import app, ged from gajim.plugins import GajimPlugin from gajim.plugins.helpers import log, log_calls from gajim.plugins.gui import GajimPluginConfigDialog class AntiSpamPlugin(GajimPlugin): @log_calls('AntiSpamPlugin') def init(self): self.description = _('Allows to block some kind of incoming messages') self.config_dialog = AntiSpamPluginConfigDialog(self) self.gui_extension_points = { } self.events_handlers = { 'atom-entry-received': (ged.POSTCORE, self._nec_atom_entry_received), 'message-received': (ged.PRECORE, self._nec_message_received_received), 'decrypted-message-received': (ged.PRECORE, self._nec_decrypted_message_received_received), 'subscribe-presence-received': (ged.POSTCORE, self._nec_subscribe_presence_received), 'message-outgoing': (ged.OUT_PRECORE, self._nec_message_outgoing) } self.config_default_values = { 'block_pubsub_messages': (False, 'If True, Gajim will block incoming messages from pubsub.'), 'disable_xhtml_muc': (False, ''), 'disable_xhtml_pm': (False, ''), 'block_subscription_requests': (False, ''), 'msgtxt_limit': (-1, ''), 'msgtxt_question': ('Please answer: 12 x 12 =', ''), 'msgtxt_answer': ('', ''), 'antispam_for_conference': (False, ''), 'conference_white_list': ([], ''), # conference private chat jid's } # List of outgoing jid's # Needs to avoid chat of two anti spam plugins # Contain all jid's where are you initiate a chat self.outgoing_jids = [] @log_calls('AntiSpamPlugin') def _nec_atom_entry_received(self, obj): if self.config['block_pubsub_messages']: log.info('discarding pubdubd message') return True @log_calls('AntiSpamPlugin') def _nec_message_received_received(self, obj): if self.config['disable_xhtml_muc'] and obj.mtype == 'groupchat': self.remove_xhtml(obj) if self.config['disable_xhtml_pm'] and obj.gc_control and \ obj.resource and obj.mtype == 'chat': self.remove_xhtml(obj) return False @log_calls('AntiSpamPlugin') def _nec_decrypted_message_received_received(self, obj): if not obj.msgtxt: return False if self._nec_decrypted_message_received_question(obj): return True limit = self.config['msgtxt_limit'] if limit > -1 and len(obj.msgtxt) > limit: return True return False @log_calls('AntiSpamPlugin') def _nec_subscribe_presence_received(self, obj): if self.config['block_subscription_requests'] and \ not app.contacts.get_contacts(obj.conn.name, obj.jid): log.info('discarding subscription request from %s' % obj.jid) return True @log_calls('AntiSpamPlugin') def _nec_decrypted_message_received_question(self, obj): if obj.mtype != 'chat' and obj.mtype != 'normal': return False tjid = obj.jid if obj.mtype == 'normal' else obj.fjid if tjid in self.outgoing_jids: return False answer = self.config['msgtxt_answer'] if len(answer) == 0: return False block_conference = self.config['antispam_for_conference'] is_conference = app.contacts.is_gc_contact(obj.conn.name, obj.fjid) if not block_conference and is_conference: return False jid = obj.jid if not is_conference else obj.fjid # If we receive conference privat message or direct message from unknown user than # anti spam question will send in background mode, without any notification for us # There are two methods to see who wrote you and not passed filter: # 1. Using XML console # 2. Running Gajim with log info messages and see logs (probably gajim.log file) if is_conference or not app.contacts.get_contacts(obj.conn.name, jid): if not self.contain_answer(obj.msgtxt, answer): if is_conference and jid in self.config['conference_white_list']: return False self.send_question(obj, jid) return True else: if is_conference and jid not in self.config['conference_white_list']: self.config['conference_white_list'].append(jid) # Need to save because 'append' method does not implement __setitem__ method self.config.save() return False @log_calls('AntiSpamPlugin') def _nec_message_outgoing(self, obj): if obj.type_ != 'chat' and obj.type_ != 'normal': return if isinstance(obj.jid, list): for i in obj.jid: if i not in self.outgoing_jids: self.outgoing_jids.append(i) else: if obj.jid not in self.outgoing_jids: self.outgoing_jids.append(obj.jid) def send_question(self, obj, jid): if obj.mtype != 'chat' and obj.mtype != 'normal': log.info('Anti_spam wrong message type: %s', obj.mtype) return # only for 'chat' messages if obj.receipt_request_tag and obj.mtype == 'chat': receipt = nbxmpp.Message(to=obj.fjid, typ='chat') receipt.setTag('received', namespace='urn:xmpp:receipts', attrs={'id': obj.id_}) if obj.thread_id: receipt.setThread(obj.thread_id) app.connections[obj.conn.name].connection.send(receipt, now=True) question = self.config['msgtxt_question'] log.info('Anti_spam enabled for %s, question: %s', jid, question) message = _('Antispam enabled. Please answer the question. The message must only ' + \ 'contain the answer. (Messages sent before the correct answer, will be lost): ') \ + question if obj.mtype == 'chat': stanza = nbxmpp.Message(to=jid, body=message, typ=obj.mtype) else: # for 'normal' type stanza = nbxmpp.Message(to=jid, body=message, subject='Antispam enabled', typ=obj.mtype) app.connections[obj.conn.name].connection.send(stanza, now=True) def contain_answer(self, msg, answer): return answer in msg.split('\n') def remove_xhtml(self, obj): html_node = obj.stanza.getTag('html') if html_node: obj.stanza.delChild(html_node) class AntiSpamPluginConfigDialog(GajimPluginConfigDialog): def init(self): self.GTK_BUILDER_FILE_PATH = self.plugin.local_file_path( 'config_dialog.ui') self.xml = Gtk.Builder() self.xml.set_translation_domain('gajim_plugins') self.xml.add_objects_from_file(self.GTK_BUILDER_FILE_PATH, ['anti_spam_config_vbox']) self.config_vbox = self.xml.get_object('anti_spam_config_vbox') self.get_child().pack_start(self.config_vbox, True, True, 0) self.block_pubsub_messages_checkbutton = self.xml.get_object( 'block_pubsub_messages_checkbutton') self.xml.connect_signals(self) def on_run(self): self.block_pubsub_messages_checkbutton.set_active(self.plugin.config[ 'block_pubsub_messages']) widget = self.xml.get_object('disable_xhtml_muc_checkbutton') widget.set_active(self.plugin.config['disable_xhtml_muc']) widget = self.xml.get_object('disable_xhtml_pm_checkbutton') widget.set_active(self.plugin.config['disable_xhtml_pm']) widget = self.xml.get_object('block_subscription_requests_checkbutton') widget.set_active(self.plugin.config['block_subscription_requests']) widget = self.xml.get_object('message_size_limit_entry') widget.set_text(str(self.plugin.config['msgtxt_limit'])) widget = self.xml.get_object('antispam_question') widget.set_text(str(self.plugin.config['msgtxt_question'])) widget = self.xml.get_object('antispam_answer') widget.set_text(str(self.plugin.config['msgtxt_answer'])) widget = self.xml.get_object('antispam_for_conference') widget.set_active(self.plugin.config['antispam_for_conference']) def on_block_pubsub_messages_checkbutton_toggled(self, button): self.plugin.config['block_pubsub_messages'] = button.get_active() def on_disable_xhtml_muc_checkbutton_toggled(self, button): self.plugin.config['disable_xhtml_muc'] = button.get_active() def on_disable_xhtml_pm_checkbutton_toggled(self, button): self.plugin.config['disable_xhtml_pm'] = button.get_active() def on_block_subscription_requests_checkbutton_toggled(self, button): self.plugin.config['block_subscription_requests'] = button.get_active() def on_message_size_limit_entry_changed(self, entry): try: self.plugin.config['msgtxt_limit'] = int(entry.get_text()) except Exception: pass def on_message_question_entry_changed(self, entry): try: self.plugin.config['msgtxt_question'] = entry.get_text() except Exception: pass def on_message_answer_entry_changed(self, entry): try: self.plugin.config['msgtxt_answer'] = entry.get_text() except Exception: pass def on_antispam_for_conference_checkbutton_toggled(self, button): self.plugin.config['antispam_for_conference'] = button.get_active() gajim-antispam/config_dialog.ui000066400000000000000000000224671316621672300171240ustar00rootroot00000000000000 True 9 vertical 4 Block pubsub messages True False False If checked, Gajim will block incoming messages from pubsub. True False 0 Disable xhtml in MUCs True False False If checked, Gajim will remove XHTML from incoming multi-user chat messages True False 1 Disable xhtml in private messages True False False If checked, Gajim will remove XHTML from incoming private messages True False 2 Block incoming subscription requests True False False If checked, Gajim will block incoming subscription requests True False 3 True False 6 True False Message size limit: False 0 True True False 1 False 4 True False False 5 True False Anti spam question (Leave an empty answer field to disable this function): True False 6 3 True False 6 True False Question: False 0 True True False 1 True False Answer: False 2 True True False 3 False 7 Enable for conferences True False False If checked, anti spam question will send for conference private messages True False 8 gajim-antispam/manifest.ini000066400000000000000000000005201316621672300162720ustar00rootroot00000000000000[info] name: Anti Spam short_name: anti_spam version: 1.4.4 description: Block some incoming messages. authors = Yann Leboulanger Denis Fomin Ilya Kanyukov homepage = https://dev.gajim.org/gajim/gajim-plugins/wikis/AntiSpamPlugin min_gajim_version: 0.16.11