Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for complex cross-realm scenarios #536

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 8 additions & 7 deletions .github/workflows/testing.yml
Original file line number Diff line number Diff line change
Expand Up @@ -61,13 +61,14 @@ jobs:
run: |
sudo DEBIAN_FRONTEND=noninteractive apt-get install -yq krb5-user
sudo chmod 666 /etc/krb5.conf
sudo docker run -d -h ns.test.gokrb5 -v /etc/localtime:/etc/localtime:ro -e "TEST_KDC_ADDR=${TEST_KDC_ADDR}" -e "TEST_HTTP_ADDR=${TEST_HTTP_ADDR}" -p ${DNSUTILS_OVERRIDE_NS}:53 -p ${DNSUTILS_OVERRIDE_NS}:53/udp --name dns jcmturner/gokrb5:dns
sudo docker run -d -h kdc.test.gokrb5 -v /etc/localtime:/etc/localtime:ro -p 88:88 -p 88:88/udp -p 464:464 -p 464:464/udp --name krb5kdc jcmturner/gokrb5:kdc-centos-default
sudo docker run -d -h kdc.test.gokrb5 -v /etc/localtime:/etc/localtime:ro -p 78:88 -p 78:88/udp --name krb5kdc-old jcmturner/gokrb5:kdc-older
sudo docker run -d -h kdc.test.gokrb5 -v /etc/localtime:/etc/localtime:ro -p 98:88 -p 98:88/udp --name krb5kdc-latest jcmturner/gokrb5:kdc-latest
sudo docker run -d -h kdc.resdom.gokrb5 -v /etc/localtime:/etc/localtime:ro -p 188:88 -p 188:88/udp --name krb5kdc-resdom jcmturner/gokrb5:kdc-resdom
sudo docker run -d -h kdc.test.gokrb5 -v /etc/localtime:/etc/localtime:ro -p 58:88 -p 58:88/udp --name krb5kdc-shorttickets jcmturner/gokrb5:kdc-shorttickets
sudo docker run -d --add-host host.test.gokrb5:127.0.0.88 -v /etc/localtime:/etc/localtime:ro -p 80:80 -p 443:443 --name gokrb5-http jcmturner/gokrb5:http
sudo docker run -d -h ns.test.gokrb5 -v /etc/localtime:/etc/localtime:ro -e "TEST_KDC_ADDR=${TEST_KDC_ADDR}" -e "TEST_HTTP_ADDR=${TEST_HTTP_ADDR}" -p ${DNSUTILS_OVERRIDE_NS}:53 -p ${DNSUTILS_OVERRIDE_NS}:53/udp --name dns ghcr.io/grafana/gokrb5-test:dns
sudo docker run -d -h kdc.test.gokrb5 -v /etc/localtime:/etc/localtime:ro -p 88:88 -p 88:88/udp -p 464:464 -p 464:464/udp --name krb5kdc ghcr.io/grafana/gokrb5-test:kdc-centos-default
sudo docker run -d -h kdc.test.gokrb5 -v /etc/localtime:/etc/localtime:ro -p 78:88 -p 78:88/udp --name krb5kdc-old ghcr.io/grafana/gokrb5-test:kdc-older
sudo docker run -d -h kdc.test.gokrb5 -v /etc/localtime:/etc/localtime:ro -p 98:88 -p 98:88/udp --name krb5kdc-latest ghcr.io/grafana/gokrb5-test:kdc-latest
sudo docker run -d -h kdc.resdom.gokrb5 -v /etc/localtime:/etc/localtime:ro -p 188:88 -p 188:88/udp --name krb5kdc-resdom ghcr.io/grafana/gokrb5-test:kdc-resdom
sudo docker run -d -h kdc.test.gokrb5 -v /etc/localtime:/etc/localtime:ro -p 58:88 -p 58:88/udp --name krb5kdc-shorttickets ghcr.io/grafana/gokrb5-test:kdc-shorttickets
sudo docker run -d --add-host host.test.gokrb5:127.0.0.88 -v /etc/localtime:/etc/localtime:ro -p 80:80 -p 443:443 --name gokrb5-http ghcr.io/grafana/gokrb5-test:http
sleep 10 # Wait for the containers to be ready
sudo sed -i 's/nameserver .*/nameserver '${DNS_IP}'/g' /etc/resolv.conf
dig _kerberos._udp.TEST.GOKRB5
id: intgTestDeps
Expand Down
16 changes: 9 additions & 7 deletions .github/workflows/testingv8.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,13 +48,15 @@ jobs:
run: |
sudo DEBIAN_FRONTEND=noninteractive apt-get install -yq krb5-user
sudo chmod 666 /etc/krb5.conf
sudo docker run -d -h ns.test.gokrb5 -v /etc/localtime:/etc/localtime:ro -e "TEST_KDC_ADDR=${TEST_KDC_ADDR}" -e "TEST_HTTP_ADDR=${TEST_HTTP_ADDR}" -p ${DNSUTILS_OVERRIDE_NS}:53 -p ${DNSUTILS_OVERRIDE_NS}:53/udp --name dns jcmturner/gokrb5:dns
sudo docker run -d -h kdc.test.gokrb5 -v /etc/localtime:/etc/localtime:ro -p 88:88 -p 88:88/udp -p 464:464 -p 464:464/udp --name krb5kdc jcmturner/gokrb5:kdc-centos-default
sudo docker run -d -h kdc.test.gokrb5 -v /etc/localtime:/etc/localtime:ro -p 78:88 -p 78:88/udp --name krb5kdc-old jcmturner/gokrb5:kdc-older
sudo docker run -d -h kdc.test.gokrb5 -v /etc/localtime:/etc/localtime:ro -p 98:88 -p 98:88/udp --name krb5kdc-latest jcmturner/gokrb5:kdc-latest
sudo docker run -d -h kdc.resdom.gokrb5 -v /etc/localtime:/etc/localtime:ro -p 188:88 -p 188:88/udp --name krb5kdc-resdom jcmturner/gokrb5:kdc-resdom
sudo docker run -d -h kdc.test.gokrb5 -v /etc/localtime:/etc/localtime:ro -p 58:88 -p 58:88/udp --name krb5kdc-shorttickets jcmturner/gokrb5:kdc-shorttickets
sudo docker run -d --add-host host.test.gokrb5:127.0.0.88 -v /etc/localtime:/etc/localtime:ro -p 80:80 -p 443:443 --name gokrb5-http jcmturner/gokrb5:http
sudo docker run -d -h ns.test.gokrb5 -v /etc/localtime:/etc/localtime:ro -e "TEST_KDC_ADDR=${TEST_KDC_ADDR}" -e "TEST_HTTP_ADDR=${TEST_HTTP_ADDR}" -p ${DNSUTILS_OVERRIDE_NS}:53 -p ${DNSUTILS_OVERRIDE_NS}:53/udp --name dns ghcr.io/grafana/gokrb5-test:dns
sudo docker run -d -h kdc.test.gokrb5 -v /etc/localtime:/etc/localtime:ro -p 88:88 -p 88:88/udp -p 464:464 -p 464:464/udp --name krb5kdc ghcr.io/grafana/gokrb5-test:kdc-centos-default
sudo docker run -d -h kdc.test.gokrb5 -v /etc/localtime:/etc/localtime:ro -p 78:88 -p 78:88/udp --name krb5kdc-old ghcr.io/grafana/gokrb5-test:kdc-older
sudo docker run -d -h kdc.test.gokrb5 -v /etc/localtime:/etc/localtime:ro -p 98:88 -p 98:88/udp --name krb5kdc-latest ghcr.io/grafana/gokrb5-test:kdc-latest
sudo docker run -d -h kdc.resdom.gokrb5 -v /etc/localtime:/etc/localtime:ro -p 188:88 -p 188:88/udp --name krb5kdc-resdom ghcr.io/grafana/gokrb5-test:kdc-resdom
sudo docker run -d -h kdc.test.gokrb5 -v /etc/localtime:/etc/localtime:ro -p 58:88 -p 58:88/udp --name krb5kdc-shorttickets ghcr.io/grafana/gokrb5-test:kdc-shorttickets
sudo docker run -d -h kdc.sub.test.gokrb5 -v /etc/localtime:/etc/localtime:ro -p 288:88 -p 288:88/udp --name krb5kdc-sub ghcr.io/grafana/gokrb5-test:kdc-sub
sudo docker run -d --add-host host.test.gokrb5:127.0.0.88 -v /etc/localtime:/etc/localtime:ro -p 80:80 -p 443:443 --name gokrb5-http ghcr.io/grafana/gokrb5-test:http
sleep 10 # Wait for the containers to be ready
sudo sed -i 's/nameserver .*/nameserver '${DNS_IP}'/g' /etc/resolv.conf
dig _kerberos._udp.TEST.GOKRB5
id: intgTestDeps
Expand Down
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,4 +98,4 @@ It is recommended to run tests with the ```-race``` argument.
There are integration tests that run against various other network services such as KDCs, HTTP web servers, DNS servers,
etc. To run these pass ```-tags=integration``` as an argument to the go test command.
There are vagrant and docker resources available to spin up these network services. See the
[readme](https://github.com/jcmturner/gokrb5/blob/master/testenv/README.md) in the testenv directory for instructions.
[readme](https://github.com/grafana/gokrb5-test/blob/master/testenv/README.md) in the testenv directory for instructions.
2 changes: 1 addition & 1 deletion test/README.md
Original file line number Diff line number Diff line change
@@ -1 +1 @@
Source for integration test dependencies can be found at https://github.com/jcmturner/gokrb5-test
Source for integration test dependencies can be found at https://github.com/grafana/gokrb5-test
4 changes: 2 additions & 2 deletions v8/client/TGSExchange.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import (

// TGSREQGenerateAndExchange generates the TGS_REQ and performs a TGS exchange to retrieve a ticket to the specified SPN.
func (cl *Client) TGSREQGenerateAndExchange(spn types.PrincipalName, kdcRealm string, tgt messages.Ticket, sessionKey types.EncryptionKey, renewal bool) (tgsReq messages.TGSReq, tgsRep messages.TGSRep, err error) {
tgsReq, err = messages.NewTGSReq(cl.Credentials.CName(), kdcRealm, cl.Config, tgt, sessionKey, spn, renewal)
tgsReq, err = messages.NewTGSReq(cl.Credentials.CName(), cl.Credentials.Domain(), kdcRealm, cl.Config, tgt, sessionKey, spn, renewal)
if err != nil {
return tgsReq, tgsRep, krberror.Errorf(err, krberror.KRBMsgError, "TGS Exchange Error: failed to generate a new TGS_REQ")
}
Expand Down Expand Up @@ -60,7 +60,7 @@ func (cl *Client) TGSExchange(tgsReq messages.TGSReq, kdcRealm string, tgt messa
return tgsReq, tgsRep, err
}
}
tgsReq, err = messages.NewTGSReq(cl.Credentials.CName(), realm, cl.Config, tgsRep.Ticket, tgsRep.DecryptedEncPart.Key, tgsReq.ReqBody.SName, tgsReq.Renewal)
tgsReq, err = messages.NewTGSReq(cl.Credentials.CName(), cl.Credentials.Domain(), realm, cl.Config, tgsRep.Ticket, tgsRep.DecryptedEncPart.Key, tgsReq.ReqBody.SName, tgsReq.Renewal)
if err != nil {
return tgsReq, tgsRep, err
}
Expand Down
48 changes: 48 additions & 0 deletions v8/client/client_integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -551,6 +551,54 @@ func TestClient_GetServiceTicket_Trusted_Resource_Domain(t *testing.T) {
}
}

// Login to the SUB.TEST.GOKRB5 domain and request service ticket for resource in the RESDOM.GOKRB5 domain.
// There is only trust between parent domain (TEST.GOKRB5) and the service domain (RESDOM.GOKRB5).
func TestClient_GetServiceTicket_Trusted_Resource_SubDomain(t *testing.T) {
test.Integration(t)

c, err := config.NewFromString(testdata.KRB5_CONF)
if err != nil {
t.Fatalf("error reading krb5 config: %v\n", err)
}

addr := os.Getenv("TEST_KDC_ADDR")
if addr == "" {
addr = testdata.KDC_IP_TEST_GOKRB5
}

for i, r := range c.Realms {
switch r.Realm {
case "TEST.GOKRB5":
c.Realms[i].KDC = []string{addr + ":" + testdata.KDC_PORT_TEST_GOKRB5}
case "SUB.TEST.GOKRB5":
c.Realms[i].KDC = []string{addr + ":" + testdata.KDC_PORT_TEST_GOKRB5_SUB}
case "RESDOM.GOKRB5":
c.Realms[i].KDC = []string{addr + ":" + testdata.KDC_PORT_TEST_GOKRB5_RESDOM}
}
}

c.LibDefaults.DefaultRealm = "SUB.TEST.GOKRB5"
c.LibDefaults.DefaultTktEnctypes = []string{"aes256-cts-hmac-sha1-96"}
c.LibDefaults.DefaultTktEnctypeIDs = []int32{etypeID.ETypesByName["aes256-cts-hmac-sha1-96"]}
c.LibDefaults.DefaultTGSEnctypes = []string{"aes256-cts-hmac-sha1-96"}
c.LibDefaults.DefaultTGSEnctypeIDs = []int32{etypeID.ETypesByName["aes256-cts-hmac-sha1-96"]}

cl := client.NewWithPassword("testuser1", "SUB.TEST.GOKRB5", "passwordvalue", c)
err = cl.Login()
if err != nil {
t.Fatalf("error on login: %v\n", err)
}

spn := "HTTP/host.resdom.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.PrincipalNameString())
assert.Equal(t, etypeID.ETypesByName["aes256-cts-hmac-sha1-96"], key.KeyType)
}

const (
kinitCmd = "kinit"
kvnoCmd = "kvno"
Expand Down
10 changes: 5 additions & 5 deletions v8/messages/KDCReq.go
Original file line number Diff line number Diff line change
Expand Up @@ -154,12 +154,12 @@ func NewASReq(realm string, c *config.Config, cname, sname types.PrincipalName)
}

// NewTGSReq generates a new KRB_TGS_REQ struct.
func NewTGSReq(cname types.PrincipalName, kdcRealm string, c *config.Config, tgt Ticket, sessionKey types.EncryptionKey, sname types.PrincipalName, renewal bool) (TGSReq, error) {
func NewTGSReq(cname types.PrincipalName, paRealm, kdcRealm string, c *config.Config, tgt Ticket, sessionKey types.EncryptionKey, sname types.PrincipalName, renewal bool) (TGSReq, error) {
a, err := tgsReq(cname, sname, kdcRealm, renewal, c)
if err != nil {
return a, err
}
err = a.setPAData(tgt, sessionKey)
err = a.setPAData(paRealm, tgt, sessionKey)
return a, err
}

Expand All @@ -171,7 +171,7 @@ func NewUser2UserTGSReq(cname types.PrincipalName, kdcRealm string, c *config.Co
}
a.ReqBody.AdditionalTickets = []Ticket{verifyingTGT}
types.SetFlag(&a.ReqBody.KDCOptions, flags.EncTktInSkey)
err = a.setPAData(clientTGT, sessionKey)
err = a.setPAData(clientTGT.Realm, clientTGT, sessionKey)
return a, err
}

Expand Down Expand Up @@ -226,7 +226,7 @@ func tgsReq(cname, sname types.PrincipalName, kdcRealm string, renewal bool, c *
}, nil
}

func (k *TGSReq) setPAData(tgt Ticket, sessionKey types.EncryptionKey) error {
func (k *TGSReq) setPAData(paRealm string, tgt Ticket, sessionKey types.EncryptionKey) error {
// Marshal the request and calculate checksum
b, err := k.ReqBody.Marshal()
if err != nil {
Expand All @@ -243,7 +243,7 @@ func (k *TGSReq) setPAData(tgt Ticket, sessionKey types.EncryptionKey) error {

// Form PAData for TGS_REQ
// Create authenticator
auth, err := types.NewAuthenticator(tgt.Realm, k.ReqBody.CName)
auth, err := types.NewAuthenticator(paRealm, k.ReqBody.CName)
if err != nil {
return krberror.Errorf(err, krberror.KRBMsgError, "error generating new authenticator")
}
Expand Down
2 changes: 1 addition & 1 deletion v8/test/README.md
Original file line number Diff line number Diff line change
@@ -1 +1 @@
Source for integration test dependencies can be found at https://github.com/jcmturner/gokrb5-test
Source for integration test dependencies can be found at https://github.com/grafana/gokrb5-test
8 changes: 8 additions & 0 deletions v8/test/testdata/test_vectors.go
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ const (
KDC_PORT_TEST_GOKRB5 = "88"
KDC_PORT_TEST_GOKRB5_LASTEST = "98"
KDC_PORT_TEST_GOKRB5_RESDOM = "188"
KDC_PORT_TEST_GOKRB5_SUB = "288"
KDC_PORT_TEST_GOKRB5_OLD = "78"
KDC_PORT_TEST_GOKRB5_SHORTTICKETS = "58"

Expand All @@ -153,6 +154,11 @@ const (
admin_server = 127.0.0.1:749
default_domain = test.gokrb5
}
SUB.TEST.GOKRB5 = {
kdc = 127.0.0.1:288
admin_server = 127.0.0.1:749
default_domain = sub.test.gokrb5
}
RESDOM.GOKRB5 = {
kdc = 10.80.88.88:188
admin_server = 127.0.0.1:749
Expand All @@ -162,6 +168,8 @@ const (
[domain_realm]
.test.gokrb5 = TEST.GOKRB5
test.gokrb5 = TEST.GOKRB5
.sub.test.gokrb5 = SUB.TEST.GOKRB5
sub.test.gokrb5 = SUB.TEST.GOKRB5
.resdom.gokrb5 = RESDOM.GOKRB5
resdom.gokrb5 = RESDOM.GOKRB5
`
Expand Down