Initial commit
This commit is contained in:
85
internal/kcpolicy/socketmap.go
Normal file
85
internal/kcpolicy/socketmap.go
Normal file
@@ -0,0 +1,85 @@
|
||||
package kcpolicy
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"context"
|
||||
"fmt"
|
||||
"net"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func RunSocketmap(ctx context.Context, cfg *Config, db *AliasDB) error {
|
||||
sock := cfg.Sockets.SocketmapSocket
|
||||
_ = os.Remove(sock)
|
||||
|
||||
l, err := net.Listen("unix", sock)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer l.Close()
|
||||
|
||||
if err := ChownChmodSocket(sock, cfg); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for {
|
||||
conn, err := l.Accept()
|
||||
if err != nil {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return nil
|
||||
default:
|
||||
return err
|
||||
}
|
||||
}
|
||||
go handleSocketmapConn(conn, cfg, db)
|
||||
}
|
||||
}
|
||||
|
||||
// Socketmap protocol: "mapname key\n" -> "OK value\n" or "NOTFOUND\n" or "TEMP\n"
|
||||
func handleSocketmapConn(conn net.Conn, cfg *Config, db *AliasDB) {
|
||||
defer conn.Close()
|
||||
r := bufio.NewReader(conn)
|
||||
|
||||
for {
|
||||
line, err := r.ReadString('\n')
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
line = strings.TrimSpace(line)
|
||||
if line == "" {
|
||||
continue
|
||||
}
|
||||
parts := strings.SplitN(line, " ", 2)
|
||||
if len(parts) != 2 {
|
||||
fmt.Fprint(conn, "TEMP\n")
|
||||
continue
|
||||
}
|
||||
mapName := parts[0]
|
||||
key := strings.ToLower(strings.TrimSpace(parts[1]))
|
||||
|
||||
if mapName != "alias" {
|
||||
fmt.Fprint(conn, "NOTFOUND\n")
|
||||
continue
|
||||
}
|
||||
|
||||
// Only handle our domain
|
||||
if !strings.HasSuffix(key, "@"+strings.ToLower(cfg.Policy.Domain)) {
|
||||
fmt.Fprint(conn, "NOTFOUND\n")
|
||||
continue
|
||||
}
|
||||
|
||||
username, ok, err := db.AliasOwner(key)
|
||||
if err != nil {
|
||||
fmt.Fprint(conn, "TEMP\n")
|
||||
continue
|
||||
}
|
||||
if !ok {
|
||||
fmt.Fprint(conn, "NOTFOUND\n")
|
||||
continue
|
||||
}
|
||||
// rewrite alias -> primary rcpt (username@domain)
|
||||
fmt.Fprintf(conn, "OK %s@%s\n", username, strings.ToLower(cfg.Policy.Domain))
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user