[Tkabber-dev] r2111 - trunk/tkabber

tkabber-svn at jabber.ru tkabber-svn at jabber.ru
Mon Jan 27 15:54:30 MSK 2014


Author: sergei
Date: 2014-01-27 15:54:30 +0400 (Mon, 27 Jan 2014)
New Revision: 2111

Modified:
   trunk/tkabber/ChangeLog
   trunk/tkabber/gpgme.tcl
   trunk/tkabber/presence.tcl
Log:
	* gpgme.tcl, presence.tcl: Fixed checking message signature in case
	  when another plugin (like OTR) rewrites message body. Optionally
	  add the user's JID and timestamp to outgoing messages to prevent
	  replay attacks. Unfortunately, these JIDs and timestamps aren't
	  shown in user's own chat log.


Modified: trunk/tkabber/ChangeLog
===================================================================
--- trunk/tkabber/ChangeLog	2014-01-27 08:46:15 UTC (rev 2110)
+++ trunk/tkabber/ChangeLog	2014-01-27 11:54:30 UTC (rev 2111)
@@ -1,3 +1,11 @@
+2014-01-27  Sergei Golovan  <sgolovan at nes.ru>
+
+	* gpgme.tcl, presence.tcl: Fixed checking message signature in case
+	  when another plugin (like OTR) rewrites message body. Optionally
+	  add the user's JID and timestamp to outgoing messages to prevent
+	  replay attacks. Unfortunately, these JIDs and timestamps aren't
+	  shown in user's own chat log.
+
 2014-01-26  Sergei Golovan  <sgolovan at nes.ru>
 
 	* plugins/chat/logger.tcl, plugins/general/message_archive.tcl:

Modified: trunk/tkabber/gpgme.tcl
===================================================================
--- trunk/tkabber/gpgme.tcl	2014-01-27 08:46:15 UTC (rev 2110)
+++ trunk/tkabber/gpgme.tcl	2014-01-27 11:54:30 UTC (rev 2111)
@@ -82,13 +82,27 @@
 	-group GPG -type boolean
 
     custom::defvar options(sign-traffic) 0 \
-	[::msgcat::mc "GPG-sign outgoing messages and presence updates."] \
+	[::msgcat::mc "GPG-sign outgoing presence updates."] \
 	-group GPG -type boolean
 
+    custom::defvar options(sign-personal-messages) 0 \
+	[::msgcat::mc "GPG-sign outgoing personal messages."] \
+	-group GPG -type boolean
+
+    custom::defvar options(sign-groupchat-messages) 0 \
+	[::msgcat::mc "GPG-sign outgoing groupchat messages."] \
+	-group GPG -type boolean
+
     custom::defvar options(encrypt-traffic) 0 \
 	[::msgcat::mc "GPG-encrypt outgoing messages where possible."] \
 	-group GPG -type boolean
 
+    custom::defvar options(prevent-replay-attack) 1 \
+	[::msgcat::mc "Add your JID and timestamp to the GPG-signed outgoing messages\
+		       or presence updates. This prevents replay attacks, but shows\
+		       your JID in every message or presence status."] \
+	-group GPG -type boolean
+
     custom::defvar options(key) "" \
 	[::msgcat::mc "Use specified key ID for signing and decrypting messages."] \
 	-group GPG -type string
@@ -465,8 +479,18 @@
     variable warnings
     variable gpg_error_id
 
