예제 #1
0
        protected void SBParseMSG(PacketStream stream, TransactionNode payloadNode, int payloadLength)
        {
            List <PacketSlice> slices = new List <PacketSlice>(2);

            string content = stream.PeekStringUTF8(payloadLength);

            TransactionNode headersNode = new TransactionNode(payloadNode, "Headers");

            int    pos     = content.IndexOf("\r\n\r\n");
            string headers = content.Substring(0, pos);

            string[] lines = headers.Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries);
            foreach (string line in lines)
            {
                stream.ReadBytes(StaticUtils.GetUTF8ByteCount(line), slices);

                string[] tokens = line.Split(new char[] { ':' }, 2);
                tokens[1] = tokens[1].TrimStart(new char[] { ' ' });

                headersNode.AddField(tokens[0], tokens[1], "Message header field.", slices);

                // Skip CRLF
                stream.ReadBytes(2);
            }

            // Skip extra CRLF
            stream.ReadBytes(2);

            int bodyLength = payloadLength - StaticUtils.GetUTF8ByteCount(headers) - 4;

            if (bodyLength > 0)
            {
                TransactionNode bodyNode = new TransactionNode(payloadNode, "Body");

                string contentType = (string)headersNode.Fields["Content-Type"];
                contentType = contentType.Split(new char[] { ';' }, 2)[0];

                if (contentType == "application/x-msnmsgrp2p")
                {
                    ReadNextP2PMessageChunk(stream, bodyNode);

                    UInt32 appID = stream.ReadU32BE(slices);
                    bodyNode.AddField("AppID", appID, "Application ID.", slices);
                }
                else if (contentType == "text/x-msmsgsinvite")
                {
                    string bodyStr = stream.ReadStringUTF8(bodyLength, slices);

                    bodyNode.AddTextField("Body", bodyStr, "Invite body.", slices);
                }
                else
                {
                    string bodyStr = stream.ReadStringUTF8(bodyLength, slices);

                    bodyNode.AddField("Body", bodyStr, "Body.", slices);
                }
            }
        }
예제 #2
0
        protected void AddBodyNode(PacketStream stream,
                                   TransactionNode transactionNode,
                                   string contentType,
                                   string contentEncoding,
                                   int bodyLen)
        {
            List <PacketSlice> slices = new List <PacketSlice>(1);

            TransactionNode bodyNode = new TransactionNode("Body");

            byte[] body = stream.ReadBytes(bodyLen, slices);

            if (contentType == "text/html" || contentType == "text/xml")
            {
                int realBodyLen = body.Length;
                if (body[realBodyLen - 1] == '\0')
                {
                    realBodyLen--;
                }

                Decoder dec;
                if (contentEncoding == "utf-8")
                {
                    dec = Encoding.UTF8.GetDecoder();
                }
                else
                {
                    dec = Encoding.ASCII.GetDecoder();
                }

                char[] bodyChars = new char[dec.GetCharCount(body, 0, realBodyLen)];
                dec.GetChars(body, 0, realBodyLen, bodyChars, 0);
                string bodyStr = new string(bodyChars);

                if (contentType == "text/xml")
                {
                    bodyNode.AddXMLField("XML", bodyStr, "Body XML data.", slices);
                }
                else
                {
                    bodyNode.AddTextField("HTML", bodyStr, "Body HTML data.", slices);
                }
            }
            else if (contentType == "application/vnd.ms-sync.wbxml")
            {
                string xml = WBXML.ConvertToXML(body);
                bodyNode.AddXMLField("WBXML", xml, "Body WBXML data.", slices);
            }
            else
            {
                bodyNode.AddField("Raw", body, StaticUtils.FormatByteArray(body),
                                  "Raw body data.", slices);
            }

            transactionNode.AddChild(bodyNode);
        }
