-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.go
104 lines (91 loc) · 2.59 KB
/
main.go
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
100
101
102
103
104
package main
import (
"crypto/tls"
"flag"
"fmt"
"log"
"net"
"os"
)
var options struct {
listenAddress string
pgAddress string
clientCertPath string
clientKeyPath string
connectionPassword string
}
func argFatal(s string) {
fmt.Fprintln(os.Stderr, s)
flag.Usage()
os.Exit(1)
}
func main() {
flag.Usage = func() {
fmt.Fprintf(os.Stderr, "usage: %s [options]\n", os.Args[0])
flag.PrintDefaults()
}
// parse arguments
flag.StringVar(&options.listenAddress, "l", "127.0.0.1:15432", "Listen address")
flag.StringVar(&options.pgAddress, "p", "", "Postgres address")
flag.StringVar(&options.clientCertPath, "c", "", "clientCertPath")
flag.StringVar(&options.clientKeyPath, "k", "", "clientKeyPath")
flag.StringVar(&options.connectionPassword, "s", "", "Password used to authenticate to pgssl\n" +
"can alternatively be specified via the PGSSL_PASSWORD environment variable")
flag.Parse()
if options.pgAddress == "" {
argFatal("postgres address must be specified")
}
if (options.clientCertPath == "") != (options.clientKeyPath == "") {
argFatal("You must specify both clientKeyPath and clientCertPath to use a client certificate")
}
var envPassword string = os.Getenv("PGSSL_PASSWORD")
if envPassword != "" {
if options.connectionPassword != "" {
log.Println("PGSSL_PASSWORD and -s <password> specified. Ignoring env variable.")
} else {
options.connectionPassword = envPassword
}
}
// create pgSSL instance
pgSSL := &PgSSL{
pgAddr: options.pgAddress,
connectionPassword: options.connectionPassword,
}
if (options.clientCertPath != "") && (options.clientKeyPath != "") {
// load client certificate and key
cert, err := tls.LoadX509KeyPair(options.clientCertPath, options.clientKeyPath)
if err != nil {
log.Fatal(err)
}
// recreate pgSSL instance with our client cert
pgSSL = &PgSSL{
pgAddr: options.pgAddress,
clientCert: &cert,
connectionPassword: options.connectionPassword,
}
}
// bind listening socket
ln, err := net.Listen("tcp", options.listenAddress)
if err != nil {
log.Fatal(err)
}
log.Println("Listening on", ln.Addr())
// start accepting connection
var connNum int
for {
conn, err := ln.Accept()
if err != nil {
log.Fatal(err)
}
connNum++
log.Printf("[%3d] Accepted connection from %s\n", connNum, conn.RemoteAddr())
// handle connection in goroutine
go func(n int) {
err := pgSSL.HandleConn(conn)
if err != nil {
log.Printf("[%3d] error in connection: %s", n, err)
}
log.Printf("[%3d] Closed connection from %s", n, conn.RemoteAddr())
}(connNum)
}
}