Skip to content

Commit cf20c9c

Browse files
authored
Add expiry to TURN password. (livekit#4515)
* Add expiry to TURN password. Defaults to 5m. For backwards compatibility expiry = 0 skips adding it. * fix variable shadowing
1 parent 20d4a3a commit cf20c9c

2 files changed

Lines changed: 30 additions & 17 deletions

File tree

pkg/service/roommanager.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1036,8 +1036,8 @@ func (r *RoomManager) iceServersForParticipant(apiKey string, participant types.
10361036
urls = append(urls, fmt.Sprintf("turns:%s:443?transport=tcp", r.config.TURN.Domain))
10371037
}
10381038
if len(urls) > 0 {
1039-
username := r.turnAuthHandler.CreateUsername(apiKey, participant.ID(), r.config.TURN.TTLSeconds)
1040-
password, err := r.turnAuthHandler.CreatePassword(apiKey, participant.ID())
1039+
username, expiry := r.turnAuthHandler.CreateUsername(apiKey, participant.ID(), r.config.TURN.TTLSeconds)
1040+
password, err := r.turnAuthHandler.CreatePassword(apiKey, participant.ID(), expiry)
10411041
if err != nil {
10421042
participant.GetLogger().Warnw("could not create turn password", err)
10431043
hasSTUN = false

pkg/service/turn.go

Lines changed: 28 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ const (
4343
allocateRetries = 50
4444
)
4545

46+
var ErrExpired = errors.New("expired")
47+
4648
func NewTurnServer(conf *config.Config, authHandler turn.AuthHandler, standalone bool) (*turn.Server, error) {
4749
turnConf := conf.TURN
4850
if !turnConf.Enabled {
@@ -202,38 +204,47 @@ func NewTURNAuthHandler(keyProvider auth.KeyProvider) *TURNAuthHandler {
202204
}
203205
}
204206

205-
func (h *TURNAuthHandler) CreateUsername(apiKey string, pID livekit.ParticipantID, ttlSeconds int) string {
207+
func (h *TURNAuthHandler) CreateUsername(apiKey string, pID livekit.ParticipantID, ttlSeconds int) (string, int64) {
206208
expiry := time.Now().Add(time.Duration(ttlSeconds) * time.Second).Unix()
207-
return base62.EncodeToString(fmt.Appendf(nil, "%s|%s|%d", apiKey, pID, expiry))
209+
return base62.EncodeToString(fmt.Appendf(nil, "%s|%s|%d", apiKey, pID, expiry)), expiry
208210
}
209211

210-
func (h *TURNAuthHandler) ParseUsername(username string) (apiKey string, pID livekit.ParticipantID, expiry time.Time, err error) {
212+
func (h *TURNAuthHandler) ParseUsername(username string) (apiKey string, pID livekit.ParticipantID, expiry int64, err error) {
211213
decoded, err := base62.DecodeString(username)
212214
if err != nil {
213-
return "", "", time.Time{}, err
215+
return "", "", 0, err
214216
}
215217
parts := strings.Split(string(decoded), "|")
216218
if len(parts) != 2 && len(parts) != 3 {
217-
return "", "", time.Time{}, errors.New("invalid username")
219+
return "", "", 0, errors.New("invalid username")
218220
}
219-
expiry = time.Time{}
221+
expiry = 0
220222
if len(parts) == 3 {
221-
if unixTime, err := strconv.ParseInt(parts[2], 10, 64); err != nil {
222-
return "", "", time.Time{}, err
223-
} else {
224-
expiry = time.Unix(unixTime, 0)
223+
var err error
224+
if expiry, err = strconv.ParseInt(parts[2], 10, 64); err != nil {
225+
return "", "", 0, err
225226
}
226227
}
227228

228229
return parts[0], livekit.ParticipantID(parts[1]), expiry, nil
229230
}
230231

231-
func (h *TURNAuthHandler) CreatePassword(apiKey string, pID livekit.ParticipantID) (string, error) {
232+
func (h *TURNAuthHandler) CreatePassword(apiKey string, pID livekit.ParticipantID, expiry int64) (string, error) {
232233
secret := h.keyProvider.GetSecret(apiKey)
233234
if secret == "" {
234235
return "", ErrInvalidAPIKey
235236
}
237+
236238
keyInput := fmt.Sprintf("%s|%s", secret, pID)
239+
if expiry != 0 {
240+
expiryTime := time.Unix(expiry, 0)
241+
if time.Now().After(expiryTime) {
242+
return "", ErrExpired
243+
}
244+
245+
keyInput = fmt.Sprintf("%s|%s|%d", secret, pID, expiry)
246+
}
247+
237248
sum := sha256.Sum256([]byte(keyInput))
238249
return base62.EncodeToString(sum[:]), nil
239250
}
@@ -247,17 +258,19 @@ func (h *TURNAuthHandler) HandleAuth(username, realm string, srcAddr net.Addr) (
247258
if len(parts) != 2 && len(parts) != 3 {
248259
return nil, false
249260
}
261+
expiry := int64(0)
250262
if len(parts) == 3 {
251-
if unixTime, err := strconv.ParseInt(parts[2], 10, 64); err != nil {
263+
var err error
264+
if expiry, err = strconv.ParseInt(parts[2], 10, 64); err != nil {
252265
return nil, false
253266
} else {
254-
expiry := time.Unix(unixTime, 0)
255-
if time.Now().After(expiry) {
267+
expiryTime := time.Unix(expiry, 0)
268+
if time.Now().After(expiryTime) {
256269
return nil, false
257270
}
258271
}
259272
}
260-
password, err := h.CreatePassword(parts[0], livekit.ParticipantID(parts[1]))
273+
password, err := h.CreatePassword(parts[0], livekit.ParticipantID(parts[1]), expiry)
261274
if err != nil {
262275
logger.Warnw("could not create TURN password", err, "username", username)
263276
return nil, false

0 commit comments

Comments
 (0)