/// <summary> /// Gets information about the remote host. /// Automatically creates and initializes a new instance of the HostInformation class when /// it is necessary. /// </summary> public HostInformation this[string uri] { get { lock (this.SyncRoot) { HostInformation hostInformation = this.Get(uri); if (hostInformation == null) { hostInformation = new HostInformation(uri, this.ITransportContext); this.UpdateHost(uri, hostInformation); // set a reasonable start up lifetime property value int expiration = GenuineUtility.ConvertToMilliseconds(this.ITransportContext.IParameterProvider[GenuineParameter.ConnectTimeout]); hostInformation.Renew(expiration, true); // LOG: BinaryLogWriter binaryLogWriter = GenuineLoggingServices.BinaryLogWriter; if (binaryLogWriter != null && binaryLogWriter[LogCategory.HostInformation] > 0) { binaryLogWriter.WriteEvent(LogCategory.HostInformation, "KnownHosts.this[string]", LogMessageType.HostInformationCreated, null, null, hostInformation, null, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, null, null, -1, 0, 0, 0, null, null, null, null, "The HostInformation has been created for the remote host: {0}.", uri); } } return(hostInformation); } } }
/// <summary> /// Registers the broadcast sender that sends a message to several receivers. /// Returns Guid (it's like URI for an MBR object) assigned for this sender that can be used /// to delete this broadcast sender later. /// </summary> /// <param name="generalBroadcastSender">The broadcast sender which sends a message via "true" multicast channel.</param> public string Add(GeneralBroadcastSender generalBroadcastSender) { // just add it as it would be the usual receiver ReceiverInfo receiverInfo = new ReceiverInfo(); receiverInfo.GeneralBroadcastSender = generalBroadcastSender; receiverInfo.Local = false; string uri = Guid.NewGuid().ToString("N") + "/" + generalBroadcastSender.Court; receiverInfo.MbrUri = uri; // register it using (WriterAutoLocker writer = new WriterAutoLocker(this._readerWriterLock)) { this._cachedReceiversInfoArray = null; this._receivers[uri] = receiverInfo; } // LOG: BinaryLogWriter binaryLogWriter = GenuineLoggingServices.BinaryLogWriter; if (binaryLogWriter != null && binaryLogWriter[LogCategory.BroadcastEngine] > 0) { binaryLogWriter.WriteBroadcastEngineEvent(LogCategory.BroadcastEngine, "Dispatcher.Add", LogMessageType.BroadcastRecipientAdded, null, null, null, null, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, null, null, false, this, null, true, receiverInfo, generalBroadcastSender.Court, generalBroadcastSender.ITransportContext.HostIdentifier, "The \"true\" multicast sender is added."); } return(uri); }
/// <summary> /// Checks whether the timeout has expired. /// </summary> public void TimerCallback() { lock (this) { if (this._isCompleted || this._isAborted) { return; } if (GenuineUtility.IsTimeoutExpired(this._timeoutExpiresAt)) { // TODO: remove this // LOG: BinaryLogWriter binaryLogWriter = GenuineLoggingServices.BinaryLogWriter; if (binaryLogWriter != null) { binaryLogWriter.WriteEvent(LogCategory.Debugging, "HttpWebRequestCop.TimerCallback", LogMessageType.DebuggingWarning, null, null, null, null, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, null, null, -1, 0, 0, 0, null, null, null, null, "Stopping the web request."); } this._isAborted = true; this._httpWebRequest.Abort(); } } }
/// <summary> /// Initiates an asynchronous operation. /// </summary> public void StartAsynchronousOperation() { // LOG: BinaryLogWriter binaryLogWriter = GenuineLoggingServices.BinaryLogWriter; try { this._socket.BeginSend(this._buffer, this._offset, this._size, SocketFlags.None, this._asyncCallback, this._state); // LOG: if (binaryLogWriter != null && binaryLogWriter[LogCategory.LowLevelTransport] > 0) { binaryLogWriter.WriteEvent(LogCategory.LowLevelTransport, "Async_InitiateSocketSending.StartAsynchronousOperation", LogMessageType.LowLevelTransport_AsyncSendingInitiated, null, null, null, new MemoryStream(this._buffer, this._offset, this._size), GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, null, null, -1, this._buffer.GetHashCode(), this._offset, this._size, null, null, null, null, "Sending has been initiated. Socket: {0}.", (long)this._socket.Handle); } } catch (Exception ex) { // LOG: if (binaryLogWriter != null && binaryLogWriter[LogCategory.LowLevelTransport] > 0) { binaryLogWriter.WriteEvent(LogCategory.LowLevelTransport, "Async_InitiateSocketSending.StartAsynchronousOperation", LogMessageType.LowLevelTransport_AsyncSendingInitiated, ex, null, null, new MemoryStream(this._buffer, this._offset, this._size), GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, null, null, -1, this._buffer.GetHashCode(), this._offset, this._size, null, null, null, null, "Sending cannot be initiated. Socket: {0}.", (long)this._socket.Handle); } } }
/// <summary> /// Requests processing from the current sink of the response from a method call sent asynchronously. /// It's a reply to a previously processed async call. /// Parameter state is expected to contain source message. /// </summary> /// <param name="sinkStack">A stack of sinks leading back to the server transport sink.</param> /// <param name="state">Information generated on the request side that is associated with this sink.</param> /// <param name="msg">The response message.</param> /// <param name="headers">The headers to add to the return message heading to the client.</param> /// <param name="stream">The stream heading back to the transport sink.</param> public void AsyncProcessResponse(IServerResponseChannelSinkStack sinkStack, object state, IMessage msg, ITransportHeaders headers, Stream stream) { Message message = (Message)state; BinaryLogWriter binaryLogWriter = message.ITransportContext.BinaryLogWriter; Message reply = new Message(message, headers, stream); // LOG: put down the log record if (binaryLogWriter != null && binaryLogWriter[LogCategory.MessageProcessing] > 0) { string invocationTarget = msg.Properties["__Uri"] as string; string methodName = BinaryLogWriter.ParseInvocationMethod(msg.Properties["__MethodName"] as string, msg.Properties["__TypeName"] as string); binaryLogWriter.WriteMessageCreatedEvent("GenuineUniversalServerTransportSink.AsyncProcessResponse", LogMessageType.MessageCreated, null, reply, false, reply.Recipient, this.ITransportContext.BinaryLogWriter[LogCategory.MessageProcessing] > 1 ? reply.Stream : null, invocationTarget, methodName, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, null, -1, -1, null, -1, null, "The response message has been created."); reply.ITransportHeaders[Message.TransportHeadersInvocationTarget] = invocationTarget; reply.ITransportHeaders[Message.TransportHeadersMethodName] = methodName; binaryLogWriter.WriteEvent(LogCategory.MessageProcessing, "GenuineUniversalServerTransportSink.AsyncProcessResponse", LogMessageType.MessageRequestInvoked, null, reply, message.Sender, null, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, null, null, -1, GenuineUtility.TickCount, 0, message.SeqNo, null, null, null, null, "The .NET Remoting invocation has been performed."); } message.ITransportContext.ConnectionManager.Send(reply); }
/// <summary> /// Initiates an asynchronous operation. /// </summary> public void StartAsynchronousOperation() { // LOG: BinaryLogWriter binaryLogWriter = GenuineLoggingServices.BinaryLogWriter; try { this._socket.BeginReceive(this._buffer, this._offset, this._size, SocketFlags.None, this._asyncCallback, this._state); // LOG: if (binaryLogWriter != null && binaryLogWriter[LogCategory.LowLevelTransport] > 0) { binaryLogWriter.WriteEvent(LogCategory.LowLevelTransport, "Async_InitiateSocketReceiving.StartAsynchronousOperation", LogMessageType.LowLevelTransport_AsyncReceivingInitiated, null, null, null, null, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, null, null, -1, 0, 0, 0, null, null, null, null, "Socket.BeginReceive(). Socket: {0}. Buffer: {1}. Offset: {2}. Size: {3}.", (long)this._socket.Handle, this._buffer.GetHashCode(), this._offset, this._size); } } catch (Exception ex) { // LOG: if (binaryLogWriter != null && binaryLogWriter[LogCategory.LowLevelTransport] > 0) { binaryLogWriter.WriteEvent(LogCategory.LowLevelTransport, "Async_InitiateSocketReceiving.StartAsynchronousOperation", LogMessageType.LowLevelTransport_AsyncReceivingInitiated, ex, null, null, null, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, null, null, -1, this._buffer.GetHashCode(), this._offset, this._size, null, null, null, null, "Socket.BeginReceive(). Socket: {0}. Buffer: {1}. Offset: {2}. Size: {3}.", (long)this._socket.Handle, this._buffer.GetHashCode(), this._offset, this._size); } } }
/// <summary> /// Associates the provided key provider with the specified Security Session name. /// Removes the record if iKeyProvider is a null reference. /// </summary> /// <param name="name">The name of Security Context.</param> /// <param name="iKeyProvider">The key provider or a null reference.</param> public static void SetGlobalKey(string name, IKeyProvider iKeyProvider) { BinaryLogWriter binaryLogWriter = GenuineLoggingServices.BinaryLogWriter; if (iKeyProvider == null) { // LOG: if (binaryLogWriter != null && binaryLogWriter[LogCategory.Security] > 0) { binaryLogWriter.WriteEvent(LogCategory.Security, "SecuritySessionServices.SetGlobalKey", LogMessageType.KeyProviderDissociated, null, null, null, null, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, null, null, -1, 0, 0, 0, iKeyProvider.ToString(), name, null, null, "The Key Provider (\"{0}\") has been dissociated from the \"{1}\" name.", iKeyProvider.ToString(), name); } _globalKeys.Remove(name); } else { if (binaryLogWriter != null && binaryLogWriter[LogCategory.Security] > 0) { binaryLogWriter.WriteEvent(LogCategory.Security, "SecuritySessionServices.SetGlobalKey", LogMessageType.KeyProviderAssociated, null, null, null, null, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, null, null, -1, 0, 0, 0, iKeyProvider.ToString(), name, null, null, "The Key Provider (\"{0}\") has been associated with the \"{1}\" name.", iKeyProvider.ToString(), name); } _globalKeys[name] = iKeyProvider; } }
/// <summary> /// Initializes encryptor and decryptor. /// </summary> protected override void SessionEstablished() { lock (this) { Rijndael rijndael = Rijndael.Create(); rijndael.Key = this.RijndaelKey; rijndael.Mode = CipherMode.ECB; if (this._encryptor == null) { this._encryptor = rijndael.CreateEncryptor(); this._decryptor = rijndael.CreateDecryptor(); } // LOG: BinaryLogWriter binaryLogWriter = GenuineLoggingServices.BinaryLogWriter; if (binaryLogWriter != null && binaryLogWriter[LogCategory.Security] > 0) { binaryLogWriter.WriteEvent(LogCategory.Security, "SecuritySession_SelfEstablishingSymmetric.SessionEstablished", LogMessageType.SecuritySessionKey, null, null, this.Remote, null, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, this, this.Name, -1, 0, 0, 0, "Encryption with " + rijndael.GetType().ToString(), null, null, null, "Security Session security information is initialized."); } } base.SessionEstablished(); }
/// <summary> /// Informs all dependent entities that the Security Session has been established. /// </summary> protected override void SessionEstablished() { // LOG: BinaryLogWriter binaryLogWriter = GenuineLoggingServices.BinaryLogWriter; if (binaryLogWriter != null && binaryLogWriter[LogCategory.Security] > 0) { WindowsIdentity windowsIdentity = this.WindowsIdentity; binaryLogWriter.WriteEvent(LogCategory.Security, "SecuritySession_SspiServer.SessionEstablished", LogMessageType.SecuritySessionKey, null, null, this.Remote, null, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, this, this.Name, -1, 0, 0, 0, string.Format("SSPI Package: {0} Features: {1} Win Auth Type: {2} IsAnonymous: {3} IsGuest: {4} IsSystem: {5} Name: {6}", this.KeyProvider_SspiServer.PackageName, Enum.Format(typeof(SspiFeatureFlags), this.KeyProvider_SspiServer.RequiredFeatures, "g"), windowsIdentity.AuthenticationType, windowsIdentity.IsAnonymous, windowsIdentity.IsGuest, windowsIdentity.IsSystem, windowsIdentity.Name), null, null, null, "Security Session security information is initialized."); } this._isEstablished.Set(); SendAssociatedMessages(); }
/// <summary> /// Stops listening to the specified end point. Does not close any connections. /// </summary> /// <param name="endPoint">The end point</param> public override void StopListening(object endPoint) { lock (this) { if (this._socket == null) { return; } // LOG: BinaryLogWriter binaryLogWriter = this.ITransportContext.BinaryLogWriter; if (binaryLogWriter != null && binaryLogWriter[LogCategory.Connection] > 0) { binaryLogWriter.WriteEvent(LogCategory.Connection, "UdpConnectionManager.StopListening", LogMessageType.ListeningStopped, null, null, null, null, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, null, null, this.DbgConnectionId, 0, 0, 0, null, null, null, null, "The listening socket is not longer associated with the {0} local end point.", endPoint == null ? string.Empty : endPoint.ToString()); } SocketUtility.CloseSocket(this._socket); this._socket = null; this._closing = true; } if (!this._receivingThreadClosed.WaitOne(TimeSpan.FromMinutes(2), false)) { throw GenuineExceptions.Get_Processing_LogicError("Receiving thread didn't exit within 2 minutes."); } }
// /// <summary> // /// The moment when this request was received. // /// </summary> // public int Received = GenuineUtility.TickCount; /// <summary> /// Completes the asynchronous invocation. /// </summary> /// <param name="completedSynchronously">True if the request was completed synchronously.</param> public void Complete(bool completedSynchronously) { try { this._completedSynchronously = completedSynchronously; this._asyncWaitHandle.Set(); if (this.AsyncCallback != null) { this.AsyncCallback.DynamicInvoke(new object[] { (IAsyncResult)this }); } } catch (Exception ex) { // LOG: BinaryLogWriter binaryLogWriter = GenuineLoggingServices.BinaryLogWriter; if (binaryLogWriter != null) { binaryLogWriter.WriteImplementationWarningEvent("HttpServerRequestResult.Complete", LogMessageType.CriticalError, ex, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, "Fatal logic error."); } } }
/// <summary> /// Returns the filtered array of the ReceiverInfo instances. /// </summary> /// <param name="arrayOfReceiverInfo">The list of receivers being filtered out.</param> /// <param name="iMessage">The invocation.</param> /// <param name="resultCollector">The Result Collector obtaining the list of receivers. Is used for debugging purposes only.</param> public void GetListOfReceivers(out object[] arrayOfReceiverInfo, IMessage iMessage, ResultCollector resultCollector) { arrayOfReceiverInfo = null; try { using (ReaderAutoLocker reader = new ReaderAutoLocker(this._readerWriterLock)) { // check whether they were cached if (this._cachedReceiversInfoArray == null) { this._cachedReceiversInfoArray = new object[this._receivers.Values.Count]; this._receivers.Values.CopyTo(this._cachedReceiversInfoArray, 0); } // get the cached array arrayOfReceiverInfo = this._cachedReceiversInfoArray; // and drive it thru the filter IMulticastFilter iMulticastFilter = Dispatcher.GetCurrentFilter(); if (iMulticastFilter == null) { iMulticastFilter = this.IMulticastFilter; } if (iMulticastFilter != null) { // LOG: BinaryLogWriter binaryLogWriter = GenuineLoggingServices.BinaryLogWriter; if (binaryLogWriter != null && binaryLogWriter[LogCategory.BroadcastEngine] > 0) { binaryLogWriter.WriteBroadcastEngineEvent(LogCategory.BroadcastEngine, "Dispatcher.GetListOfReceivers", LogMessageType.BroadcastFilterCalled, null, null, null, null, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, null, null, false, this, resultCollector, false, null, iMulticastFilter.GetType().ToString(), null, "The broadcast filter is called. The type of the filter: {0}.", iMulticastFilter.GetType().ToString()); } arrayOfReceiverInfo = iMulticastFilter.GetReceivers(arrayOfReceiverInfo, iMessage); } } } catch (Exception ex) { // LOG: BinaryLogWriter binaryLogWriter = GenuineLoggingServices.BinaryLogWriter; if (binaryLogWriter != null && binaryLogWriter[LogCategory.BroadcastEngine] > 0) { binaryLogWriter.WriteBroadcastEngineEvent(LogCategory.BroadcastEngine, "Dispatcher.GetListOfReceivers", LogMessageType.BroadcastFilterCalled, ex, null, null, null, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, null, null, false, this, resultCollector, false, null, null, null, "The exception occurred while calling the broadcast filter."); } } }
/// <summary> /// Sends a message synchronously. Does not process exceptions! /// </summary> /// <param name="content">The content being sent to the remote host.</param> /// <param name="timeout">The sending must be completed before this moment.</param> public void LowLevel_SendSync(Stream content, int timeout) { // apply the connection-level security session if (this.ConnectionLevelSecurity != null) { GenuineChunkedStream outputStream = new GenuineChunkedStream(true); this.ConnectionLevelSecurity.Encrypt(content, outputStream); content = outputStream; } for ( ; ;) { if (!this.IsValid) { throw GenuineExceptions.Get_Processing_TransportConnectionFailed(); } if (!GenuineUtility.WaitOne(_namedEventRemoteReadCompleted.ManualResetEvent, GenuineUtility.GetMillisecondsLeft(timeout))) { throw GenuineExceptions.Get_Send_Timeout(); } if (this._closed != 0) { throw GenuineExceptions.Get_Receive_ConnectionClosed(); } this._namedEventRemoteReadCompleted.ManualResetEvent.Reset(); // read the next portion int bytesRead = content.Read(this._sendBuffer, 0, this._sendSpaceSize); // LOG: BinaryLogWriter binaryLogWriter = this.ITransportContext.BinaryLogWriter; if (binaryLogWriter != null && binaryLogWriter[LogCategory.LowLevelTransport] > 0) { binaryLogWriter.WriteTransportContentEvent(LogCategory.LowLevelTransport, "GenuineSaredMemoryConnection.LowLevel_SendSync", LogMessageType.LowLevelTransport_AsyncSendingInitiating, null, null, this.Remote, binaryLogWriter[LogCategory.LowLevelTransport] > 1 ? new MemoryStream(this._sendBuffer, 0, bytesRead) : null, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, this.DbgConnectionId, bytesRead, null, null, null, "Content sending."); } Marshal.Copy(this._sendBuffer, 0, (IntPtr)(this._pointer.ToInt32() + this._sendOffset + SHARE_CONTENT_OFFSET), bytesRead); this._MessageToSendTotalSize = bytesRead; this._MessageToSendFinishFlag = bytesRead < this._sendSpaceSize ? 1 : 0; this._namedEventWriteCompleted.ManualResetEvent.Set(); if (bytesRead < this._sendSpaceSize) { this.UpdateLastTimeAMessageWasSent(); return; } } }
/// <summary> /// Writes a sequence of bytes to the current stream and advances the current position within this stream by the number of bytes written. /// </summary> /// <param name="buffer">An array of bytes.</param> /// <param name="offset">The zero-based byte offset in buffer at which to begin copying bytes to the current stream.</param> /// <param name="count">The number of bytes to be written to the current stream.</param> public override void Write(byte[] buffer, int offset, int count) { BinaryLogWriter binaryLogWriter = this._remote.ITransportContext.BinaryLogWriter; try { while (count > 0) { int milliseconds = GenuineUtility.GetMillisecondsLeft(this._writeTimeout); if (milliseconds <= 0) { throw GenuineExceptions.Get_Send_Timeout(); } this._socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.SendTimeout, milliseconds); int bytesSent = this._socket.Send(buffer, offset, count, SocketFlags.None); // LOG: if (binaryLogWriter != null && binaryLogWriter[LogCategory.LowLevelTransport] > 0) { binaryLogWriter.WriteTransportContentEvent(LogCategory.LowLevelTransport, "SyncSocketWritingStream.Write", LogMessageType.LowLevelTransport_SyncSendingCompleted, null, null, this._remote, binaryLogWriter[LogCategory.LowLevelTransport] > 1 ? new MemoryStream(GenuineUtility.CutOutBuffer(buffer, offset, count)) : null, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, this._dbgConnectionId, count, this._socket.RemoteEndPoint.ToString(), null, null, "Immediately after Socket.Send(). Size: {0}. Sent: {1}.", count, bytesSent); } if (bytesSent == 0) { throw GenuineExceptions.Get_Send_TransportProblem(); } offset += bytesSent; count -= bytesSent; this._connectionManager.IncreaseBytesSent(bytesSent); } } catch (Exception ex) { // LOG: if (binaryLogWriter != null && binaryLogWriter[LogCategory.LowLevelTransport] > 0) { binaryLogWriter.WriteTransportContentEvent(LogCategory.LowLevelTransport, "SyncSocketWritingStream.Write", LogMessageType.LowLevelTransport_SyncSendingCompleted, ex, null, this._remote, binaryLogWriter[LogCategory.LowLevelTransport] > 1 ? new MemoryStream(GenuineUtility.CutOutBuffer(buffer, offset, count)) : null, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, this._dbgConnectionId, count, null, null, null, "Socket.Send(); ERROR."); } throw GenuineExceptions.Get_Send_TransportProblem(); } }
/// <summary> /// Releases all acquired resources. /// Warning: must be called only by the instance of the KnownHosts class. /// </summary> /// <param name="reason">The reason of resource releasing.</param> /// <returns>False if host resources have already been released before this call.</returns> internal bool Dispose(Exception reason) { if (this.IsDisposed) { return(false); } lock (this.DisposeLock) { if (this.IsDisposed) { return(false); } this._isDisposed = true; this.DisposeReason = reason; // LOG: BinaryLogWriter binaryLogWriter = this.ITransportContext.BinaryLogWriter; if (binaryLogWriter != null && binaryLogWriter[LogCategory.HostInformation] > 0) { string stackTrace = String.Empty; try { stackTrace = Environment.StackTrace; } catch { } binaryLogWriter.WriteEvent(LogCategory.HostInformation, "HostInformation.Dispose", LogMessageType.HostInformationReleased, reason, null, this, null, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, null, null, -1, 0, 0, 0, this.Uri, this.Url, null, null, "The HostInformation is released. The caller: {0}.", stackTrace); } // release all Security Sessions that need this lock (this._securitySessions) { foreach (DictionaryEntry entry in this._securitySessions) { IDisposable iDisposable = entry.Value as IDisposable; if (iDisposable != null) { iDisposable.Dispose(); } } this._securitySessions.Clear(); } } return(true); }
/// <summary> /// Constructs an instance of the SecuritySession_Basic class. /// </summary> /// <param name="name">The name of the security context.</param> public SecuritySession_Basic(string name) : base(name, null) { this.IsEstablishedEvent.Set(); // LOG: BinaryLogWriter binaryLogWriter = GenuineLoggingServices.BinaryLogWriter; if (binaryLogWriter != null && binaryLogWriter[LogCategory.Security] > 0) { binaryLogWriter.WriteEvent(LogCategory.Security, "SecuritySession_Basic.SecuritySession_Basic", LogMessageType.SecuritySessionKey, null, null, this.Remote, null, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, this, this.Name, -1, 0, 0, 0, "No security features supported.", null, null, null, "This Security Session does not require establishing."); } }
/// <summary> /// Sets up all security stuff for encrypting content and checking integrity. /// </summary> /// <param name="password">The password.</param> protected void SetupSecurityAlgorithms(string password) { lock (this) { if ((this.ZpaFeatureFlags & ZpaFeatureFlags.ElectronicCodebookEncryption) != 0 || (this.ZpaFeatureFlags & ZpaFeatureFlags.CipherBlockChainingEncryption) != 0) { // encryption this.SymmetricAlgorithm = Rijndael.Create(); this.SymmetricAlgorithm.Key = ZeroProofAuthorizationUtility.GeneratePasswordBasedSequence("Key" + password, this.Salt, 32); this.SymmetricAlgorithm.IV = ZeroProofAuthorizationUtility.GeneratePasswordBasedSequence("IV" + password, this.Salt, 16); this.SymmetricAlgorithm.Mode = (this.ZpaFeatureFlags & ZpaFeatureFlags.ElectronicCodebookEncryption) != 0 ? CipherMode.ECB : CipherMode.CBC; this._encryptor = this.SymmetricAlgorithm.CreateEncryptor(); this._decryptor = this.SymmetricAlgorithm.CreateDecryptor(); } // and integrity checking if ((this.ZpaFeatureFlags & ZpaFeatureFlags.Mac3DesCbcSigning) != 0) { this.KeyedHashAlgorithm = MACTripleDES.Create(); } if ((this.ZpaFeatureFlags & ZpaFeatureFlags.HmacSha1Signing) != 0) { this.KeyedHashAlgorithm = HMACSHA1.Create(); } if (this.KeyedHashAlgorithm != null) { this.KeyedHashAlgorithm.Key = ZeroProofAuthorizationUtility.GeneratePasswordBasedSequence("M3D" + password, this.Salt, 24); } // LOG: BinaryLogWriter binaryLogWriter = GenuineLoggingServices.BinaryLogWriter; if (binaryLogWriter != null && binaryLogWriter[LogCategory.Security] > 0) { binaryLogWriter.WriteEvent(LogCategory.Security, "SecuritySession_BaseZpaSession.SetupSecurityAlgorithms", LogMessageType.SecuritySessionKey, null, null, this.Remote, null, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, this, this.Name, -1, 0, 0, 0, string.Format("Zero Proof Authorization Flags: {0} Encryption: {1} Data Integrity: {2}", Enum.Format(typeof(ZpaFeatureFlags), this.ZpaFeatureFlags, "g"), this.SymmetricAlgorithm == null ? "No" : this.SymmetricAlgorithm.GetType().ToString(), this.KeyedHashAlgorithm == null ? "No" : this.KeyedHashAlgorithm.GetType().ToString()), null, null, null, "Security Session security information is initialized."); } } }
/// <summary> /// Exludes the message from the queue. /// </summary> /// <returns>The message or a null reference.</returns> public Message GetMessage() { Message message = null; using (new ReaderAutoLocker(this._disposeLock)) { if (this._disposed) { return(null); } lock (this._queue) { if (this._queue.Count > 0) { message = (Message)this._queue.Dequeue(); } // correct queue total size if (message != null) { this._currentTotalMessages--; this._currentTotalSize -= message.EffectiveMessageSize; // reflect the change in the queue state if (message.Recipient != null) { message.Recipient.QueueLength = this._queue.Count; } // LOG: BinaryLogWriter binaryLogWriter = this._iTransportContext.BinaryLogWriter; if (binaryLogWriter != null && binaryLogWriter[LogCategory.MessageProcessing] > 0) { binaryLogWriter.WriteEvent(LogCategory.MessageProcessing, "MessageContainer.GetMessage", LogMessageType.MessageHasBeenDequeued, null, message, message.Recipient, null, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, null, null, -1, 0, 0, 0, null, null, null, null, "The message has been dequeued. Messages in the queue: {0}. Queue size: {1}.", this._currentTotalMessages, this._currentTotalSize); } } } } return(message); }
/// <summary> /// Releases all resources related to the specified connection. /// </summary> /// <param name="exception">The reason.</param> /// <param name="sharedMemoryConnection">The connection.</param> private void ConnectionFailed(Exception exception, SharedMemoryConnection sharedMemoryConnection) { BinaryLogWriter binaryLogWriter = this.ITransportContext.BinaryLogWriter; try { sharedMemoryConnection.IsValid = false; // LOG: if (binaryLogWriter != null && binaryLogWriter[LogCategory.Connection] > 0) { binaryLogWriter.WriteEvent(LogCategory.Connection, "SharedMemoryConnectionManager.ConnectionFailed", LogMessageType.ConnectionFailed, exception, null, sharedMemoryConnection.Remote, null, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, null, null, sharedMemoryConnection.DbgConnectionId, 0, 0, 0, null, null, null, null, "Connection has failed."); } // unregister the connection if (sharedMemoryConnection.Remote.GenuinePersistentConnectionState == GenuinePersistentConnectionState.Accepted) { this._persistent.Remove(sharedMemoryConnection.Remote.Uri); } else { this._persistent.Remove(sharedMemoryConnection.Remote.Url); } // release all resources this.ITransportContext.KnownHosts.ReleaseHostResources(sharedMemoryConnection.Remote, exception); sharedMemoryConnection.ReleaseUnmanagedResources(); sharedMemoryConnection.SignalState(GenuineEventType.GeneralConnectionClosed, exception, null); } catch (Exception ex) { // LOG: if (binaryLogWriter != null) { binaryLogWriter.WriteImplementationWarningEvent("SharedMemoryConnectionManager.ConnectionFailed", LogMessageType.CriticalError, ex, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, "Unexpected exception inside the SharedMemoryClientConnectionManager.ConnectionFailed method. Most likely, something must be fixed."); } } }
/// <summary> /// Informs all dependent entities that the Security Session has been established. /// </summary> protected virtual void SessionEstablished() { BinaryLogWriter binaryLogWriter = GenuineLoggingServices.BinaryLogWriter; // LOG: if (binaryLogWriter != null && binaryLogWriter[LogCategory.Security] > 0) { binaryLogWriter.WriteEvent(LogCategory.Security, "SecuritySession.SessionEstablished", LogMessageType.SecuritySessionEstablished, null, null, this.Remote, null, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, this, this.Name, -1, 0, 0, 0, null, null, null, null, "Security Session has been established."); } this._isEstablished.Set(); SendAssociatedMessages(); }
/// <summary> /// Initiates establishing Security Session with specific remote host via specified IConnectionManager. /// </summary> /// <param name="securitySessionParameters">Security Session parameters.</param> public void InitiateEstablishingSecuritySession(SecuritySessionParameters securitySessionParameters) { BinaryLogWriter binaryLogWriter = GenuineLoggingServices.BinaryLogWriter; if (binaryLogWriter != null && binaryLogWriter[LogCategory.Security] > 0) { binaryLogWriter.WriteEvent(LogCategory.Security, "SecuritySession.InitiateEstablishingSecuritySession", LogMessageType.SecuritySessionInitiated, null, null, this.Remote, null, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, this, this.Name, -1, 0, 0, 0, this.GetType().Name, this.Name, null, null, "Security Session establishing is initiated."); } this.Failed.Reset(); this._establishingSecuritySessionParameters = securitySessionParameters; GenuineThreadPool.QueueUserWorkItem(new WaitCallback(this.Internal_InitiateEstablishingSecuritySession), securitySessionParameters, false); }
/// <summary> /// Reads messages from the connection and processes them synchronously. /// </summary> public void ReceiveSynchronously() { try { for ( ; ;) { if (!this.SharedMemoryConnection.IsValid) { return; } using (Stream stream = this.SharedMemoryConnection.LowLevel_ReadSync(GenuineUtility.GetTimeout(this.SharedMemoryConnection._closeAfterInactivity))) { // receive the message GenuineChunkedStream theMessage = new GenuineChunkedStream(true); GenuineUtility.CopyStreamToStream(stream, theMessage); // a message was successfully received this.SharedMemoryConnection.Renew(); if (theMessage.Length == 0) { // LOG: BinaryLogWriter binaryLogWriter = this.SharedMemoryConnectionManager.ITransportContext.BinaryLogWriter; if (binaryLogWriter != null && binaryLogWriter[LogCategory.Connection] > 0) { binaryLogWriter.WriteEvent(LogCategory.Connection, "SharedMemoryConnectionManager.ReceiveSynchronously", LogMessageType.ConnectionPingReceived, null, null, null, null, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, null, null, this.SharedMemoryConnection.DbgConnectionId, 0, 0, 0, null, null, null, null, "A message with zero size is treated as ping."); } continue; } this.SharedMemoryConnectionManager.ITransportContext.IIncomingStreamHandler.HandleMessage(theMessage, this.SharedMemoryConnection.Remote, GenuineConnectionType.Persistent, null, this.SharedMemoryConnection.DbgConnectionId, false, null, this.SharedMemoryConnection.ConnectionLevelSecurity, null); this.SharedMemoryConnection.Renew(); } } } catch (Exception ex) { this.SharedMemoryConnectionManager.ConnectionFailed(ex, this.SharedMemoryConnection); } }
/// <summary> /// Reads data from the socket. /// </summary> /// <param name="buffer">An array of type Byte that is the storage location for received data.</param> /// <param name="offset">The location in buffer to store the received data.</param> /// <param name="count">The number of bytes to receive.</param> /// <returns>The number of bytes read.</returns> public int ReadFromSocket(byte[] buffer, int offset, int count) { BinaryLogWriter binaryLogWriter = this._tcpConnectionManager.ITransportContext.BinaryLogWriter; try { int millisecondsRemained = GenuineUtility.GetMillisecondsLeft(this._receiveTimeout); if (millisecondsRemained <= 0) { throw GenuineExceptions.Get_Send_ServerDidNotReply(); } this._tcpSocketInfo.Socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, millisecondsRemained); int bytesReceived = this._tcpSocketInfo.Socket.Receive(buffer, offset, count, SocketFlags.None); // LOG: if (binaryLogWriter != null && binaryLogWriter[LogCategory.LowLevelTransport] > 0) { binaryLogWriter.WriteTransportContentEvent(LogCategory.LowLevelTransport, "SyncSocketReadingStream.ReadFromSocket", LogMessageType.LowLevelTransport_SyncReceivingCompleted, null, null, this._tcpSocketInfo.Remote, binaryLogWriter[LogCategory.LowLevelTransport] > 1 ? new MemoryStream(buffer, offset, bytesReceived) : null, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, this._tcpSocketInfo.DbgConnectionId, bytesReceived, this._tcpSocketInfo.Socket.RemoteEndPoint.ToString(), null, null, "Socket.Receive(). Bytes received: {0}.", bytesReceived); } this._tcpConnectionManager.IncreaseBytesReceived(bytesReceived); return(bytesReceived); } catch (Exception ex) { // LOG: if (binaryLogWriter != null && binaryLogWriter[LogCategory.LowLevelTransport] > 0) { binaryLogWriter.WriteEvent(LogCategory.LowLevelTransport, "SyncSocketReadingStream.ReadFromSocket", LogMessageType.LowLevelTransport_SyncReceivingCompleted, ex, null, this._tcpSocketInfo.Remote, null, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, null, null, this._tcpSocketInfo.DbgConnectionId, 0, 0, 0, null, null, null, null, "Socket.Receive() failed."); } throw; } }
/// <summary> /// Initializes an instance of the SecuritySession class. /// </summary> /// <param name="name">The name of the Security Session.</param> /// <param name="remote">Information about remote host.</param> public SecuritySession(string name, HostInformation remote) { this._name = name; this.Remote = remote; // LOG: BinaryLogWriter binaryLogWriter = GenuineLoggingServices.BinaryLogWriter; if (binaryLogWriter != null && binaryLogWriter[LogCategory.Security] > 0) { binaryLogWriter.WriteEvent(LogCategory.Security, "SecuritySession.SecuritySession", LogMessageType.SecuritySessionCreated, null, null, remote, null, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, this, name, -1, 0, 0, 0, this.GetType().Name, null, null, null, "Security Session has been created."); } }
/// <summary> /// Closes the specified connections to the remote host and releases acquired resources. /// </summary> /// <param name="hostInformation">The host information.</param> /// <param name="genuineConnectionType">A value indicating what kind of connections will be affected by this operation.</param> /// <param name="reason">The reason of resource releasing.</param> public override void ReleaseConnections(HostInformation hostInformation, GenuineConnectionType genuineConnectionType, Exception reason) { BinaryLogWriter binaryLogWriter = this.ITransportContext.BinaryLogWriter; reason = GenuineExceptions.Get_Channel_ConnectionShutDown(reason); // LOG: if (binaryLogWriter != null && binaryLogWriter[LogCategory.Connection] > 0) { binaryLogWriter.WriteEvent(LogCategory.Connection, "SharedMemoryConnectionManager.ReleaseConnections", LogMessageType.ReleaseConnections, reason, null, hostInformation, null, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, null, null, -1, 0, 0, 0, Enum.Format(typeof(GenuineConnectionType), genuineConnectionType, "g"), null, null, null, "Connections \"{0}\" will be terminated.", Enum.Format(typeof(GenuineConnectionType), genuineConnectionType, "g"), null); } if (hostInformation == null) { this.InternalDispose(reason); return; } SharedMemoryConnection sharedMemoryConnection = null; if (hostInformation.Url != null) { sharedMemoryConnection = this._persistent[hostInformation.Url] as SharedMemoryConnection; } if (sharedMemoryConnection != null) { this.ConnectionFailed(reason, sharedMemoryConnection); } sharedMemoryConnection = null; if (hostInformation.Uri != null) { sharedMemoryConnection = this._persistent[hostInformation.Uri] as SharedMemoryConnection; } if (sharedMemoryConnection != null) { this.ConnectionFailed(reason, sharedMemoryConnection); } }
/// <summary> /// Resets the status of reestablishing. /// </summary> public void Reestablish_ResetStatus() { lock (this._accessToLocalMembers) { if (!_reestablish_IsBeingReestablished) { BinaryLogWriter binaryLogWriter = GenuineLoggingServices.BinaryLogWriter; if (binaryLogWriter != null) { binaryLogWriter.WriteImplementationWarningEvent("PhysicalConnection.Reestablish_ResetStatus", LogMessageType.Error, GenuineExceptions.Get_Debugging_GeneralWarning("The connection is not being reestablished!"), GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, "The connection is not being reestablished!"); } } _reestablish_IsBeingReestablished = false; } }
/// <summary> /// Initializes an instance of the SecuritySession_KnownSymmetric class. /// </summary> /// <param name="symmetricAlgorithm">The symmetricAlgorithm to be used.</param> /// <param name="name">The name of the security context.</param> public SecuritySession_KnownSymmetric(SymmetricAlgorithm symmetricAlgorithm, string name) : base(name, null) { // LOG: BinaryLogWriter binaryLogWriter = GenuineLoggingServices.BinaryLogWriter; if (binaryLogWriter != null && binaryLogWriter[LogCategory.Security] > 0) { binaryLogWriter.WriteEvent(LogCategory.Security, "SecuritySession_KnownSymmetric.SecuritySession_KnownSymmetric", LogMessageType.SecuritySessionKey, null, null, this.Remote, null, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, this, name, -1, 0, 0, 0, "Encryption using " + symmetricAlgorithm.GetType().ToString(), null, null, null, "Security Session security information is initialized."); } this.SymmetricAlgorithm = symmetricAlgorithm; this._encryptor = this.SymmetricAlgorithm.CreateEncryptor(); this._decryptor = this.SymmetricAlgorithm.CreateDecryptor(); this.IsEstablishedEvent.Set(); }
/// <summary> /// Stops listening to the specified end point. Does not close any connections. /// </summary> /// <param name="endPoint">The end point</param> public override void StopListening(object endPoint) { BinaryLogWriter binaryLogWriter = this.ITransportContext.BinaryLogWriter; if (this._smAcceptConnectionClosure != null) { // LOG: if (binaryLogWriter != null && binaryLogWriter[LogCategory.Connection] > 0) { binaryLogWriter.WriteEvent(LogCategory.AcceptingConnection, "SharedMemoryConnectionManager.StopListening", LogMessageType.ListeningStopped, null, null, null, null, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, null, null, -1, 0, 0, 0, this._smAcceptConnectionClosure.ShareName, null, null, null, "\"{0}\" is not now listened.", this._smAcceptConnectionClosure.ShareName); } this._smAcceptConnectionClosure.StopListening.Set(); this._smAcceptConnectionClosure = null; } }
/// <summary> /// Removes the receiver or the broadcast sender associated with the specified uri. /// Returns false if there is no such receiver found in the list of receivers. /// </summary> /// <param name="uri">The uri of the receiver.</param> public bool Remove(string uri) { if (uri == null || uri.Length <= 0) { return(false); } using (WriterAutoLocker writer = new WriterAutoLocker(this._readerWriterLock)) { // check if it is in the list if (!this._receivers.ContainsKey(uri)) { return(false); } this._cachedReceiversInfoArray = null; ReceiverInfo receiverInfo = (ReceiverInfo)this._receivers[uri]; this._receivers.Remove(uri); // LOG: BinaryLogWriter binaryLogWriter = GenuineLoggingServices.BinaryLogWriter; if (binaryLogWriter != null && binaryLogWriter[LogCategory.BroadcastEngine] > 0) { binaryLogWriter.WriteBroadcastEngineEvent(LogCategory.BroadcastEngine, "Dispatcher.Remove", LogMessageType.BroadcastRecipientRemoved, null, null, receiverInfo.DbgRemoteHost, null, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, null, null, false, this, null, true, receiverInfo, uri, null, "The broadcast recipient or \"true\" broadcast sender is removed from the list of recipients."); } // Sponsor is being deleted in another thread; otherwise client disconnection // will cause dispatcher to be freezed for lengthy time out GenuineThreadPool.QueueUserWorkItem(new WaitCallback(this.DeleteSponsorFromTheObjectAndFireEvent), receiverInfo, false); } return(true); }
/// <summary> /// Decreases all queue counters according to the provided message. /// WARNING: Releases all message resoruces. /// </summary> /// <param name="message">The message.</param> public void UnregisterSyncMessage(Message message) { lock (this._queue) { this._currentTotalMessages--; this._currentTotalSize -= message.EffectiveMessageSize; if (this._currentTotalMessages < 0 || this._currentTotalSize < 0) { // LOG: BinaryLogWriter binaryLogWriter = GenuineLoggingServices.BinaryLogWriter; if (binaryLogWriter != null) { binaryLogWriter.WriteImplementationWarningEvent("MessageContainer.UnregisterSyncMessage", LogMessageType.CriticalError, GenuineExceptions.Get_Debugging_GeneralWarning("Implementation bug."), GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, "Incorrect queue state. CurrentTotalMessages = {0}. CurrentTotalSize = {1}.", this._currentTotalMessages, this._currentTotalSize); } } } }