예제 #3
0
파일: MSN.cs 프로젝트: SayHalou/ospy
        private bool HandleSwitchboardSession(IPSession session)
        {
            List<PacketSlice> slices = new List<PacketSlice>(1);

            logger.AddMessage(String.Format("\r\n\r\nparsing session with remote endpoint: {0}\r\n", session.RemoteEndpoint));

            while (true)
            {
                PacketStream stream = session.GetNextStreamDirection();

                if (stream.GetBytesAvailable() == 0)
                {
                    stream = session.GetNextStreamDirection();
                    if (stream.GetBytesAvailable() == 0)
                    {
                        break;
                    }
                }

                IPPacket pkt = stream.CurPacket;
                PacketDirection direction = pkt.Direction;

                try
                {
                    string line = stream.PeekLineUTF8();

                    // Split the line up into CMD and the rest (being arguments, if any)
                    string[] tokens = line.Split(new char[] { ' ' }, 2);

                    logger.AddMessage(String.Format("{0} parsing command '{1}' (line: {2})",
                        (direction == PacketDirection.PACKET_DIRECTION_INCOMING) ? "<<" : ">>",
                        tokens[0], line));

                    // Set cmd and create an array of arguments if present
                    string cmd = tokens[0];
                    string[] arguments = new string[0];
                    if (tokens.Length > 1)
                    {
                        arguments = tokens[1].Split(new char[] { ' ' });
                    }

                    // Create command node
                    TransactionNode node = new TransactionNode("MSNSBCommand");
                    node.Description = cmd;

                    // Command field
                    stream.ReadBytes(StaticUtils.GetUTF8ByteCount(tokens[0]), slices);
                    node.AddField("Command", tokens[0], "Switchboard command.", slices);

                    if (arguments.Length > 0)
                    {
                        // Skip space between command and arguments
                        stream.ReadByte();

                        stream.ReadBytes(StaticUtils.GetUTF8ByteCount(tokens[1]), slices);

                        // Arguments fields
                        node.AddField("Arguments", tokens[1], "Arguments to command.", slices);
                    }

                    // Skip CRLF
                    stream.ReadBytes(2);

                    // Is there a payload?
                    bool hasPayload = false;
                    if (arguments.Length > 0)
                    {
                        List<string> payloadCommands =
                            (direction == PacketDirection.PACKET_DIRECTION_OUTGOING) ? payloadCommandsFromClient : payloadCommandsFromServer;

                        hasPayload = payloadCommands.Contains(cmd);
                    }

                    if (hasPayload)
                    {
                        int payloadLength = -1;

                        try
                        {
                            payloadLength = (int)Convert.ToUInt32(arguments[arguments.Length - 1]);
                        }
                        catch (FormatException)
                        {
                        }

                        if (payloadLength > 0)
                        {
                            TransactionNode payloadNode = new TransactionNode(node, "Payload");

                            logger.AddMessage(String.Format("Parsing {0} bytes of payload", payloadLength));

                            PayloadFormat format = PayloadFormat.TEXT;

                            string cmdUpper = cmd.ToUpper();
                            if (payloadCommandFormats.ContainsKey(cmdUpper))
                                format = payloadCommandFormats[cmdUpper];

                            if (format == PayloadFormat.MESSAGE)
                            {
                                SBParseMSG(stream, payloadNode, payloadLength);
                            }
                            else
                            {
                                string body = stream.ReadStringUTF8(payloadLength, slices);

                                switch (format)
                                {
                                    case PayloadFormat.SLP:
                                        payloadNode.AddTextField("MSNSLP", body, "MSNSLP data.", slices);
                                        break;
                                    case PayloadFormat.XML:
                                        payloadNode.AddXMLField("XML", body, "XML data.", slices);
                                        break;
                                    default:
                                        payloadNode.AddTextField("Text", body, "Text.", slices);
                                        break;
                                }
                            }
                        }
                    }

                    session.AddNode(node);
                }
                catch (EndOfStreamException e)
                {
                    logger.AddMessage(String.Format("MSNSwitchboard: EOS at {0} ({1})", stream.Position, e));
                    break;
                }
            }

            logger.AddMessage("done with session\r\n\r\n");

            return true;
        }
