Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
G
gajim-plugins
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Model registry
Operate
Environments
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
gajim
gajim-plugins
Commits
8b85e8a0
Commit
8b85e8a0
authored
7 years ago
by
Philipp Hörist
Browse files
Options
Downloads
Plain Diff
Merge branch 'omemo' into 'gtk3'
omemo version 2.3.0 See merge request
!38
parents
de369fc6
ddf3f86b
No related branches found
Branches containing commit
No related tags found
Tags containing commit
2 merge requests
!41
Improved error messages
,
!38
omemo version 2.3.0
Changes
4
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
omemo/CHANGELOG
+3
-0
3 additions, 0 deletions
omemo/CHANGELOG
omemo/manifest.ini
+1
-1
1 addition, 1 deletion
omemo/manifest.ini
omemo/omemoplugin.py
+230
-237
230 additions, 237 deletions
omemo/omemoplugin.py
omemo/ui.py
+35
-314
35 additions, 314 deletions
omemo/ui.py
with
269 additions
and
552 deletions
omemo/CHANGELOG
+
3
−
0
View file @
8b85e8a0
2.3.0 / 2017-05-07
- Make plugin compatible with Gajims encryption API
2.2.1 / 2017-04-15
- Recognize aesgcm uri scheme
...
...
This diff is collapsed.
Click to expand it.
omemo/manifest.ini
+
1
−
1
View file @
8b85e8a0
[info]
name:
OMEMO
short_name:
omemo
version:
2.
2.1
version:
2.
3.0
description:
OMEMO
is
an
XMPP
Extension
Protocol
(XEP)
for
secure
multi-client
end-to-end
encryption
based
on
Axolotl
and
PEP.
You
need
to
install
some
dependencys,
you
can
find
install
instructions
for
your
system
in
the
Github
Wiki.
authors:
Bahtiar
`kalkin-`
Gadimov
<bahtiar@gadimov.de>
Daniel
Gultsch
<daniel@gultsch.de>
...
...
This diff is collapsed.
Click to expand it.
omemo/omemoplugin.py
+
230
−
237
View file @
8b85e8a0
This diff is collapsed.
Click to expand it.
omemo/ui.py
+
35
−
314
View file @
8b85e8a0
# -*- 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
:
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment