/// <summary> /// Create a Kpassword Request /// </summary> /// <param name="newPwd">The new password to change</param> /// <returns></returns> public KpasswordRequest CreateKpasswordRequest(string newPwd) { //Generate the subkey, which will be used to encrypt/decrypt KRB-PRIV message EncryptionKey subkey = KerberosUtility.MakeKey((EncryptionType)this.Context.Ticket.SessionKey.keytype.Value, "Password01!", "This is a salt"); Context.Subkey = subkey; Authenticator authenticator = CreateAuthenticator(this.Context.Ticket, null, subkey); KpasswordRequest request = new KpasswordRequest(this.Context.Ticket, authenticator, newPwd); return request; }
//Get the expected Kerberos PDU from byte array private KerberosPdu getExpectedPduFromBytes( byte[] receivedBytes, out int consumedLength, out int expectedLength) { // initialize lengths consumedLength = 0; expectedLength = 0; if (null == receivedBytes || 0 == receivedBytes.Length) { return(null); } // TCP has a 4 bytes length header, while UDP has not byte[] pduBytes = receivedBytes; if ((this.Context.TransportType == TransportType.TCP)) { // insufficient data, needs to receive more if (receivedBytes.Length < sizeof(int)) { return(null); } // get pdu data length byte[] lengthBytes = ArrayUtility.SubArray(receivedBytes, 0, sizeof(int)); Array.Reverse(lengthBytes); int pduLength = BitConverter.ToInt32(lengthBytes, 0); // insufficient data, needs to receive more expectedLength = sizeof(int) + pduLength; if (receivedBytes.Length < expectedLength) { return(null); } // remove length header from pdu bytes pduBytes = ArrayUtility.SubArray <byte>(receivedBytes, sizeof(int), pduLength); } else { // UDP has no length header expectedLength = pduBytes.Length; } consumedLength = expectedLength; KerberosPdu pdu = null; //Get AP data in message to judge the kpassword type byte[] apLengthBytes = ArrayUtility.SubArray <byte>(pduBytes, 2 * sizeof(ushort), sizeof(ushort)); Array.Reverse(apLengthBytes); ushort apLength = BitConverter.ToUInt16(apLengthBytes, 0); //If the length is zero, then the last field contains a KRB-ERROR message instead of a KRB-PRIV message. if (apLength == 0) { pdu = new KerberosKrbError(); pdu.FromBytes(ArrayUtility.SubArray <byte>(pduBytes, 3 * sizeof(ushort))); return(pdu); } // get message type // (the lower 5 bits indicates its message type) byte[] apBytes = ArrayUtility.SubArray <byte>(pduBytes, 3 * sizeof(ushort), apLength); MsgType kpassMsgType = (MsgType)(apBytes[0] & 0x1f); if (kpassMsgType == MsgType.KRB_AP_REQ) { pdu = new KpasswordRequest(); } else { pdu = new KpasswordResponse(); pdu.FromBytes(pduBytes); } return(pdu); }
//Get the expected Kerberos PDU from byte array private KerberosPdu getExpectedPduFromBytes( byte[] receivedBytes, out int consumedLength, out int expectedLength) { // initialize lengths consumedLength = 0; expectedLength = 0; if (null == receivedBytes || 0 == receivedBytes.Length) { return null; } // TCP has a 4 bytes length header, while UDP has not byte[] pduBytes = receivedBytes; if ((this.Context.TransportType == TransportType.TCP)) { // insufficient data, needs to receive more if (receivedBytes.Length < sizeof(int)) { return null; } // get pdu data length byte[] lengthBytes = ArrayUtility.SubArray(receivedBytes, 0, sizeof(int)); Array.Reverse(lengthBytes); int pduLength = BitConverter.ToInt32(lengthBytes, 0); // insufficient data, needs to receive more expectedLength = sizeof(int) + pduLength; if (receivedBytes.Length < expectedLength) { return null; } // remove length header from pdu bytes pduBytes = ArrayUtility.SubArray<byte>(receivedBytes, sizeof(int), pduLength); } else { // UDP has no length header expectedLength = pduBytes.Length; } consumedLength = expectedLength; KerberosPdu pdu = null; //Get AP data in message to judge the kpassword type byte[] apLengthBytes = ArrayUtility.SubArray<byte>(pduBytes, 2 * sizeof(ushort), sizeof(ushort)); Array.Reverse(apLengthBytes); ushort apLength = BitConverter.ToUInt16(apLengthBytes, 0); //If the length is zero, then the last field contains a KRB-ERROR message instead of a KRB-PRIV message. if (apLength == 0) { pdu = new KerberosKrbError(); pdu.FromBytes(ArrayUtility.SubArray<byte>(pduBytes, 3 * sizeof(ushort))); return pdu; } // get message type // (the lower 5 bits indicates its message type) byte[] apBytes = ArrayUtility.SubArray<byte>(pduBytes, 3 * sizeof(ushort), apLength); MsgType kpassMsgType = (MsgType)(apBytes[0] & 0x1f); if (kpassMsgType == MsgType.KRB_AP_REQ) { pdu = new KpasswordRequest(); } else { pdu = new KpasswordResponse(); pdu.FromBytes(pduBytes); } return pdu; }