/// <summary>
        /// Parse a payload byte buffer into a payload data structure.
        /// </summary>
        /// <param name="inBuffer">Incoming byte buffer to parse</param>
        /// <param name="payload">Reference to the payload data structure in which to put the parsed data</param>
        /// <returns>Daedalus return code</returns>
        public DaedalusGlobal.ReturnCodes parsePayload(byte[] inBuffer, int startIndex, out Dictionary <string, DaedalusGlobal.PayloadElement> payload)
        {
            payload = new Dictionary <string, DaedalusGlobal.PayloadElement>();
            //if (payload == null)
            //{
            //    throw new ArgumentNullException("payload", "Payload object passed to " + this.GetType().ToString() + ".parsePayload() as null, should be a instantiated Dictionary.");
            //}

            DaedalusGlobal.ReturnCodes returnCode = DaedalusGlobal.ReturnCodes.Valid;

            payload.Add("hash", new DaedalusGlobal.PayloadElement()
            {
                elementName   = "hash",
                elementOffset = 0,
                elementSize   = 20,
                //elementData = new UserHash(inBuffer, DecryptedDaedalusPacket.elementCommandPayload.ElementStaticOffset)
                elementData = new UserHash(inBuffer, startIndex)
            });
            payload.Add("actionTaken", new DaedalusGlobal.PayloadElement()
            {
                elementName   = "actionTaken",
                elementOffset = (ushort)(payload["hash"].elementSize + payload["hash"].elementOffset),
                elementSize   = 1,
                //elementData = (ReadHashActions)inBuffer[DecryptedDaedalusPacket.elementCommandPayload.ElementStaticOffset + payload["hash"].elementSize]
                elementData = (ReadHashActions)inBuffer[startIndex + payload["hash"].elementSize]
            });

            return(returnCode);
        }
        public DaedalusGlobal.ReturnCodes payloadToByteBuffer(Dictionary <string, DaedalusGlobal.PayloadElement> payload, out byte[] outputBuffer)
        {
            if (payload == null)
            {
                throw new ArgumentNullException("payload", "Payload object passed to " + this.GetType().ToString() + ".payloadToByteBuffer() as null, should be a instantiated Dictionary.");
            }

            DaedalusGlobal.ReturnCodes returnCode = DaedalusGlobal.ReturnCodes.Valid;

            // Make sure the payload has the fields required by this command in it
            if (payload.ContainsKey("hash") && payload.ContainsKey("actionTaken"))
            {
                int payloadLength = payload.Sum(x => x.Value.elementSize);

                outputBuffer = new byte[payloadLength];
                byte[] hash = ((UserHash)(payload["hash"].elementData)).getByteBuffer();

                Array.Copy(hash, outputBuffer, UserHash.hashSize);

                outputBuffer[payload["actionTaken"].elementOffset] = (byte)payload["actionTaken"].elementData;
            }
            else
            {
                outputBuffer = null;
                return(DaedalusGlobal.ReturnCodes.PayloadFieldMissing);
            }

            return(returnCode);
        }
