1 // ucspi/cmd/tlss -- UCSPI TCP proxy server
2 // Copyright (C) 2021-2024 Sergey Matveev <stargrave@stargrave.org>
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, version 3 of the License.
8 // This program is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 // GNU General Public License for more details.
13 // You should have received a copy of the GNU General Public License
14 // along with this program. If not, see <http://www.gnu.org/licenses/>.
28 "go.cypherpunks.ru/ucspi"
32 crtPath := flag.String("cert", "cert.pem", "Path to server X.509 certificate")
33 prvPath := flag.String("key", "prv.pem", "Path to server PKCS#8 private key")
34 casPath := flag.String("client-ca", "", "Require client authentication, path to CA certificates file")
36 fmt.Fprintf(os.Stderr, `Usage: tcpserver host port tlss [-client-ca CAs.pem]
37 -cert cert.pem -key prv.pem program [args...]
43 log.SetFlags(log.Lshortfile)
45 crtRaw, _, err := ucspi.CertificateFromFile(*crtPath)
49 prv, err := ucspi.PrivateKeyFromFile(*prvPath)
53 var cas *x509.CertPool
55 _, cas, err = ucspi.CertPoolFromFile(*casPath)
62 Certificates: []tls.Certificate{{
63 Certificate: [][]byte{crtRaw},
69 cfg.ClientAuth = tls.RequireAndVerifyClientCert
72 conn, _ := ucspi.NewConn(os.Stdin, os.Stdout)
73 tlsConn := tls.Server(conn, cfg)
74 if err = tlsConn.Handshake(); err != nil {
79 dn = tlsConn.ConnectionState().PeerCertificates[0].Subject.String()
82 rr, rw, err := os.Pipe()
86 wr, ww, err := os.Pipe()
91 cmd := exec.Command(args[0], args[1:]...)
94 cmd.Stderr = os.Stderr
95 cmd.Env = append(os.Environ(), "PROTO=TLS")
97 cmd.Env = append(cmd.Env, "TLSREMOTEDN="+dn)
100 if err = cmd.Start(); err != nil {
103 worker := make(chan struct{})