From: Sergey Matveev <stargrave@stargrave.org> Date: Sun, 12 Sep 2021 10:49:51 +0000 (+0300) Subject: More pleasant Tk dialogs X-Git-Tag: v0.1.0~66 X-Git-Url: http://www.git.stargrave.org/?a=commitdiff_plain;h=b4e23c13d7b2ea73f8b1167c044a521d540120ad;p=tofuproxy.git More pleasant Tk dialogs --- diff --git a/doc/dialog.webp b/doc/dialog.webp index bff3268..dd19649 100644 Binary files a/doc/dialog.webp and b/doc/dialog.webp differ 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)