[Tkabber-dev] r2074 - in trunk/tkabber-plugins: . otr otr/tclotr

tkabber-svn at jabber.ru tkabber-svn at jabber.ru
Tue Jan 21 19:52:37 MSK 2014


Author: sergei
Date: 2014-01-21 19:52:37 +0400 (Tue, 21 Jan 2014)
New Revision: 2074

Modified:
   trunk/tkabber-plugins/ChangeLog
   trunk/tkabber-plugins/otr/otr.tcl
   trunk/tkabber-plugins/otr/tclotr/otr.tcl
Log:
	* otr/otr.tcl, otr/tclotr/otr.tcl: Tell the OTR plugin about state
	  changes and SMP progress using callbacks and only in case of actual
	  change.


Modified: trunk/tkabber-plugins/ChangeLog
===================================================================
--- trunk/tkabber-plugins/ChangeLog	2014-01-21 09:21:49 UTC (rev 2073)
+++ trunk/tkabber-plugins/ChangeLog	2014-01-21 15:52:37 UTC (rev 2074)
@@ -8,6 +8,10 @@
 
 	* otr/otr.tcl: Fixed updating default OTR policy from GUI.
 
+	* otr/otr.tcl, otr/tclotr/otr.tcl: Tell the OTR plugin about state
+	  changes and SMP progress using callbacks and only in case of actual
+	  change.
+
 2014-01-20  Sergei Golovan <sgolovan at nes.ru>
 
 	* otr/tclotr/otr.tcl: Do not send the OTR query message after an OTR

Modified: trunk/tkabber-plugins/otr/otr.tcl
===================================================================
--- trunk/tkabber-plugins/otr/otr.tcl	2014-01-21 09:21:49 UTC (rev 2073)
+++ trunk/tkabber-plugins/otr/otr.tcl	2014-01-21 15:52:37 UTC (rev 2074)
@@ -227,14 +227,37 @@
         return
     }
 
-    set result [::otr::new $::OTRPrivateKey -policy [get_policy $xlib $jid]]
-    array set res $result
-    set ctx($xlib,$jid) $res(token)
-    foreach state {authstate msgstate smpstate} {
-	set ctx($state,$xlib,$jid) $res($state)
-    }
+    set ctx($xlib,$jid) \
+	[::otr::new $::OTRPrivateKey \
+		-policy [get_policy $xlib $jid] \
+		-authstatecommand [namespace code [list on_authstate_change $xlib $jid]] \
+		-msgstatecommand [namespace code [list on_msgstate_change $xlib $jid]] \
+		-smpstatecommand [namespace code [list on_smpstate_change $xlib $jid]] \
+		-smpprogresscommand [namespace code [list progress_smp $xlib $jid]]]
 }
 
+#############################################################################
+
+proc otr::on_authstate_change {xlib jid authstate} {
+    variable ctx
+
+    set ctx(authstate,$xlib,$jid) $authstate
+}
+
+proc otr::on_msgstate_change {xlib jid msgstate} {
+    variable ctx
+
+    set ctx(msgstate,$xlib,$jid) $msgstate
+}
+
+proc otr::on_smpstate_change {xlib jid smpstate} {
+    variable ctx
+
+    set ctx(smpstate,$xlib,$jid) $smpstate
+}
+
+#############################################################################
+
 proc otr::get_policy {xlib jid} {
     variable options
     variable PolicyFlags
@@ -392,11 +415,6 @@
     if {[info exists res(body)]} {
 	::xmpp::sendMessage $xlib $jid -type $type -body $res(body)
     }
-    foreach state {authstate msgstate smpstate} {
-	if {[info exists res($state)]} {
-	    set ctx($state,$xlib,$jid) $res($state)
-	}
-    }
 }
 
 #############################################################################
@@ -475,7 +493,7 @@
     grid $l3 -row 1 -column 0 -sticky nsw
     set e3 [entry $pf2.e3]
     grid $e3 -row 2 -column 0 -sticky nswe
-    ProgressBar $pf2.pb -variable [namespace current]::ctx(progress,$xlib,$jid) -maximum 2
+    ProgressBar $pf2.pb -variable [namespace current]::ctx(progress,$xlib,$jid) -maximum 3
     grid $pf2.pb -row 3 -column 0 -sticky ew
     set l4 [label $pf2.l4 -textvariable [namespace current]::ctx(status,$xlib,$jid)]
     grid $l4 -row 4 -column 0