예제 #4
0
파일: MSN.cs 프로젝트: SayHalou/ospy
        protected void SBParseMSG(PacketStream stream, TransactionNode payloadNode, int payloadLength)
        {
            List<PacketSlice> slices = new List<PacketSlice>(2);

            string content = stream.PeekStringUTF8(payloadLength);

            TransactionNode headersNode = new TransactionNode(payloadNode, "Headers");

            int pos = content.IndexOf("\r\n\r\n");
            string headers = content.Substring(0, pos);
            string[] lines = headers.Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries);
            foreach (string line in lines)
            {
                stream.ReadBytes(StaticUtils.GetUTF8ByteCount(line), slices);

                string[] tokens = line.Split(new char[] { ':' }, 2);
                tokens[1] = tokens[1].TrimStart(new char[] { ' ' });

                headersNode.AddField(tokens[0], tokens[1], "Message header field.", slices);

                // Skip CRLF
                stream.ReadBytes(2);
            }

            // Skip extra CRLF
            stream.ReadBytes(2);

            int bodyLength = payloadLength - StaticUtils.GetUTF8ByteCount(headers) - 4;

            if (bodyLength > 0)
            {
                TransactionNode bodyNode = new TransactionNode(payloadNode, "Body");

                string contentType = (string)headersNode.Fields["Content-Type"];
                contentType = contentType.Split(new char[] { ';' }, 2)[0];

                if (contentType == "application/x-msnmsgrp2p")
                {
                    ReadNextP2PMessageChunk(stream, bodyNode);

                    UInt32 appID = stream.ReadU32BE(slices);
                    bodyNode.AddField("AppID", appID, "Application ID.", slices);
                }
                else if (contentType == "text/x-msmsgsinvite")
                {
                    string bodyStr = stream.ReadStringUTF8(bodyLength, slices);

                    bodyNode.AddTextField("Body", bodyStr, "Invite body.", slices);
                }
                else
                {
                    string bodyStr = stream.ReadStringUTF8(bodyLength, slices);

                    bodyNode.AddField("Body", bodyStr, "Body.", slices);
                }
            }
        }
예제 #5
0
파일: MSN.cs 프로젝트: SayHalou/ospy
        protected void ReadNextP2PMessageChunk(PacketStream stream, TransactionNode parentNode)
        {
            TransactionNode p2pNode = new TransactionNode(parentNode, "MSNP2PMessageChunk");

            // Headers
            TransactionNode p2pHeaders = new TransactionNode(p2pNode, "Headers");

            List<PacketSlice> slices = new List<PacketSlice>();

            UInt32 sessionID = stream.ReadU32LE(slices);
            p2pHeaders.AddField("SessionID", sessionID, "Session ID.", slices);

            UInt32 messageID = stream.ReadU32LE(slices);
            p2pHeaders.AddField("MessageID", messageID, "Message ID.", slices);

            UInt64 dataOffset = stream.ReadU64LE(slices);
            p2pHeaders.AddField("DataOffset", dataOffset, "Data offset.", slices);

            UInt64 dataSize = stream.ReadU64LE(slices);
            p2pHeaders.AddField("DataSize", dataSize, "Data size.", slices);

            UInt32 chunkSize = stream.ReadU32LE(slices);
            p2pHeaders.AddField("ChunkSize", chunkSize, "Chunk size.", slices);

            UInt32 flags = stream.ReadU32LE(slices);
            p2pHeaders.AddField("Flags", flags, StaticUtils.FormatFlags(flags), "Flags.", slices);

            UInt32 ackedMsgID = stream.ReadU32LE(slices);
            p2pHeaders.AddField("AckedMsgID", ackedMsgID, "MessageID of the message to be acknowledged.", slices);

            UInt32 prevAckedMsgID = stream.ReadU32LE(slices);
            p2pHeaders.AddField("PrevAckedMsgID", prevAckedMsgID, "AckedMsgID of the last chunk to ack.", slices);

            UInt64 ackedDataSize = stream.ReadU64LE(slices);
            p2pHeaders.AddField("AckedDataSize", ackedDataSize, "Acknowledged data size.", slices);

            // Body
            TransactionNode p2pContent = null;
            if (chunkSize > 0)
            {
                p2pContent = new TransactionNode(p2pNode, "Content");

                byte[] bytes = stream.ReadBytes((int)chunkSize, slices);

                if (sessionID != 0)
                {
                    p2pContent.AddField("Raw", bytes, StaticUtils.FormatByteArray(bytes), "Raw content.", slices);
                }
                else
                {
                    p2pContent.AddTextField("MSNSLP", bytes, StaticUtils.DecodeUTF8(bytes), "MSNSLP data.", slices);
                }
            }
        }
