forked from eXeC64/Rosella
/
main.go
136 lines (111 loc) · 3.2 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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
package main
import (
"crypto/tls"
"flag"
"log"
"os"
"strings"
"syscall"
)
var (
tlsKeyFile = flag.String("tls-key", "tls.key", "The private key file used for TLS")
tlsCertFile = flag.String("tls-cert", "tls.crt", "The certificate file used for TLS")
ircAddress = flag.String("irc-address", ":6697", "The address:port to bind to and listen for clients on")
serverName = flag.String("irc-servername", "rosella", "Server name displayed to clients")
authFile = flag.String("irc-authfile", "", "File containing usernames and passwords of operators.")
motdFile = flag.String("irc-motdfile", "", "File container motd to display to clients.")
groupId = flag.Int("perm-gid", 0, "Group id to drop to if running as root")
userId = flag.Int("perm-uid", 0, "User id to drop to if running as root")
)
func main() {
flag.Parse()
log.Printf("Rosella v%s Initialising.", VERSION)
//Init rosella itself
server := NewServer()
server.name = *serverName
if *authFile != "" {
log.Printf("Loading auth file: %q", *authFile)
f, err := os.Open(*authFile)
if err != nil {
log.Fatal(err)
}
data := make([]byte, 1024)
size, err := f.Read(data)
if err != nil {
log.Fatal(err)
}
lines := strings.Split(string(data[:size]), "\n")
for _, line := range lines {
if strings.HasPrefix(line, "#") {
continue
}
fields := strings.Fields(line)
if len(fields) == 2 {
server.operatorMap[fields[0]] = fields[1]
}
}
}
if *motdFile != "" {
log.Printf("Loading motd file: %q", *motdFile)
f, err := os.Open(*motdFile)
if err != nil {
log.Fatal(err)
}
data := make([]byte, 1024)
size, err := f.Read(data)
if err != nil {
log.Fatal(err)
}
server.motd = string(data[:size])
}
go server.Run()
tlsConfig := new(tls.Config)
tlsConfig.PreferServerCipherSuites = true
tlsConfig.CipherSuites = []uint16{
tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
tls.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
tls.TLS_RSA_WITH_AES_256_CBC_SHA,
tls.TLS_RSA_WITH_AES_128_CBC_SHA,
tls.TLS_RSA_WITH_3DES_EDE_CBC_SHA}
cert, err := tls.LoadX509KeyPair(*tlsCertFile, *tlsKeyFile)
if err != nil {
log.Printf("Error loading tls certificate and key files.")
log.Printf(err.Error())
return
}
log.Printf("Loaded certificate and key successfully.")
tlsConfig.Certificates = []tls.Certificate{cert}
//Fills out tlsConfig.NameToCertificate
tlsConfig.BuildNameToCertificate()
tlsListener, err := tls.Listen("tcp", *ircAddress, tlsConfig)
if err != nil {
log.Printf("Could not open tls listener.")
log.Printf(err.Error())
return
}
log.Printf("Listening on %s", *ircAddress)
if syscall.Getuid() == 0 {
if *groupId < 1 || *userId < 1 {
log.Printf("Rosella may not be run as root. Please specify a non-root uid and gid that it may drop to.")
return
}
if syscall.Setgid(*groupId) != nil {
log.Printf("Failed to set gid to %i", *groupId)
return
}
if syscall.Setuid(*userId) != nil {
log.Printf("Failed to set uid to %i", *userId)
return
}
}
for {
conn, err := tlsListener.Accept()
if err != nil {
log.Printf("Error accepting connection.")
log.Printf(err.Error())
continue
}
server.HandleConnection(conn)
}
}