]> Cypherpunks.ru repositories - ucspi.git/blobdiff - cmd/tlss/main.go
Raised copyright years
[ucspi.git] / cmd / tlss / main.go
index 7740ecd5cdf07443908de03885378f48437120e1..752204a8e1938a51df5d383f1144dfa7292c8b82 100644 (file)
@@ -1,6 +1,6 @@
 /*
 ucspi/cmd/tlsc -- UCSPI TLS server
-Copyright (C) 2021 Sergey Matveev <stargrave@stargrave.org>
+Copyright (C) 2021-2022 Sergey Matveev <stargrave@stargrave.org>
 
 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
@@ -22,6 +22,7 @@ import (
        "crypto/x509"
        "flag"
        "fmt"
+       "io"
        "log"
        "os"
        "os/exec"
@@ -70,7 +71,7 @@ func main() {
                cfg.ClientAuth = tls.RequireAndVerifyClientCert
        }
 
-       conn := &ucspi.Conn{R: os.Stdin, W: os.Stdout}
+       conn, _ := ucspi.NewConn(os.Stdin, os.Stdout)
        tlsConn := tls.Server(conn, cfg)
        if err = tlsConn.Handshake(); err != nil {
                log.Fatalln(err)
@@ -80,10 +81,18 @@ func main() {
                dn = tlsConn.ConnectionState().PeerCertificates[0].Subject.String()
        }
 
+       rr, rw, err := os.Pipe()
+       if err != nil {
+               log.Fatalln(err)
+       }
+       wr, ww, err := os.Pipe()
+       if err != nil {
+               log.Fatalln(err)
+       }
        args := flag.Args()
        cmd := exec.Command(args[0], args[1:]...)
-       cmd.Stdin = tlsConn
-       cmd.Stdout = tlsConn
+       cmd.Stdin = rr
+       cmd.Stdout = ww
        cmd.Stderr = os.Stderr
        cmd.Env = append(os.Environ(), "PROTO=TLS")
        if dn != "" {
@@ -93,7 +102,20 @@ func main() {
        if err = cmd.Start(); err != nil {
                log.Fatalln(err)
        }
-       if _, err = cmd.Process.Wait(); err != nil {
+       worker := make(chan struct{})
+       go func() {
+               io.Copy(rw, tlsConn)
+               rw.Close()
+       }()
+       go func() {
+               io.Copy(tlsConn, wr)
+               tlsConn.Close()
+               close(worker)
+       }()
+       err = cmd.Wait()
+       ww.Close()
+       <-worker
+       if err != nil {
                log.Fatalln(err)
        }
 }