Refactor the way we decide whether GPG is usable or not: Ability to change keys when no valid passphrase could be entered.
See #1210. Workaround for unavailable keys. Remove useless except block: import of GnuPGInterface is the same on Debian and non Debian systems.
This commit is contained in:
parent
f671b9bff7
commit
fef742c863
|
@ -28,24 +28,12 @@
|
||||||
## along with Gajim. If not, see <http://www.gnu.org/licenses/>.
|
## along with Gajim. If not, see <http://www.gnu.org/licenses/>.
|
||||||
##
|
##
|
||||||
|
|
||||||
import os
|
import gajim
|
||||||
from os import tmpfile
|
from os import tmpfile
|
||||||
from common import helpers
|
from common import helpers
|
||||||
|
|
||||||
USE_GPG = True
|
if gajim.HAVE_GPG:
|
||||||
|
import GnuPGInterface
|
||||||
try:
|
|
||||||
import GnuPGInterface # Debian package doesn't distribute 'our' file
|
|
||||||
except ImportError:
|
|
||||||
try:
|
|
||||||
from common import GnuPGInterface # use 'our' file
|
|
||||||
except ImportError:
|
|
||||||
USE_GPG = False # user can't do OpenGPG only if he or she removed the file!
|
|
||||||
|
|
||||||
else:
|
|
||||||
status = os.system('gpg -h >/dev/null 2>&1')
|
|
||||||
if status != 0:
|
|
||||||
USE_GPG = False
|
|
||||||
|
|
||||||
class GnuPG(GnuPGInterface.GnuPG):
|
class GnuPG(GnuPGInterface.GnuPG):
|
||||||
def __init__(self, use_agent = False):
|
def __init__(self, use_agent = False):
|
||||||
|
@ -88,8 +76,6 @@ else:
|
||||||
return resp
|
return resp
|
||||||
|
|
||||||
def encrypt(self, str, recipients):
|
def encrypt(self, str, recipients):
|
||||||
if not USE_GPG:
|
|
||||||
return str, 'GnuPG not usable'
|
|
||||||
self.options.recipients = recipients # a list!
|
self.options.recipients = recipients # a list!
|
||||||
|
|
||||||
proc = self.run(['--encrypt'], create_fhs=['stdin', 'stdout', 'status',
|
proc = self.run(['--encrypt'], create_fhs=['stdin', 'stdout', 'status',
|
||||||
|
@ -125,8 +111,6 @@ else:
|
||||||
return self._stripHeaderFooter(output), error
|
return self._stripHeaderFooter(output), error
|
||||||
|
|
||||||
def decrypt(self, str, keyID):
|
def decrypt(self, str, keyID):
|
||||||
if not USE_GPG:
|
|
||||||
return str
|
|
||||||
proc = self.run(['--decrypt', '-q', '-u %s'%keyID], create_fhs=['stdin', 'stdout'])
|
proc = self.run(['--decrypt', '-q', '-u %s'%keyID], create_fhs=['stdin', 'stdout'])
|
||||||
enc = self._addHeaderFooter(str, 'MESSAGE')
|
enc = self._addHeaderFooter(str, 'MESSAGE')
|
||||||
proc.handles['stdin'].write(enc)
|
proc.handles['stdin'].write(enc)
|
||||||
|
@ -140,8 +124,6 @@ else:
|
||||||
return output
|
return output
|
||||||
|
|
||||||
def sign(self, str, keyID):
|
def sign(self, str, keyID):
|
||||||
if not USE_GPG:
|
|
||||||
return str
|
|
||||||
proc = self.run(['-b', '-u %s'%keyID], create_fhs=['stdin', 'stdout', 'status', 'stderr'])
|
proc = self.run(['-b', '-u %s'%keyID], create_fhs=['stdin', 'stdout', 'status', 'stderr'])
|
||||||
proc.handles['stdin'].write(str)
|
proc.handles['stdin'].write(str)
|
||||||
try:
|
try:
|
||||||
|
@ -170,8 +152,6 @@ else:
|
||||||
return 'BAD_PASSPHRASE'
|
return 'BAD_PASSPHRASE'
|
||||||
|
|
||||||
def verify(self, str, sign):
|
def verify(self, str, sign):
|
||||||
if not USE_GPG:
|
|
||||||
return str
|
|
||||||
if str == None:
|
if str == None:
|
||||||
return ''
|
return ''
|
||||||
f = tmpfile()
|
f = tmpfile()
|
||||||
|
@ -200,8 +180,6 @@ else:
|
||||||
return keyid
|
return keyid
|
||||||
|
|
||||||
def get_keys(self, secret = False):
|
def get_keys(self, secret = False):
|
||||||
if not USE_GPG:
|
|
||||||
return {}
|
|
||||||
if secret:
|
if secret:
|
||||||
opt = '--list-secret-keys'
|
opt = '--list-secret-keys'
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -48,7 +48,6 @@ from common import passwords
|
||||||
from common import exceptions
|
from common import exceptions
|
||||||
|
|
||||||
from connection_handlers import *
|
from connection_handlers import *
|
||||||
USE_GPG = GnuPG.USE_GPG
|
|
||||||
|
|
||||||
from common.rst_xhtml_generator import create_xhtml
|
from common.rst_xhtml_generator import create_xhtml
|
||||||
|
|
||||||
|
@ -105,7 +104,9 @@ class Connection(ConnectionHandlers):
|
||||||
self.last_connection = None # last ClientCommon instance
|
self.last_connection = None # last ClientCommon instance
|
||||||
self.is_zeroconf = False
|
self.is_zeroconf = False
|
||||||
self.gpg = None
|
self.gpg = None
|
||||||
if USE_GPG:
|
self.USE_GPG = False
|
||||||
|
if gajim.HAVE_GPG:
|
||||||
|
self.USE_GPG = True
|
||||||
self.gpg = GnuPG.GnuPG(gajim.config.get('use_gpg_agent'))
|
self.gpg = GnuPG.GnuPG(gajim.config.get('use_gpg_agent'))
|
||||||
self.status = ''
|
self.status = ''
|
||||||
self.priority = gajim.get_priority(name, 'offline')
|
self.priority = gajim.get_priority(name, 'offline')
|
||||||
|
@ -179,7 +180,7 @@ class Connection(ConnectionHandlers):
|
||||||
self.dispatch('STATUS', 'connecting')
|
self.dispatch('STATUS', 'connecting')
|
||||||
self.retrycount += 1
|
self.retrycount += 1
|
||||||
self.on_connect_auth = self._init_roster
|
self.on_connect_auth = self._init_roster
|
||||||
self.connect_and_init(self.old_show, self.status, self.gpg != None)
|
self.connect_and_init(self.old_show, self.status, self.USE_GPG)
|
||||||
else:
|
else:
|
||||||
# reconnect succeeded
|
# reconnect succeeded
|
||||||
self.time_to_reconnect = None
|
self.time_to_reconnect = None
|
||||||
|
@ -268,7 +269,8 @@ class Connection(ConnectionHandlers):
|
||||||
if not common.xmpp.isResultNode(result):
|
if not common.xmpp.isResultNode(result):
|
||||||
self.dispatch('ACC_NOT_OK', (result.getError()))
|
self.dispatch('ACC_NOT_OK', (result.getError()))
|
||||||
return
|
return
|
||||||
if USE_GPG:
|
if gajim.HAVE_GPG:
|
||||||
|
self.USE_GPG = True
|
||||||
self.gpg = GnuPG.GnuPG(gajim.config.get(
|
self.gpg = GnuPG.GnuPG(gajim.config.get(
|
||||||
'use_gpg_agent'))
|
'use_gpg_agent'))
|
||||||
self.dispatch('ACC_OK', (self.new_account_info))
|
self.dispatch('ACC_OK', (self.new_account_info))
|
||||||
|
@ -796,7 +798,7 @@ class Connection(ConnectionHandlers):
|
||||||
callback is the function to call when user give the passphrase'''
|
callback is the function to call when user give the passphrase'''
|
||||||
signed = ''
|
signed = ''
|
||||||
keyID = gajim.config.get_per('accounts', self.name, 'keyid')
|
keyID = gajim.config.get_per('accounts', self.name, 'keyid')
|
||||||
if keyID and self.gpg:
|
if keyID and self.USE_GPG:
|
||||||
use_gpg_agent = gajim.config.get('use_gpg_agent')
|
use_gpg_agent = gajim.config.get('use_gpg_agent')
|
||||||
if self.gpg.passphrase is None and not use_gpg_agent:
|
if self.gpg.passphrase is None and not use_gpg_agent:
|
||||||
# We didn't set a passphrase
|
# We didn't set a passphrase
|
||||||
|
@ -804,7 +806,7 @@ class Connection(ConnectionHandlers):
|
||||||
if self.gpg.passphrase is not None or use_gpg_agent:
|
if self.gpg.passphrase is not None or use_gpg_agent:
|
||||||
signed = self.gpg.sign(msg, keyID)
|
signed = self.gpg.sign(msg, keyID)
|
||||||
if signed == 'BAD_PASSPHRASE':
|
if signed == 'BAD_PASSPHRASE':
|
||||||
self.gpg = None
|
self.USE_GPG = False
|
||||||
signed = ''
|
signed = ''
|
||||||
self.dispatch('BAD_PASSPHRASE', ())
|
self.dispatch('BAD_PASSPHRASE', ())
|
||||||
return signed
|
return signed
|
||||||
|
@ -881,7 +883,8 @@ class Connection(ConnectionHandlers):
|
||||||
safe_substitute({
|
safe_substitute({
|
||||||
'hostname': socket.gethostname()
|
'hostname': socket.gethostname()
|
||||||
})
|
})
|
||||||
if USE_GPG:
|
if gajim.HAVE_GPG:
|
||||||
|
self.USE_GPG = True
|
||||||
self.gpg = GnuPG.GnuPG(gajim.config.get('use_gpg_agent'))
|
self.gpg = GnuPG.GnuPG(gajim.config.get('use_gpg_agent'))
|
||||||
self.connect_and_init(show, msg, sign_msg)
|
self.connect_and_init(show, msg, sign_msg)
|
||||||
|
|
||||||
|
@ -958,7 +961,7 @@ class Connection(ConnectionHandlers):
|
||||||
fjid += '/' + resource
|
fjid += '/' + resource
|
||||||
msgtxt = msg
|
msgtxt = msg
|
||||||
msgenc = ''
|
msgenc = ''
|
||||||
if keyID and self.gpg:
|
if keyID and self.USE_GPG:
|
||||||
#encrypt
|
#encrypt
|
||||||
msgenc, error = self.gpg.encrypt(msg, [keyID])
|
msgenc, error = self.gpg.encrypt(msg, [keyID])
|
||||||
if msgenc and not error:
|
if msgenc and not error:
|
||||||
|
|
|
@ -35,7 +35,6 @@ from calendar import timegm
|
||||||
import socks5
|
import socks5
|
||||||
import common.xmpp
|
import common.xmpp
|
||||||
|
|
||||||
from common import GnuPG
|
|
||||||
from common import helpers
|
from common import helpers
|
||||||
from common import gajim
|
from common import gajim
|
||||||
from common import atom
|
from common import atom
|
||||||
|
@ -1629,7 +1628,7 @@ class ConnectionHandlers(ConnectionVcard, ConnectionBytestream, ConnectionDisco,
|
||||||
if not user_nick:
|
if not user_nick:
|
||||||
user_nick = ''
|
user_nick = ''
|
||||||
|
|
||||||
if encTag and GnuPG.USE_GPG:
|
if encTag and self.USE_GPG:
|
||||||
#decrypt
|
#decrypt
|
||||||
encmsg = encTag.getData()
|
encmsg = encTag.getData()
|
||||||
|
|
||||||
|
@ -1901,7 +1900,7 @@ returns the session that we last sent a message to.'''
|
||||||
except:
|
except:
|
||||||
prio = 0
|
prio = 0
|
||||||
keyID = ''
|
keyID = ''
|
||||||
if sigTag and self.gpg:
|
if sigTag and self.USE_GPG:
|
||||||
# verify
|
# verify
|
||||||
sigmsg = sigTag.getData()
|
sigmsg = sigTag.getData()
|
||||||
keyID = self.gpg.verify(status, sigmsg)
|
keyID = self.gpg.verify(status, sigmsg)
|
||||||
|
|
|
@ -154,6 +154,17 @@ try:
|
||||||
except ImportError:
|
except ImportError:
|
||||||
HAVE_PYSEXY = False
|
HAVE_PYSEXY = False
|
||||||
|
|
||||||
|
HAVE_GPG = True
|
||||||
|
try:
|
||||||
|
import GnuPGInterface
|
||||||
|
except ImportError:
|
||||||
|
HAVE_GPG = False
|
||||||
|
else:
|
||||||
|
import os
|
||||||
|
status = os.system('gpg -h >/dev/null 2>&1')
|
||||||
|
if status != 0:
|
||||||
|
HAVE_GPG = False
|
||||||
|
|
||||||
def get_nick_from_jid(jid):
|
def get_nick_from_jid(jid):
|
||||||
pos = jid.find('@')
|
pos = jid.find('@')
|
||||||
return jid[:pos]
|
return jid[:pos]
|
||||||
|
|
|
@ -32,7 +32,6 @@ from calendar import timegm
|
||||||
from common import socks5
|
from common import socks5
|
||||||
import common.xmpp
|
import common.xmpp
|
||||||
|
|
||||||
from common import GnuPG
|
|
||||||
from common import helpers
|
from common import helpers
|
||||||
from common import gajim
|
from common import gajim
|
||||||
from common.zeroconf import zeroconf
|
from common.zeroconf import zeroconf
|
||||||
|
@ -726,7 +725,7 @@ class ConnectionHandlersZeroconf(ConnectionVcard, ConnectionBytestream):
|
||||||
if not user_nick:
|
if not user_nick:
|
||||||
user_nick = ''
|
user_nick = ''
|
||||||
|
|
||||||
if encTag and GnuPG.USE_GPG:
|
if encTag and self.USE_GPG:
|
||||||
#decrypt
|
#decrypt
|
||||||
encmsg = encTag.getData()
|
encmsg = encTag.getData()
|
||||||
|
|
||||||
|
|
|
@ -49,8 +49,6 @@ from common.zeroconf import client_zeroconf
|
||||||
from common.zeroconf import zeroconf
|
from common.zeroconf import zeroconf
|
||||||
from connection_handlers_zeroconf import *
|
from connection_handlers_zeroconf import *
|
||||||
|
|
||||||
USE_GPG = GnuPG.USE_GPG
|
|
||||||
|
|
||||||
class ConnectionZeroconf(ConnectionHandlersZeroconf):
|
class ConnectionZeroconf(ConnectionHandlersZeroconf):
|
||||||
'''Connection class'''
|
'''Connection class'''
|
||||||
def __init__(self, name):
|
def __init__(self, name):
|
||||||
|
@ -62,7 +60,9 @@ class ConnectionZeroconf(ConnectionHandlersZeroconf):
|
||||||
self.connected = 0 # offline
|
self.connected = 0 # offline
|
||||||
self.connection = None
|
self.connection = None
|
||||||
self.gpg = None
|
self.gpg = None
|
||||||
if USE_GPG:
|
self.USE_GPG = False
|
||||||
|
if gajim.HAVE_GPG:
|
||||||
|
self.USE_GPG = True
|
||||||
self.gpg = GnuPG.GnuPG(gajim.config.get('use_gpg_agent'))
|
self.gpg = GnuPG.GnuPG(gajim.config.get('use_gpg_agent'))
|
||||||
self.is_zeroconf = True
|
self.is_zeroconf = True
|
||||||
self.privacy_rules_supported = False
|
self.privacy_rules_supported = False
|
||||||
|
@ -91,7 +91,8 @@ class ConnectionZeroconf(ConnectionHandlersZeroconf):
|
||||||
self.activity = {}
|
self.activity = {}
|
||||||
# Do we continue connection when we get roster (send presence,get vcard...)
|
# Do we continue connection when we get roster (send presence,get vcard...)
|
||||||
self.continue_connect_info = None
|
self.continue_connect_info = None
|
||||||
if USE_GPG:
|
if gajim.HAVE_GPG:
|
||||||
|
self.USE_GPG = True
|
||||||
self.gpg = GnuPG.GnuPG(gajim.config.get('use_gpg_agent'))
|
self.gpg = GnuPG.GnuPG(gajim.config.get('use_gpg_agent'))
|
||||||
|
|
||||||
self.get_config_values_or_default()
|
self.get_config_values_or_default()
|
||||||
|
@ -163,7 +164,7 @@ class ConnectionZeroconf(ConnectionHandlersZeroconf):
|
||||||
def get_signed_msg(self, msg):
|
def get_signed_msg(self, msg):
|
||||||
signed = ''
|
signed = ''
|
||||||
keyID = gajim.config.get_per('accounts', self.name, 'keyid')
|
keyID = gajim.config.get_per('accounts', self.name, 'keyid')
|
||||||
if keyID and USE_GPG:
|
if keyID and self.USE_GPG:
|
||||||
use_gpg_agent = gajim.config.get('use_gpg_agent')
|
use_gpg_agent = gajim.config.get('use_gpg_agent')
|
||||||
if self.connected < 2 and self.gpg.passphrase is None and \
|
if self.connected < 2 and self.gpg.passphrase is None and \
|
||||||
not use_gpg_agent:
|
not use_gpg_agent:
|
||||||
|
@ -373,7 +374,7 @@ class ConnectionZeroconf(ConnectionHandlersZeroconf):
|
||||||
|
|
||||||
msgtxt = msg
|
msgtxt = msg
|
||||||
msgenc = ''
|
msgenc = ''
|
||||||
if keyID and USE_GPG:
|
if keyID and self.USE_GPG:
|
||||||
# encrypt
|
# encrypt
|
||||||
msgenc, error = self.gpg.encrypt(msg, [keyID])
|
msgenc, error = self.gpg.encrypt(msg, [keyID])
|
||||||
if msgenc and not error:
|
if msgenc and not error:
|
||||||
|
@ -510,7 +511,7 @@ class ConnectionZeroconf(ConnectionHandlersZeroconf):
|
||||||
gajim.log.debug('This should not happen (send_agent_status)')
|
gajim.log.debug('This should not happen (send_agent_status)')
|
||||||
|
|
||||||
def gpg_passphrase(self, passphrase):
|
def gpg_passphrase(self, passphrase):
|
||||||
if USE_GPG:
|
if self.gpg:
|
||||||
use_gpg_agent = gajim.config.get('use_gpg_agent')
|
use_gpg_agent = gajim.config.get('use_gpg_agent')
|
||||||
if use_gpg_agent:
|
if use_gpg_agent:
|
||||||
self.gpg.passphrase = None
|
self.gpg.passphrase = None
|
||||||
|
@ -518,13 +519,13 @@ class ConnectionZeroconf(ConnectionHandlersZeroconf):
|
||||||
self.gpg.passphrase = passphrase
|
self.gpg.passphrase = passphrase
|
||||||
|
|
||||||
def ask_gpg_keys(self):
|
def ask_gpg_keys(self):
|
||||||
if USE_GPG:
|
if self.gpg:
|
||||||
keys = self.gpg.get_keys()
|
keys = self.gpg.get_keys()
|
||||||
return keys
|
return keys
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def ask_gpg_secrete_keys(self):
|
def ask_gpg_secrete_keys(self):
|
||||||
if USE_GPG:
|
if self.gpg:
|
||||||
keys = self.gpg.get_secret_keys()
|
keys = self.gpg.get_secret_keys()
|
||||||
return keys
|
return keys
|
||||||
return None
|
return None
|
||||||
|
|
|
@ -2079,8 +2079,7 @@ class AccountsWindow:
|
||||||
|
|
||||||
# self.current_account is None and/or gajim.connections is {}
|
# self.current_account is None and/or gajim.connections is {}
|
||||||
else:
|
else:
|
||||||
from common import GnuPG
|
if gajim.HAVE_GPG:
|
||||||
if GnuPG.USE_GPG:
|
|
||||||
secret_keys = GnuPG.GnuPG().get_secret_keys()
|
secret_keys = GnuPG.GnuPG().get_secret_keys()
|
||||||
else:
|
else:
|
||||||
secret_keys = []
|
secret_keys = []
|
||||||
|
@ -3674,8 +3673,7 @@ class ZeroconfPropertiesWindow:
|
||||||
|
|
||||||
# self.account is None and/or gajim.connections is {}
|
# self.account is None and/or gajim.connections is {}
|
||||||
else:
|
else:
|
||||||
from common import GnuPG
|
if gajim.HAVE_GPG:
|
||||||
if GnuPG.USE_GPG:
|
|
||||||
secret_keys = GnuPG.GnuPG().get_secret_keys()
|
secret_keys = GnuPG.GnuPG().get_secret_keys()
|
||||||
else:
|
else:
|
||||||
secret_keys = []
|
secret_keys = []
|
||||||
|
|
|
@ -179,8 +179,8 @@ class FeaturesWindow:
|
||||||
def gpg_available(self):
|
def gpg_available(self):
|
||||||
if os.name == 'nt':
|
if os.name == 'nt':
|
||||||
return False
|
return False
|
||||||
from common import GnuPG
|
from common import gajim
|
||||||
return GnuPG.USE_GPG
|
return gajim.HAVE_GPG
|
||||||
|
|
||||||
def network_manager_available(self):
|
def network_manager_available(self):
|
||||||
if os.name == 'nt':
|
if os.name == 'nt':
|
||||||
|
|
Loading…
Reference in New Issue