From b4e23c13d7b2ea73f8b1167c044a521d540120ad Mon Sep 17 00:00:00 2001 From: Sergey Matveev Date: Sun, 12 Sep 2021 13:49:51 +0300 Subject: [PATCH] More pleasant Tk dialogs --- doc/dialog.webp | Bin 23184 -> 24744 bytes tlsauth.go | 42 +++++++----- verify.go | 172 +++++++++++++++++++++++++++++++----------------- 3 files changed, 138 insertions(+), 76 deletions(-) diff --git a/doc/dialog.webp b/doc/dialog.webp index bff32689fc2ca043d51cc596a295e999f82b5273..dd19649882c5e64bb3ab3ff4fae71fca5ee224cc 100644 GIT binary patch literal 24744 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 diff --git a/tlsauth.go b/tlsauth.go index 0965335..b980e08 100644 --- a/tlsauth.go +++ b/tlsauth.go @@ -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() diff --git a/verify.go b/verify.go index f1bb49f..ed98650 100644 --- 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) -- 2.44.0