| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460 |
- // +build integration
- // To turn on this test use -tags=integration in go test command
- package client
- import (
- "encoding/hex"
- "github.com/stretchr/testify/assert"
- "gopkg.in/jcmturner/gokrb5.v2/config"
- "gopkg.in/jcmturner/gokrb5.v2/credentials"
- "gopkg.in/jcmturner/gokrb5.v2/iana/etypeID"
- "gopkg.in/jcmturner/gokrb5.v2/keytab"
- "gopkg.in/jcmturner/gokrb5.v2/testdata"
- "net/http"
- "os"
- "testing"
- )
- func TestClient_SuccessfulLogin_Keytab(t *testing.T) {
- addr := os.Getenv("TEST_KDC_ADDR")
- if addr == "" {
- addr = testdata.TEST_KDC_ADDR
- }
- b, err := hex.DecodeString(testdata.TESTUSER1_KEYTAB)
- kt, _ := keytab.Parse(b)
- c, _ := config.NewConfigFromString(testdata.TEST_KRB5CONF)
- var tests = []string{
- testdata.TEST_KDC,
- testdata.TEST_KDC_OLD,
- testdata.TEST_KDC_LASTEST,
- }
- for _, test := range tests {
- c.Realms[0].KDC = []string{addr + ":" + test}
- cl := NewClientWithKeytab("testuser1", "TEST.GOKRB5", kt)
- cl.WithConfig(c)
- err = cl.Login()
- if err != nil {
- t.Errorf("Error on logging in with KDC %s: %v\n", test, err)
- }
- }
- }
- func TestClient_SuccessfulLogin_Password(t *testing.T) {
- addr := os.Getenv("TEST_KDC_ADDR")
- if addr == "" {
- addr = testdata.TEST_KDC_ADDR
- }
- c, _ := config.NewConfigFromString(testdata.TEST_KRB5CONF)
- var tests = []string{
- testdata.TEST_KDC,
- testdata.TEST_KDC_OLD,
- testdata.TEST_KDC_LASTEST,
- }
- for _, test := range tests {
- c.Realms[0].KDC = []string{addr + ":" + test}
- cl := NewClientWithPassword("testuser1", "TESTGOKRB5", "passwordvalue")
- cl.WithConfig(c)
- err := cl.Login()
- if err != nil {
- t.Errorf("Error on logging in with KDC %s: %v\n", test, err)
- }
- }
- }
- func TestClient_SuccessfulLogin_TCPOnly(t *testing.T) {
- b, err := hex.DecodeString(testdata.TESTUSER1_KEYTAB)
- kt, _ := keytab.Parse(b)
- c, _ := config.NewConfigFromString(testdata.TEST_KRB5CONF)
- addr := os.Getenv("TEST_KDC_ADDR")
- if addr == "" {
- addr = testdata.TEST_KDC_ADDR
- }
- c.Realms[0].KDC = []string{addr + ":" + testdata.TEST_KDC}
- c.LibDefaults.UDPPreferenceLimit = 1
- cl := NewClientWithKeytab("testuser1", "TEST.GOKRB5", kt)
- cl.WithConfig(c)
- err = cl.Login()
- if err != nil {
- t.Fatalf("Error on login: %v\n", err)
- }
- }
- func TestClient_ASExchange_TGSExchange_EncTypes_Keytab(t *testing.T) {
- b, err := hex.DecodeString(testdata.TESTUSER1_KEYTAB)
- kt, _ := keytab.Parse(b)
- c, _ := config.NewConfigFromString(testdata.TEST_KRB5CONF)
- addr := os.Getenv("TEST_KDC_ADDR")
- if addr == "" {
- addr = testdata.TEST_KDC_ADDR
- }
- c.Realms[0].KDC = []string{addr + ":" + testdata.TEST_KDC_LASTEST}
- var tests = []string{
- "des3-cbc-sha1-kd",
- "aes128-cts-hmac-sha1-96",
- "aes256-cts-hmac-sha1-96",
- "aes128-cts-hmac-sha256-128",
- "aes256-cts-hmac-sha384-192",
- "rc4-hmac",
- }
- for _, test := range tests {
- c.LibDefaults.DefaultTktEnctypes = []string{test}
- c.LibDefaults.DefaultTktEnctypeIDs = []int{etypeID.ETypesByName[test]}
- c.LibDefaults.DefaultTGSEnctypes = []string{test}
- c.LibDefaults.DefaultTGSEnctypeIDs = []int{etypeID.ETypesByName[test]}
- cl := NewClientWithKeytab("testuser1", "TEST.GOKRB5", kt)
- cl.WithConfig(c)
- err = cl.Login()
- if err != nil {
- t.Errorf("Error on login using enctype %s: %v\n", test, err)
- }
- tkt, key, err := cl.GetServiceTicket("HTTP/host.test.gokrb5")
- if err != nil {
- t.Errorf("Error in TGS exchange using enctype %s: %v", test, err)
- }
- assert.Equal(t, "TEST.GOKRB5", tkt.Realm, "Realm in ticket not as expected for %s test", test)
- assert.Equal(t, etypeID.ETypesByName[test], key.KeyType, "Key is not for enctype %s", test)
- }
- }
- func TestClient_ASExchange_TGSExchange_EncTypes_Password(t *testing.T) {
- c, _ := config.NewConfigFromString(testdata.TEST_KRB5CONF)
- addr := os.Getenv("TEST_KDC_ADDR")
- if addr == "" {
- addr = testdata.TEST_KDC_ADDR
- }
- c.Realms[0].KDC = []string{addr + ":" + testdata.TEST_KDC_LASTEST}
- var tests = []string{
- "des3-cbc-sha1-kd",
- "aes128-cts-hmac-sha1-96",
- "aes256-cts-hmac-sha1-96",
- "aes128-cts-hmac-sha256-128",
- "aes256-cts-hmac-sha384-192",
- "rc4-hmac",
- }
- for _, test := range tests {
- c.LibDefaults.DefaultTktEnctypes = []string{test}
- c.LibDefaults.DefaultTktEnctypeIDs = []int{etypeID.ETypesByName[test]}
- c.LibDefaults.DefaultTGSEnctypes = []string{test}
- c.LibDefaults.DefaultTGSEnctypeIDs = []int{etypeID.ETypesByName[test]}
- cl := NewClientWithPassword("testuser1", "TESTGOKRB5", "passwordvalue")
- cl.WithConfig(c)
- err := cl.Login()
- if err != nil {
- t.Errorf("Error on login using enctype %s: %v\n", test, err)
- }
- tkt, key, err := cl.GetServiceTicket("HTTP/host.test.gokrb5")
- if err != nil {
- t.Errorf("Error in TGS exchange using enctype %s: %v", test, err)
- }
- assert.Equal(t, "TEST.GOKRB5", tkt.Realm, "Realm in ticket not as expected for %s test", test)
- assert.Equal(t, etypeID.ETypesByName[test], key.KeyType, "Key is not for enctype %s", test)
- }
- }
- func TestClient_FailedLogin(t *testing.T) {
- b, err := hex.DecodeString(testdata.TESTUSER1_WRONGPASSWD)
- kt, _ := keytab.Parse(b)
- c, _ := config.NewConfigFromString(testdata.TEST_KRB5CONF)
- addr := os.Getenv("TEST_KDC_ADDR")
- if addr == "" {
- addr = testdata.TEST_KDC_ADDR
- }
- c.Realms[0].KDC = []string{addr + ":" + testdata.TEST_KDC}
- cl := NewClientWithKeytab("testuser1", "TEST.GOKRB5", kt)
- cl.WithConfig(c)
- err = cl.Login()
- if err == nil {
- t.Fatal("Login with incorrect password did not error")
- }
- }
- func TestClient_SuccessfulLogin_UserRequiringPreAuth(t *testing.T) {
- b, err := hex.DecodeString(testdata.TESTUSER2_KEYTAB)
- kt, _ := keytab.Parse(b)
- c, _ := config.NewConfigFromString(testdata.TEST_KRB5CONF)
- addr := os.Getenv("TEST_KDC_ADDR")
- if addr == "" {
- addr = testdata.TEST_KDC_ADDR
- }
- c.Realms[0].KDC = []string{addr + ":" + testdata.TEST_KDC}
- cl := NewClientWithKeytab("testuser2", "TEST.GOKRB5", kt)
- cl.WithConfig(c)
- err = cl.Login()
- if err != nil {
- t.Fatalf("Error on login: %v\n", err)
- }
- }
- func TestClient_SuccessfulLogin_UserRequiringPreAuth_TCPOnly(t *testing.T) {
- b, err := hex.DecodeString(testdata.TESTUSER2_KEYTAB)
- kt, _ := keytab.Parse(b)
- c, _ := config.NewConfigFromString(testdata.TEST_KRB5CONF)
- addr := os.Getenv("TEST_KDC_ADDR")
- if addr == "" {
- addr = testdata.TEST_KDC_ADDR
- }
- c.Realms[0].KDC = []string{addr + ":" + testdata.TEST_KDC}
- c.LibDefaults.UDPPreferenceLimit = 1
- cl := NewClientWithKeytab("testuser2", "TEST.GOKRB5", kt)
- cl.WithConfig(c)
- err = cl.Login()
- if err != nil {
- t.Fatalf("Error on login: %v\n", err)
- }
- }
- func TestClient_NetworkTimeout(t *testing.T) {
- b, err := hex.DecodeString(testdata.TESTUSER1_KEYTAB)
- kt, _ := keytab.Parse(b)
- c, _ := config.NewConfigFromString(testdata.TEST_KRB5CONF)
- c.Realms[0].KDC = []string{testdata.TEST_KDC_BADADDR + ":88"}
- cl := NewClientWithKeytab("testuser1", "TEST.GOKRB5", kt)
- cl.WithConfig(c)
- err = cl.Login()
- if err == nil {
- t.Fatal("Login with incorrect KDC address did not error")
- }
- }
- func TestClient_GetServiceTicket(t *testing.T) {
- b, err := hex.DecodeString(testdata.TESTUSER1_KEYTAB)
- kt, _ := keytab.Parse(b)
- c, _ := config.NewConfigFromString(testdata.TEST_KRB5CONF)
- addr := os.Getenv("TEST_KDC_ADDR")
- if addr == "" {
- addr = testdata.TEST_KDC_ADDR
- }
- c.Realms[0].KDC = []string{addr + ":" + testdata.TEST_KDC}
- cl := NewClientWithKeytab("testuser1", "TEST.GOKRB5", kt)
- cl.WithConfig(c)
- err = cl.Login()
- if err != nil {
- t.Fatalf("Error on login: %v\n", err)
- }
- spn := "HTTP/host.test.gokrb5"
- tkt, key, err := cl.GetServiceTicket(spn)
- if err != nil {
- t.Fatalf("Error getting service ticket: %v\n", err)
- }
- assert.Equal(t, spn, tkt.SName.GetPrincipalNameString())
- assert.Equal(t, 18, key.KeyType)
- //Check cache use - should get the same values back again
- tkt2, key2, err := cl.GetServiceTicket(spn)
- if err != nil {
- t.Fatalf("Error getting service ticket: %v\n", err)
- }
- assert.Equal(t, tkt.EncPart.Cipher, tkt2.EncPart.Cipher)
- assert.Equal(t, key.KeyValue, key2.KeyValue)
- }
- func TestClient_GetServiceTicket_OlderKDC(t *testing.T) {
- b, err := hex.DecodeString(testdata.TESTUSER1_KEYTAB)
- kt, _ := keytab.Parse(b)
- c, _ := config.NewConfigFromString(testdata.TEST_KRB5CONF)
- addr := os.Getenv("TEST_KDC_ADDR")
- if addr == "" {
- addr = testdata.TEST_KDC_ADDR
- }
- c.Realms[0].KDC = []string{addr + ":" + testdata.TEST_KDC_OLD}
- cl := NewClientWithKeytab("testuser1", "TEST.GOKRB5", kt)
- cl.WithConfig(c)
- err = cl.Login()
- if err != nil {
- t.Fatalf("Error on login: %v\n", err)
- }
- spn := "HTTP/host.test.gokrb5"
- tkt, key, err := cl.GetServiceTicket(spn)
- if err != nil {
- t.Fatalf("Error getting service ticket: %v\n", err)
- }
- assert.Equal(t, spn, tkt.SName.GetPrincipalNameString())
- assert.Equal(t, 18, key.KeyType)
- }
- func TestClient_SetSPNEGOHeader(t *testing.T) {
- b, _ := hex.DecodeString(testdata.TESTUSER1_KEYTAB)
- kt, _ := keytab.Parse(b)
- c, _ := config.NewConfigFromString(testdata.TEST_KRB5CONF)
- addr := os.Getenv("TEST_KDC_ADDR")
- if addr == "" {
- addr = testdata.TEST_KDC_ADDR
- }
- c.Realms[0].KDC = []string{addr + ":" + testdata.TEST_KDC}
- cl := NewClientWithKeytab("testuser1", "TEST.GOKRB5", kt)
- cl.WithConfig(c)
- err := cl.Login()
- if err != nil {
- t.Fatalf("Error on AS_REQ: %v\n", err)
- }
- url := os.Getenv("TEST_HTTP_URL")
- if url == "" {
- url = testdata.TEST_HTTP_URL
- }
- r, _ := http.NewRequest("GET", url, nil)
- httpResp, err := http.DefaultClient.Do(r)
- if err != nil {
- t.Fatalf("Request error: %v\n", err)
- }
- assert.Equal(t, http.StatusUnauthorized, httpResp.StatusCode, "Status code in response to client with no SPNEGO not as expected")
- err = cl.SetSPNEGOHeader(r, "HTTP/host.test.gokrb5")
- if err != nil {
- t.Fatalf("Error setting client SPNEGO header: %v", err)
- }
- httpResp, err = http.DefaultClient.Do(r)
- if err != nil {
- t.Fatalf("Request error: %v\n", err)
- }
- assert.Equal(t, http.StatusOK, httpResp.StatusCode, "Status code in response to client SPNEGO request not as expected")
- }
- func TestMultiThreadedClientUse(t *testing.T) {
- b, _ := hex.DecodeString(testdata.TESTUSER1_KEYTAB)
- kt, _ := keytab.Parse(b)
- c, _ := config.NewConfigFromString(testdata.TEST_KRB5CONF)
- addr := os.Getenv("TEST_KDC_ADDR")
- if addr == "" {
- addr = testdata.TEST_KDC_ADDR
- }
- c.Realms[0].KDC = []string{addr + ":" + testdata.TEST_KDC}
- cl := NewClientWithKeytab("testuser1", "TEST.GOKRB5", kt)
- cl.WithConfig(c)
- for i := 0; i < 5; i++ {
- go login(t, &cl)
- }
- for i := 0; i < 5; i++ {
- go spnegoGet(t, &cl)
- }
- }
- func login(t *testing.T, cl *Client) {
- err := cl.Login()
- if err != nil {
- t.Fatalf("Error on AS_REQ: %v\n", err)
- }
- }
- func spnegoGet(t *testing.T, cl *Client) {
- url := os.Getenv("TEST_HTTP_URL")
- if url == "" {
- url = testdata.TEST_HTTP_URL
- }
- r, _ := http.NewRequest("GET", url, nil)
- httpResp, err := http.DefaultClient.Do(r)
- if err != nil {
- t.Fatalf("Request error: %v\n", err)
- }
- assert.Equal(t, http.StatusUnauthorized, httpResp.StatusCode, "Status code in response to client with no SPNEGO not as expected")
- err = cl.SetSPNEGOHeader(r, "HTTP/host.test.gokrb5")
- if err != nil {
- t.Fatalf("Error setting client SPNEGO header: %v", err)
- }
- httpResp, err = http.DefaultClient.Do(r)
- if err != nil {
- t.Fatalf("Request error: %v\n", err)
- }
- assert.Equal(t, http.StatusOK, httpResp.StatusCode, "Status code in response to client SPNEGO request not as expected")
- }
- func TestNewClientFromCCache(t *testing.T) {
- b, err := hex.DecodeString(testdata.CCACHE_TEST)
- if err != nil {
- t.Fatalf("Error decoding test data")
- }
- cc, err := credentials.ParseCCache(b)
- if err != nil {
- t.Fatal("Error getting test CCache")
- }
- cl, err := NewClientFromCCache(cc)
- if err != nil {
- t.Fatalf("Error creating client from CCache: %v", err)
- }
- c, _ := config.NewConfigFromString(testdata.TEST_KRB5CONF)
- addr := os.Getenv("TEST_KDC_ADDR")
- if addr == "" {
- addr = testdata.TEST_KDC_ADDR
- }
- c.Realms[0].KDC = []string{addr + ":" + testdata.TEST_KDC}
- cl.WithConfig(c)
- if ok, err := cl.IsConfigured(); !ok {
- t.Fatalf("Client was not configured from CCache: %v", err)
- }
- }
- func TestResolveKDC(t *testing.T) {
- //ns := os.Getenv("DNSUTILS_OVERRIDE_NS")
- //if ns == "" {
- // os.Setenv("DNSUTILS_OVERRIDE_NS", testdata.TEST_NS)
- //}
- c, _ := config.NewConfigFromString(testdata.TEST_KRB5CONF)
- c.LibDefaults.DNSLookupKDC = true
- var cl Client
- cl.WithConfig(c)
- count, res, err := cl.resolveKDC(c.LibDefaults.DefaultRealm, true)
- if err != nil {
- t.Errorf("error resolving KDC via DNS TCP: %v", err)
- }
- assert.Equal(t, 5, count, "Number of SRV records not as expected: %v", res)
- assert.Equal(t, count, len(res), "Map size does not match: %v", res)
- t.Logf("res: %v", res)
- expected := []string{
- "kdc.test.gokrb5:88",
- "kdc1a.test.gokrb5:88",
- "kdc2a.test.gokrb5:88",
- "kdc1b.test.gokrb5:88",
- "kdc2b.test.gokrb5:88",
- }
- for _, s := range expected {
- var found bool
- for _, v := range res {
- if s == v {
- found = true
- break
- }
- }
- assert.True(t, found, "Record %s not found in results", s)
- }
- c.LibDefaults.DNSLookupKDC = false
- _, res, err = cl.resolveKDC(c.LibDefaults.DefaultRealm, true)
- if err != nil {
- t.Errorf("error resolving KDCs from config: %v", err)
- }
- assert.Equal(t, "127.0.0.1:88", res[1], "KDC not read from config as expected")
- }
- func TestClient_Login_DNSKDCs(t *testing.T) {
- //ns := os.Getenv("DNSUTILS_OVERRIDE_NS")
- //if ns == "" {
- // os.Setenv("DNSUTILS_OVERRIDE_NS", testdata.TEST_NS)
- //}
- c, _ := config.NewConfigFromString(testdata.TEST_KRB5CONF)
- // Set to lookup KDCs in DNS
- c.LibDefaults.DNSLookupKDC = true
- //Blank out the KDCs to ensure they are not being used
- c.Realms = []config.Realm{}
- b, err := hex.DecodeString(testdata.TESTUSER1_KEYTAB)
- kt, _ := keytab.Parse(b)
- cl := NewClientWithKeytab("testuser1", "TEST.GOKRB5", kt)
- cl.WithConfig(c)
- err = cl.Login()
- if err != nil {
- t.Errorf("Error on logging in using DNS lookup of KDCs: %v\n", err)
- }
- }
|