112 lines
1.8 KiB
Go
112 lines
1.8 KiB
Go
// vim:ts=4:sts=4:sw=4:noet:tw=72
|
|
|
|
package main
|
|
|
|
import (
|
|
"flag"
|
|
"fmt"
|
|
"log"
|
|
"net"
|
|
"strings"
|
|
"time"
|
|
|
|
"code.dnix.de/an/irc"
|
|
"code.dnix.de/an/xlog"
|
|
)
|
|
|
|
var saddr = flag.String("server", "irc.example.com:6667", "Server address")
|
|
var laddr = flag.String("listen", "0.0.0.0:6667", "Listen address")
|
|
|
|
func init() {
|
|
flag.Parse()
|
|
}
|
|
|
|
func main() {
|
|
listen, err := net.Listen("tcp", *laddr)
|
|
if err != nil {
|
|
xlog.Fatal(err.Error())
|
|
return
|
|
}
|
|
for {
|
|
cconn, err := listen.Accept()
|
|
if err != nil {
|
|
log.Println(err)
|
|
continue
|
|
}
|
|
go bounce(cconn, saddr)
|
|
}
|
|
}
|
|
|
|
func bounce(cconn net.Conn, saddr *string) {
|
|
done := make(chan bool, 5)
|
|
|
|
client := NewIRCConn(cconn, done)
|
|
defer func() {
|
|
client.Close()
|
|
}()
|
|
|
|
sconn, err := net.Dial("tcp", *saddr)
|
|
if err != nil {
|
|
log.Println(err)
|
|
return
|
|
}
|
|
server := NewIRCConn(sconn, done)
|
|
defer func() {
|
|
server.Close()
|
|
}()
|
|
|
|
if !login(server, client) {
|
|
return
|
|
}
|
|
|
|
go relay(server, client)
|
|
go relay(client, server)
|
|
|
|
<-done
|
|
}
|
|
|
|
func login(server, client *IRCConn) bool {
|
|
nick := ""
|
|
user := ""
|
|
pass := ""
|
|
for {
|
|
s := client.Read()
|
|
msg := irc.Parse(s)
|
|
msg.Cmd = strings.ToUpper(msg.Cmd)
|
|
switch msg.Cmd {
|
|
case "PASS":
|
|
pass = msg.Args[0]
|
|
case "USER":
|
|
user = msg.Args[0]
|
|
case "NICK":
|
|
nick = msg.Args[0]
|
|
}
|
|
if nick != "" && user != "" {
|
|
if authenticate(nick, pass) {
|
|
server.Write(fmt.Sprintf("NICK %s", nick))
|
|
server.Write(fmt.Sprintf("USER %s %s %s :%s", user, user, user, user))
|
|
return true
|
|
} else {
|
|
return false
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func authenticate(name, password string) bool {
|
|
return true
|
|
}
|
|
|
|
func relay(conn1 *IRCConn, conn2 *IRCConn) {
|
|
for {
|
|
if conn1.closed || conn2.closed {
|
|
return
|
|
}
|
|
s := conn1.Read()
|
|
if s != "" {
|
|
conn2.Write(s)
|
|
}
|
|
time.Sleep(1 * time.Millisecond)
|
|
}
|
|
}
|