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
|
package identd
import (
"fmt"
"net"
"net/textproto"
"strings"
"sync"
)
// Server - An IdentD server
type Server struct {
Entries map[string]string
EntriesLock sync.Mutex
}
// NewIdentdServer - Create a new IdentdServer instance
func NewIdentdServer() Server {
return Server{
Entries: make(map[string]string),
}
}
// AddIdent - Add an ident to be looked up
func (i *Server) AddIdent(localPort, remotePort int, ident string, iface string) {
i.EntriesLock.Lock()
i.Entries[fmt.Sprintf("%d-%d", localPort, remotePort)] = ident
i.EntriesLock.Unlock()
}
// RemoveIdent - Remove an ident from being looked up
func (i *Server) RemoveIdent(localPort, remotePort int, iface string) {
i.EntriesLock.Lock()
delete(i.Entries, fmt.Sprintf("%d-%d", localPort, remotePort))
i.EntriesLock.Unlock()
}
// Run - Start listening for ident lookups
func (i *Server) Run() error {
serv, err := net.Listen("tcp", ":113")
if err != nil {
return err
}
go i.ListenForRequests(&serv)
return nil
}
// ListenForRequests - Listen on a net.Listener for ident lookups
func (i *Server) ListenForRequests(serverSocket *net.Listener) {
for {
serv := *serverSocket
client, err := serv.Accept()
if err != nil {
break
}
go func(conn net.Conn) {
tc := textproto.NewConn(conn)
line, err := tc.ReadLine()
if err != nil {
conn.Close()
return
}
// Remove all spaces, some servers like to send "%d , %d" but the spec examples use "%d, %d"
line = strings.ReplaceAll(line, " ", "")
var localPort, remotePort int
fmt.Sscanf(line, "%d,%d", &localPort, &remotePort)
if localPort > 0 && remotePort > 0 {
i.EntriesLock.Lock()
ident, ok := i.Entries[fmt.Sprintf("%d-%d", localPort, remotePort)]
i.EntriesLock.Unlock()
if !ok {
fmt.Fprintf(conn, "%d, %d : ERROR : NO-USER\r\n", localPort, remotePort)
} else {
fmt.Fprintf(conn, "%d, %d : USERID : UNIX : %s\r\n", localPort, remotePort, ident)
}
}
conn.Close()
}(client)
}
}
|