Jonathan Turner 7 лет назад
Родитель
Сommit
9b13d2cfcf
1 измененных файлов с 32 добавлено и 22 удалено
  1. 32 22
      spnego/negotiationToken.go

+ 32 - 22
spnego/negotiationToken.go

@@ -140,34 +140,41 @@ func (n *NegTokenInit) Unmarshal(b []byte) error {
 // Verify an Init negotiation token
 // Verify an Init negotiation token
 func (n *NegTokenInit) Verify() (bool, gssapi.Status) {
 func (n *NegTokenInit) Verify() (bool, gssapi.Status) {
 	// Check if supported mechanisms are in the MechTypeList
 	// Check if supported mechanisms are in the MechTypeList
+	var mtSupported bool
 	for _, m := range n.MechTypes {
 	for _, m := range n.MechTypes {
 		if m.Equal(gssapi.OID(gssapi.OIDKRB5)) || m.Equal(gssapi.OID(gssapi.OIDMSLegacyKRB5)) {
 		if m.Equal(gssapi.OID(gssapi.OIDKRB5)) || m.Equal(gssapi.OID(gssapi.OIDMSLegacyKRB5)) {
 			if n.mechToken == nil && n.MechTokenBytes == nil {
 			if n.mechToken == nil && n.MechTokenBytes == nil {
 				return false, gssapi.Status{Code: gssapi.StatusContinueNeeded}
 				return false, gssapi.Status{Code: gssapi.StatusContinueNeeded}
 			}
 			}
-			mt := new(KRB5Token)
-			mt.settings = n.settings
-			if n.mechToken == nil {
-				err := mt.Unmarshal(n.MechTokenBytes)
-				if err != nil {
-					return false, gssapi.Status{Code: gssapi.StatusDefectiveToken, Message: err.Error()}
-				}
-				n.mechToken = mt
-			} else {
-				var ok bool
-				mt, ok = n.mechToken.(*KRB5Token)
-				if !ok {
-					return false, gssapi.Status{Code: gssapi.StatusDefectiveToken, Message: "MechToken is not a KRB5 token as expected"}
-				}
-			}
-			if !mt.OID.Equal(n.MechTypes[0]) {
-				return false, gssapi.Status{Code: gssapi.StatusDefectiveToken, Message: "OID of MechToken does not match the first in the MechTypeList"}
-			}
-			// Verify the mechtoken
-			return n.mechToken.Verify()
+			mtSupported = true
+			break
 		}
 		}
 	}
 	}
-	return false, gssapi.Status{Code: gssapi.StatusBadMech, Message: "no supported mechanism specified in negotiation"}
+	if !mtSupported {
+		return false, gssapi.Status{Code: gssapi.StatusBadMech, Message: "no supported mechanism specified in negotiation"}
+	}
+	// There should be some mechtoken bytes for a KRB5Token (other mech types are not supported)
+	mt := new(KRB5Token)
+	mt.settings = n.settings
+	if n.mechToken == nil {
+		err := mt.Unmarshal(n.MechTokenBytes)
+		if err != nil {
+			return false, gssapi.Status{Code: gssapi.StatusDefectiveToken, Message: err.Error()}
+		}
+		n.mechToken = mt
+	} else {
+		var ok bool
+		mt, ok = n.mechToken.(*KRB5Token)
+		if !ok {
+			return false, gssapi.Status{Code: gssapi.StatusDefectiveToken, Message: "MechToken is not a KRB5 token as expected"}
+		}
+	}
+	// RFC4178 states that the initial negotiation message can optionally contain the initial mechanism token for the preferred mechanism of the client.
+	if !mt.OID.Equal(n.MechTypes[0]) {
+		return false, gssapi.Status{Code: gssapi.StatusDefectiveToken, Message: "OID of MechToken does not match the first in the MechTypeList"}
+	}
+	// Verify the mechtoken
+	return n.mechToken.Verify()
 }
 }
 
 
 // Context returns the SPNEGO context which will contain any verify user identity information.
 // Context returns the SPNEGO context which will contain any verify user identity information.
@@ -230,7 +237,7 @@ func (n *NegTokenResp) Verify() (bool, gssapi.Status) {
 		if n.mechToken == nil && n.ResponseToken == nil {
 		if n.mechToken == nil && n.ResponseToken == nil {
 			return false, gssapi.Status{Code: gssapi.StatusContinueNeeded}
 			return false, gssapi.Status{Code: gssapi.StatusContinueNeeded}
 		}
 		}
-		var mt *KRB5Token
+		mt := new(KRB5Token)
 		mt.settings = n.settings
 		mt.settings = n.settings
 		if n.mechToken == nil {
 		if n.mechToken == nil {
 			err := mt.Unmarshal(n.ResponseToken)
 			err := mt.Unmarshal(n.ResponseToken)
@@ -245,6 +252,9 @@ func (n *NegTokenResp) Verify() (bool, gssapi.Status) {
 				return false, gssapi.Status{Code: gssapi.StatusDefectiveToken, Message: "MechToken is not a KRB5 token as expected"}
 				return false, gssapi.Status{Code: gssapi.StatusDefectiveToken, Message: "MechToken is not a KRB5 token as expected"}
 			}
 			}
 		}
 		}
+		if mt == nil {
+			return false, gssapi.Status{Code: gssapi.StatusContinueNeeded}
+		}
 		// Verify the mechtoken
 		// Verify the mechtoken
 		return mt.Verify()
 		return mt.Verify()
 	}
 	}