Changeset 9861
- Timestamp:
- 06/29/08 06:39:29 (3 months ago)
- Location:
- trunk
- Files:
-
- 1 added
- 7 modified
-
data/glade/esession_info_window.glade (added)
-
data/glade/message_window.glade (modified) (1 diff)
-
src/chat_control.py (modified) (6 diffs)
-
src/common/stanza_session.py (modified) (3 diffs)
-
src/dialogs.py (modified) (2 diffs)
-
src/negotiation.py (modified) (3 diffs)
-
src/secrets.py (modified) (1 diff)
-
src/session.py (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/data/glade/message_window.glade
r9653 r9861 112 112 <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> 113 113 <child> 114 <widget class="GtkImage" id="lock_image"> 115 <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> 116 <property name="no_show_all">True</property> 117 <property name="stock">gtk-dialog-authentication</property> 118 <property name="icon_size">1</property> 119 </widget> 114 <widget class="GtkButton" id="authentication_button"> 115 <property name="no_show_all">True</property> 116 <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> 117 <property name="relief">GTK_RELIEF_NONE</property> 118 <property name="focus_on_click">False</property> 119 <property name="response_id">0</property> 120 <child> 121 <widget class="GtkImage" id="lock_image"> 122 <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> 123 <property name="stock">gtk-dialog-authentication</property> 124 <property name="icon_size">1</property> 125 </widget> 126 </child> 127 </widget> 120 128 <packing> 121 129 <property name="expand">False</property> -
trunk/src/chat_control.py
r9811 r9861 1057 1057 gajim.config.get('hide_chat_banner')) 1058 1058 1059 self.authentication_button = self.xml.get_widget('authentication_button') 1060 id = self.authentication_button.connect('clicked', self._on_authentication_button_clicked) 1061 self.handlers[id] = self.authentication_button 1062 1059 1063 # Add lock image to show chat encryption 1060 1064 self.lock_image = self.xml.get_widget('lock_image') … … 1116 1120 self.handlers[id] = widget 1117 1121 1118 self.session = session 1122 if not session: 1123 session = gajim.connections[self.account].find_controlless_session(self.contact.jid) 1124 self.session = session 1125 1119 1126 if session: 1120 1127 session.control = self 1121 1122 # Enable ecryption if needed 1128 self.session = session 1129 1130 if session.enable_encryption: 1131 self.print_esession_details() 1132 1133 # Enable encryption if needed 1123 1134 e2e_is_active = hasattr(self, 'session') and self.session and self.session.enable_encryption 1124 1135 self.gpg_is_active = False … … 1135 1146 self.session.loggable = gajim.config.get('log_encrypted_sessions') 1136 1147 self._show_lock_image(self.gpg_is_active, 'GPG', self.gpg_is_active, self.session and \ 1137 self.session.is_loggable() )1148 self.session.is_loggable(), self.session and self.session.verified_identity) 1138 1149 1139 1150 self.status_tooltip = gtk.Tooltips() … … 1366 1377 1367 1378 self._show_lock_image(self.gpg_is_active, 'GPG', self.gpg_is_active, self.session and \ 1368 self.session.is_loggable() )1379 self.session.is_loggable(), self.session and self.session.verified_identity) 1369 1380 1370 1381 def _show_lock_image(self, visible, enc_type = '', enc_enabled = False, chat_logged = False, authenticated = False): … … 1374 1385 logged_string = chat_logged and 'will' or 'will NOT' 1375 1386 1376 if enc_type == 'OTR':1377 authenticated_string = authenticated \1378 and ' and authenticated' \1379 or ' and NOT authenticated'1380 else:1381 authenticated_string = ''1382 1383 tooltip = '%s Encryption %s active%s.\n' \1387 if authenticated: 1388 authenticated_string = ' and authenticated' 1389 self.lock_image.set_from_stock('gtk-dialog-authentication', 1) 1390 else: 1391 authenticated_string = ' and NOT authenticated' 1392 self.lock_image.set_from_stock('gtk-dialog-warning', 1) 1393 1394 tooltip = '%s encryption %s active%s.\n' \ 1384 1395 'Your chat session %s be logged.' % \ 1385 (enc_type, status_string, authenticated_string, 1396 (enc_type, status_string, authenticated_string, 1386 1397 logged_string) 1387 1398 1388 self.lock_tooltip.set_tip(self. lock_image, tooltip)1389 self.widget_set_visible(self. lock_image, not visible)1399 self.lock_tooltip.set_tip(self.authentication_button, tooltip) 1400 self.widget_set_visible(self.authentication_button, not visible) 1390 1401 self.lock_image.set_sensitive(enc_enabled) 1402 1403 def _on_authentication_button_clicked(self, widget): 1404 if self.session and self.session.enable_encryption: 1405 dialogs.ESessionInfoWindow(self.session) 1391 1406 1392 1407 def _process_command(self, message): … … 1589 1604 1590 1605 ChatControlBase.print_conversation_line(self, msg, 'status', '', None) 1606 1607 if not self.session.verified_identity: 1608 ChatControlBase.print_conversation_line(self, 'SAS not verified', 'status', '', None) 1591 1609 else: 1592 1610 msg = _('E2E encryption disabled') 1593 1611 ChatControlBase.print_conversation_line(self, msg, 'status', '', None) 1612 1594 1613 self._show_lock_image(e2e_is_active, 'E2E', e2e_is_active, self.session and \ 1595 self.session.is_loggable() )1614 self.session.is_loggable(), self.session and self.session.verified_identity) 1596 1615 1597 1616 def print_conversation(self, text, frm='', tim=None, encrypted=False, -
trunk/src/common/stanza_session.py
r9802 r9861 184 184 self._kc_o = None 185 185 186 # has the remote contact's identity ever been verified? 187 self.verified_identity = False 188 186 189 # keep the encrypter updated with my latest cipher key 187 190 def set_kc_s(self, value): … … 339 342 340 343 if i_o == 'a' and self.sas_algs == 'sas28x5': 341 # XXX not necessary if there's a verified retained secret 344 # we don't need to calculate this if there's a verified retained secret 345 # (but we do anyways) 342 346 self.sas = crypto.sas_28x5(m_o, self.form_s) 343 347 … … 845 849 self.control.print_esession_details() 846 850 847 # calculate and store the new retained secret848 # prompt the user to check the remote party's identity (if necessary)849 def do_retained_secret(self, k, srs): 851 def do_retained_secret(self, k, old_srs): 852 '''calculate the new retained secret. determine if the user needs to check the remote party's identity. set up callbacks for when the identity has been verified.''' 853 850 854 new_srs = self.hmac(k, 'New Retained Secret') 855 self.srs = new_srs 856 851 857 account = self.conn.name 852 858 bjid = self.jid.getStripped() 853 859 854 if srs: 855 if secrets.secrets().srs_verified(account, bjid, srs): 856 secrets.secrets().replace_srs(account, bjid, srs, new_srs, True) 860 self.verified_identity = False 861 862 if old_srs: 863 if secrets.secrets().srs_verified(account, bjid, old_srs): 864 # already had a stored secret verified by the user. 865 secrets.secrets().replace_srs(account, bjid, old_srs, new_srs, True) 866 # continue without warning. 867 self.verified_identity = True 857 868 else: 858 def _cb(verified): 859 secrets.secrets().replace_srs(account, bjid, srs, new_srs, verified) 860 861 self.check_identity(_cb) 862 else: 863 def _cb(verified): 864 secrets.secrets().save_new_srs(account, bjid, new_srs, verified) 865 866 self.check_identity(_cb) 869 # had a secret, but it wasn't verified. 870 secrets.secrets().replace_srs(account, bjid, old_srs, new_srs, False) 871 else: 872 # we don't even have an SRS 873 secrets.secrets().save_new_srs(account, bjid, new_srs, False) 874 875 def _verified_srs_cb(self): 876 secrets.secrets().replace_srs(self.conn.name, self.jid.getStripped(), self.srs, self.srs, True) 867 877 868 878 def make_dhfield(self, modp_options, sigmai): -
trunk/src/dialogs.py
r9857 r9861 3781 3781 self.dataform_widget.show_all() 3782 3782 self.vbox.pack_start(self.dataform_widget) 3783 3783 3784 3784 def on_ok(self): 3785 3785 form = self.dataform_widget.data_form … … 3789 3789 self.df_response_ok(form) 3790 3790 self.destroy() 3791 3792 class ESessionInfoWindow: 3793 '''Class for displaying information about a XEP-0116 encrypted session''' 3794 def __init__(self, session): 3795 self.session = session 3796 3797 self.xml = gtkgui_helpers.get_glade('esession_info_window.glade') 3798 self.xml.signal_autoconnect(self) 3799 3800 self.update_info() 3801 3802 self.window = self.xml.get_widget('esession_info_window') 3803 self.window.show_all() 3804 3805 def update_info(self): 3806 labeltext = _('''Your chat session with %s is encrypted.\n\nSAS is: %s''') % (self.session.jid, self.session.sas) 3807 3808 if self.session.verified_identity: 3809 labeltext += '\n\n' + _('''You have already verified this contact's identity.''') 3810 w = self.xml.get_widget('verification_info') 3811 w.set_no_show_all(True) 3812 w.hide() 3813 3814 self.xml.get_widget('info_display').set_text(labeltext) 3815 3816 def on_close_button_clicked(self, widget): 3817 self.window.destroy() 3818 3819 def on_verify_now_button_clicked(self, widget): 3820 pritext = _('''Have you verified the remote contact's identity?''') 3821 sectext = _('''To prevent a man-in-the-middle attack, you should speak to this person directly (in person or on the phone) and verify that they see the same SAS as you.\n\nThis session's SAS: %s''') % self.session.sas 3822 sectext += '\n\n' + _('Did you talk to the remote contact and verify the SAS?') 3823 3824 dialog = YesNoDialog(pritext, sectext) 3825 3826 if dialog.get_response() == gtk.RESPONSE_YES: 3827 self.session._verified_srs_cb() 3828 self.session.verified_identity = True 3829 self.update_info() -
trunk/src/negotiation.py
r9115 r9861 14 14 elif features['logging'] == 'mustnot': 15 15 return _('- messages will not be logged') 16 17 def show_sas_dialog(session, jid, sas, on_success):18 def success_cb(checked):19 on_success(checked)20 21 def failure_cb():22 session.reject_negotiation()23 24 dialogs.ConfirmationDialogCheck(_('''OK to continue with negotiation?'''),25 _('''You've begun an encrypted session with %s, but it can't be guaranteed that you're talking directly to the person you think you are.26 27 You should speak with them directly (in person or on the phone) and confirm that their Short Authentication String is identical to this one: %s28 29 Would you like to continue with the encrypted session?''') % (jid, sas),30 31 _('Yes, I verified the Short Authentication String'),32 on_response_ok=success_cb, on_response_cancel=failure_cb, is_modal=False)33 16 34 17 class FeatureNegotiationWindow: … … 68 51 69 52 def on_cancel_button_clicked(self, widget): 70 # XXX determine whether to reveal presence71 72 53 rejection = xmpp.Message(self.jid) 73 54 rejection.setThread(self.session.thread_id) … … 81 62 feature.addChild(node=x) 82 63 83 # XXX optional <body/>84 85 64 gajim.connections[self.account].send_stanza(rejection) 86 65 -
trunk/src/secrets.py
r8873 r9861 137 137 def srs_verified(self, account, jid, srs): 138 138 return self.find_srs(account, jid, srs)[1] 139 139 140 140 def replace_srs(self, account, jid, old_secret, new_secret, verified): 141 141 our_secrets = self.srs[account][jid] -
trunk/src/session.py
r9846 r9861 335 335 # ---- ESessions stuff --- 336 336 337 def check_identity(self, on_success):338 negotiation.show_sas_dialog(self, self.jid, self.sas, on_success)339 340 337 def handle_negotiation(self, form): 341 338 if form.getField('accept') and not form['accept'] in ('1', 'true'):
