Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Malte L
gajim-plugins
Commits
b8ff3d19
Commit
b8ff3d19
authored
May 07, 2017
by
Philipp Hörist
Browse files
[omemo] Use Gajims encryption API
parent
de369fc6
Changes
2
Expand all
Hide whitespace changes
Inline
Side-by-side
omemo/omemoplugin.py
View file @
b8ff3d19
This diff is collapsed.
Click to expand it.
omemo/ui.py
View file @
b8ff3d19
# -*- coding: utf-8 -*-
#
# Copyright 2015 Bahtiar `kalkin-` Gadimov <bahtiar@gadimov.de>
# Copyright 2015 Daniel Gultsch <daniel@cgultsch.de>
#
# This file is part of Gajim-OMEMO plugin.
#
# The Gajim-OMEMO plugin is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option) any
# later version.
#
# Gajim-OMEMO is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along with
# the Gajim-OMEMO plugin. If not, see <http://www.gnu.org/licenses/>.
#
'''
Copyright 2015 Bahtiar `kalkin-` Gadimov <bahtiar@gadimov.de>
Copyright 2015 Daniel Gultsch <daniel@cgultsch.de>
Copyright 2016 Philipp Hörist <philipp@hoerist.com>
This file is part of Gajim-OMEMO plugin.
The Gajim-OMEMO plugin is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by the Free
Software Foundation, either version 3 of the License, or (at your option) any
later version.
Gajim-OMEMO is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
the Gajim-OMEMO plugin. If not, see <http://www.gnu.org/licenses/>.
'''
import
binascii
import
logging
import
os
import
message_control
from
gi.repository
import
GObject
,
Gtk
,
GdkPixbuf
,
Gdk
from
enum
import
IntEnum
,
unique
# pylint: disable=import-error
import
gtkgui_helpers
from
common
import
gajim
from
dialogs
import
YesNoDialog
from
plugins.gui
import
GajimPluginConfigDialog
from
gi.repository
import
Gtk
,
GdkPixbuf
,
Gdk
from
axolotl.state.sessionrecord
import
SessionRecord
from
common
import
configpaths
log
=
logging
.
getLogger
(
'gajim.plugin_system.omemo'
)
...
...
@@ -43,285 +38,17 @@ except Exception as e:
log
.
exception
(
'Error:'
)
log
.
error
(
'python-qrcode or dependencies of it, are not available'
)
# pylint: enable=import-error
UNDECIDED
=
2
TRUSTED
=
1
UNTRUSTED
=
0
class
OmemoButton
(
Gtk
.
Button
):
def
__init__
(
self
,
plugin
,
chat_control
,
ui
,
enabled
):
super
(
OmemoButton
,
self
).
__init__
(
label
=
None
,
stock
=
None
)
self
.
chat_control
=
chat_control
self
.
set_property
(
'relief'
,
Gtk
.
ReliefStyle
.
NONE
)
self
.
set_property
(
'can-focus'
,
False
)
self
.
set_sensitive
(
True
)
icon
=
Gtk
.
Image
.
new_from_file
(
plugin
.
local_file_path
(
'omemo16x16.png'
))
self
.
set_image
(
icon
)
self
.
set_tooltip_text
(
'OMEMO Encryption'
)
self
.
connect
(
'clicked'
,
self
.
on_click
)
self
.
menu
=
OmemoMenu
(
ui
,
enabled
)
def
on_click
(
self
,
widget
):
"""
Popup omemo menu
"""
gtkgui_helpers
.
popup_emoticons_under_button
(
self
.
menu
,
widget
,
self
.
chat_control
.
parent_win
)
def
set_omemo_state
(
self
,
state
):
self
.
menu
.
set_omemo_state
(
state
)
class
OmemoMenu
(
Gtk
.
Menu
):
def
__init__
(
self
,
ui
,
enabled
):
super
(
OmemoMenu
,
self
).
__init__
()
self
.
ui
=
ui
self
.
item_omemo_state
=
Gtk
.
CheckMenuItem
(
'Activate OMEMO'
)
self
.
item_omemo_state
.
set_active
(
enabled
)
self
.
item_omemo_state
.
connect
(
'activate'
,
self
.
on_toggle_omemo
)
self
.
append
(
self
.
item_omemo_state
)
item
=
Gtk
.
ImageMenuItem
(
'Fingerprints'
)
icon
=
Gtk
.
Image
.
new_from_stock
(
Gtk
.
STOCK_DIALOG_AUTHENTICATION
,
Gtk
.
IconSize
.
MENU
)
item
.
set_image
(
icon
)
item
.
connect
(
'activate'
,
self
.
on_open_fingerprint_window
)
self
.
append
(
item
)
self
.
show_all
()
def
on_toggle_omemo
(
self
,
widget
):
self
.
ui
.
set_omemo_state
(
widget
.
get_active
())
def
on_open_fingerprint_window
(
self
,
widget
):
self
.
ui
.
show_fingerprint_window
()
def
set_omemo_state
(
self
,
state
):
self
.
item_omemo_state
.
handler_block_by_func
(
self
.
on_toggle_omemo
)
self
.
item_omemo_state
.
set_active
(
state
)
self
.
item_omemo_state
.
handler_unblock_by_func
(
self
.
on_toggle_omemo
)
class
Ui
(
object
):
def
__init__
(
self
,
plugin
,
chat_control
,
enabled
,
state
):
self
.
contact
=
chat_control
.
contact
self
.
chat_control
=
chat_control
self
.
plugin
=
plugin
self
.
state
=
state
self
.
account
=
self
.
contact
.
account
.
name
self
.
windowinstances
=
{}
self
.
groupchat
=
False
if
chat_control
.
type_id
==
message_control
.
TYPE_GC
:
self
.
groupchat
=
True
self
.
omemo_capable
=
False
self
.
room
=
self
.
chat_control
.
room_jid
self
.
display_omemo_state
()
self
.
refresh_auth_lock_icon
()
self
.
omemobutton
=
OmemoButton
(
plugin
,
chat_control
,
self
,
enabled
)
self
.
actions_hbox
=
chat_control
.
xml
.
get_object
(
'actions_hbox'
)
send_button
=
chat_control
.
xml
.
get_object
(
'send_button'
)
send_button_pos
=
self
.
actions_hbox
.
child_get_property
(
send_button
,
'position'
)
self
.
actions_hbox
.
add
(
self
.
omemobutton
)
self
.
actions_hbox
.
reorder_child
(
self
.
omemobutton
,
send_button_pos
-
1
)
self
.
omemobutton
.
show_all
()
# add a OMEMO entry to the context/advanced menu
self
.
chat_control
.
omemo_orig_prepare_context_menu
=
\
self
.
chat_control
.
prepare_context_menu
def
omemo_prepare_context_menu
(
hide_buttonbar_items
=
False
):
menu
=
self
.
chat_control
.
\
omemo_orig_prepare_context_menu
(
hide_buttonbar_items
)
submenu
=
OmemoMenu
(
self
,
self
.
encryption_active
())
item
=
Gtk
.
ImageMenuItem
(
'OMEMO Encryption'
)
icon_path
=
plugin
.
local_file_path
(
'omemo16x16.png'
)
item
.
set_image
(
Gtk
.
Image
.
new_from_file
(
icon_path
))
item
.
set_submenu
(
submenu
)
if
self
.
groupchat
:
item
.
set_sensitive
(
self
.
omemo_capable
)
# at index 8 is the separator after the esession encryption entry
menu
.
insert
(
item
,
8
)
return
menu
self
.
chat_control
.
prepare_context_menu
=
omemo_prepare_context_menu
# Hook into Send Button so we can check Stuff before sending
self
.
chat_control
.
orig_send_message
=
\
self
.
chat_control
.
send_message
def
omemo_send_message
(
message
,
keyID
=
''
,
chatstate
=
None
,
xhtml
=
None
,
process_commands
=
True
,
attention
=
False
):
self
.
new_fingerprints_available
()
if
self
.
encryption_active
()
and
\
self
.
plugin
.
are_keys_missing
(
self
.
account
,
self
.
contact
.
jid
):
log
.
debug
(
self
.
account
+
' => No Trusted Fingerprints for '
+
self
.
contact
.
jid
)
self
.
no_trusted_fingerprints_warning
()
else
:
self
.
chat_control
.
orig_send_message
(
message
,
keyID
,
chatstate
,
xhtml
,
process_commands
,
attention
)
log
.
debug
(
self
.
account
+
' => Sending Message to '
+
self
.
contact
.
jid
)
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
)
if
self
.
groupchat
:
self
.
chat_control
.
send_message
=
omemo_send_gc_message
else
:
self
.
chat_control
.
send_message
=
omemo_send_message
def
set_omemo_state
(
self
,
enabled
):
"""
Enable or disable OMEMO for this window's contact and update the
window ui accordingly
"""
if
enabled
:
log
.
debug
(
self
.
contact
.
account
.
name
+
' => Enable OMEMO for '
+
self
.
contact
.
jid
)
self
.
plugin
.
omemo_enable_for
(
self
.
contact
.
jid
,
self
.
contact
.
account
.
name
)
self
.
refresh_auth_lock_icon
()
else
:
log
.
debug
(
self
.
contact
.
account
.
name
+
' => Disable OMEMO for '
+
self
.
contact
.
jid
)
self
.
plugin
.
omemo_disable_for
(
self
.
contact
.
jid
,
self
.
contact
.
account
.
name
)
self
.
refresh_auth_lock_icon
()
self
.
omemobutton
.
set_omemo_state
(
enabled
)
self
.
display_omemo_state
()
def
sensitive
(
self
,
value
):
self
.
omemobutton
.
set_sensitive
(
value
)
self
.
omemo_capable
=
value
if
value
:
self
.
chat_control
.
prepare_context_menu
def
encryption_active
(
self
):
return
self
.
state
.
encryption
.
is_active
(
self
.
contact
.
jid
)
def
activate_omemo
(
self
):
if
not
self
.
encryption_active
():
self
.
set_omemo_state
(
True
)
def
new_fingerprints_available
(
self
):
jid
=
self
.
contact
.
jid
if
self
.
groupchat
and
self
.
room
in
self
.
plugin
.
groupchat
:
for
nick
in
self
.
plugin
.
groupchat
[
self
.
room
]:
real_jid
=
self
.
plugin
.
groupchat
[
self
.
room
][
nick
]
fingerprints
=
self
.
state
.
store
.
\
getNewFingerprints
(
real_jid
)
if
fingerprints
:
self
.
show_fingerprint_window
(
fingerprints
)
elif
not
self
.
groupchat
:
fingerprints
=
self
.
state
.
store
.
getNewFingerprints
(
jid
)
if
fingerprints
:
self
.
show_fingerprint_window
(
fingerprints
)
def
show_fingerprint_window
(
self
,
fingerprints
=
None
):
if
'dialog'
not
in
self
.
windowinstances
:
if
self
.
groupchat
:
self
.
windowinstances
[
'dialog'
]
=
\
FingerprintWindow
(
self
.
plugin
,
self
.
contact
,
self
.
chat_control
.
parent_win
.
window
,
self
.
windowinstances
,
groupchat
=
True
)
else
:
self
.
windowinstances
[
'dialog'
]
=
\
FingerprintWindow
(
self
.
plugin
,
self
.
contact
,
self
.
chat_control
.
parent_win
.
window
,
self
.
windowinstances
)
self
.
windowinstances
[
'dialog'
].
show_all
()
if
fingerprints
:
log
.
debug
(
self
.
account
+
' => Showing Fingerprint Prompt for '
+
self
.
contact
.
jid
)
self
.
state
.
store
.
setShownFingerprints
(
fingerprints
)
else
:
self
.
windowinstances
[
'dialog'
].
update_context_list
()
if
fingerprints
:
self
.
state
.
store
.
setShownFingerprints
(
fingerprints
)
def
plain_warning
(
self
):
self
.
chat_control
.
print_conversation_line
(
'Received plaintext message! '
+
'Your next message will still be encrypted!'
,
'status'
,
''
,
None
)
def
display_omemo_state
(
self
):
if
self
.
encryption_active
():
msg
=
u
'OMEMO encryption enabled'
else
:
msg
=
u
'OMEMO encryption disabled'
self
.
chat_control
.
print_conversation_line
(
msg
,
'status'
,
''
,
None
)
def
no_trusted_fingerprints_warning
(
self
):
msg
=
"To send an encrypted message, you have to "
\
"first trust the fingerprint of your contact!"
self
.
chat_control
.
print_conversation_line
(
msg
,
'status'
,
''
,
None
)
from
common
import
gajim
from
common
import
configpaths
from
dialogs
import
YesNoDialog
from
plugins.gui
import
GajimPluginConfigDialog
def
refresh_auth_lock_icon
(
self
):
if
self
.
groupchat
:
return
if
self
.
encryption_active
():
if
self
.
state
.
getUndecidedFingerprints
(
self
.
contact
.
jid
):
self
.
chat_control
.
_show_lock_image
(
True
,
'OMEMO'
,
True
,
True
,
False
)
else
:
self
.
chat_control
.
_show_lock_image
(
True
,
'OMEMO'
,
True
,
True
,
True
)
else
:
self
.
chat_control
.
_show_lock_image
(
False
,
'OMEMO'
,
False
,
True
,
False
)
def
removeUi
(
self
):
self
.
actions_hbox
.
remove
(
self
.
omemobutton
)
self
.
chat_control
.
_show_lock_image
(
False
,
'OMEMO'
,
False
,
True
,
False
)
self
.
chat_control
.
prepare_context_menu
=
\
self
.
chat_control
.
omemo_orig_prepare_context_menu
self
.
chat_control
.
send_message
=
self
.
chat_control
.
orig_send_message
@
unique
class
State
(
IntEnum
):
UNTRUSTED
=
0
TRUSTED
=
1
UNDECIDED
=
2
class
OMEMOConfigDialog
(
GajimPluginConfigDialog
):
...
...
@@ -480,7 +207,7 @@ class OMEMOConfigDialog(GajimPluginConfigDialog):
mod
,
paths
=
self
.
fpr_view
.
get_selection
().
get_selected_rows
()
def
on_yes
(
checked
,
identity_key
):
state
.
store
.
setTrust
(
identity_key
,
TRUSTED
)
state
.
store
.
setTrust
(
identity_key
,
State
.
TRUSTED
)
try
:
if
self
.
plugin
.
ui_list
[
account
]:
self
.
plugin
.
ui_list
[
account
][
jid
].
\
...
...
@@ -490,7 +217,7 @@ class OMEMOConfigDialog(GajimPluginConfigDialog):
self
.
update_context_list
()
def
on_no
(
identity_key
):
state
.
store
.
setTrust
(
identity_key
,
UNTRUSTED
)
state
.
store
.
setTrust
(
identity_key
,
State
.
UNTRUSTED
)
try
:
if
jid
in
self
.
plugin
.
ui_list
[
account
]:
self
.
plugin
.
ui_list
[
account
][
jid
].
\
...
...
@@ -700,17 +427,11 @@ class FingerprintWindow(Gtk.Dialog):
mod
,
paths
=
self
.
fpr_view
.
get_selection
().
get_selected_rows
()
def
on_yes
(
checked
,
identity_key
):
state
.
store
.
setTrust
(
identity_key
,
TRUSTED
)
if
not
self
.
groupchat
:
self
.
plugin
.
ui_list
[
self
.
account
][
self
.
contact
.
jid
].
\
refresh_auth_lock_icon
()
state
.
store
.
setTrust
(
identity_key
,
State
.
TRUSTED
)
self
.
update_context_list
()
def
on_no
(
identity_key
):
state
.
store
.
setTrust
(
identity_key
,
UNTRUSTED
)
if
not
self
.
groupchat
:
self
.
plugin
.
ui_list
[
self
.
account
][
self
.
contact
.
jid
].
\
refresh_auth_lock_icon
()
state
.
store
.
setTrust
(
identity_key
,
State
.
UNTRUSTED
)
self
.
update_context_list
()
for
path
in
paths
:
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment