/// <summary>
        /// Reads the Flash policy request and returns the policy response if Flash requests are allowed.
        /// </summary>
        /// <param name="sender">The <see cref="AsyncSocket"/></param>
        /// <param name="readBytes">The bytes read from the socket</param>
        /// <param name="tag">A tag identifying the read request</param>
        void ReadPolicyRequest(AsyncSocket sender, byte[] readBytes, long tag)
        {
            // remove this now that we are done with it
            this.socket.DidRead -= new AsyncSocket.SocketDidRead(ReadPolicyRequest);

            if (tag == FLASH_POLICY_REQUEST_TAG)
            {
                Data data = new Data(readBytes);
                this.AlreadyReceivedData.Append(data.ToString());

                string request = this.AlreadyReceivedData.ToString();
                if (request == FlashPolicy.REQUEST)
                {
                    if (this.allowFlash)
                    {
                        this.socket.Write(FlashPolicy.ResponseBytes, TIMEOUT_FLASHPOLICYRESPONSE, FLASH_POLICY_RESPONSE_TAG);
                        this.socket.CloseAfterWriting();
                    }
                    else
                    {
                        OnError(ErrorCode.NOT_AUTHORIZED, ErrorDescription.BROWSER_CONNECTIONS_NOT_ALLOWED);
                    }
                }
                else
                {
                    OnError(ErrorCode.INVALID_REQUEST, ErrorDescription.UNRECOGNIZED_REQUEST);
                }
            }
        }
        /// <summary>
        /// Reads the socket data and handles the request
        /// </summary>
        /// <param name="alreadyReadBytes">Any bytes that were already read from the socket</param>
        public void Read(byte[] alreadyReadBytes)
        {
            Data data = new Data(alreadyReadBytes);
            string s = data.ToString();
            this.AlreadyReceivedData.Append(s);

            this.socket.DidRead += new AsyncSocket.SocketDidRead(ReadPolicyRequest);
            this.socket.Read(FlashPolicy.REQUEST.Length - s.Length, TIMEOUT_FLASHPOLICYREQUEST, FLASH_POLICY_REQUEST_TAG);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// This method automatically increases the length of the data by the proper length,
        /// and copies the bytes from the given data object into the mutable data array.
        /// </summary>
        /// <param name="data">
        ///		A Data object to copy bytes from.
        ///	</param>
        public void AppendData(Data data)
        {
            // We're not going to bother checking to see if data is null.
            // The NullReferenceException will automatically get thrown for us if it is.

            AppendData(data.ByteArray);
        }
Ejemplo n.º 4
0
 public MutableData(Data data, int offset, int length)
     : base(data, offset, length)
 {
     // Nothing to do here
 }
Ejemplo n.º 5
0
 public MutableData(Data data, bool copy)
     : base(data, copy)
 {
     // Nothing to do here
 }
Ejemplo n.º 6
0
 public MutableData(Data data)
     : base(data, false)
 {
     // Nothing to do here
 }
Ejemplo n.º 7
0
 public static bool IsEqual(Data d1, int d1Offset, Data d2, int d2Offset, int length)
 {
     return IsEqual(d1.ByteArray, d1Offset, d2.ByteArray, d2Offset, length);
 }
Ejemplo n.º 8
0
 /// <summary>
 /// This method automatically increases the length of the data by the proper length,
 /// and copies the data from the given byte array into the underlying buffer.
 /// The data is copied starting at the given offset up to the given length.
 /// The data is inserted into the underlying buffer at the given index.
 /// </summary>
 /// <param name="index">
 ///		The position in this instance where insertion begins.
 /// </param>
 /// <param name="data">
 ///		The data to insert into the underlying buffer.
 /// </param>
 /// <param name="offset">
 ///		The offset from which to start copying data from the given data.
 /// </param>
 /// <param name="length">
 ///		The amount of data to copy from the given data.
 ///	</param>
 public void InsertData(int index, Data data, int offset, int length)
 {
     InsertData(index, data.ByteArray, offset, length);
 }
Ejemplo n.º 9
0
 /// <summary>
 /// Creates a new Data object using the given data.
 /// If the copy flag is set, this method will create a new buffer, and copy the buffer from the given data into it.
 /// Thus changes to the given data will not affect this Data object.
 /// Otherwise the new Data object will simply form a wrapper around the given data (without copying anything).
 /// 
 /// Note: If you pass a Data object which uses an internal stream (IsStream = true), the data is always copied.
 /// </summary>
 /// <param name="buffer">
 ///		Byte array to use for underlying data.
 /// </param>
 /// <param name="copy">
 ///		Whether or not to copy data from the given buffer into a new buffer.
 ///	</param>
 public Data(Data data, bool copy)
     : this(data.ByteArray, copy)
 {
     // Nothing to do here
 }
Ejemplo n.º 10
0
 /// <summary>
 /// Creates a new Data object using the data.
 /// The data is not copied.
 /// That is, the new Data object is simply a wrapper around that same data.
 /// </summary>
 /// <param name="buffer">
 ///		Data to use as underlying data.
 ///	</param>
 public Data(Data data)
     : this(data.ByteArray, false)
 {
     // Nothing to do here
 }
Ejemplo n.º 11
0
        /// <summary>
        /// Reads the entire file, and stores the result in a Data object wrapping the read bytes.
        /// Warning: This method is only to be used for small files.
        /// </summary>
        /// <param name="filePath">
        ///		Relative or absolute path to file.
        /// </param>
        /// <returns>
        ///		A regular Data object, which wraps the read bytes from the file.
        /// </returns>
        public static Data ReadFile(string filePath)
        {
            Data result = null;
            FileStream fs = null;

            try
            {
                fs = new FileStream(filePath, FileMode.Open, FileAccess.Read);
                result = new Data((int)fs.Length);

                int amountRead = fs.Read(result.ByteArray, 0, result.Length);
                int totalAmountRead = amountRead;

                while ((amountRead > 0) && (totalAmountRead < result.Length))
                {
                    amountRead = fs.Read(result.ByteArray, totalAmountRead, result.Length - totalAmountRead);
                    totalAmountRead += amountRead;
                }

                if (totalAmountRead < result.Length)
                {
                    result = null;
                }
            }
            catch
            {
                result = null;
            }
            finally
            {
                if (fs != null) fs.Close();
            }

            return result;
        }
Ejemplo n.º 12
0
        /// <summary>
        /// Logs the specified data.
        /// </summary>
        /// <param name="data">The <see cref="Data"/> to log</param>
        public void Log(Data data)
        {
            try
            {
                if (this.loggingEnabled && !String.IsNullOrEmpty(this.logFolder))
                {
                    string filename = String.Format(@"GNTP_{0}.txt", this.requestInfo.RequestID);
                    string filepath = PathUtility.Combine(this.logFolder, filename);
                    bool exists = System.IO.File.Exists(filepath);
                    if (!exists)
                    {
                        // log the initial request/response
                        System.IO.StreamWriter w = System.IO.File.CreateText(filepath);
                        using (w)
                        {
                            w.Write("Timestamp: {0}\r\n", DateTime.Now.ToString());
                            foreach (string item in this.requestInfo.HandlingInfo)
                            {
                                w.Write(String.Format("{0}\r\n", item));
                            }
                            w.Write(SEPERATOR);

                            if (this.requestReader != null)
                            {
                                w.Write(this.requestReader.ReceivedData);

                                if (!String.IsNullOrEmpty(this.requestReader.DecryptedData))
                                {
                                    w.Write(SEPERATOR);
                                    w.Write(this.requestReader.DecryptedData);
                                }
                            }

                            w.Write(SEPERATOR);
                            w.Write(data.ToString());
                            w.Close();
                            this.requestInfo.HandlingInfo.Clear();
                        }
                    }
                    else
                    {
                        // this is for logging callback data
                        System.IO.StreamWriter w = new System.IO.StreamWriter(filepath, true);
                        using (w)
                        {
                            w.Write(SEPERATOR);
                            w.Write("Timestamp: {0}\r\n", DateTime.Now.ToString());
                            foreach (string item in this.requestInfo.HandlingInfo)
                            {
                                w.Write(String.Format("{0}\r\n", item));
                            }
                            w.Write(SEPERATOR);
                            w.Write(data.ToString());
                            w.Close();
                        }
                    }
                }
            }
            catch
            {
                // suppress logging exceptions
            }
        }
Ejemplo n.º 13
0
        /// <summary>
        /// Performs the actual writing of data to the socket. Used by all other Write* methods.
        /// </summary>
        /// <param name="socket">The <see cref="AsyncSocket"/> to write the data to</param>
        /// <param name="bytes">The bytes to write to the socket</param>
        /// <param name="timeout">The socket write timeout value</param>
        /// <param name="tag">The tag that will identify the write operation (can be referenced in the socket's DidWrite event)</param>
        /// <param name="disconnectAfterWriting">Indicates if the server should disconnect the socket after writing the data</param>
        /// <param name="requestComplete">Indicates if the request is complete once the data is written</param>
        protected void FinalWrite(AsyncSocket socket, byte[] bytes, int timeout, long tag, bool disconnectAfterWriting, bool requestComplete)
        {
            Data data = new Data(bytes);
            Log(data);

            // give any custom readers the change to modify the output before we send it (especially useful for WebSockets that need to frame their data)
            if (this.requestReader != null)
                this.requestReader.BeforeResponse(ref bytes);

            // if we are done sending stuff back (all responses and callbacks), we need to initiate an orderly shutdown
            if (!disconnectAfterWriting && requestComplete)
                OrderlySocketShutdown();

            // send the data
            socket.Write(bytes, timeout, tag);

            // if we are the ones disconnecting, do it now. (usually if we are sending back an error response)
            // if not, we can just leave the socket alone
            if (disconnectAfterWriting)
            {
                OnSocketUsageComplete(socket);
                socket.CloseAfterWriting();
            }
        }
Ejemplo n.º 14
0
        /// <summary>
        /// Handles the socket's DidRead event after reading only the first four bytes of data.
        /// </summary>
        /// <param name="socket">The <see cref="AsyncSocket"/></param>
        /// <param name="readBytes">Array of <see cref="byte"/>s that were read</param>
        /// <param name="tag">The tag identifying the read operation</param>
        private void SocketDidReadIndicatorBytes(AsyncSocket socket, byte[] readBytes, long tag)
        {
            // remove this event handler since we dont need it any more
            socket.DidRead -= new AsyncSocket.SocketDidRead(this.SocketDidReadIndicatorBytes);

            Data data = new Data(readBytes);
            string s = data.ToString();

            if (tag == ACCEPT_TAG)
            {
                if (s == FlashPolicy.REQUEST_INDICATOR)
                {
                    GNTPFlashSocketReader gfsr = new GNTPFlashSocketReader(socket, allowBrowserConnections);
                    gfsr.Read(readBytes);
                }
                else if (s == WebSocketHandshakeHandler.REQUEST_INDICATOR)
                {
                    // this is a GNTP over WebSocket request, so we have to do the WebSocket handshake first
                    socket.Tag = readBytes;
                    WebSocketHandshakeHandler wshh = new WebSocketHandshakeHandler(socket, "*", "ws://localhost:23053");
                    wshh.DoHandshake(delegate()
                    {
                        // now pass off to the GNTPWebSocketReader (which is just a normal GNTPSocketReader that can deal with the WebSocket framing of packets)
                        GNTPWebSocketReader gwsr = new GNTPWebSocketReader(socket, passwordManager, passwordRequired, allowNetworkNotifications, allowBrowserConnections, allowSubscriptions, this.requestInfo);
                        this.requestReader = gwsr;
                        gwsr.MessageParsed += new GNTPRequestReader.GNTPRequestReaderMessageParsedEventHandler(requestReader_MessageParsed);
                        gwsr.Error += new GNTPRequestReader.GNTPRequestReaderErrorEventHandler(requestReader_Error);
                        gwsr.Read(readBytes);
                    });
                }
                else
                {
                    // this is a normal GNTP/TCP connection, so handle it as such
                    GNTPSocketReader gsr = new GNTPSocketReader(socket, passwordManager, passwordRequired, allowNetworkNotifications, allowBrowserConnections, allowSubscriptions, this.requestInfo);
                    this.requestReader = gsr;
                    gsr.MessageParsed += new GNTPRequestReader.GNTPRequestReaderMessageParsedEventHandler(requestReader_MessageParsed);
                    gsr.Error += new GNTPRequestReader.GNTPRequestReaderErrorEventHandler(requestReader_Error);
                    gsr.Read(readBytes);
                }
            }
            else
            {
                WriteError(socket, ErrorCode.INVALID_REQUEST, ErrorDescription.MALFORMED_REQUEST);
            }
        }
        /// <summary>
        /// Handles the socket's DidRead event.
        /// </summary>
        /// <param name="socket">The <see cref="AsyncSocket"/></param>
        /// <param name="readBytes">Array of <see cref="byte"/>s that were read</param>
        /// <param name="tag">The tag identifying the read operation</param>
        protected virtual void SocketDidRead(AsyncSocket socket, byte[] readBytes, long tag)
        {
            try
            {
                Data data = new Data(readBytes);
                this.AlreadyReceivedData.Append(data.ToString());

                GNTPParser parser = (GNTPParser)socket.Tag;
                NextIndicator next = parser.Parse(readBytes);
                if (next.ShouldContinue)
                {
                    if (next.UseBytes)
                        socket.Read(next.Bytes, TIMEOUT_GNTP_HEADER, parser.Tag);
                    else
                        socket.Read(next.Length, TIMEOUT_GNTP_BINARY, parser.Tag);
                }
            }
            catch (GrowlException gEx)
            {
                OnError(gEx.ErrorCode, gEx.Message, gEx.AdditionalInfo);
            }
            catch (Exception ex)
            {
                OnError(ErrorCode.INVALID_REQUEST, ErrorDescription.MALFORMED_REQUEST, ex.Message);
            }
        }
Ejemplo n.º 16
0
 /// <summary>
 /// Reads from the given data, starting at the given offset and reading the given length,
 /// and appends the read data to the underlying buffer.
 /// The underlying buffer length is automatically increased as needed.
 /// 
 /// This method properly handles reading from stream data (data.IsStream == true).
 /// </summary>
 /// <param name="data">
 ///		The data to append to the end of the underlying buffer.
 /// </param>
 /// <param name="offset">
 ///		The offset from which to start copying from the given data.
 /// </param>
 /// <param name="length">
 ///		The amount to copy from the given data.
 /// </param>
 public void AppendData(Data data, int offset, int length)
 {
     AppendData(data.ByteArray, offset, length);
 }
Ejemplo n.º 17
0
 /// <summary>
 /// This method automatically increases the length of the data by the proper length,
 /// and copies the data from the given byte array into the underlying buffer.
 /// The data is copied starting at the given offset up to the given length.
 /// The data is inserted into the underlying buffer at the given index.
 /// </summary>
 /// <param name="index">
 ///		The position in this instance where insertion begins.
 /// </param>
 /// <param name="data">
 ///		The data to insert into the underlying buffer.
 /// </param>
 public void InsertData(int index, Data data)
 {
     InsertData(index, data.ByteArray);
 }
Ejemplo n.º 18
0
 /// <summary>
 /// Creates a new Data object using a specified subset of the given data.
 /// The data must necessarily be copied (otherwise it would be unsafe).
 /// </summary>
 /// <param name="buffer">
 ///		Byte array to use for underlying data.
 /// </param>
 /// <param name="offset">
 ///		The offset within data to start reading from.
 /// </param>
 /// <param name="data">
 ///		The amount to read from data.
 /// </param>
 public Data(Data data, int offset, int length)
     : this(data.ByteArray, offset, length)
 {
     // Nothing to do here
 }
        private void ProcessBuffer()
        {
            try
            {
                Data data = new Data(buffer.ToArray());
                string s = data.ToString();
                alreadyReceived.Append(s);

                if (tag == START_TAG)
                {
                    // start looking for GNTP header
                    tag = GNTP_IDENTIFIER_TAG;
                    ContinueProcessing();
                }

                else if (tag == GNTP_IDENTIFIER_TAG)
                {
                    string line = s;
                    Match match = ParseGNTPHeaderLine(line, this.passwordRequired);

                    if (match.Success)
                    {
                        this.version = match.Groups["Version"].Value;
                        if (version == MessageParser.GNTP_SUPPORTED_VERSION)
                        {
                            string d = match.Groups["Directive"].Value;
                            if (Enum.IsDefined(typeof(RequestType), d))
                            {
                                this.directive = (RequestType)Enum.Parse(typeof(RequestType), d);

                                // check for supported but not allowed requests
                                if (this.directive == RequestType.SUBSCRIBE && !this.allowSubscriptions)
                                {
                                    OnError(ErrorCode.NOT_AUTHORIZED, ErrorDescription.SUBSCRIPTIONS_NOT_ALLOWED);
                                }
                                else
                                {
                                    this.encryptionAlgorithm = Cryptography.GetEncryptionType(match.Groups["EncryptionAlgorithm"].Value);
                                    this.ivHex = (match.Groups["IV"] != null ? match.Groups["IV"].Value : null);
                                    if (!String.IsNullOrEmpty(this.ivHex)) this.iv = Cryptography.HexUnencode(this.ivHex);
                                    string keyHash = match.Groups["KeyHash"].Value.ToUpper();

                                    bool authorized = false;
                                    // Any of the following criteria require a password:
                                    //    1. the request did not originate on the local machine or LAN
                                    //    2. the request came from the LAN, but LAN passwords are required
                                    //    2. it is a SUBSCRIBE request (all subscriptions require a password)
                                    //    3. the user's preferences require even local requests to supply a password
                                    // Additionally, even if a password is not required, it will be validated if the
                                    // sending appplication includes one
                                    string errorDescription = ErrorDescription.INVALID_KEY;
                                    if (this.passwordRequired || this.directive == RequestType.SUBSCRIBE || !String.IsNullOrEmpty(keyHash))
                                    {
                                        if (String.IsNullOrEmpty(keyHash))
                                        {
                                            errorDescription = ErrorDescription.MISSING_KEY;
                                        }
                                        else
                                        {
                                            string keyHashAlgorithmType = match.Groups["KeyHashAlgorithm"].Value;
                                            this.keyHashAlgorithm = Cryptography.GetKeyHashType(keyHashAlgorithmType);
                                            string salt = match.Groups["Salt"].Value.ToUpper();
                                            authorized = this.passwordManager.IsValid(keyHash, salt, this.keyHashAlgorithm, this.encryptionAlgorithm, out this.key);
                                        }
                                    }
                                    else
                                    {
                                        authorized = true;
                                        this.key = Key.None;
                                    }

                                    if (authorized)
                                    {
                                        if (this.encryptionAlgorithm == Cryptography.SymmetricAlgorithmType.PlainText)
                                        {
                                            tag = HEADER_TAG;
                                            ContinueProcessing();
                                        }
                                        else
                                        {
                                            tag = ENCRYPTED_HEADERS_TAG;
                                            ContinueProcessing();
                                        }
                                    }
                                    else
                                    {
                                        OnError(ErrorCode.NOT_AUTHORIZED, errorDescription);
                                    }
                                }
                            }
                            else
                            {
                                OnError(ErrorCode.INVALID_REQUEST, ErrorDescription.UNSUPPORTED_DIRECTIVE, d);
                            }
                        }
                        else
                        {
                            OnError(ErrorCode.UNKNOWN_PROTOCOL_VERSION, ErrorDescription.UNSUPPORTED_VERSION, version);
                        }
                    }
                    else
                    {
                        OnError(ErrorCode.UNKNOWN_PROTOCOL, ErrorDescription.MALFORMED_REQUEST);
                    }
                }

                else if (tag == HEADER_TAG)
                {
                    if (s == MessageParser.BLANK_LINE)
                    {
                        // if this is a REGISTER message, check Notifications-Count value
                        // to see how many notification sections to expect
                        if (this.directive == RequestType.REGISTER)
                        {
                            if (this.expectedNotifications > 0)
                            {
                                tag = NOTIFICATION_TYPE_TAG;
                                ContinueProcessing();
                            }
                            else
                            {
                                // a REGISTER request with no notifications is not valid
                                OnError(ErrorCode.INVALID_REQUEST, ErrorDescription.NO_NOTIFICATIONS_REGISTERED);
                            }
                        }
                        else
                        {
                            // otherwise, check the number of resource pointers we got and start reading those
                            this.pointersExpected = GetNumberOfPointers();
                            if (this.pointersExpected > 0)
                            {
                                this.pointersExpectedRemaining = this.pointersExpected;
                                this.currentPointer = 1;
                                tag = RESOURCE_HEADER_TAG;
                                ContinueProcessing();
                            }
                            else
                            {
                                OnMessageParsed();
                            }
                        }
                    }
                    else
                    {
                        Header header = Header.ParseHeader(s);
                        if (header != null)
                        {
                            bool addHeader = true;
                            if (header.Name == Header.APPLICATION_NAME)
                            {
                                this.applicationName = header.Value;
                            }
                            if (header.Name == Header.NOTIFICATIONS_COUNT)
                            {
                                this.expectedNotifications = Convert.ToInt32(header.Value);
                                this.expectedNotificationsRemaining = this.expectedNotifications;
                                this.currentNotification = 1;
                            }
                            if (header.Name == Header.NOTIFICATION_CALLBACK_CONTEXT)
                            {
                                this.callbackData = header.Value;
                            }
                            if (header.Name == Header.NOTIFICATION_CALLBACK_CONTEXT_TYPE)
                            {
                                this.callbackDataType = header.Value;
                            }
                            if (header.Name == Header.NOTIFICATION_CALLBACK_TARGET || header.Name == Header.NOTIFICATION_CALLBACK_CONTEXT_TARGET)   // left in for compatibility
                            {
                                this.callbackUrl = header.Value;
                            }
                            if (header.Name == Header.RECEIVED)
                            {
                                this.requestInfo.PreviousReceivedHeaders.Add(header);
                                addHeader = false;
                            }

                            if (addHeader) this.headers.AddHeader(header);
                        }
                        tag = HEADER_TAG;
                        ContinueProcessing();
                    }
                }

                else if (tag == NOTIFICATION_TYPE_TAG)
                {
                    if (s == MessageParser.BLANK_LINE)
                    {
                        this.expectedNotificationsRemaining--;
                        if (this.expectedNotificationsRemaining > 0)
                        {
                            this.currentNotification++;
                            tag = NOTIFICATION_TYPE_TAG;
                            ContinueProcessing();
                        }
                        else
                        {
                            // otherwise, check the number of resource pointers we got and start reading those
                            this.pointersExpected = GetNumberOfPointers();
                            if (this.pointersExpected > 0)
                            {
                                this.pointersExpectedRemaining = this.pointersExpected;
                                this.currentPointer = 1;
                                tag = RESOURCE_HEADER_TAG;
                                ContinueProcessing();
                            }
                            else
                            {
                                OnMessageParsed();
                            }
                        }
                    }
                    else
                    {
                        if (this.notificationsToBeRegistered.Count < this.currentNotification)
                        {
                            this.notificationsToBeRegistered.Add(new HeaderCollection());
                        }

                        Header header = Header.ParseHeader(s);
                        this.notificationsToBeRegistered[this.currentNotification - 1].AddHeader(header);
                        tag = NOTIFICATION_TYPE_TAG;
                        ContinueProcessing();
                    }
                }

                else if (tag == RESOURCE_HEADER_TAG)
                {
                    if (s == MessageParser.BLANK_LINE)
                    {
                        // we should have found an Identifier header and Length header, or we are just starting a new section
                        Pointer p = this.pointers[this.currentPointer - 1];
                        if (p.Identifier != null && p.Length > 0)
                        {
                            // read #of bytes
                            int length = this.pointers[this.currentPointer - 1].Length;
                            tag = RESOURCE_TAG;
                            ContinueProcessing();
                        }
                        else
                        {
                            tag = RESOURCE_HEADER_TAG;
                            ContinueProcessing();
                        }
                    }
                    else
                    {
                        Header header = Header.ParseHeader(s);
                        // should be Identifer or Length
                        if (header != null)
                        {
                            bool validHeader = false;
                            if (header.Name == Header.RESOURCE_IDENTIFIER)
                            {
                                this.pointers[this.currentPointer - 1].Identifier = header.Value;
                                validHeader = true;
                            }
                            else if (header.Name == Header.RESOURCE_LENGTH)
                            {
                                this.pointers[this.currentPointer - 1].Length = Convert.ToInt32(header.Value);
                                validHeader = true;
                            }
                            else
                            {
                                OnError(ErrorCode.INVALID_REQUEST, ErrorDescription.UNRECOGNIZED_RESOURCE_HEADER, header.Name);
                            }

                            if (validHeader)
                            {
                                tag = RESOURCE_HEADER_TAG;
                                ContinueProcessing();
                            }
                        }
                        else
                        {
                            OnError(ErrorCode.INVALID_REQUEST, ErrorDescription.UNRECOGNIZED_RESOURCE_HEADER);
                        }
                    }
                }

                else if (tag == RESOURCE_TAG)
                {
                    // deal with data bytes
                    byte[] bytes = this.key.Decrypt(data.ByteArray, this.iv);

                    Pointer pointer = this.pointers[this.currentPointer - 1];
                    pointer.ByteArray = bytes;
                    BinaryData binaryData = new BinaryData(pointer.Identifier, pointer.ByteArray);
                    ResourceCache.Add(this.applicationName, binaryData);

                    this.pointersExpectedRemaining--;
                    if (this.pointersExpectedRemaining > 0)
                    {
                        this.currentPointer++;
                        tag = RESOURCE_HEADER_TAG;
                        ContinueProcessing();
                    }
                    else
                    {
                        OnMessageParsed();
                    }
                }

                else if (tag == ENCRYPTED_HEADERS_TAG)
                {
                    // see if a length was specified (the original spec did not require the main encrypted headers portion to specify a length)
                    if (s.StartsWith(Header.RESOURCE_LENGTH))
                    {
                        Header header = Header.ParseHeader(s);
                        if (header != null)
                        {
                            int len = Convert.ToInt32(header.Value);
                            tag = ENCRYPTED_HEADERS_TAG;
                            ContinueProcessing();
                        }
                    }

                    ParseEncryptedMessage(data.ByteArray);
                    if (this.pointersExpected > 0)
                    {
                        tag = RESOURCE_HEADER_TAG;
                        ContinueProcessing();
                    }
                    else
                    {
                        OnMessageParsed();
                    }
                }

                else
                {
                    OnError(ErrorCode.INVALID_REQUEST, ErrorDescription.MALFORMED_REQUEST);
                }
            }
            catch (GrowlException gEx)
            {
                OnError(gEx.ErrorCode, gEx.Message, gEx.AdditionalInfo);
            }
            catch (Exception ex)
            {
                OnError(ErrorCode.INVALID_REQUEST, ErrorDescription.MALFORMED_REQUEST, ex.Message);
            }
        }
Ejemplo n.º 20
0
 public static bool IsEqual(Data d1, Data d2)
 {
     return IsEqual(d1.ByteArray, d2.ByteArray);
 }