160 lines
4.2 KiB
Go
160 lines
4.2 KiB
Go
package gircclient
|
|
|
|
import (
|
|
"bufio"
|
|
"crypto/ecdsa"
|
|
"crypto/elliptic"
|
|
"crypto/rand"
|
|
"crypto/tls"
|
|
"crypto/x509"
|
|
"crypto/x509/pkix"
|
|
"encoding/pem"
|
|
"fmt"
|
|
"math/big"
|
|
"net"
|
|
"runtime"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
func TestPlainConnection(t *testing.T) {
|
|
reactor := NewReactor()
|
|
client := reactor.CreateServer("local")
|
|
|
|
client.InitialNick = "coolguy"
|
|
client.InitialUser = "c"
|
|
client.InitialRealName = "girc-go Test Client "
|
|
|
|
// we mock up a server connection to test the client
|
|
listener, _ := net.Listen("tcp", ":0")
|
|
|
|
client.Connect(listener.Addr().String(), false, nil)
|
|
|
|
testServerConnection(t, reactor, client, listener)
|
|
}
|
|
|
|
func TestTLSConnection(t *testing.T) {
|
|
reactor := NewReactor()
|
|
client := reactor.CreateServer("local")
|
|
|
|
client.InitialNick = "coolguy"
|
|
client.InitialUser = "c"
|
|
client.InitialRealName = "girc-go Test Client "
|
|
|
|
// generate a test certificate to use
|
|
priv, _ := ecdsa.GenerateKey(elliptic.P521(), rand.Reader)
|
|
|
|
duration30Days, _ := time.ParseDuration("-30h")
|
|
notBefore := time.Now().Add(duration30Days) // valid 30 hours ago
|
|
duration1Year, _ := time.ParseDuration("90h")
|
|
notAfter := notBefore.Add(duration1Year) // for 90 hours
|
|
|
|
serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128)
|
|
serialNumber, _ := rand.Int(rand.Reader, serialNumberLimit)
|
|
|
|
template := x509.Certificate{
|
|
SerialNumber: serialNumber,
|
|
Subject: pkix.Name{
|
|
Organization: []string{"gIRC-Go Co"},
|
|
},
|
|
NotBefore: notBefore,
|
|
NotAfter: notAfter,
|
|
KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign,
|
|
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
|
|
BasicConstraintsValid: true,
|
|
IsCA: true,
|
|
}
|
|
|
|
template.IPAddresses = append(template.IPAddresses, net.ParseIP("127.0.0.1"))
|
|
template.IPAddresses = append(template.IPAddresses, net.ParseIP("::"))
|
|
template.DNSNames = append(template.DNSNames, "localhost")
|
|
|
|
derBytes, _ := x509.CreateCertificate(rand.Reader, &template, &template, &priv.PublicKey, priv)
|
|
|
|
c := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: derBytes})
|
|
b, _ := x509.MarshalECPrivateKey(priv)
|
|
k := pem.EncodeToMemory(&pem.Block{Type: "EC PRIVATE KEY", Bytes: b})
|
|
|
|
// we mock up a server connection to test the client
|
|
listenerKeyPair, _ := tls.X509KeyPair(c, k)
|
|
|
|
var listenerTLSConfig tls.Config
|
|
listenerTLSConfig.Certificates = make([]tls.Certificate, 0)
|
|
listenerTLSConfig.Certificates = append(listenerTLSConfig.Certificates, listenerKeyPair)
|
|
listener, _ := tls.Listen("tcp", ":0", &listenerTLSConfig)
|
|
|
|
// mock up the client side too
|
|
clientTLSCertPool := x509.NewCertPool()
|
|
clientTLSCertPool.AppendCertsFromPEM(c)
|
|
|
|
var clientTLSConfig tls.Config
|
|
clientTLSConfig.RootCAs = clientTLSCertPool
|
|
clientTLSConfig.ServerName = "localhost"
|
|
go client.Connect(listener.Addr().String(), true, &clientTLSConfig)
|
|
|
|
testServerConnection(t, reactor, client, listener)
|
|
}
|
|
|
|
func testServerConnection(t *testing.T, reactor Reactor, client *ServerConnection, listener net.Listener) {
|
|
conn, _ := listener.Accept()
|
|
reader := bufio.NewReader(conn)
|
|
|
|
// test each message in sequence
|
|
var message string
|
|
|
|
message, _ = reader.ReadString('\n')
|
|
if message != "NICK coolguy\r\n" {
|
|
t.Error(
|
|
"Did not receive NICK message, received: [",
|
|
message,
|
|
"]",
|
|
)
|
|
return
|
|
}
|
|
|
|
message, _ = reader.ReadString('\n')
|
|
if message != "USER c 0 * :girc-go Test Client \r\n" {
|
|
t.Error(
|
|
"Did not receive USER message, received: [",
|
|
message,
|
|
"]",
|
|
)
|
|
return
|
|
}
|
|
|
|
// make sure nick changes properly
|
|
// need to wait for a quick moment here for TLS to do this properly
|
|
fmt.Fprintf(conn, "\r\n\r\n\r\n") // these should be silently ignored
|
|
fmt.Fprintf(conn, ":example.com 001 dan :Welcome to the gIRC-Go Test Network!\r\n")
|
|
runtime.Gosched()
|
|
waitTime, _ := time.ParseDuration("10ms")
|
|
time.Sleep(waitTime)
|
|
|
|
if client.Nick != "dan" {
|
|
t.Error(
|
|
"Nick was not set with 001, expected",
|
|
"dan",
|
|
"got",
|
|
client.Nick,
|
|
)
|
|
return
|
|
}
|
|
|
|
// shutdown client
|
|
reactor.Shutdown(" Get mad! ")
|
|
|
|
message, _ = reader.ReadString('\n')
|
|
if message != "QUIT : Get mad! \r\n" {
|
|
t.Error(
|
|
"Did not receive QUIT message, received: [",
|
|
message,
|
|
"]",
|
|
)
|
|
return
|
|
}
|
|
|
|
// close connection and listener
|
|
conn.Close()
|
|
listener.Close()
|
|
}
|