From f89ccfe441a8947a711b1a1a1acdff186bb30779 Mon Sep 17 00:00:00 2001
From: Yann Leboulanger <asterix@lagaule.org>
Date: Wed, 6 Dec 2006 16:19:47 +0000
Subject: [PATCH] detect error while encrypting message, block sending it, and
 display error message. fixes #2712

---
 src/chat_control.py      | 17 ++++++++++-------
 src/common/GnuPG.py      |  8 ++++++--
 src/common/connection.py | 13 +++++++++----
 src/gajim.py             |  9 ++++++++-
 src/message_control.py   |  5 +++--
 5 files changed, 36 insertions(+), 16 deletions(-)

diff --git a/src/chat_control.py b/src/chat_control.py
index 624c869033..712aefa6b3 100644
--- a/src/chat_control.py
+++ b/src/chat_control.py
@@ -498,16 +498,19 @@ class ChatControlBase(MessageControl):
 
 	def send_message(self, message, keyID = '', type = 'chat', chatstate = None,
 	msg_id = None, composing_jep = None, resource = None):
-		'''Send the given message to the active tab'''
+		'''Send the given message to the active tab. Doesn't return None if error
+		'''
 		if not message or message == '\n':
-			return
+			return 1
 
 
 		if not self._process_command(message):
-			MessageControl.send_message(self, message, keyID, type = type,
+			ret = MessageControl.send_message(self, message, keyID, type = type,
 				chatstate = chatstate, msg_id = msg_id,
 				composing_jep = composing_jep, resource = resource,
 				user_nick = self.user_nick)
+			if ret:
+				return ret
 			# Record message history
 			self.save_sent_message(message)
 
@@ -1166,10 +1169,10 @@ class ChatControl(ChatControlBase):
 				gobject.source_remove(self.possible_inactive_timeout_id)
 				self._schedule_activity_timers()
 				
-		ChatControlBase.send_message(self, message, keyID, type = 'chat',
-			chatstate = chatstate_to_send,
-			composing_jep = composing_jep)
-		self.print_conversation(message, self.contact.jid, encrypted = encrypted)
+		if not ChatControlBase.send_message(self, message, keyID, type = 'chat',
+		chatstate = chatstate_to_send, composing_jep = composing_jep):
+			self.print_conversation(message, self.contact.jid,
+				encrypted = encrypted)
 
 	def check_for_possible_paused_chatstate(self, arg):
 		''' did we move mouse of that window or write something in message
diff --git a/src/common/GnuPG.py b/src/common/GnuPG.py
index af38cddf91..02e4838aa4 100644
--- a/src/common/GnuPG.py
+++ b/src/common/GnuPG.py
@@ -79,16 +79,20 @@ else:
 				return str
 			self.options.recipients = recipients   # a list!
 
-			proc = self.run(['--encrypt'], create_fhs=['stdin', 'stdout'])
+			proc = self.run(['--encrypt'], create_fhs=['stdin', 'stdout',
+				'stderr'])
 			proc.handles['stdin'].write(str)
 			proc.handles['stdin'].close()
 
 			output = proc.handles['stdout'].read()
 			proc.handles['stdout'].close()
 
+			error = proc.handles['stderr'].read()
+			proc.handles['stderr'].close()
+
 			try: proc.wait()
 			except IOError: pass
-			return self._stripHeaderFooter(output)
+			return self._stripHeaderFooter(output), error
 
 		def decrypt(self, str, keyID):
 			if not USE_GPG:
diff --git a/src/common/connection.py b/src/common/connection.py
index 8b75c96953..d8cd978a57 100644
--- a/src/common/connection.py
+++ b/src/common/connection.py
@@ -687,11 +687,11 @@ class Connection(ConnectionHandlers):
 	chatstate = None, msg_id = None, composing_jep = None, resource = None,
 	user_nick = None, xhtml = None):
 		if not self.connection:
-			return
+			return 1
 		if msg and not xhtml and gajim.config.get('rst_formatting_outgoing_messages'):
 			xhtml = create_xhtml(msg)
 		if not msg and chatstate is None:
-			return
+			return 2
 		fjid = jid
 		if resource:
 			fjid += '/' + resource
@@ -699,14 +699,19 @@ class Connection(ConnectionHandlers):
 		msgenc = ''
 		if keyID and USE_GPG:
 			#encrypt
-			msgenc = self.gpg.encrypt(msg, [keyID])
-			if msgenc:
+			msgenc, error = self.gpg.encrypt(msg, [keyID])
+			if msgenc and not error:
 				msgtxt = '[This message is encrypted]'
 				lang = os.getenv('LANG')
 				if lang is not None and lang != 'en': # we're not english
 					# one  in locale and one en
 					msgtxt = _('[This message is *encrypted* (See :JEP:`27`]') +\
 						' ([This message is *encrypted* (See :JEP:`27`])'
+			else:
+				# Encryption failed, do not send message
+				tim = time.localtime()
+				self.dispatch('MSGNOTSENT', (jid, error, msgtxt, tim))
+				return 3
 		if msgtxt and not xhtml and gajim.config.get(
 			'rst_formatting_outgoing_messages'):
 			# Generate a XHTML part using reStructured text markup
diff --git a/src/gajim.py b/src/gajim.py
index 759da777d6..db4260936d 100755
--- a/src/gajim.py
+++ b/src/gajim.py
@@ -710,7 +710,13 @@ class Interface:
 		# do not play sound when standalone chatstate message (eg no msg)
 		if msg and gajim.config.get_per('soundevents', 'message_sent', 'enabled'):
 			helpers.play_sound('message_sent')
-		
+
+	def handle_event_msgnotsent(self, account, array):
+		#('MSGNOTSENT', account, (jid, ierror_msg, msg, time))
+		msg = _('error while sending %s ( %s )') % (array[2], array[1])
+		self.roster.on_message(array[0], msg, array[3], account,
+			msg_type='error')
+
 	def handle_event_subscribe(self, account, array):
 		#('SUBSCRIBE', account, (jid, text, user_nick)) user_nick is JEP-0172
 		dialogs.SubscriptionRequestWindow(array[0], array[1], account, array[2])
@@ -1780,6 +1786,7 @@ class Interface:
 			'MSG': self.handle_event_msg,
 			'MSGERROR': self.handle_event_msgerror,
 			'MSGSENT': self.handle_event_msgsent,
+			'MSGNOTSENT': self.handle_event_msgnotsent,
 			'SUBSCRIBED': self.handle_event_subscribed,
 			'UNSUBSCRIBED': self.handle_event_unsubscribed,
 			'SUBSCRIBE': self.handle_event_subscribe,
diff --git a/src/message_control.py b/src/message_control.py
index 6d44d31438..0a2cde3a0c 100644
--- a/src/message_control.py
+++ b/src/message_control.py
@@ -117,10 +117,11 @@ class MessageControl:
 	def send_message(self, message, keyID = '', type = 'chat',
 	chatstate = None, msg_id = None, composing_jep = None, resource = None,
 	user_nick = None):
-		'''Send the given message to the active tab'''
+		'''Send the given message to the active tab. Doesn't return None if error
+		'''
 		jid = self.contact.jid
 		# Send and update history
-		gajim.connections[self.account].send_message(jid, message, keyID,
+		return gajim.connections[self.account].send_message(jid, message, keyID,
 			type = type, chatstate = chatstate, msg_id = msg_id,
 			composing_jep = composing_jep, resource = self.resource,
 			user_nick = user_nick)
-- 
GitLab