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