session_test.go 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. package client
  2. import (
  3. "encoding/hex"
  4. "fmt"
  5. "io/ioutil"
  6. "os"
  7. "runtime"
  8. "sync"
  9. "testing"
  10. "time"
  11. "github.com/jcmturner/gokrb5/v8/config"
  12. "github.com/jcmturner/gokrb5/v8/iana/etypeID"
  13. "github.com/jcmturner/gokrb5/v8/keytab"
  14. "github.com/jcmturner/gokrb5/v8/test"
  15. "github.com/jcmturner/gokrb5/v8/test/testdata"
  16. "github.com/stretchr/testify/assert"
  17. )
  18. func TestMultiThreadedClientSession(t *testing.T) {
  19. test.Integration(t)
  20. b, _ := hex.DecodeString(testdata.TESTUSER1_KEYTAB)
  21. kt := keytab.New()
  22. kt.Unmarshal(b)
  23. c, _ := config.NewFromString(testdata.TEST_KRB5CONF)
  24. addr := os.Getenv("TEST_KDC_ADDR")
  25. if addr == "" {
  26. addr = testdata.TEST_KDC_ADDR
  27. }
  28. c.Realms[0].KDC = []string{addr + ":" + testdata.TEST_KDC}
  29. cl := NewWithKeytab("testuser1", "TEST.GOKRB5", kt, c)
  30. err := cl.Login()
  31. if err != nil {
  32. t.Fatalf("failed to log in: %v", err)
  33. }
  34. s, ok := cl.sessions.get("TEST.GOKRB5")
  35. if !ok {
  36. t.Fatal("error initially getting session")
  37. }
  38. go func() {
  39. for {
  40. err := cl.renewTGT(s)
  41. if err != nil {
  42. t.Logf("error renewing TGT: %v", err)
  43. }
  44. time.Sleep(time.Millisecond * 100)
  45. }
  46. }()
  47. var wg sync.WaitGroup
  48. wg.Add(10)
  49. for i := 0; i < 10; i++ {
  50. go func() {
  51. defer wg.Done()
  52. tgt, _, err := cl.sessionTGT("TEST.GOKRB5")
  53. if err != nil || tgt.Realm != "TEST.GOKRB5" {
  54. t.Logf("error getting session: %v", err)
  55. }
  56. _, _, _, r, _ := cl.sessionTimes("TEST.GOKRB5")
  57. fmt.Fprintf(ioutil.Discard, "%v", r)
  58. }()
  59. time.Sleep(time.Second)
  60. }
  61. wg.Wait()
  62. }
  63. func TestClient_AutoRenew_Goroutine(t *testing.T) {
  64. test.Integration(t)
  65. // Tests that the auto renew of client credentials is not spawning goroutines out of control.
  66. addr := os.Getenv("TEST_KDC_ADDR")
  67. if addr == "" {
  68. addr = testdata.TEST_KDC_ADDR
  69. }
  70. b, _ := hex.DecodeString(testdata.TESTUSER2_KEYTAB)
  71. kt := keytab.New()
  72. kt.Unmarshal(b)
  73. c, _ := config.NewFromString(testdata.TEST_KRB5CONF)
  74. c.Realms[0].KDC = []string{addr + ":" + testdata.TEST_KDC_SHORTTICKETS}
  75. c.LibDefaults.PreferredPreauthTypes = []int{int(etypeID.DES3_CBC_SHA1_KD)} // a preauth etype the KDC does not support. Test this does not cause renewal to fail.
  76. cl := NewWithKeytab("testuser2", "TEST.GOKRB5", kt, c)
  77. err := cl.Login()
  78. if err != nil {
  79. t.Errorf("error on logging in: %v\n", err)
  80. }
  81. n := runtime.NumGoroutine()
  82. for i := 0; i < 24; i++ {
  83. time.Sleep(time.Second * 5)
  84. _, endTime, _, _, err := cl.sessionTimes("TEST.GOKRB5")
  85. if err != nil {
  86. t.Errorf("could not get client's session: %v", err)
  87. }
  88. if time.Now().UTC().After(endTime) {
  89. t.Fatalf("session auto update failed")
  90. }
  91. spn := "HTTP/host.test.gokrb5"
  92. tkt, key, err := cl.GetServiceTicket(spn)
  93. if err != nil {
  94. t.Fatalf("error getting service ticket: %v\n", err)
  95. }
  96. b, _ := hex.DecodeString(testdata.HTTP_KEYTAB)
  97. skt := keytab.New()
  98. skt.Unmarshal(b)
  99. tkt.DecryptEncPart(skt, nil)
  100. assert.Equal(t, spn, tkt.SName.PrincipalNameString())
  101. assert.Equal(t, int32(18), key.KeyType)
  102. if runtime.NumGoroutine() > n {
  103. t.Fatalf("number of goroutines is increasing: should not be more than %d, is %d", n, runtime.NumGoroutine())
  104. }
  105. }
  106. }