@@ -587,11 +605,6 @@
     if {[info exists res(body)]} {
 	::xmpp::sendMessage $xlib $jid -body $res(body)
     }
-    foreach state {authstate msgstate smpstate} {
-	if {[info exists res($state)]} {
-	    set ctx($state,$xlib,$jid) $res($state)
-	}
-    }
 }
 
 #############################################################################
@@ -731,14 +744,6 @@
     if {[info exists res(body)]} {
 	::xmpp::sendMessage $xlib $jid -body $res(body)
     }
-    foreach state {authstate msgstate smpstate} {
-	if {[info exists res($state)]} {
-	    set ctx($state,$xlib,$jid) $res($state)
-	}
-    }
-    if {[info exists res(smpprogress)]} {
-	progress_smp $xlib $jid $res(smpprogress)
-    }
 }
 
 proc otr::abort_smp {w xlib jid} {
@@ -750,14 +755,6 @@
 	if {[info exists res(body)]} {
 	    ::xmpp::sendMessage $xlib $jid -body $res(body)
 	}
-	foreach state {authstate msgstate smpstate} {
-	    if {[info exists res($state)]} {
-		set ctx($state,$xlib,$jid) $res($state)
-	    }
-	}
-	if {[info exists res(smpprogress)]} {
-	    progress_smp $xlib $jid $res(smpprogress)
-	}
     }
 
     destroy $w
@@ -786,22 +783,22 @@
 	    incr ctx(progress,$xlib,$jid)
 	}
 	SMP_ABORT {
-	    set ctx(progress,$xlib,$jid) 2
+	    set ctx(progress,$xlib,$jid) 3
 	    set ctx(status,$xlib,$jid) [::msgcat::mc "Authentication aborted"]
 	    result_smp $w $xlib $jid
 	}
 	SMP_CHEATING {
-	    set ctx(progress,$xlib,$jid) 2
+	    set ctx(progress,$xlib,$jid) 3
 	    set ctx(status,$xlib,$jid) [::msgcat::mc "Protocol error"]
 	    result_smp $w $xlib $jid
 	}
 	SMP_SUCCESS {
-	    set ctx(progress,$xlib,$jid) 2
+	    set ctx(progress,$xlib,$jid) 3
 	    set ctx(status,$xlib,$jid) [::msgcat::mc "Authentication succeeded"]
 	    result_smp $w $xlib $jid
 	}
 	SMP_FAILURE {
-	    set ctx(progress,$xlib,$jid) 2
+	    set ctx(progress,$xlib,$jid) 3
 	    set ctx(status,$xlib,$jid) [::msgcat::mc "Authentication failed"]
 	    result_smp $w $xlib $jid
 	}
@@ -834,12 +831,6 @@
 
     array set res $result
 
-    foreach state {authstate msgstate smpstate} {
-	if {[info exists res($state)]} {
-	    set ctx($state,$xlib,$from) $res($state)
-	}
-    }
-
     if {[info exists res(reply)]} {
 	foreach message $res(reply) {
 	    set command [list ::xmpp::sendMessage $xlib $from -body $message]
@@ -850,10 +841,6 @@
 	}
     }
 
-    if {[info exists res(smpprogress)]} {
-	progress_smp $xlib $from $res(smpprogress)
-    }
-
     if {[info exists res(error)]} {
 	set type error
 	set body ""
@@ -922,24 +909,6 @@
 
 ###############################################################################
 
-proc otr::filter:output {xlib to data} {
-    variable ctx
-
-    once_only $xlib $to
-
-    set result [::otr::outgoingMessage $ctx($xlib,$to) $data]
-
-    debugmsg otr "FILTER_OUTPUT: $xlib; $to; $result"
-
-    array set res $result
-    switch -- $res(action) {
-	send {
-	    return [list $res(body) send]
-	}
-    }
-    list $data ""
-}
-
 proc otr::rewrite_outgoing_message_body \
      {vxlib vto vid vtype vsubject vbody verr vthread vx} {
     upvar 2 $vxlib xlib
@@ -960,17 +929,20 @@
 
     array set res $result
 
-    if {[info exists res(body)]} {
-	set body $res(body)
-    }
-
     if {[info exists res(info)]} {
 	set chatid [::chat::chatid $xlib $to]
 	chat::add_message $chatid $to info $res(info) {}
 	hook::unset_flag chat_send_message_hook draw
+    }
+
+    if {[info exists res(body)]} {
+	set body $res(body)
+    } else {
 	# Rewrite to JID to disable sending.
+
 	set to ""
     }
+
 }
 
 hook::add rewrite_outgoing_message_hook \
@@ -1111,6 +1083,7 @@
 	# TODO: nice report
 	append info "\n\t    Authstate: $ctx(authstate,$xlib,$jid)"
 	append info "\n\t    Msgstate: $ctx(msgstate,$xlib,$jid)"
+	append info "\n\t    SMPstate: $ctx(smpstate,$xlib,$jid)"
     }
 }
 