예제 #3
0
        private void cmdSendCommand_Click(object sender, EventArgs e)
        {
            // Decrypted packet that we're going to send out
            DecryptedDaedalusPacket outPacket = new DecryptedDaedalusPacket();

            // Should probably invert this and only allow the fields to be set via a constructor (readonly)

            outPacket.commandType = getDaedalusCommandTypeFromComboBox(cboProtocolCommand);
            unchecked { outPacket.packetIndex = packetIndex++; }
            outPacket.command        = outPacket.commandType.getCommand();
            outPacket.commandVersion = Byte.Parse((string)Invoke((Func <object>)(() => txtCommandVersion.Text)));
            string payloadString = (string)Invoke((Func <object>)(() => txtPacketPayload.Text));

            byte[] payloadBuffer = GlobalHelpers.GlobalMethods.XXHexStringToByteArray(payloadString.Replace(" ", ""));
            Dictionary <string, DaedalusGlobal.PayloadElement> payload;

            DaedalusGlobal.ReturnCodes rc = outPacket.commandType.parsePayload(payloadBuffer, 0, out payload);
            outPacket.payload = payload;
            if (rc == DaedalusGlobal.ReturnCodes.Valid)
            {
                outPacket.setPacketLengthFieldValue();
                // At this point the decrypted packet should be ready to go

                // Build encrypted packet here
                EncryptedDaedalusPacket encPacket = new EncryptedDaedalusPacket(outPacket, AESKey);

                string     IPString            = (string)Invoke((Func <object>)(() => txtDestinationIP.Text));
                IPEndPoint destinationEndPoint = new IPEndPoint(IPAddress.Parse(IPString), DaedalusGlobal.DaedalusPort);
                //lock (commLocker)
                //{
                lock (selectedNetworkInterfaceLocker)
                {
                    comm.outPackets.Add(new NetPacket
                    {
                        destination   = destinationEndPoint,
                        source        = new IPEndPoint(getDefaultIPv4AddressFromInterface(selectedNetworkInterface), DaedalusGlobal.DaedalusPort),
                        transportType = TransportType.Tcp,
                        payload       = encPacket.toByteBuffer()
                    });
                }
                //}
            }
            else
            {
                throw new ArgumentException("Packet payload incorrectly formatted for this command type.");
            }
        }
        internal DecryptedDaedalusPacket toDecryptedDaedalusPacket(out DaedalusGlobal.ReturnCodes returnCode)
        {
            DaedalusGlobal.ReturnCodes rc;
            int start;
            int len;

            // Build a clear text packet from the decrypted data
            if (DecryptedDaedalusPacket.IsValidPacket(decryptedPayload, out rc, out start, out len))
            {
                returnCode = DaedalusGlobal.ReturnCodes.Valid;
                return(new DecryptedDaedalusPacket(decryptedPayload, start, len, out rc));
            }
            else
            {
                returnCode = rc;
                return(null);
            }
        }
        internal static bool IsValidPacket(byte[] inBuffer,
                                           out DaedalusGlobal.ReturnCodes returnCode, out int validatedPacketStart, out int validatedPacketLength)
        {
            // Try to find the SOH that starts the packet
            int startIndex = inBuffer.FirstIndexOfSequence(new byte[] { GlobalConstants.SOH }, 0);

            // If we couldn't find an SOH, there's no packet
            if (startIndex == -1)
            {
#if DEBUG
                GlobalMethods.TestLog("Packet " + BitConverter.ToString(inBuffer) + " could not find SOH.");
#endif
                returnCode            = DaedalusGlobal.ReturnCodes.InvalidPacketStructure;
                validatedPacketStart  = int.MaxValue;
                validatedPacketLength = int.MaxValue;
                return(false);
            }

            // Decode packetLength from the next two bytes
            // Note packetLength is number of bytes between end of packetLength and CRC
            // Yes, I did that on purpose
            ushort inPacketLength = BitConverter.ToUInt16(inBuffer, startIndex + elementSTX.ElementSize);

            // Check to make sure bufferLength can fit a whole packet
            if (inBuffer.Length < (startIndex + inPacketLength + elementSTX.ElementSize + elementCRC.ElementSize + elementEOT.ElementSize))
            {
#if DEBUG
                GlobalMethods.TestLog("Packet " + BitConverter.ToString(inBuffer) + " failed length check. Length was " +
                                      inBuffer.Length + ", should have been at least " + (startIndex + inPacketLength + elementSTX.ElementSize + elementCRC.ElementSize + elementEOT.ElementSize + 1).ToString());
#endif
                returnCode            = DaedalusGlobal.ReturnCodes.InvalidPacketStructure;
                validatedPacketStart  = int.MaxValue;
                validatedPacketLength = int.MaxValue;
                return(false);
            }

            // CRC position should be packetLength from index 3, which is just after packetLength
            int CRCIndex = startIndex + elementSTX.ElementSize + elementPacketLength.ElementSize + inPacketLength;

            // Check for an ETX character right before the CRC and EOT after the CRC
            if (((inBuffer[CRCIndex - 1]) != GlobalConstants.ETX) || ((inBuffer[CRCIndex + 2]) != GlobalConstants.EOT))
            {
#if DEBUG
                GlobalMethods.TestLog("Packet " + BitConverter.ToString(inBuffer) + " failed ETX/EOT check. Byte at ETX position was " + inBuffer[CRCIndex - 1].ToString("X") + ", should be 0x03. Byte at EOT position was " +
                                      inBuffer[CRCIndex + 2].ToString("X") + ", should have been 0x04.");
#endif
                returnCode            = DaedalusGlobal.ReturnCodes.InvalidPacketStructure;
                validatedPacketStart  = int.MaxValue;
                validatedPacketLength = int.MaxValue;
                return(false);
            }

            // Read in CRC of input packet
            ushort CRCIn = BitConverter.ToUInt16(inBuffer, CRCIndex);

            // Calculate CRC from content of input packet, STX to ETX, inclusive
            ushort CRCCalc = CRC16.calc_crc(inBuffer, startIndex, elementSTX.ElementSize + elementPacketLength.ElementSize + inPacketLength);

            // If the CRC check failed...
            if (CRCIn != CRCCalc)
            {
#if DEBUG
                GlobalMethods.TestLog("Packet " + BitConverter.ToString(inBuffer) + " failed CRC verification. Calculated CRC was " + CRCCalc.ToString("X") + ", input CRC was " + CRCIn.ToString("X"));
#endif
                returnCode            = DaedalusGlobal.ReturnCodes.IncorrectCRC;
                validatedPacketStart  = int.MaxValue;
                validatedPacketLength = int.MaxValue;
                return(false);
            }

#if DEBUG
            GlobalMethods.TestLog("Packet " + BitConverter.ToString(inBuffer) + " verified.");
#endif
            returnCode            = DaedalusGlobal.ReturnCodes.Valid;
            validatedPacketStart  = (int)startIndex;
            validatedPacketLength = (int)(elementSTX.ElementSize + elementPacketLength.ElementSize + inPacketLength + elementCRC.ElementSize + elementEOT.ElementSize);
            return(true);
        }