X-Git-Url: http://www.git.stargrave.org/?a=blobdiff_plain;f=verify.go;h=dc852a8b747a7b31ed67f7b5c28a1702bc851616;hb=0c0a261a6ef4fddfc34a9150005f7964cc69c420;hp=f1bb49f33efec4dcdae20bb670d922c4778c6077;hpb=6450081d248fb268db96fbfc3fd8321fe400ba5c;p=tofuproxy.git diff --git a/verify.go b/verify.go index f1bb49f..dc852a8 100644 --- a/verify.go +++ b/verify.go @@ -1,5 +1,5 @@ /* -tofuproxy -- HTTP proxy with TLS certificates management +tofuproxy -- flexible HTTP/WARC proxy with TLS certificates management Copyright (C) 2021 Sergey Matveev This program is free software: you can redistribute it and/or modify @@ -36,6 +36,107 @@ 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 [subst { + set page$name \[paginator \$page$name +1 \$t$name \$l$name \$certs$name] + }] + button .bPrev$name -text "Prev" -command [subst { + 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" +} +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 .fButtons +grid .lDANE .bAccept .bOnce .bReject -in .fButtons +grid rowconfigure . 0 -weight 1 +grid columnconfigure . 0 -weight 1 + +bind . {switch -exact %K { + q {exit 0} ; # reject once + a doAccept + o doOnce + r doReject + n {.bNextTheir invoke} + p {.bPrevTheir invoke} + N {.bNextOur invoke} + P {.bPrevOur invoke} +}} +` + var ( CmdCerttool = "certtool" CmdWish = "wish8.6" @@ -62,16 +163,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 +219,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)