Skip to content

Commit 550aa91

Browse files
Adding additional logging for failed auths (#414)
* Adding additional logging for failed auths * PR feedback
1 parent 6c101e8 commit 550aa91

File tree

1 file changed

+68
-1
lines changed

1 file changed

+68
-1
lines changed

pkg/sip/inbound.go

Lines changed: 68 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ package sip
1616

1717
import (
1818
"context"
19+
"crypto/sha256"
20+
"encoding/hex"
1921
"fmt"
2022
"log/slog"
2123
"math"
@@ -55,6 +57,15 @@ const (
5557
audioBridgeMaxDelay = 1 * time.Second
5658
)
5759

60+
// hashPassword creates a SHA256 hash of the password for logging purposes
61+
func hashPassword(password string) string {
62+
if password == "" {
63+
return "<empty>"
64+
}
65+
hash := sha256.Sum256([]byte(password))
66+
return hex.EncodeToString(hash[:8]) // Use first 8 bytes for shorter hash
67+
}
68+
5869
func (s *Server) getInvite(from string) *inProgressInvite {
5970
s.imu.Lock()
6071
defer s.imu.Unlock()
@@ -72,37 +83,81 @@ func (s *Server) getInvite(from string) *inProgressInvite {
7283
}
7384

7485
func (s *Server) handleInviteAuth(log logger.Logger, req *sip.Request, tx sip.ServerTransaction, from, username, password string) (ok bool) {
86+
log = log.WithValues(
87+
"username", username,
88+
"passwordHash", hashPassword(password),
89+
"method", req.Method.String(),
90+
"uri", req.Recipient.String(),
91+
)
92+
93+
log.Infow("Starting SIP invite authentication")
94+
7595
if username == "" || password == "" {
96+
log.Debugw("Skipping authentication - no credentials provided")
7697
return true
7798
}
99+
78100
if s.conf.HideInboundPort {
79101
// We will send password request anyway, so might as well signal that the progress is made.
102+
log.Debugw("Sending processing response due to HideInboundPort config")
80103
_ = tx.Respond(sip.NewResponseFromRequest(req, 100, "Processing", nil))
81104
}
82105

83106
inviteState := s.getInvite(from)
107+
log = log.WithValues("inviteStateFrom", from)
84108

85109
h := req.GetHeader("Proxy-Authorization")
86110
if h == nil {
87-
log.Infow("Requesting inbound auth")
88111
inviteState.challenge = digest.Challenge{
89112
Realm: UserAgent,
90113
Nonce: fmt.Sprintf("%d", time.Now().UnixMicro()),
91114
Algorithm: "MD5",
92115
}
93116

117+
log.Debugw("Created digest challenge",
118+
"realm", inviteState.challenge.Realm,
119+
"nonce", inviteState.challenge.Nonce,
120+
"algorithm", inviteState.challenge.Algorithm,
121+
)
122+
94123
res := sip.NewResponseFromRequest(req, 407, "Unauthorized", nil)
95124
res.AppendHeader(sip.NewHeader("Proxy-Authenticate", inviteState.challenge.String()))
96125
_ = tx.Respond(res)
126+
log.Infow("No Proxy header found. Sending 407 Unauthorized response with Proxy-Authenticate header")
97127
return false
98128
}
99129

130+
log.Debugw("Found Proxy-Authorization header, parsing credentials")
100131
cred, err := digest.ParseCredentials(h.Value())
101132
if err != nil {
133+
log.Warnw("Failed to parse Proxy-Authorization credentials", err,
134+
"headerValue", h.Value(),
135+
)
102136
_ = tx.Respond(sip.NewResponseFromRequest(req, 401, "Bad credentials", nil))
103137
return false
104138
}
105139

140+
// Set credURI and credUsername in logger early to avoid repetitive logging
141+
log = log.WithValues("credURI", cred.URI, "credUsername", cred.Username)
142+
143+
log.Debugw("Parsed credentials successfully", "cred", cred)
144+
145+
// Check if we have a valid challenge state
146+
if inviteState.challenge.Realm == "" {
147+
log.Warnw("No challenge state found for authentication attempt", nil,
148+
"from", from,
149+
"expectedRealm", UserAgent,
150+
)
151+
_ = tx.Respond(sip.NewResponseFromRequest(req, 401, "Bad credentials", nil))
152+
return false
153+
}
154+
155+
log.Debugw("Computing digest response",
156+
"challengeRealm", inviteState.challenge.Realm,
157+
"challengeNonce", inviteState.challenge.Nonce,
158+
"challengeAlgorithm", inviteState.challenge.Algorithm,
159+
)
160+
106161
digCred, err := digest.Digest(&inviteState.challenge, digest.Options{
107162
Method: req.Method.String(),
108163
URI: cred.URI,
@@ -111,15 +166,27 @@ func (s *Server) handleInviteAuth(log logger.Logger, req *sip.Request, tx sip.Se
111166
})
112167

113168
if err != nil {
169+
log.Warnw("Failed to compute digest response", err)
114170
_ = tx.Respond(sip.NewResponseFromRequest(req, 401, "Bad credentials", nil))
115171
return false
116172
}
117173

174+
log.Debugw("Digest computation completed",
175+
"expectedResponse", digCred.Response,
176+
"receivedResponse", cred.Response,
177+
"responsesMatch", cred.Response == digCred.Response,
178+
)
179+
118180
if cred.Response != digCred.Response {
181+
log.Warnw("Authentication failed - response mismatch", nil,
182+
"expectedResponse", digCred.Response,
183+
"receivedResponse", cred.Response,
184+
)
119185
_ = tx.Respond(sip.NewResponseFromRequest(req, 401, "Unauthorized", nil))
120186
return false
121187
}
122188

189+
log.Infow("SIP invite authentication successful")
123190
return true
124191
}
125192

0 commit comments

Comments
 (0)