Modified: trunk/tkabber-plugins/otr/tclotr/otr.tcl
===================================================================
--- trunk/tkabber-plugins/otr/tclotr/otr.tcl	2014-01-21 09:21:49 UTC (rev 2073)
+++ trunk/tkabber-plugins/otr/tclotr/otr.tcl	2014-01-21 15:52:37 UTC (rev 2074)
@@ -59,15 +59,21 @@
 #       Create new OTR instance.
 #
 # Arguments:
-#       privkey             Private key (tuple {p q g y x}).
-#       -policy policy      List of policy flags.
-#       -heartbeat time     (minutes) Interval before which a heartbeat
-#                           message will not be sent.
-#       -maxsize size       (ASCII chars) Max message size to send (not
-#                           implemented yet (TODO)).
+#       privkey                 Private key (tuple {p q g y x}).
+#       -policy policy          List of policy flags.
+#       -authstatecommand cmd   Callback which is called on every authstate
+#                               change.
+#       -msgstatecommand cmd    Callback which is called on every msgstate
+#                               change.
+#       -smpstatecommand cmd    Callback which is called on every smpstate
+#                               change.
+#       -heartbeat time         (minutes) Interval before which a heartbeat
+#                               message will not be sent.
+#       -maxsize size           (ASCII chars) Max message size to send (not
+#                               implemented yet (TODO)).
 #
 # Result:
-#       Serialized array with fields 'token', 'authstate', 'msgstate'.
+#       An OTR token.
 #
 # Side effects:
 #       The state variable is created.
@@ -80,11 +86,19 @@
     }
 
     set policy {}
+    set authstatecommands {}
+    set msgstatecommands {}
+    set smpstatecommands {}
+    set smpprogresscommands {}
     set heartbeat 0
     set maxsize 0
     foreach {key val} $args {
         switch -- $key {
             -policy { set policy $val }
+            -authstatecommand { set authstatecommands [list $val] }
+            -msgstatecommand { set msgstatecommands [list $val] }
+            -smpstatecommand { set smpstatecommands [list $val] }
+            -smpprogresscommand { set smpprogresscommands [list $val] }
             -heartbeat { set heartbeat $val }
             -maxsize { set maxsize $val }
         }
@@ -100,9 +114,11 @@
 
     array unset state
 
-    set state(AuthState) AUTHSTATE_NONE
-    set state(MsgState) MSGSTATE_PLAINTEXT
-    set state(SMPState) SMPSTATE_EXPECT1
+    set state(AuthStateCommands) $authstatecommands
+    set state(MsgStateCommands) $msgstatecommands
+    set state(SMPStateCommands) $smpstatecommands
+    set state(SMPProgressCommands) $smpprogresscommands
+
     set state(StoredMessages) {}
     set state(PrivateKey) $privkey
     set state(Policy) $policy
@@ -121,10 +137,26 @@
 
     InitDHKeys $token
 
-    list token $token \
-         authstate $state(AuthState) \
-         msgstate $state(MsgState) \
-         smpstate $state(SMPState)
+    # Track state changes
+
+    trace add variable ${token}(AuthState) write \
+                [namespace code [list TrackAuthState $token]]
+    trace add variable ${token}(MsgState) write \
+                [namespace code [list TrackMsgState $token]]
+    trace add variable ${token}(SMPState) write \
+                [namespace code [list TrackSMPState $token]]
+    trace add variable ${token}(SMPProgress) write \
+                [namespace code [list TrackSMPProgress $token]]
+
+    set state(StoredAuthState) ""
+    set state(StoredMsgState) ""
+    set state(StoredSMPState) ""
+    set state(AuthState) AUTHSTATE_NONE
+    set state(MsgState) MSGSTATE_PLAINTEXT
+    set state(SMPState) SMPSTATE_EXPECT1
+    set state(SMPProgress) SMP_NONE
+
+    set token
 }
 
 proc ::otr::configure {token key args} {
@@ -276,12 +308,11 @@
             set message [CreateEncryptedMessage $token {} "" {1 ""}]
             set state(MsgState) MSGSTATE_PLAINTEXT
             InitDHKeys $token
-            return [list body     $message \
-                         msgstate $state(MsgState)]
+            return [list body $message]
         }
         MSGSTATE_FINISHED {
             set state(MsgState) MSGSTATE_PLAINTEXT
-            return [list msgstate $state(MsgState)]
+            return {}
         }
     }
 }
