Add an ident server

Closes: https://todo.sr.ht/~emersion/soju/69
This commit is contained in:
Simon Ser 2020-08-11 10:36:14 +02:00
parent 6faa081a7c
commit 65302d3c1e
No known key found for this signature in database
GPG Key ID: 0FDE7BE0E88F5E48
3 changed files with 39 additions and 0 deletions

View File

@ -124,6 +124,22 @@ func main() {
go func() {
log.Fatal(httpSrv.ListenAndServe())
}()
case "ident":
if srv.Identd == nil {
srv.Identd = soju.NewIdentd()
}
host := u.Host
if _, _, err := net.SplitHostPort(host); err != nil {
host = host + ":113"
}
ln, err := net.Listen("tcp", host)
if err != nil {
log.Fatalf("failed to start listener on %q: %v", listen, err)
}
go func() {
log.Fatal(srv.Identd.Serve(ln))
}()
default:
log.Fatalf("failed to listen on %q: unsupported scheme", listen)
}

View File

@ -51,6 +51,7 @@ type Server struct {
Debug bool
HTTPOrigins []string
AcceptProxyIPs config.IPSet
Identd *Identd // can be nil
db *DB

22
user.go
View File

@ -1,6 +1,9 @@
package soju
import (
"crypto/sha256"
"encoding/base64"
"encoding/binary"
"fmt"
"time"
@ -99,6 +102,17 @@ func (net *network) isStopped() bool {
}
}
func userIdent(u *User) string {
// The ident is a string we will send to upstream servers in clear-text.
// For privacy reasons, make sure it doesn't expose any meaningful user
// metadata. We just use the base64-encoded hashed ID, so that people don't
// start relying on the string being an integer or following a pattern.
var b [64]byte
binary.LittleEndian.PutUint64(b[:], uint64(u.ID))
h := sha256.Sum256(b[:])
return base64.RawStdEncoding.EncodeToString(h[:])
}
func (net *network) run() {
var lastTry time.Time
for {
@ -120,6 +134,10 @@ func (net *network) run() {
continue
}
if net.user.srv.Identd != nil {
net.user.srv.Identd.Store(uc.RemoteAddr().String(), uc.LocalAddr().String(), userIdent(&net.user.User))
}
uc.register()
if err := uc.runUntilRegistered(); err != nil {
uc.logger.Printf("failed to register: %v", err)
@ -138,6 +156,10 @@ func (net *network) run() {
}
uc.Close()
net.user.events <- eventUpstreamDisconnected{uc}
if net.user.srv.Identd != nil {
net.user.srv.Identd.Delete(uc.RemoteAddr().String(), uc.LocalAddr().String())
}
}
}