session.go 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. package client
  2. import (
  3. "github.com/jcmturner/gokrb5/iana/nametype"
  4. "github.com/jcmturner/gokrb5/krberror"
  5. "github.com/jcmturner/gokrb5/messages"
  6. "github.com/jcmturner/gokrb5/types"
  7. "time"
  8. )
  9. // Client session struct.
  10. type session struct {
  11. AuthTime time.Time
  12. EndTime time.Time
  13. RenewTill time.Time
  14. TGT messages.Ticket
  15. SessionKey types.EncryptionKey
  16. SessionKeyExpiration time.Time
  17. }
  18. // EnableAutoSessionRenewal turns on the automatic renewal for the client's TGT session.
  19. func (cl *Client) EnableAutoSessionRenewal() {
  20. // TODO look into using a context here
  21. go func() {
  22. for {
  23. //Wait until one minute before endtime
  24. w := (cl.session.EndTime.Sub(time.Now().UTC()) * 5) / 6
  25. if w < 0 {
  26. return
  27. }
  28. time.Sleep(w)
  29. cl.updateTGT()
  30. }
  31. }()
  32. }
  33. // RenewTGT renews the client's TGT session.
  34. func (cl *Client) RenewTGT() error {
  35. spn := types.PrincipalName{
  36. NameType: nametype.KRB_NT_SRV_INST,
  37. NameString: []string{"krbtgt", cl.session.TGT.Realm},
  38. }
  39. _, tgsRep, err := cl.TGSExchange(spn, cl.session.TGT, cl.session.SessionKey, true)
  40. if err != nil {
  41. return krberror.Errorf(err, krberror.KRBMsgError, "Error renewing TGT")
  42. }
  43. cl.session = &session{
  44. AuthTime: tgsRep.DecryptedEncPart.AuthTime,
  45. EndTime: tgsRep.DecryptedEncPart.EndTime,
  46. RenewTill: tgsRep.DecryptedEncPart.RenewTill,
  47. TGT: tgsRep.Ticket,
  48. SessionKey: tgsRep.DecryptedEncPart.Key,
  49. SessionKeyExpiration: tgsRep.DecryptedEncPart.KeyExpiration,
  50. }
  51. return nil
  52. }
  53. func (cl *Client) updateTGT() error {
  54. if time.Now().UTC().Before(cl.session.RenewTill) {
  55. err := cl.RenewTGT()
  56. if err != nil {
  57. return err
  58. }
  59. } else {
  60. err := cl.Login()
  61. if err != nil {
  62. return err
  63. }
  64. }
  65. return nil
  66. }