]> Sergey Matveev's repositories - tofuproxy.git/commitdiff
More pleasant Tk dialogs
authorSergey Matveev <stargrave@stargrave.org>
Sun, 12 Sep 2021 10:49:51 +0000 (13:49 +0300)
committerSergey Matveev <stargrave@stargrave.org>
Sun, 12 Sep 2021 19:08:43 +0000 (22:08 +0300)
doc/dialog.webp
tlsauth.go
verify.go

index bff32689fc2ca043d51cc596a295e999f82b5273..dd19649882c5e64bb3ab3ff4fae71fca5ee224cc 100644 (file)
Binary files a/doc/dialog.webp and b/doc/dialog.webp differ
index 0965335a3ffb3ad3a3a07ee41f76d7fcbe826836..b980e08122f17f12ea97c43bb81a13e255756bea 100644 (file)
@@ -51,19 +51,42 @@ func (g *ClientCertificateGetter) get(
        if tlsCert != nil {
                return tlsCert, nil
        }
+       sigSchemes := make([]string, 0, len(cri.SignatureSchemes))
+       for _, ss := range cri.SignatureSchemes {
+               sigSchemes = append(sigSchemes, ss.String())
+       }
        var b bytes.Buffer
        b.WriteString(fmt.Sprintf(`
 tk_setPalette grey
 wm title . "TLS client authentication: %s"
 
-label .lVersion -text "Version: %s"
-grib .lVersion
-
 set lb [listbox .lb]
 .lb insert end ""
+grid .lb
+
+proc submit {} {
+    global lb
+    puts [$lb get active]
+    exit
+}
+
+button .submit -text "Use" -command submit
+grid .submit
+
+label .lTLSVersion -text "TLS version: %s"
+grid .lTLSVersion
+
+set sigSchemeRow 0
+foreach sigScheme {%s} {
+    label .lSignatureScheme$sigSchemeRow -text "Signature scheme: $sigScheme"
+    grid .lSignatureScheme$sigSchemeRow
+    incr sigSchemeRow
+}
+
 `,
                g.host,
                ucspi.TLSVersion(cri.Version),
+               strings.Join(sigSchemes, " "),
        ))
 
        ents, err := os.ReadDir(CCerts)
@@ -89,18 +112,7 @@ set lb [listbox .lb]
                })
                b.WriteString(fmt.Sprintf(".lb insert end \"%d: %s\"\n", i, cert.Subject))
        }
-       b.WriteString(`
-grid .lb
-
-proc submit {} {
-    global lb
-    puts [$lb get active]
-    exit
-}
-
-button .submit -text "Use" -command submit
-grid .submit
-`)
+       // ioutil.WriteFile("/tmp/tls-auth-dialog.tcl", b.Bytes(), 0666)
        cmd := exec.Command(CmdWish)
        cmd.Stdin = &b
        out, err := cmd.Output()
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)