@@ -304,15 +335,14 @@
     switch -- $state(MsgState) {
         MSGSTATE_ENCRYPTED {
             lassign [CreateSMP1 $question $secret $token] \
-                    state(SMPState) progress flags body tlvlist
+                    state(SMPState) state(SMPProgress) flags body tlvlist
             set message [CreateEncryptedMessage $token $flags $body $tlvlist]
 
-            return [list body        $message \
-                         smpstate    $state(SMPState) \
-                         smpprogress $progress]
+            return [list body $message]
         }
         default {
-            return [list smpprogress SMP_ABORT]
+            set state(SMPProgress) SMP_ABORT
+            return {}
         }
     }
 }
@@ -324,15 +354,14 @@
     switch -- $state(MsgState) {
         MSGSTATE_ENCRYPTED {
             lassign [CreateSMP2 $secret $token] \
-                    state(SMPState) progress flags body tlvlist
+                    state(SMPState) state(SMPProgress) flags body tlvlist
             set message [CreateEncryptedMessage $token $flags $body $tlvlist]
 
-            return [list body        $message \
-                         smpstate    $state(SMPState) \
-                         smpprogress $progress]
+            return [list body $message]
         }
         default {
-            return [list smpprogress SMP_ABORT]
+            set state(SMPProgress) SMP_ABORT
+            return {}
         }
     }
 }
@@ -346,12 +375,12 @@
             set message [CreateEncryptedMessage $token {} "" {6 ""}]
 
             set state(SMPState) SMPSTATE_EXPECT1
-            return [list body        $message \
-                         smpstate    $state(SMPState) \
-                         smpprogress SMP_ABORT]
+            set state(SMPProgress) SMP_ABORT
+            return [list body $message]
         }
         default {
-            return [list smpprogress SMP_ABORT]
+            set state(SMPProgress) SMP_ABORT
+            return {}
         }
     }
 }
@@ -366,7 +395,9 @@
         MSGSTATE_PLAINTEXT {
             if {[QueryPolicy $token REQUIRE_ENCRYPTION]} {
                 Store $token $body
-                return [list body [::otr::data::queryMessage $state(Policy)]]
+                return [list body [::otr::data::queryMessage $state(Policy)] \
+                             info "Message is not sent. Trying to start\
+                                   private conversation..."]
             } elseif {[QueryPolicy $token SEND_WHITESPACE_TAG] &&
                       ([QueryPolicy $token ALLOW_V2] ||
                        [QueryPolicy $token ALLOW_V3])} {
@@ -444,9 +475,7 @@
                         $state(x,$keyid) \
                         -sinstance $state(sinstance)] \
                         state(AuthState) state(MsgState) message
-        return [list authstate $state(AuthState) \
-                     msgstate  $state(MsgState) \
-                     reply     [list $message]]
+        return [list reply [list $message]]
     } elseif {![catch {::otr::data::findWhitespaceTag $message} versions]} {
         # Plaintext with the whitespace tag
 
@@ -470,10 +499,8 @@
                             state(AuthState) state(MsgState) reply
             switch -- $state(MsgState) {
                 MSGSTATE_PLAINTEXT {
-                    set ret [list authstate $state(AuthState) \
-                                  msgstate  $state(MsgState) \
-                                  body      $message \
-                                  reply     [list $reply]]
+                    set ret [list body  $message \
+                                  reply [list $reply]]
                     if {[QueryPolicy $token REQUIRE_ENCRYPTION]} {
                         return [linsert $ret 0 warn 1]
                     } else {
@@ -483,11 +510,9 @@
                 }
                 MSGSTATE_ENCRYPTED -
                 MSGSTATE_FINISHED {
-                    return [list authstate $state(AuthState) \
-                                 msgstate  $state(MsgState) \
-                                 warn      1 \
-                                 body      $message \
-                                 reply     [list $reply]]
+                    return [list warn  1 \
+                                 body  $message \
+                                 reply [list $reply]]
                 }
             }
         } else {
@@ -687,12 +712,9 @@
             state(egxmpi) state(hgxmpi)
 
     if {$message eq ""} {
-        return [list authstate $state(AuthState) \
-                     msgstate  $state(MsgState)]
+        return {}
     } else {
-        return [list authstate $state(AuthState) \
-                     msgstate  $state(MsgState) \
-                     reply     [list $message]]
+        return [list reply [list $message]]
     }
 }
 
@@ -725,12 +747,9 @@
             state(AuthState) state(MsgState) message state(gy)
 
     if {$message eq ""} {
-        return [list authstate $state(AuthState) \
-                     msgstate  $state(MsgState)]
+        return {}
     } else {
-        return [list authstate $state(AuthState) \
-                     msgstate  $state(MsgState) \
-                     reply     [list $message]]
+        return [list reply [list $message]]
     }
 }
 
