summaryrefslogtreecommitdiff
path: root/tlsserver.go
blob: 3022f0eacd665de638a0ca5e30aa4bb0f12abd7d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
package main

import (
	"crypto/tls"
	"log"
	"net"
	"flag"
	"fmt"
	"os"
	"os/exec"
)

var (
	cfile = flag.String("cert", "cert.pem", "Certificate file in PEM format")
	kfile = flag.String("key", "key.pem", "Key file in PEM format")
	port = flag.Int("port", 1234, "Port to bind to")
	args []string
	nargs int
)

func main() {

	flag.Parse()
	 args = flag.Args()
	nargs = flag.NArg()
	if nargs < 1 {
		fmt.Println("Usage: tlsserver [options] cmd [flags for cmd]")
		fmt.Println("options:")
		flag.PrintDefaults()
		os.Exit(1)
	}

	// setup certs etc. for TLS-socket
	tconf := new(tls.Config)
	cert, err := tls.LoadX509KeyPair(*cfile, *kfile)
	if err != nil {
		fmt.Println("error with certs:", err)
		os.Exit(2)
	}

	tconf.Certificates = append(tconf.Certificates, cert)
	tconf.BuildNameToCertificate()

	// start listening
	sport := fmt.Sprintf(":%d", *port)
	sock, err := tls.Listen("tcp", sport , tconf)
	if err != nil {
		fmt.Println("error with tcp-socket:", err)
		os.Exit(3)
	}
	defer sock.Close()

	// accept-loop
	for {
		conn, err := sock.Accept()
		if err != nil {
			log.Println("error during Accept()", err)
			continue
		}
		log.Println("Got connection:", conn.RemoteAddr())
		go handleConnection(conn)
	}
}

func handleConnection(conn net.Conn) {
	defer conn.Close()

	// setup cmd
	cmd := exec.Command(args[0])
	cmd.Args = args
	cmd.Stdin = conn
	cmd.Stdout = conn
	cmd.Stderr = os.Stderr

	// prepare environment according to tcp-environ(5)
	lh, lp, err := net.SplitHostPort(conn.LocalAddr().String())
	if err != nil {
		log.Println(err)
		return
	}
	rh, rp, err := net.SplitHostPort(conn.LocalAddr().String())
	if err != nil {
		log.Println(err)
		return
	}
	cmd.Env = make([]string,0)
	cmd.Env = append(cmd.Env, "PATH="+os.Getenv("PATH"))
	cmd.Env = append(cmd.Env, "PROTO=TCP")
	cmd.Env = append(cmd.Env, "TCPLOCALIP="+lh)
	cmd.Env = append(cmd.Env, "TCPLOCALPORT="+lp)
	cmd.Env = append(cmd.Env, "TCPREMOTEIP="+rh)
	cmd.Env = append(cmd.Env, "TCPREMOTEPORT="+rp)

	err = cmd.Run()
	if err != nil {
		log.Println("after Run: ", err)
	}
	log.Println("Done with connection", conn.RemoteAddr())
}