lt_cred.go 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. package turn
  2. import ( //nolint:gci
  3. "crypto/hmac"
  4. "crypto/sha1" //nolint:gosec,gci
  5. "encoding/base64"
  6. "net"
  7. "strconv"
  8. "time"
  9. "github.com/pion/logging"
  10. )
  11. // GenerateLongTermCredentials can be used to create credentials valid for [duration] time
  12. func GenerateLongTermCredentials(sharedSecret string, duration time.Duration) (string, string, error) {
  13. t := time.Now().Add(duration).Unix()
  14. username := strconv.FormatInt(t, 10)
  15. password, err := longTermCredentials(username, sharedSecret)
  16. return username, password, err
  17. }
  18. func longTermCredentials(username string, sharedSecret string) (string, error) {
  19. mac := hmac.New(sha1.New, []byte(sharedSecret))
  20. _, err := mac.Write([]byte(username))
  21. if err != nil {
  22. return "", err // Not sure if this will ever happen
  23. }
  24. password := mac.Sum(nil)
  25. return base64.StdEncoding.EncodeToString(password), nil
  26. }
  27. // NewLongTermAuthHandler returns a turn.AuthAuthHandler used with Long Term (or Time Windowed) Credentials.
  28. // https://tools.ietf.org/search/rfc5389#section-10.2
  29. func NewLongTermAuthHandler(sharedSecret string, l logging.LeveledLogger) AuthHandler {
  30. if l == nil {
  31. l = logging.NewDefaultLoggerFactory().NewLogger("turn")
  32. }
  33. return func(username, realm string, srcAddr net.Addr) (key []byte, ok bool) {
  34. l.Tracef("Authentication username=%q realm=%q srcAddr=%v\n", username, realm, srcAddr)
  35. t, err := strconv.Atoi(username)
  36. if err != nil {
  37. l.Errorf("Invalid time-windowed username %q", username)
  38. return nil, false
  39. }
  40. if int64(t) < time.Now().Unix() {
  41. l.Errorf("Expired time-windowed username %q", username)
  42. return nil, false
  43. }
  44. password, err := longTermCredentials(username, sharedSecret)
  45. if err != nil {
  46. l.Error(err.Error())
  47. return nil, false
  48. }
  49. return GenerateAuthKey(username, realm, password), true
  50. }
  51. }