Просмотр исходного кода

respect keytab principal given

Becca Petrin 6 лет назад
Родитель
Сommit
0b0d9d762b
3 измененных файлов с 53 добавлено и 3 удалено
  1. 6 2
      v8/messages/APReq.go
  2. 1 1
      v8/service/APExchange.go
  3. 46 0
      v8/service/APExchange_test.go

+ 6 - 2
v8/messages/APReq.go

@@ -153,7 +153,7 @@ func (a *APReq) Marshal() ([]byte, error) {
 
 
 // Verify an AP_REQ using service's keytab, spn and max acceptable clock skew duration.
 // Verify an AP_REQ using service's keytab, spn and max acceptable clock skew duration.
 // The service ticket encrypted part and authenticator will be decrypted as part of this operation.
 // The service ticket encrypted part and authenticator will be decrypted as part of this operation.
-func (a *APReq) Verify(kt *keytab.Keytab, d time.Duration, cAddr types.HostAddress) (bool, error) {
+func (a *APReq) Verify(kt *keytab.Keytab, d time.Duration, cAddr types.HostAddress, snameOverride *types.PrincipalName) (bool, error) {
 	// Decrypt ticket's encrypted part with service key
 	// Decrypt ticket's encrypted part with service key
 	//TODO decrypt with service's session key from its TGT is use-to-user. Need to figure out how to get TGT.
 	//TODO decrypt with service's session key from its TGT is use-to-user. Need to figure out how to get TGT.
 	//if types.IsFlagSet(&a.APOptions, flags.APOptionUseSessionKey) {
 	//if types.IsFlagSet(&a.APOptions, flags.APOptionUseSessionKey) {
@@ -178,7 +178,11 @@ func (a *APReq) Verify(kt *keytab.Keytab, d time.Duration, cAddr types.HostAddre
 	//		return false, krberror.Errorf(err, krberror.DecryptingError, "error decrypting encpart of service ticket provided")
 	//		return false, krberror.Errorf(err, krberror.DecryptingError, "error decrypting encpart of service ticket provided")
 	//	}
 	//	}
 	//}
 	//}
-	err := a.Ticket.DecryptEncPart(kt, &a.Ticket.SName)
+	sname := &a.Ticket.SName
+	if snameOverride != nil {
+		sname = snameOverride
+	}
+	err := a.Ticket.DecryptEncPart(kt, sname)
 	if err != nil {
 	if err != nil {
 		return false, krberror.Errorf(err, krberror.DecryptingError, "error decrypting encpart of service ticket provided")
 		return false, krberror.Errorf(err, krberror.DecryptingError, "error decrypting encpart of service ticket provided")
 	}
 	}

+ 1 - 1
v8/service/APExchange.go

@@ -11,7 +11,7 @@ import (
 // VerifyAPREQ verifies an AP_REQ sent to the service. Returns a boolean for if the AP_REQ is valid and the client's principal name and realm.
 // VerifyAPREQ verifies an AP_REQ sent to the service. Returns a boolean for if the AP_REQ is valid and the client's principal name and realm.
 func VerifyAPREQ(APReq *messages.APReq, s *Settings) (bool, *credentials.Credentials, error) {
 func VerifyAPREQ(APReq *messages.APReq, s *Settings) (bool, *credentials.Credentials, error) {
 	var creds *credentials.Credentials
 	var creds *credentials.Credentials
-	ok, err := APReq.Verify(s.Keytab, s.MaxClockSkew(), s.ClientAddress())
+	ok, err := APReq.Verify(s.Keytab, s.MaxClockSkew(), s.ClientAddress(), s.KeytabPrincipal())
 	if err != nil || !ok {
 	if err != nil || !ok {
 		return false, creds, err
 		return false, creds, err
 	}
 	}

+ 46 - 0
v8/service/APExchange_test.go

@@ -2,6 +2,7 @@ package service
 
 
 import (
 import (
 	"encoding/hex"
 	"encoding/hex"
+	"strings"
 	"testing"
 	"testing"
 	"time"
 	"time"
 
 
@@ -60,6 +61,51 @@ func TestVerifyAPREQ(t *testing.T) {
 	}
 	}
 }
 }
 
 
+func TestVerifyAPREQWithPrincipalOverride(t *testing.T) {
+	t.Parallel()
+	cl := getClient()
+	sname := types.PrincipalName{
+		NameType:   nametype.KRB_NT_PRINCIPAL,
+		NameString: []string{"HTTP", "host.test.gokrb5"},
+	}
+	b, _ := hex.DecodeString(testdata.HTTP_KEYTAB)
+	kt := keytab.New()
+	kt.Unmarshal(b)
+	st := time.Now().UTC()
+	tkt, sessionKey, err := messages.NewTicket(cl.Credentials.CName(), cl.Credentials.Domain(),
+		sname, "TEST.GOKRB5",
+		types.NewKrbFlags(),
+		kt,
+		18,
+		1,
+		st,
+		st,
+		st.Add(time.Duration(24)*time.Hour),
+		st.Add(time.Duration(48)*time.Hour),
+	)
+	if err != nil {
+		t.Fatalf("Error getting test ticket: %v", err)
+	}
+	apReq, err := messages.NewAPReq(
+		tkt,
+		sessionKey,
+		newTestAuthenticator(*cl.Credentials),
+	)
+	if err != nil {
+		t.Fatalf("Error getting test AP_REQ: %v", err)
+	}
+
+	h, _ := types.GetHostAddress("127.0.0.1:1234")
+	s := NewSettings(kt, ClientAddress(h), KeytabPrincipal("foo"))
+	ok, _, err := VerifyAPREQ(&apReq, s)
+	if ok || err == nil {
+		t.Fatalf("Validation of AP_REQ should have failed")
+	}
+	if !strings.Contains(err.Error(), "Looking for [foo] realm") {
+		t.Fatalf("Looking for wrong entity: %s", err.Error())
+	}
+}
+
 func TestVerifyAPREQ_KRB_AP_ERR_BADMATCH(t *testing.T) {
 func TestVerifyAPREQ_KRB_AP_ERR_BADMATCH(t *testing.T) {
 	t.Parallel()
 	t.Parallel()
 	cl := getClient()
 	cl := getClient()