From 3e9ff9973468596205d695f49a899d7dc97e3dbf Mon Sep 17 00:00:00 2001 From: Sergey Matveev Date: Wed, 8 Sep 2021 20:47:54 +0300 Subject: [PATCH] Missing source --- tlsauth.go | 112 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 112 insertions(+) create mode 100644 tlsauth.go diff --git a/tlsauth.go b/tlsauth.go new file mode 100644 index 0000000..531245d --- /dev/null +++ b/tlsauth.go @@ -0,0 +1,112 @@ +/* +tofuproxy -- HTTP proxy with TLS certificates management +Copyright (C) 2021 Sergey Matveev + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, version 3 of the License. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ + +package tofuproxy + +import ( + "bytes" + "crypto/tls" + "crypto/x509" + "errors" + "fmt" + "log" + "os" + "os/exec" + "path/filepath" + "strconv" + "strings" + + "go.cypherpunks.ru/ucspi" + "go.stargrave.org/tofuproxy/fifos" +) + +var CCerts string + +type ClientCertificateGetter struct { + host string +} + +func (g *ClientCertificateGetter) get( + cri *tls.CertificateRequestInfo, +) (*tls.Certificate, error) { + var b bytes.Buffer + b.WriteString(fmt.Sprintf(` +wm title . "TLS client authentication: %s" + +label .lVersion -text "Version: %s" +grib .lVersion + +set lb [listbox .lb] +.lb insert end "" +`, + g.host, + ucspi.TLSVersion(cri.Version), + )) + + ents, err := os.ReadDir(CCerts) + if err != nil { + log.Fatalln(err) + } + certs := make([]*x509.Certificate, 0, len(ents)) + tlsCerts := make([]*tls.Certificate, 0, len(ents)) + for i, ent := range ents { + p := filepath.Join(CCerts, ent.Name()) + _, cert, err := ucspi.CertificateFromFile(p) + if err != nil { + log.Fatalln(err) + } + prv, err := ucspi.PrivateKeyFromFile(p) + if err != nil { + log.Fatalln(err) + } + certs = append(certs, cert) + tlsCerts = append(tlsCerts, &tls.Certificate{ + Certificate: [][]byte{cert.Raw}, + PrivateKey: prv, + }) + 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 +`) + cmd := exec.Command(CmdWish) + cmd.Stdin = &b + out, err := cmd.Output() + if err != nil { + return nil, err + } + lines := strings.Split(string(out), "\n") + if len(lines) < 1 { + return nil, errors.New("invalid output from authentication form") + } + t := strings.Split(lines[0], ":")[0] + i, err := strconv.Atoi(t) + if err != nil { + return &tls.Certificate{}, nil + } + fifos.SinkCert <- fmt.Sprintf("ClientAuth\t%s\t%s", g.host, certs[i].Subject) + return tlsCerts[i], nil +} -- 2.44.0