-    if {!$options(sign-traffic)} {
-        return
+    if {[llength $args] == 0} {
+	# Presence
+	if {!$options(sign-traffic)} return
+    } else {
+	# Message
+	set to [lindex $args 0]
+	set chatid [chat::chatid $xlib $to]
+	if {[chat::is_groupchat $chatid]} {
+	    if {!$options(sign-groupchat-messages)} return
+	} else {
+	    if {!$options(sign-personal-messages)} return
+	}
     }
 
     once_only $xlib
@@ -474,6 +498,8 @@
     if {[catch {$ctx($xlib) sign -input $data \
 				 -mode  detach} result]} {
         set options(sign-traffic) 0
+        set options(sign-personal-messages) 0
+        set options(sign-groupchat-messages) 0
 
         debugmsg ssj "signature processing error ($xlib): $result ($data)"
 
@@ -733,19 +759,41 @@
 
     set x $xs
 
-    if {!$badenc} return
+    if {$badenc} {
+	# if decryption failed, then remove signature. It can't be correct.
 
-    # if decryption failed, then remove signature. It can't be correct.
-    set xs {}
-    foreach xe $x {
-	::xmpp::xml::split $xe tag xmlns attrs cdata subels
+	set xs {}
+	foreach xe $x {
+	    ::xmpp::xml::split $xe tag xmlns attrs cdata subels
 
-	if {![string equal $xmlns $::NS(signed)]} {
-	    lappend xs $xe
+	    if {![string equal $xmlns $::NS(signed)]} {
+		lappend xs $xe
+	    }
 	}
+	set x $xs
+    } else {
+	# Check the signature before some other plugin rewrites the message body
+
+	set xs {}
+	foreach xe $x {
+	    ::xmpp::xml::split $xe tag xmlns attrs cdata subels
+
+	    if {![string equal $xmlns $::NS(signed)]} {
+		lappend xs $xe
+	    } else {
+		# in case the sender didn't check the exit code from gpg...
+		if {![string equal $cdata ""]} {
+		    # Create special tag with signature info
+		    lappend xs [::xmpp::xml::create "" -xmlns $::NS(signed) \
+				    -attrs [signed:input $xlib $from $cdata $body \
+						[::msgcat::mc "Message body"]]]
+		}
+	    }
+	}
+	puts $xs
+	set x $xs
     }
-
-    set x $xs
+    return
 }
 
 hook::add rewrite_message_hook ::ssj::rewrite_message_body 70
@@ -1169,6 +1217,27 @@
 
 #############################################################################
 
+proc ::ssj::add_timestamp_to_signature {varname xlib} {
+    variable options
+    upvar 2 $varname var
+
+    if {!$options(prevent-replay-attack)} return
+
+    if {![catch {signed:output $xlib $var} cdata] &&
+	    ![string equal $cdata ""]} {
+	set timestamp [clock format [clock seconds] \
+				    -format "%Y%m%dT%TZ" -gmt true]
+	if {![string equal $var ""]} {
+	    set var " $var"
+	}
+	set var "\[[::xmpp::jid::removeResource [connection_jid $xlib]],\
+		 $timestamp\]$var"
+    }
+    return
+}
+
+hook::add rewrite_presence_status_hook ::ssj::add_timestamp_to_signature
+
 proc ::ssj::make_signature {varname xlib status} {
     upvar 2 $varname var
 
@@ -1184,6 +1253,32 @@
 
 #############################################################################
 
+proc ::ssj::add_timestamp {vxlib vto vid vtype vsubject vbody verr vthread vx} {
+    variable options
+    upvar 2 $vxlib xlib
+    upvar 2 $vto to
+    upvar 2 $vbody body
+    upvar 2 $vx x
+
+    if {!$options(prevent-replay-attack)} return
+
+    if {![info exists body]} return
+
+    if {![catch { ssj::signed:output $xlib $body $to } cdata] &&
+	    ![string equal $cdata ""]} {
+	set timestamp [clock format [clock seconds] \
+				    -format "%Y%m%dT%TZ" -gmt true]
+	if {![string equal $body ""]} {
+	    set body " $body"
+	}
+	set body "\[[::xmpp::jid::removeResource [connection_jid $xlib]],\
+		  $timestamp\] $body"
+    }
+    return
+}
+
+hook::add rewrite_outgoing_message_hook ::ssj::add_timestamp 5
+
 proc ::ssj::sign_encrypt_body {vxlib vto vid vtype vsubject vbody verr vthread vx} {
     upvar 2 $vxlib xlib
     upvar 2 $vto to
@@ -1303,17 +1398,6 @@
 proc ::ssj::message_buttons {mw xlib jid} {
     set bbox1 [ButtonBox $mw.bottom.buttons1 -spacing 0]
 
-    set b [$bbox1 add \
-		  -image [signed:icon] \
-		  -helptype balloon \
-		  -helptext [::msgcat::mc "Toggle signing"] \
-		  -height 24 \
-		  -width 24 \
-		  -relief link \
-		  -bd $::tk_borderwidth \
-		  -command ::ssj::sign:toggleP]
-    signed:trace "$b configure -image \[::ssj::signed:icon\]"
-    
     # TODO reflect changes of xlib
     set b [$bbox1 add \
 		  -image [encrypted:icon $xlib $jid] \
@@ -1346,11 +1430,8 @@
     foreach xa $x {
 	::xmpp::xml::split $xa tag xmlns attrs cdata subels
 
-	if {$xmlns != $::NS(signed)} continue
-
-	# in case the sender didn't check the exit code from gpg...
-	if {[string equal $cdata ""]} {
-	    return
+	if {$tag != "" || $xmlns != $::NS(signed)} {
+	    continue
 	}
 
 	set lb [join [lrange [split $f .] 0 end-1] .].title.signed
@@ -1358,10 +1439,7 @@
 	    destroy $lb
 	}
 
-	signed:Label $lb $xlib $from \
-		     [signed:input $xlib $from $cdata $body \
-				   [::msgcat::mc "Message body"]]
-	grid $lb -row 1 -column 2 -sticky e
+	grid [signed:Label $lb $xlib $from $attrs] -row 1 -column 2 -sticky e
     }
 
     return
@@ -1391,9 +1469,7 @@
     foreach xe $x {
         ::xmpp::xml::split $xe tag xmlns attrs cdata subels
 
-	# in case the sender didn't check the exit code from gpg...
-        if {[string equal $cdata ""] || \
-		![string equal $xmlns $::NS(signed)]} {
+        if {$tag != "" || ![string equal $xmlns $::NS(signed)]} {
             continue
         }
 
@@ -1402,9 +1478,7 @@
         catch {
 	    set lb $chatw.signed$signedid
             $chatw window create end \
-                  -window [signed:Label $lb $xlib $from \
-                              [signed:input $xlib $from $cdata $body \
-                                  [::msgcat::mc "Message body"]]]
+                  -window [signed:Label $lb $xlib $from $attrs]
 	    $lb configure -bg [get_conf $chatw -bg]
         }
     }
@@ -1440,7 +1514,7 @@
     set idx [ifacetk::add_toolbar_button \
 		 [signed:icon] \
 		 ::ssj::sign:toggleP \
-		 [::msgcat::mc "Toggle signing"]]
+		 [::msgcat::mc "Toggle signing presence updates"]]
     signed:trace \
 	[list ifacetk::set_toolbar_icon $idx ::ssj::signed:icon]
 
@@ -1466,9 +1540,9 @@
 
 	set mm .ssj_menu
 	menu $mm -tearoff $::ifacetk::options(show_tearoffs)
-	$mm add checkbutton -label [::msgcat::mc "Sign traffic"] \
+	$mm add checkbutton -label [::msgcat::mc "Sign presence updates"] \
 	    -variable ::ssj::options(sign-traffic)
-	$mm add checkbutton -label [::msgcat::mc "Encrypt traffic (when possible)"] \
+	$mm add checkbutton -label [::msgcat::mc "Encrypt messages (when possible)"] \
 	    -variable ::ssj::options(encrypt-traffic)
 
 	$m insert $ind cascade -label [::msgcat::mc "Encryption"] \

Modified: trunk/tkabber/presence.tcl
===================================================================
--- trunk/tkabber/presence.tcl	2014-01-27 08:46:15 UTC (rev 2110)
+++ trunk/tkabber/presence.tcl	2014-01-27 11:54:30 UTC (rev 2111)
@@ -493,17 +493,23 @@
     }
 
     set xlist {}
+    set to ""
     set stat ""
     foreach {opt val} $args {
 	switch -- $opt {
 	    -id       { lappend newargs -id $val }
-	    -to       { lappend newargs -to $val }
+	    -to       {
+		set to $val
+		lappend newargs -to $val
+	    }
 	    -priority { lappend newargs -priority $val }
 	    -xlist    { set xlist $val }
 	    -status   { set stat $val }
 	}
     }
 
+    hook::run rewrite_presence_status_hook stat $xlib
+
     if {$stat != ""} {
 	lappend newargs -status $stat
     }



More information about the Tkabber-dev mailing list