@@ -756,17 +775,14 @@
 
     if {$message eq ""} {
         # Failure
-        return [list authstate $state(AuthState) \
-                     msgstate  $state(MsgState)]
+        return {}
     } else {
         # Success
         UpdatePeerDHKeysAfterAKE $token $gy $keyidy
         StoreSSID $token
 
         # TODO: Send stored messages
-        return [list authstate $state(AuthState) \
-                     msgstate  $state(MsgState) \
-                     reply     [list $message]]
+        return [list reply [list $message]]
     }
 }
 
@@ -794,8 +810,7 @@
 
         # TODO: Send stored messages
     }
-    return [list authstate $state(AuthState) \
-                 msgstate  $state(MsgState)]
+    return {}
 }
 
 proc ::otr::UpdatePeerDHKeysAfterAKE {token gy keyidy} {
@@ -905,14 +920,16 @@
             if {[info exists res(smpstate)]} {
                 set state(SMPState) $res(smpstate)
             }
+            if {[info exists res(smpprogress)]} {
+                set state(SMPProgress) $res(smpprogress)
+            }
 
             if {[info exists res(debug)]} {
                 Debug 2 $token $res(debug)
             }
 
             set ret {}
-            foreach field {msgstate smpstate smpprogress info error body
-                           interaction question} {
+            foreach field {info error body interaction question} {
                 if {[info exists res($field)]} {
                     lappend ret $field $res($field)
                 }
@@ -1160,6 +1177,7 @@
 
     set state(AuthState) AUTHSTATE_NONE
     set state(MsgState) MSGSTATE_PLAINTEXT
+    set state(SMPState) SMPSTATE_EXPECT1
 
     set state(version) $version
     set state(r) [::otr::crypto::Int2Octets [::otr::crypto::random 128] 128]
@@ -1247,6 +1265,56 @@
 
 ###########################################################################
 
+proc ::otr::TrackAuthState {token name1 name2 op} {
+    variable $token
+    upvar 0 $token state
+
+    if {$state(StoredAuthState) eq $state(AuthState)} return
+
+    set state(StoredAuthState) $state(AuthState)
+
+    foreach cmd $state(AuthStateCommands) {
+        {*}$cmd $state(AuthState)
+    }
+}
+
+proc ::otr::TrackMsgState {token name1 name2 op} {
+    variable $token
+    upvar 0 $token state
+
+    if {$state(StoredMsgState) eq $state(MsgState)} return
+
+    set state(StoredMsgState) $state(MsgState)
+
+    foreach cmd $state(MsgStateCommands) {
+        {*}$cmd $state(MsgState)
+    }
+}
+
+proc ::otr::TrackSMPState {token name1 name2 op} {
+    variable $token
+    upvar 0 $token state
+
+    if {$state(StoredSMPState) eq $state(SMPState)} return
+
+    set state(StoredSMPState) $state(SMPState)
+
+    foreach cmd $state(SMPStateCommands) {
+        {*}$cmd $state(SMPState)
+    }
+}
+
+proc ::otr::TrackSMPProgress {token name1 name2 op} {
+    variable $token
+    upvar 0 $token state
+
+    foreach cmd $state(SMPProgressCommands) {
+        {*}$cmd $state(SMPProgress)
+    }
+}
+
+###########################################################################
+
 # ::otr::Debug --
 #
 #       Prints debug information.



More information about the Tkabber-dev mailing list