예제 #6
0
        protected void ReadNextP2PMessageChunk(PacketStream stream, TransactionNode parentNode)
        {
            TransactionNode p2pNode = new TransactionNode(parentNode, "MSNP2PMessageChunk");

            // Headers
            TransactionNode p2pHeaders = new TransactionNode(p2pNode, "Headers");

            List <PacketSlice> slices = new List <PacketSlice>();

            UInt32 sessionID = stream.ReadU32LE(slices);

            p2pHeaders.AddField("SessionID", sessionID, "Session ID.", slices);

            UInt32 messageID = stream.ReadU32LE(slices);

            p2pHeaders.AddField("MessageID", messageID, "Message ID.", slices);

            UInt64 dataOffset = stream.ReadU64LE(slices);

            p2pHeaders.AddField("DataOffset", dataOffset, "Data offset.", slices);

            UInt64 dataSize = stream.ReadU64LE(slices);

            p2pHeaders.AddField("DataSize", dataSize, "Data size.", slices);

            UInt32 chunkSize = stream.ReadU32LE(slices);

            p2pHeaders.AddField("ChunkSize", chunkSize, "Chunk size.", slices);

            UInt32 flags = stream.ReadU32LE(slices);

            p2pHeaders.AddField("Flags", flags, StaticUtils.FormatFlags(flags), "Flags.", slices);

            UInt32 ackedMsgID = stream.ReadU32LE(slices);

            p2pHeaders.AddField("AckedMsgID", ackedMsgID, "MessageID of the message to be acknowledged.", slices);

            UInt32 prevAckedMsgID = stream.ReadU32LE(slices);

            p2pHeaders.AddField("PrevAckedMsgID", prevAckedMsgID, "AckedMsgID of the last chunk to ack.", slices);

            UInt64 ackedDataSize = stream.ReadU64LE(slices);

            p2pHeaders.AddField("AckedDataSize", ackedDataSize, "Acknowledged data size.", slices);

            // Body
            TransactionNode p2pContent = null;

            if (chunkSize > 0)
            {
                p2pContent = new TransactionNode(p2pNode, "Content");

                byte[] bytes = stream.ReadBytes((int)chunkSize, slices);

                if (sessionID != 0)
                {
                    p2pContent.AddField("Raw", bytes, StaticUtils.FormatByteArray(bytes), "Raw content.", slices);
                }
                else
                {
                    p2pContent.AddTextField("MSNSLP", bytes, StaticUtils.DecodeUTF8(bytes), "MSNSLP data.", slices);
                }
            }
        }
