]> Sergey Matveev's repositories - tofuproxy.git/blobdiff - verify.go
More pleasant Tk dialogs
[tofuproxy.git] / verify.go
index f1bb49f33efec4dcdae20bb670d922c4778c6077..ed9865094a8d6768ebef4cc9fbadacdeb593f08a 100644 (file)
--- a/verify.go
+++ b/verify.go
@@ -36,6 +36,93 @@ import (
        "go.stargrave.org/tofuproxy/fifos"
 )
 
+const VerifyDialog = `
+# host err daneStatus certsTheir certsOur
+
+if {[string length $err] > 0} {
+    set tErr [text .tErr]
+    $tErr insert end $err
+    $tErr configure -wrap word -height 5
+    $tErr configure -state disabled
+    grid .tErr
+}
+
+proc certsDecode {raws} {
+    set certs [list]
+    foreach raw [split $raws] {
+        set lines [list]
+        set lineN 0
+        foreach line [split [binary decode hex $raw] "\n"] {
+            lappend lines [format "%03d %s" $lineN $line]
+            incr lineN
+        }
+        lappend certs [join $lines "\n"]
+    }
+    return $certs
+}
+
+set certsTheir [certsDecode $certsTheir]
+set certsOur [certsDecode $certsOur]
+
+tk_setPalette grey
+wm title . $host
+
+proc paginator {i delta t l certs} {
+    incr i $delta
+    if {$i == [llength $certs]} {
+        set i 0
+    } elseif {$i < 0} {
+        set i [expr {[llength $certs] - 1}]
+    }
+    $t configure -state normal
+    $t delete 1.0 end
+    $t insert end [lindex $certs $i]
+    $t configure -state disabled
+    $l configure -text "[expr {$i + 1}] / [llength $certs]"
+    return $i
+}
+
+proc addCertsWindow {name} {
+    global certs$name t$name sb$name page$name l$name
+    set t [text .t$name]
+    set sb [scrollbar .sb$name -command [list $t yview]]
+    $t configure -wrap word -yscrollcommand [list $sb set]
+    $t configure -state disabled
+    grid $t $sb -sticky nsew
+    set t$name $t
+    set sb$name $t
+
+    frame .fControl$name
+    set l$name [label .lPage$name]
+    button .bNext$name -text "Next" -command "set page$name \[
+        paginator \$page$name +1 \$t$name \$l$name \$certs$name
+    ]"
+    button .bPrev$name -text "Prev" -command "set page$name \[
+        paginator \$page$name -1 \$t$name \$l$name \$certs$name
+    ]"
+    grid .fControl$name
+    grid .lPage$name .bNext$name .bPrev$name -in .fControl$name
+    set page$name [paginator -1 +1 $t [set l$name] [set certs$name]]
+}
+
+addCertsWindow Their
+if {[llength $certsOur] > 0} { addCertsWindow Our }
+frame .fButtons
+set lDANE [label .lDANE]
+if {$daneStatus ne ""} {
+    array set daneColour {ok green bad red}
+    $lDANE configure -bg $daneColour($daneStatus)
+    $lDANE configure -text "DANE-EE: $daneStatus"
+}
+button .bAccept -text "Accept" -bg green -command { exit 10 }
+button .bOnce -text "Once" -bg green -command { exit 11 }
+button .bReject -text "Reject" -bg red -command { exit 12 }
+grid .fButtons
+grid .lDANE .bAccept .bOnce .bReject -in .fButtons
+grid rowconfigure . 0 -weight 1
+grid columnconfigure . 0 -weight 1
+`
+
 var (
        CmdCerttool = "certtool"
        CmdWish     = "wish8.6"
@@ -62,16 +149,7 @@ func certInfo(certRaw []byte) string {
        if err != nil {
                return err.Error()
        }
-       lines := make([]string, 0, 128)
-       for i, line := range strings.Split(string(out), "\n") {
-               if strings.Contains(line, "ASCII:") {
-                       continue
-               }
-               lines = append(lines, fmt.Sprintf(
-                       "%03d %s", i, strings.ReplaceAll(line, `"`, `\"`),
-               ))
-       }
-       return strings.Join(lines, "\n")
+       return string(out)
 }
 
 func verifyCert(
@@ -127,66 +205,38 @@ func verifyCert(
                        return nil
                }
                var b bytes.Buffer
-               b.WriteString("tk_setPalette grey\n")
-               b.WriteString(fmt.Sprintf("wm title . \"%s\"\n", host))
-
-               if dialErr != nil {
-                       b.WriteString(fmt.Sprintf(`set tErr [text .tErr]
-$tErr insert end "%s"
-$tErr configure -wrap word -height 5
-`, dialErr.Error()))
-                       b.WriteString("grid .tErr -columnspan 3\n")
+               b.WriteString(fmt.Sprintf("set host \"%s\"\n", host))
+               if dialErr == nil {
+                       b.WriteString(fmt.Sprintf("set err \"\"\n"))
+               } else {
+                       b.WriteString(fmt.Sprintf("set err \"%s\"\n", dialErr.Error()))
                }
-
+               var daneStatus string
                if daneExists {
                        if daneMatched {
-                               b.WriteString("label .lDANE -bg green -text \"DANE matched\"\n")
+                               daneStatus = "ok"
                        } else {
-                               b.WriteString("label .lDANE -bg red -text \"DANE NOT matched\"\n")
+                               daneStatus = "bad"
                        }
-                       b.WriteString("grid .lDANE\n")
                }
-
-               var bCerts bytes.Buffer
-               for i, rawCert := range rawCerts {
-                       bCerts.WriteString(fmt.Sprintf("Their %d:\n", i))
-                       bCerts.WriteString(certInfo(rawCert))
+               b.WriteString(fmt.Sprintf("set daneStatus \"%s\"\n", daneStatus))
+               hexCerts := make([]string, 0, len(rawCerts))
+               for _, rawCert := range rawCerts {
+                       hexCerts = append(hexCerts, hex.EncodeToString([]byte(certInfo(rawCert))))
                }
-               b.WriteString(fmt.Sprintf(`set tTheir [text .tTheir]
-$tTheir insert end "%s"
-set sbTheir [scrollbar .sbTheir -command [list $tTheir yview]]
-$tTheir configure -wrap word -yscrollcommand [list $sbTheir set]
-`, bCerts.String()))
-               b.WriteString("grid $tTheir $sbTheir -sticky nsew -columnspan 3\n")
-
-               if certsOur != nil {
-                       bCerts.Reset()
-                       for i, cert := range certsOur {
-                               bCerts.WriteString(fmt.Sprintf("Our %d:\n", i))
-                               bCerts.WriteString(certInfo(cert.Raw))
-                       }
-                       b.WriteString(fmt.Sprintf(`set tOur [text .tOur]
-$tOur insert end "%s"
-set sbOur [scrollbar .sbOur -command [list $tOur yview]]
-$tOur configure -wrap word -yscrollcommand [list $sbOur set]
-`, bCerts.String()))
-                       b.WriteString("grid $tOur $sbOur -sticky nsew -columnspan 3\n")
+               b.WriteString(fmt.Sprintf(
+                       "set certsTheir \"%s\"\n", strings.Join(hexCerts, " "),
+               ))
+               hexCerts = make([]string, 0, len(certsOur))
+               for _, cert := range certsOur {
+                       hexCerts = append(hexCerts, hex.EncodeToString([]byte(certInfo(cert.Raw))))
                }
-
-               b.WriteString(`
-proc doAccept {} { exit 10 }
-proc doOnce {} { exit 11 }
-proc doReject {} { exit 12 }
-button .bAccept -text "Accept" -bg green -command doAccept
-button .bOnce -text "Once" -bg green -command doOnce
-button .bReject -text "Reject" -bg red -command doReject
-grid .bAccept .bOnce .bReject
-grid rowconfigure . 0 -weight 1
-grid columnconfigure . 0 -weight 1
-`)
-
+               b.WriteString(fmt.Sprintf(
+                       "set certsOur \"%s\"\n", strings.Join(hexCerts, " "),
+               ))
+               b.WriteString(VerifyDialog)
                cmd := exec.Command(CmdWish)
-               // ioutil.WriteFile("/tmp/w.tcl", b.Bytes(), 0666)
+               // ioutil.WriteFile("/tmp/verify-dialog.tcl", b.Bytes(), 0666)
                cmd.Stdin = &b
                err = cmd.Run()
                exitError, ok := err.(*exec.ExitError)