ccache_integration_test.go 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. package credentials
  2. import (
  3. "bufio"
  4. "bytes"
  5. "fmt"
  6. "io"
  7. "os"
  8. "os/exec"
  9. "os/user"
  10. "sync"
  11. "testing"
  12. "github.com/stretchr/testify/assert"
  13. "gopkg.in/jcmturner/gokrb5.v7/iana/nametype"
  14. "gopkg.in/jcmturner/gokrb5.v7/test"
  15. "gopkg.in/jcmturner/gokrb5.v7/test/testdata"
  16. "gopkg.in/jcmturner/gokrb5.v7/types"
  17. )
  18. const (
  19. kinitCmd = "kinit"
  20. kvnoCmd = "kvno"
  21. klistCmd = "klist"
  22. spn = "HTTP/host.test.gokrb5"
  23. )
  24. type output struct {
  25. buf *bytes.Buffer
  26. lines []string
  27. *sync.Mutex
  28. }
  29. func newOutput() *output {
  30. return &output{
  31. buf: &bytes.Buffer{},
  32. lines: []string{},
  33. Mutex: &sync.Mutex{},
  34. }
  35. }
  36. func (rw *output) Write(p []byte) (int, error) {
  37. rw.Lock()
  38. defer rw.Unlock()
  39. return rw.buf.Write(p)
  40. }
  41. func (rw *output) Lines() []string {
  42. rw.Lock()
  43. defer rw.Unlock()
  44. s := bufio.NewScanner(rw.buf)
  45. for s.Scan() {
  46. rw.lines = append(rw.lines, s.Text())
  47. }
  48. return rw.lines
  49. }
  50. func login() error {
  51. file, err := os.Create("/etc/krb5.conf")
  52. if err != nil {
  53. return fmt.Errorf("cannot open krb5.conf: %v", err)
  54. }
  55. defer file.Close()
  56. fmt.Fprintf(file, testdata.TEST_KRB5CONF)
  57. cmd := exec.Command(kinitCmd, "testuser1@TEST.GOKRB5")
  58. stdinR, stdinW := io.Pipe()
  59. stderrR, stderrW := io.Pipe()
  60. cmd.Stdin = stdinR
  61. cmd.Stderr = stderrW
  62. err = cmd.Start()
  63. if err != nil {
  64. return fmt.Errorf("could not start %s command: %v", kinitCmd, err)
  65. }
  66. go func() {
  67. io.WriteString(stdinW, "passwordvalue")
  68. stdinW.Close()
  69. }()
  70. errBuf := new(bytes.Buffer)
  71. go func() {
  72. io.Copy(errBuf, stderrR)
  73. stderrR.Close()
  74. }()
  75. err = cmd.Wait()
  76. if err != nil {
  77. return fmt.Errorf("%s did not run successfully: %v stderr: %s", kinitCmd, err, string(errBuf.Bytes()))
  78. }
  79. return nil
  80. }
  81. func getServiceTkt() error {
  82. cmd := exec.Command(kvnoCmd, spn)
  83. err := cmd.Start()
  84. if err != nil {
  85. return fmt.Errorf("could not start %s command: %v", kvnoCmd, err)
  86. }
  87. err = cmd.Wait()
  88. if err != nil {
  89. return fmt.Errorf("%s did not run successfully: %v", kvnoCmd, err)
  90. }
  91. return nil
  92. }
  93. func klist() ([]string, error) {
  94. cmd := exec.Command(klistCmd, "-Aef")
  95. stdout := newOutput()
  96. cmd.Stdout = stdout
  97. err := cmd.Start()
  98. if err != nil {
  99. return []string{}, fmt.Errorf("could not start %s command: %v", klistCmd, err)
  100. }
  101. err = cmd.Wait()
  102. if err != nil {
  103. return []string{}, fmt.Errorf("%s did not run successfully: %v", klistCmd, err)
  104. }
  105. return stdout.Lines(), nil
  106. }
  107. func loadCCache() (*CCache, error) {
  108. usr, _ := user.Current()
  109. cpath := "/tmp/krb5cc_" + usr.Uid
  110. return LoadCCache(cpath)
  111. }
  112. func TestLoadCCache(t *testing.T) {
  113. test.Privileged(t)
  114. err := login()
  115. if err != nil {
  116. t.Fatalf("error logging in with kinit: %v", err)
  117. }
  118. c, err := loadCCache()
  119. if err != nil {
  120. t.Errorf("error loading CCache: %v", err)
  121. }
  122. pn := c.GetClientPrincipalName()
  123. assert.Equal(t, "testuser1", pn.PrincipalNameString(), "principal not as expected")
  124. assert.Equal(t, "TEST.GOKRB5", c.GetClientRealm(), "realm not as expected")
  125. }
  126. func TestCCacheEntries(t *testing.T) {
  127. test.Privileged(t)
  128. err := login()
  129. if err != nil {
  130. t.Fatalf("error logging in with kinit: %v", err)
  131. }
  132. err = getServiceTkt()
  133. if err != nil {
  134. t.Fatalf("error getting service ticket: %v", err)
  135. }
  136. clist, _ := klist()
  137. t.Log("OS Creds Cache contents:")
  138. for _, l := range clist {
  139. t.Log(l)
  140. }
  141. c, err := loadCCache()
  142. if err != nil {
  143. t.Errorf("error loading CCache: %v", err)
  144. }
  145. creds := c.GetEntries()
  146. var found bool
  147. n := types.NewPrincipalName(nametype.KRB_NT_PRINCIPAL, spn)
  148. for _, cred := range creds {
  149. if cred.Server.PrincipalName.Equal(n) {
  150. found = true
  151. break
  152. }
  153. }
  154. if !found {
  155. t.Errorf("Entry for %s not found in CCache", spn)
  156. }
  157. }