예제 #7
0
        private bool HandleSwitchboardSession(IPSession session)
        {
            List <PacketSlice> slices = new List <PacketSlice>(1);

            logger.AddMessage(String.Format("\r\n\r\nparsing session with remote endpoint: {0}\r\n", session.RemoteEndpoint));

            while (true)
            {
                PacketStream stream = session.GetNextStreamDirection();

                if (stream.GetBytesAvailable() == 0)
                {
                    stream = session.GetNextStreamDirection();
                    if (stream.GetBytesAvailable() == 0)
                    {
                        break;
                    }
                }

                IPPacket        pkt       = stream.CurPacket;
                PacketDirection direction = pkt.Direction;

                try
                {
                    string line = stream.PeekLineUTF8();

                    // Split the line up into CMD and the rest (being arguments, if any)
                    string[] tokens = line.Split(new char[] { ' ' }, 2);

                    logger.AddMessage(String.Format("{0} parsing command '{1}' (line: {2})",
                                                    (direction == PacketDirection.PACKET_DIRECTION_INCOMING) ? "<<" : ">>",
                                                    tokens[0], line));

                    // Set cmd and create an array of arguments if present
                    string   cmd       = tokens[0];
                    string[] arguments = new string[0];
                    if (tokens.Length > 1)
                    {
                        arguments = tokens[1].Split(new char[] { ' ' });
                    }

                    // Create command node
                    TransactionNode node = new TransactionNode("MSNSBCommand");
                    node.Description = cmd;

                    // Command field
                    stream.ReadBytes(StaticUtils.GetUTF8ByteCount(tokens[0]), slices);
                    node.AddField("Command", tokens[0], "Switchboard command.", slices);

                    if (arguments.Length > 0)
                    {
                        // Skip space between command and arguments
                        stream.ReadByte();

                        stream.ReadBytes(StaticUtils.GetUTF8ByteCount(tokens[1]), slices);

                        // Arguments fields
                        node.AddField("Arguments", tokens[1], "Arguments to command.", slices);
                    }

                    // Skip CRLF
                    stream.ReadBytes(2);

                    // Is there a payload?
                    bool hasPayload = false;
                    if (arguments.Length > 0)
                    {
                        List <string> payloadCommands =
                            (direction == PacketDirection.PACKET_DIRECTION_OUTGOING) ? payloadCommandsFromClient : payloadCommandsFromServer;

                        hasPayload = payloadCommands.Contains(cmd);
                    }

                    if (hasPayload)
                    {
                        int payloadLength = -1;

                        try
                        {
                            payloadLength = (int)Convert.ToUInt32(arguments[arguments.Length - 1]);
                        }
                        catch (FormatException)
                        {
                        }

                        if (payloadLength > 0)
                        {
                            TransactionNode payloadNode = new TransactionNode(node, "Payload");

                            logger.AddMessage(String.Format("Parsing {0} bytes of payload", payloadLength));

                            PayloadFormat format = PayloadFormat.TEXT;

                            string cmdUpper = cmd.ToUpper();
                            if (payloadCommandFormats.ContainsKey(cmdUpper))
                            {
                                format = payloadCommandFormats[cmdUpper];
                            }

                            if (format == PayloadFormat.MESSAGE)
                            {
                                SBParseMSG(stream, payloadNode, payloadLength);
                            }
                            else
                            {
                                string body = stream.ReadStringUTF8(payloadLength, slices);

                                switch (format)
                                {
                                case PayloadFormat.SLP:
                                    payloadNode.AddTextField("MSNSLP", body, "MSNSLP data.", slices);
                                    break;

                                case PayloadFormat.XML:
                                    payloadNode.AddXMLField("XML", body, "XML data.", slices);
                                    break;

                                default:
                                    payloadNode.AddTextField("Text", body, "Text.", slices);
                                    break;
                                }
                            }
                        }
                    }

                    session.AddNode(node);
                }
                catch (EndOfStreamException e)
                {
                    logger.AddMessage(String.Format("MSNSwitchboard: EOS at {0} ({1})", stream.Position, e));
                    break;
                }
            }

            logger.AddMessage("done with session\r\n\r\n");

            return(true);
        }
예제 #8
0
파일: HTTP.cs 프로젝트: SayHalou/ospy
        protected void AddBodyNode(PacketStream stream,
            TransactionNode transactionNode,
            string contentType,
            string contentEncoding,
            int bodyLen)
        {
            List<PacketSlice> slices = new List<PacketSlice>(1);

            TransactionNode bodyNode = new TransactionNode("Body");
            byte[] body = stream.ReadBytes(bodyLen, slices);

            if (contentType == "text/html" || contentType == "text/xml")
            {
                int realBodyLen = body.Length;
                if (body[realBodyLen - 1] == '\0')
                    realBodyLen--;

                Decoder dec;
                if (contentEncoding == "utf-8")
                {
                    dec = Encoding.UTF8.GetDecoder();
                }
                else
                {
                    dec = Encoding.ASCII.GetDecoder();
                }

                char[] bodyChars = new char[dec.GetCharCount(body, 0, realBodyLen)];
                dec.GetChars(body, 0, realBodyLen, bodyChars, 0);
                string bodyStr = new string(bodyChars);

                if (contentType == "text/xml")
                    bodyNode.AddXMLField("XML", bodyStr, "Body XML data.", slices);
                else
                    bodyNode.AddTextField("HTML", bodyStr, "Body HTML data.", slices);
            }
            else if (contentType == "application/vnd.ms-sync.wbxml")
            {
                string xml = WBXML.ConvertToXML(body);
                bodyNode.AddXMLField("WBXML", xml, "Body WBXML data.", slices);
            }
            else
            {
                bodyNode.AddField("Raw", body, StaticUtils.FormatByteArray(body),
                    "Raw body data.", slices);
            }

            transactionNode.AddChild(bodyNode);
        }