49 lines
1.5 KiB
Go
49 lines
1.5 KiB
Go
package services
|
|
|
|
import (
|
|
"bufio"
|
|
"net"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
func NewSIPHandler(log LoggerFunc) Handler {
|
|
return func(conn net.Conn) {
|
|
defer conn.Close()
|
|
remote := conn.RemoteAddr().String()
|
|
conn.SetDeadline(time.Now().Add(8 * time.Second))
|
|
r := bufio.NewReader(conn)
|
|
// Read request line
|
|
reqLine, _ := r.ReadString('\n')
|
|
reqLine = strings.TrimSpace(reqLine)
|
|
if reqLine == "" { return }
|
|
// Read headers until blank line
|
|
headers := map[string]string{}
|
|
for {
|
|
h, _ := r.ReadString('\n')
|
|
h = strings.TrimRight(h, "\r\n")
|
|
if h == "" { break }
|
|
if i := strings.Index(h, ":"); i > 0 {
|
|
k := strings.TrimSpace(h[:i])
|
|
v := strings.TrimSpace(h[i+1:])
|
|
headers[strings.ToLower(k)] = v
|
|
}
|
|
}
|
|
det := map[string]string{"event":"request","first_line":reqLine}
|
|
for _, k := range []string{"from","to","call-id","user-agent"} {
|
|
if v, ok := headers[k]; ok { det[k] = v }
|
|
}
|
|
log(Record{Timestamp: Now(), RemoteAddr: remoteIP(remote), RemotePort: remotePort(remote), Service: "sip", Details: det})
|
|
// Respond with 401 to solicit credentials
|
|
resp := "SIP/2.0 401 Unauthorized\r\n" +
|
|
"Via: " + headers["via"] + "\r\n" +
|
|
"From: " + headers["from"] + "\r\n" +
|
|
"To: " + headers["to"] + ";tag=123456\r\n" +
|
|
"Call-ID: " + headers["call-id"] + "\r\n" +
|
|
"CSeq: 1 REGISTER\r\n" +
|
|
"WWW-Authenticate: Digest realm=\"example.com\", nonce=\"abc123\", qop=\"auth\"\r\n" +
|
|
"Content-Length: 0\r\n\r\n"
|
|
_, _ = conn.Write([]byte(resp))
|
|
}
|
|
}
|