make gotr plugin visible but not activatable if potr is missing
This commit is contained in:
@@ -74,148 +74,147 @@ try:
|
||||
import potr
|
||||
if not hasattr(potr, 'VERSION') or potr.VERSION < MINVERSION:
|
||||
raise ImportError('old / unsupported python-otr version')
|
||||
except ImportError:
|
||||
HAS_POTR = False
|
||||
|
||||
def get_jid_from_fjid(fjid):
|
||||
return gajim.get_room_and_nick_from_fjid(fjid)[0]
|
||||
def get_jid_from_fjid(fjid):
|
||||
return gajim.get_room_and_nick_from_fjid(fjid)[0]
|
||||
|
||||
class GajimContext(potr.context.Context):
|
||||
# self.peer is fjid
|
||||
# self.jid does not contain resource
|
||||
__slots__ = ['smpWindow', 'jid']
|
||||
class GajimContext(potr.context.Context):
|
||||
# self.peer is fjid
|
||||
# self.jid does not contain resource
|
||||
__slots__ = ['smpWindow', 'jid']
|
||||
|
||||
def __init__(self, account, peer):
|
||||
super(GajimContext, self).__init__(account, peer)
|
||||
self.jid = get_jid_from_fjid(peer)
|
||||
self.trustName = self.jid
|
||||
self.smpWindow = ui.ContactOtrSmpWindow(self)
|
||||
def __init__(self, account, peer):
|
||||
super(GajimContext, self).__init__(account, peer)
|
||||
self.jid = get_jid_from_fjid(peer)
|
||||
self.trustName = self.jid
|
||||
self.smpWindow = ui.ContactOtrSmpWindow(self)
|
||||
|
||||
def inject(self, msg, appdata=None):
|
||||
log.debug('inject(appdata=%s)', appdata)
|
||||
msg = unicode(msg)
|
||||
account = self.user.accountname
|
||||
def inject(self, msg, appdata=None):
|
||||
log.debug('inject(appdata=%s)', appdata)
|
||||
msg = unicode(msg)
|
||||
account = self.user.accountname
|
||||
|
||||
stanza = common.xmpp.Message(to=self.peer, body=msg, typ='chat')
|
||||
if appdata is not None:
|
||||
session = appdata.get('session', None)
|
||||
if session is not None:
|
||||
stanza.setThread(session.thread_id)
|
||||
gajim.connections[account].connection.send(stanza, now=True)
|
||||
stanza = common.xmpp.Message(to=self.peer, body=msg, typ='chat')
|
||||
if appdata is not None:
|
||||
session = appdata.get('session', None)
|
||||
if session is not None:
|
||||
stanza.setThread(session.thread_id)
|
||||
gajim.connections[account].connection.send(stanza, now=True)
|
||||
|
||||
def setState(self, newstate):
|
||||
if self.state == potr.context.STATE_ENCRYPTED:
|
||||
# we were encrypted
|
||||
if newstate == potr.context.STATE_ENCRYPTED:
|
||||
# and are still -> it's just a refresh
|
||||
OtrPlugin.gajim_log(
|
||||
_('Private conversation with %s refreshed.') % self.peer,
|
||||
self.user.accountname, self.peer)
|
||||
elif newstate == potr.context.STATE_FINISHED:
|
||||
# and aren't anymore -> other side disconnected
|
||||
OtrPlugin.gajim_log(_('%s has ended his/her private '
|
||||
'conversation with you. You should do the same.')
|
||||
% self.peer, self.user.accountname, self.peer)
|
||||
else:
|
||||
if newstate == potr.context.STATE_ENCRYPTED:
|
||||
# we are now encrypted
|
||||
trust = self.getCurrentTrust()
|
||||
if trust is None:
|
||||
fpr = str(self.getCurrentKey())
|
||||
OtrPlugin.gajim_log(_('New fingerprint for %(peer)s: %(fpr)s')
|
||||
% {'peer': self.peer, 'fpr': fpr},
|
||||
def setState(self, newstate):
|
||||
if self.state == potr.context.STATE_ENCRYPTED:
|
||||
# we were encrypted
|
||||
if newstate == potr.context.STATE_ENCRYPTED:
|
||||
# and are still -> it's just a refresh
|
||||
OtrPlugin.gajim_log(
|
||||
_('Private conversation with %s refreshed.') % self.peer,
|
||||
self.user.accountname, self.peer)
|
||||
self.setCurrentTrust('')
|
||||
trustStr = 'authenticated' if bool(trust) else '*unauthenticated*'
|
||||
elif newstate == potr.context.STATE_FINISHED:
|
||||
# and aren't anymore -> other side disconnected
|
||||
OtrPlugin.gajim_log(_('%s has ended his/her private '
|
||||
'conversation with you. You should do the same.')
|
||||
% self.peer, self.user.accountname, self.peer)
|
||||
else:
|
||||
if newstate == potr.context.STATE_ENCRYPTED:
|
||||
# we are now encrypted
|
||||
trust = self.getCurrentTrust()
|
||||
if trust is None:
|
||||
fpr = str(self.getCurrentKey())
|
||||
OtrPlugin.gajim_log(_('New fingerprint for %(peer)s: %(fpr)s')
|
||||
% {'peer': self.peer, 'fpr': fpr},
|
||||
self.user.accountname, self.peer)
|
||||
self.setCurrentTrust('')
|
||||
trustStr = 'authenticated' if bool(trust) else '*unauthenticated*'
|
||||
OtrPlugin.gajim_log(
|
||||
_('%(trustStr)s secured OTR conversation with %(peer)s started')
|
||||
% {'trustStr': trustStr, 'peer': self.peer},
|
||||
self.user.accountname, self.peer)
|
||||
|
||||
if self.state != potr.context.STATE_PLAINTEXT and \
|
||||
newstate == potr.context.STATE_PLAINTEXT:
|
||||
# we are now plaintext
|
||||
OtrPlugin.gajim_log(
|
||||
_('%(trustStr)s secured OTR conversation with %(peer)s started')
|
||||
% {'trustStr': trustStr, 'peer': self.peer},
|
||||
self.user.accountname, self.peer)
|
||||
_('Private conversation with %s lost.') % self.peer,
|
||||
self.user.accountname, self.peer)
|
||||
|
||||
if self.state != potr.context.STATE_PLAINTEXT and \
|
||||
newstate == potr.context.STATE_PLAINTEXT:
|
||||
# we are now plaintext
|
||||
OtrPlugin.gajim_log(
|
||||
_('Private conversation with %s lost.') % self.peer,
|
||||
self.user.accountname, self.peer)
|
||||
super(GajimContext, self).setState(newstate)
|
||||
OtrPlugin.update_otr(self.peer, self.user.accountname)
|
||||
self.user.plugin.update_context_list()
|
||||
|
||||
super(GajimContext, self).setState(newstate)
|
||||
OtrPlugin.update_otr(self.peer, self.user.accountname)
|
||||
self.user.plugin.update_context_list()
|
||||
def getPolicy(self, key):
|
||||
ret = self.user.plugin.get_flags(self.user.accountname, self.jid)[key]
|
||||
log.debug('getPolicy(key=%s) = %s', key, ret)
|
||||
return ret
|
||||
|
||||
def getPolicy(self, key):
|
||||
ret = self.user.plugin.get_flags(self.user.accountname, self.jid)[key]
|
||||
log.debug('getPolicy(key=%s) = %s', key, ret)
|
||||
return ret
|
||||
class GajimOtrAccount(potr.context.Account):
|
||||
contextclass = GajimContext
|
||||
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)
|
||||
|
||||
class GajimOtrAccount(potr.context.Account):
|
||||
contextclass = GajimContext
|
||||
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)
|
||||
def dropPrivkey(self):
|
||||
try:
|
||||
os.remove(self.keyFilePath + '.key3')
|
||||
except IOError, e:
|
||||
if e.errno != 2:
|
||||
log.exception('IOError occurred when removing key file for %s',
|
||||
self.name)
|
||||
self.privkey = None
|
||||
|
||||
def dropPrivkey(self):
|
||||
try:
|
||||
os.remove(self.keyFilePath + '.key3')
|
||||
except IOError, e:
|
||||
if e.errno != 2:
|
||||
log.exception('IOError occurred when removing key file for %s',
|
||||
self.name)
|
||||
self.privkey = None
|
||||
def loadPrivkey(self):
|
||||
try:
|
||||
with open(self.keyFilePath + '.key3', 'rb') as keyFile:
|
||||
return potr.crypt.PK.parsePrivateKey(keyFile.read())[0]
|
||||
except IOError, e:
|
||||
if e.errno != 2:
|
||||
log.exception('IOError occurred when loading key file for %s',
|
||||
self.name)
|
||||
return None
|
||||
|
||||
def loadPrivkey(self):
|
||||
try:
|
||||
with open(self.keyFilePath + '.key3', 'rb') as keyFile:
|
||||
return potr.crypt.PK.parsePrivateKey(keyFile.read())[0]
|
||||
except IOError, e:
|
||||
if e.errno != 2:
|
||||
def savePrivkey(self):
|
||||
try:
|
||||
with open(self.keyFilePath + '.key3', 'wb') as keyFile:
|
||||
keyFile.write(self.getPrivkey().serializePrivateKey())
|
||||
except IOError, e:
|
||||
log.exception('IOError occurred when loading key file for %s',
|
||||
self.name)
|
||||
return None
|
||||
|
||||
def savePrivkey(self):
|
||||
try:
|
||||
with open(self.keyFilePath + '.key3', 'wb') as keyFile:
|
||||
keyFile.write(self.getPrivkey().serializePrivateKey())
|
||||
except IOError, e:
|
||||
log.exception('IOError occurred when loading key file for %s',
|
||||
self.name)
|
||||
def loadTrusts(self, newCtxCb=None):
|
||||
''' load the fingerprint trustdb '''
|
||||
# it has the same format as libotr, therefore the
|
||||
# redundant account / proto field
|
||||
try:
|
||||
with open(self.keyFilePath + '.fpr', 'r') as fprFile:
|
||||
for line in fprFile:
|
||||
ctx, acc, proto, fpr, trust = line[:-1].split('\t')
|
||||
|
||||
def loadTrusts(self, newCtxCb=None):
|
||||
''' load the fingerprint trustdb '''
|
||||
# it has the same format as libotr, therefore the
|
||||
# redundant account / proto field
|
||||
try:
|
||||
with open(self.keyFilePath + '.fpr', 'r') as fprFile:
|
||||
for line in fprFile:
|
||||
ctx, acc, proto, fpr, trust = line[:-1].split('\t')
|
||||
if acc != self.name or proto != PROTOCOL:
|
||||
continue
|
||||
|
||||
if acc != self.name or proto != PROTOCOL:
|
||||
continue
|
||||
jid = get_jid_from_fjid(ctx)
|
||||
self.setTrust(jid, fpr, trust)
|
||||
except IOError, e:
|
||||
if e.errno != 2:
|
||||
log.exception('IOError occurred when loading fpr file for %s',
|
||||
self.name)
|
||||
|
||||
jid = get_jid_from_fjid(ctx)
|
||||
self.setTrust(jid, fpr, trust)
|
||||
except IOError, e:
|
||||
if e.errno != 2:
|
||||
def saveTrusts(self):
|
||||
try:
|
||||
with open(self.keyFilePath + '.fpr', 'w') as fprFile:
|
||||
for uid, trusts in self.trusts.iteritems():
|
||||
for fpr, trustVal in trusts.iteritems():
|
||||
fprFile.write('\t'.join(
|
||||
(uid, self.name, PROTOCOL, fpr, trustVal)))
|
||||
fprFile.write('\n')
|
||||
except IOError, e:
|
||||
log.exception('IOError occurred when loading fpr file for %s',
|
||||
self.name)
|
||||
|
||||
def saveTrusts(self):
|
||||
try:
|
||||
with open(self.keyFilePath + '.fpr', 'w') as fprFile:
|
||||
for uid, trusts in self.trusts.iteritems():
|
||||
for fpr, trustVal in trusts.iteritems():
|
||||
fprFile.write('\t'.join(
|
||||
(uid, self.name, PROTOCOL, fpr, trustVal)))
|
||||
fprFile.write('\n')
|
||||
except IOError, e:
|
||||
log.exception('IOError occurred when loading fpr file for %s',
|
||||
self.name)
|
||||
|
||||
except ImportError:
|
||||
HAS_POTR = False
|
||||
|
||||
def otr_dialog_destroy(widget, *args, **kwargs):
|
||||
widget.destroy()
|
||||
@@ -236,15 +235,19 @@ class OtrPlugin(GajimPlugin):
|
||||
self.gui_extension_points = {
|
||||
'chat_control' : (self.cc_connect, self.cc_disconnect)
|
||||
}
|
||||
if not HAS_POTR:
|
||||
self.activatable = False
|
||||
self.available_text = 'potr is not installed. Get it from %s' % \
|
||||
'https://github.com/afflux/pure-python-otr'
|
||||
else:
|
||||
for acc in gajim.contacts.get_accounts():
|
||||
self.us[acc] = GajimOtrAccount(self, acc)
|
||||
self.us[acc].loadTrusts()
|
||||
|
||||
for acc in gajim.contacts.get_accounts():
|
||||
self.us[acc] = GajimOtrAccount(self, acc)
|
||||
self.us[acc].loadTrusts()
|
||||
|
||||
acc = str(acc)
|
||||
if acc not in self.config or None not in self.config[acc]:
|
||||
self.config[acc] = {None:DEFAULTFLAGS.copy()}
|
||||
self.update_context_list()
|
||||
acc = str(acc)
|
||||
if acc not in self.config or None not in self.config[acc]:
|
||||
self.config[acc] = {None:DEFAULTFLAGS.copy()}
|
||||
self.update_context_list()
|
||||
|
||||
@log_calls('OtrPlugin')
|
||||
def activate(self):
|
||||
|
||||
@@ -24,7 +24,11 @@ from common import gajim
|
||||
from plugins.gui import GajimPluginConfigDialog
|
||||
|
||||
import otrmodule
|
||||
import potr
|
||||
HAS_PORT = True
|
||||
try:
|
||||
import potr
|
||||
except:
|
||||
HAS_POTR = False
|
||||
|
||||
|
||||
class OtrPluginConfigDialog(GajimPluginConfigDialog):
|
||||
|
||||
Reference in New Issue
Block a user