/// <summary> /// Initializes a new instance of the <see cref="GNTPParser"/> class. /// </summary> /// <param name="passwordManager">The <see cref="PasswordManager"/> containing a list of allowed passwords</param> /// <param name="passwordRequired">Indicates if a password is required</param> /// <param name="allowNetworkNotifications">Indicates if network requests are allowed</param> /// <param name="allowBrowserConnections">Indicates if browser requests are allowed</param> /// <param name="allowSubscriptions">Indicates if SUBSCRIPTION requests are allowed</param> /// <param name="requestInfo">The <see cref="RequestInfo"/> associated with this request</param> public GNTPParser2(PasswordManager passwordManager, bool passwordRequired, bool allowNetworkNotifications, bool allowBrowserConnections, bool allowSubscriptions, RequestInfo requestInfo) { this.passwordManager = passwordManager; this.passwordRequired = passwordRequired; this.allowNetworkNotifications = allowNetworkNotifications; this.allowBrowserConnections = allowBrowserConnections; this.allowSubscriptions = allowSubscriptions; this.requestInfo = requestInfo; this.alreadyReceived = new StringBuilder(); this.headers = new HeaderCollection(); this.notificationsToBeRegistered = new List <HeaderCollection>(); this.pointers = new List <Pointer>(); this.callbackInfo = new CallbackInfo(); ms = new MemoryStream(); gntpReader = new GNTPStreamReader(ms); buffer = new List <byte>(); nextIndicator = AsyncSocket.CRLFData; tag = GNTP_IDENTIFIER_TAG; }
/// <summary> /// Parses the encrypted message. /// </summary> /// <param name="bytes">The encrypted bytes</param> private void ParseEncryptedMessage(byte[] bytes) { byte[] encryptedBytes = null; if (bytes[bytes.Length - 4] == ((byte)'\r') && bytes[bytes.Length - 3] == ((byte)'\n') && bytes[bytes.Length - 2] == ((byte)'\r') && bytes[bytes.Length - 1] == ((byte)'\n')) { encryptedBytes = new byte[bytes.Length - 4]; } else { encryptedBytes = new byte[bytes.Length]; } Buffer.BlockCopy(bytes, 0, encryptedBytes, 0, encryptedBytes.Length); byte[] decryptedBytes = this.key.Decrypt(encryptedBytes, this.iv); // log the decrypted data #if DEBUG this.decryptedRequest = Encoding.UTF8.GetString(decryptedBytes); #endif System.IO.MemoryStream stream = new System.IO.MemoryStream(decryptedBytes); using (stream) { GNTPStreamReader reader = new GNTPStreamReader(stream); using (reader) { // main headers while (!reader.EndOfStream) { string s = reader.ReadLine().Trim(); if (String.IsNullOrEmpty(s)) { // 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) { // a REGISTER request with no notifications is not valid OnError(ErrorCode.INVALID_REQUEST, ErrorDescription.NO_NOTIFICATIONS_REGISTERED); } } break; } 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); } } } } // any notification type headers if (this.expectedNotifications > 0) { while (!reader.EndOfStream) { string s = reader.ReadLine().Trim(); if (s == String.Empty) { this.expectedNotificationsRemaining--; if (this.expectedNotificationsRemaining > 0) { this.currentNotification++; } else { break; } } else { if (this.notificationsToBeRegistered.Count < this.currentNotification) { this.notificationsToBeRegistered.Add(new HeaderCollection()); } Header header = Header.ParseHeader(s); this.notificationsToBeRegistered[this.currentNotification - 1].AddHeader(header); } } } // now that we have read the stream, check for any embedded resources this.pointersExpected = GetNumberOfPointers(); if (this.pointersExpected > 0) { this.pointersExpectedRemaining = this.pointersExpected; this.currentPointer = 1; } } } }