Kaynağa Gözat

prevent duplicate pa-data type when adding PA_ENC_TIMESTAMP

Jonathan Turner 7 yıl önce
ebeveyn
işleme
f1d155c1dc
1 değiştirilmiş dosya ile 25 ekleme ve 9 silme
  1. 25 9
      client/ASExchange.go

+ 25 - 9
client/ASExchange.go

@@ -76,32 +76,41 @@ func setPAData(cl *Client, krberr messages.KRBError, ASReq *messages.ASReq) erro
 		ASReq.PAData = append(ASReq.PAData, pa)
 		ASReq.PAData = append(ASReq.PAData, pa)
 	}
 	}
 	if cl.settings.AssumePreAuthentication() {
 	if cl.settings.AssumePreAuthentication() {
-		paTSb, err := types.GetPAEncTSEncAsnMarshalled()
-		if err != nil {
-			return krberror.Errorf(err, krberror.KRBMsgError, "error creating PAEncTSEnc for Pre-Authentication")
-		}
+		// Identify the etype to use to encrypt the PA Data
 		var et etype.EType
 		var et etype.EType
+		var err error
+		var key types.EncryptionKey
 		if krberr.ErrorCode == 0 {
 		if krberr.ErrorCode == 0 {
-			etn := cl.settings.preAuthEType
+			// There is no KRB Error that tells us the etype to use
+			etn := cl.settings.preAuthEType // Use the etype that may have previously been negotiated
 			if etn == 0 {
 			if etn == 0 {
-				etn = int32(cl.Config.LibDefaults.PreferredPreauthTypes[0])
+				etn = int32(cl.Config.LibDefaults.PreferredPreauthTypes[0]) // Resort to config
 			}
 			}
 			// This is not in response to an error from the KDC. It is preemptive or renewal
 			// This is not in response to an error from the KDC. It is preemptive or renewal
 			et, err = crypto.GetEtype(etn) // Take the first as preference
 			et, err = crypto.GetEtype(etn) // Take the first as preference
 			if err != nil {
 			if err != nil {
 				return krberror.Errorf(err, krberror.EncryptingError, "error getting etype for pre-auth encryption")
 				return krberror.Errorf(err, krberror.EncryptingError, "error getting etype for pre-auth encryption")
 			}
 			}
+			key, err = cl.Key(et, nil)
+			if err != nil {
+				return krberror.Errorf(err, krberror.EncryptingError, "error getting key from credentials")
+			}
 		} else {
 		} else {
 			// Get the etype to use from the PA data in the KRBError e-data
 			// Get the etype to use from the PA data in the KRBError e-data
 			et, err = preAuthEType(krberr)
 			et, err = preAuthEType(krberr)
 			if err != nil {
 			if err != nil {
 				return krberror.Errorf(err, krberror.EncryptingError, "error getting etype for pre-auth encryption")
 				return krberror.Errorf(err, krberror.EncryptingError, "error getting etype for pre-auth encryption")
 			}
 			}
-			cl.settings.preAuthEType = et.GetETypeID()
+			cl.settings.preAuthEType = et.GetETypeID() // Set the etype that has been defined for potential future use
+			key, err = cl.Key(et, &krberr)
+			if err != nil {
+				return krberror.Errorf(err, krberror.EncryptingError, "error getting key from credentials")
+			}
 		}
 		}
-		key, err := cl.Key(et, &krberr)
+		// Generate the
+		paTSb, err := types.GetPAEncTSEncAsnMarshalled()
 		if err != nil {
 		if err != nil {
-			return krberror.Errorf(err, krberror.EncryptingError, "error getting key from credentials")
+			return krberror.Errorf(err, krberror.KRBMsgError, "error creating PAEncTSEnc for Pre-Authentication")
 		}
 		}
 		paEncTS, err := crypto.GetEncryptedData(paTSb, key, keyusage.AS_REQ_PA_ENC_TIMESTAMP, 1)
 		paEncTS, err := crypto.GetEncryptedData(paTSb, key, keyusage.AS_REQ_PA_ENC_TIMESTAMP, 1)
 		if err != nil {
 		if err != nil {
@@ -115,6 +124,13 @@ func setPAData(cl *Client, krberr messages.KRBError, ASReq *messages.ASReq) erro
 			PADataType:  patype.PA_ENC_TIMESTAMP,
 			PADataType:  patype.PA_ENC_TIMESTAMP,
 			PADataValue: pb,
 			PADataValue: pb,
 		}
 		}
+		// Look for and delete any exiting patype.PA_ENC_TIMESTAMP
+		for i, pa := range ASReq.PAData {
+			if pa.PADataType == patype.PA_ENC_TIMESTAMP {
+				ASReq.PAData[i] = ASReq.PAData[len(ASReq.PAData)-1]
+				ASReq.PAData = ASReq.PAData[:len(ASReq.PAData)-1]
+			}
+		}
 		ASReq.PAData = append(ASReq.PAData, pa)
 		ASReq.PAData = append(ASReq.PAData, pa)
 	}
 	}
 	return nil
 	return nil