/// <summary> /// Collects expired elements. /// </summary> /// <param name="collectedHosts">The collected items.</param> /// <param name="now">The current moment.</param> private void CollectExpiredHostInformation(ArrayList collectedHosts, int now) { #if DEBUG if (GenuineUtility.IsDebuggingModeEnabled) { return; } #endif lock (this.SyncRoot) { // by all uris foreach (DictionaryEntry entry in this._hashtable) { ArrayList arrayList = (ArrayList)entry.Value; // all available hosts for (int i = 0; i < arrayList.Count;) { HostInformation hostInformation = (HostInformation)arrayList[i]; if (GenuineUtility.IsTimeoutExpired(hostInformation.ExpireTime, now) || hostInformation.IsDisposed) { collectedHosts.Add(hostInformation); arrayList.RemoveAt(i); continue; } i++; } } } }
/// <summary> /// Sends the content to the specified remote host and returns a response sent by the remote /// host in reply. /// </summary> /// <param name="destination">The remote host.</param> /// <param name="serviceName">The name of the service.</param> /// <param name="content">The content.</param> /// <returns>The response.</returns> public Stream SendSync(HostInformation destination, string serviceName, Stream content) { // create the message Message message = new Message(this.ITransportContext, destination, 0, new TransportHeaders(), content); message.IsSynchronous = true; message.GenuineMessageType = GenuineMessageType.ExternalStreamConsumer; message.DestinationMarshalByRef = serviceName; // register the response catcher SyncResponseProcessorWithEvent syncResponseProcessorWithEvent = new SyncResponseProcessorWithEvent(message); this.ITransportContext.IIncomingStreamHandler.RegisterResponseProcessor(message.MessageId, syncResponseProcessorWithEvent); // and send the message this.ITransportContext.ConnectionManager.Send(message); int timeSpanInMilliseconds = GenuineUtility.GetMillisecondsLeft(message.FinishTime); if (timeSpanInMilliseconds <= 0) { throw GenuineExceptions.Get_Send_ServerDidNotReply(); } if (!syncResponseProcessorWithEvent.IsReceivedEvent.WaitOne(timeSpanInMilliseconds, false)) { throw GenuineExceptions.Get_Send_ServerDidNotReply(); } if (syncResponseProcessorWithEvent.DispatchedException != null) { throw OperationException.WrapException(syncResponseProcessorWithEvent.DispatchedException); } return(syncResponseProcessorWithEvent.Response.Stream); }
/// <summary> /// Releases expired streams. /// </summary> public void TimerCallback() { int now = GenuineUtility.TickCount; int releaseAfter = GenuineUtility.ConvertToMilliseconds(this.ITransportContext.IParameterProvider[GenuineParameter.UdpAssembleTimeSpan]); lock (this._streams.SyncRoot) { // gather expired stream ArrayList itemsDeleted = new ArrayList(); foreach (DictionaryEntry entry in this._streams) { StreamAssembled streamAssembled = (StreamAssembled)entry.Value; if (GenuineUtility.IsTimeoutExpired(streamAssembled.Started + releaseAfter, now) && !streamAssembled.IsProcessed) { itemsDeleted.Add(entry.Key); streamAssembled.Close(); } } // and remove them foreach (object key in itemsDeleted) { this._streams.Remove(key); } } }
/// <summary> /// Constructs an instance of the UdpConnectionManager class. /// </summary> /// <param name="iTransportContext">The transport context.</param> public UdpConnectionManager(ITransportContext iTransportContext) : base(iTransportContext) { this.Local = new HostInformation("_gudp://" + iTransportContext.HostIdentifier, iTransportContext); this._sendBuffer = new byte[(int)iTransportContext.IParameterProvider[GenuineParameter.UdpPacketSize]]; TimerProvider.Attach(this); this._closeInvocationConnectionAfterInactivity = GenuineUtility.ConvertToMilliseconds(iTransportContext.IParameterProvider[GenuineParameter.CloseInvocationConnectionAfterInactivity]); }
/// <summary> /// Constructs an instance of the SharedMemoryConnectionManager class. /// </summary> /// <param name="iTransportContext">The transport context.</param> public SharedMemoryConnectionManager(ITransportContext iTransportContext) : base(iTransportContext) { this._sendTimeoutSpan = GenuineUtility.ConvertToMilliseconds(iTransportContext.IParameterProvider[GenuineParameter.SMSendTimeout]); this.Local = new HostInformation("_gshmem://" + iTransportContext.HostIdentifier, iTransportContext); TimerProvider.Attach(this); }
/// <summary> /// Establishes Connection Level Security Session and gather their output into specified stream. /// </summary> /// <param name="senderInput">The input stream.</param> /// <param name="listenerInput">The input stream.</param> /// <param name="output">The output stream.</param> /// <param name="sender">The sender's Security Session.</param> /// <param name="listener">The listener's Security Session.</param> /// <returns>True if at least one Security Session requested sending of data.</returns> public bool GatherContentOfConnectionLevelSecuritySessions(Stream senderInput, Stream listenerInput, GenuineChunkedStream output, SecuritySession sender, SecuritySession listener) { bool clssDataPresents = false; Stream clsseStream; // CLSSE info using (new GenuineChunkedStreamSizeLabel(output)) { if (sender != null && !sender.IsEstablished) { clsseStream = sender.EstablishSession(senderInput, true); if (clsseStream != null) { clssDataPresents = true; GenuineUtility.CopyStreamToStream(clsseStream, output); } } } // CLSSE info using (new GenuineChunkedStreamSizeLabel(output)) { if (listener != null && !listener.IsEstablished) { clsseStream = listener.EstablishSession(listenerInput, true); if (clsseStream != null) { clssDataPresents = true; GenuineUtility.CopyStreamToStream(clsseStream, output); } } } return(clssDataPresents); }
/// <summary> /// Ensures that the file is opened. Opens the file if necessary. /// </summary> private void CheckThatCorrectFileIsOpened() { try { DateTime now = DateTime.Today; if ((this._lastDateTimeValue != now || _fileStream == null) && GenuineUtility.IsTimeoutExpired(nextTry)) { if (this._fileStream != null) { this._fileStream.Close(); } this._lastDateTimeValue = DateTime.Today; string filename = this._baseFileName; if (this._addSuffixToBaseFileName) { filename += "." + this._lastDateTimeValue.ToString("yyyy-MM-dd") + ".genchlog"; } this._fileStream = new FileStream(filename, FileMode.OpenOrCreate, FileAccess.Write, FileShare.Read); this._fileStream.Seek(0, SeekOrigin.End); } } catch { this._fileStream = null; nextTry = GenuineUtility.GetTimeout(15000); } }
/// <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> /// Encrypts the message data and put a result into the specified output stream. /// </summary> /// <param name="input">The stream containing the serialized message.</param> /// <param name="output">The result stream with the data being sent to the remote host.</param> public override void Encrypt(Stream input, GenuineChunkedStream output) { #if DEBUG input.Position = 0; #endif output.WriteByte(1); lock (this) { // write encrypted content if (this._encryptor != null) { GenuineUtility.CopyStreamToStream(new CryptoStream(new FinishReadingStream(input), this._encryptor, CryptoStreamMode.Read), output); } else { output.WriteStream(input); } if (this.KeyedHashAlgorithm != null) { // and write down the calculated message hash input.Position = 0; output.WriteBuffer(this.KeyedHashAlgorithm.ComputeHash(input), -1); // it's in the content, reset its position if (this._encryptor == null) { input.Position = 0; } } } }
/// <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> /// Makes message up from the IMessage. /// </summary> /// <param name="iTransportContext">The Transport Context.</param> /// <param name="iMessage">IMessage to make the message up from.</param> /// <param name="iTransportHeaders">Trasport headers.</param> /// <param name="stream">Message body.</param> /// <param name="isSynchronous">True if the invocation is synchronous.</param> /// <returns>An instance of the Message class.</returns> public static Message CreateOutcomingMessage(ITransportContext iTransportContext, IMessage iMessage, ITransportHeaders iTransportHeaders, Stream stream, bool isSynchronous) { // when microsoft guys start caring about detailed .NET remoting documentation??? string url = (string)iMessage.Properties["__Uri"]; string objectURI; string channelUri = GenuineUtility.Parse(url, out objectURI); if (objectURI == null) { objectURI = url; // not well-known object } iTransportHeaders[TransportHeaderName_RemoteObjectUri] = objectURI; Message message = new Message(iTransportContext, null, 0, iTransportHeaders, stream); message.IMessage = iMessage; message.IsSynchronous = isSynchronous; if (iTransportHeaders[Message.TransportHeadersGenuineMessageType] != null) { message.GenuineMessageType = (GenuineMessageType)iTransportHeaders[Message.TransportHeadersGenuineMessageType]; } return(message); }
/// <summary> /// Puts down a structure describing the specified message. /// </summary> /// <param name="message">The message.</param> /// <param name="isSent">Whether it will be executed on a remote host.</param> /// <param name="invocationTarget">The target of the invocation.</param> /// <param name="methodName">The name of the method.</param> private void WriteMessage(Message message, bool isSent, string invocationTarget, string methodName) { this.BinaryWriter.Write((int)message.SeqNo); this.BinaryWriter.Write((int)message.MessageId); this.BinaryWriter.Write((int)message.ReplyToId); this.BinaryWriter.Write((bool)isSent); this.BinaryWriter.Write((bool)message.IsOneWay); this.BinaryWriter.Write((bool)message.IsSynchronous); this.BinaryWriter.Write((int)message.GenuineMessageType); this.BinaryWriter.Write((int)GenuineUtility.GetMillisecondsLeft(message.FinishTime)); this.WriteString(invocationTarget); this.WriteString(methodName); // the size of the message if (message.Stream != null && message.Stream.CanSeek) { try { this.BinaryWriter.Write((int)message.Stream.Length); } catch { this.BinaryWriter.Write((int)0); } } else { this.BinaryWriter.Write((int)0); } }
/// <summary> /// Initiates sending of the specified HTTP request. /// </summary> /// <param name="connectionInfo">The connection.</param> /// <param name="stream">The content of the request.</param> /// <param name="timeout">The timeout of the operation.</param> private void InitiateSending(ConnectionInfo connectionInfo, Stream stream, int timeout) { Stream requestStream = null; try { // try to send it connectionInfo.HttpWebRequest.ContentLength = stream.Length; requestStream = connectionInfo.HttpWebRequest.GetRequestStream(); #if DEBUG byte[] content = new byte[(int)stream.Length]; GenuineUtility.ReadDataFromStream(stream, content, 0, content.Length); // this.ITransportContext.IEventLogger.Log(LogMessageCategory.TransportLayer, null, "HttpInvocationConnection.InitiateSending", // content, "The content of the request sent by the client application. Size: {0}.", stream.Length); stream = new MemoryStream(content); #endif GenuineUtility.CopyStreamToStream(stream, requestStream, (int)stream.Length); //connectionInfo.HttpWebRequest.BeginGetResponse(this._asyncCallback_onRequestCompleted, connectionInfo); HttpWebRequestCop webRequestCop = new HttpWebRequestCop(connectionInfo.HttpWebRequest, this._asyncCallback_onRequestCompleted, connectionInfo, this._httpAsynchronousRequestTimeout); } finally { if (requestStream != null) { requestStream.Close(); } } }
/// <summary> /// Renews the Security Session life time. /// The first call of this method is always reset the lifetime value to the specified value. /// </summary> /// <param name="timeSpan">A time period to renew all host-related information.</param> /// <param name="canMakeShorter">Indicates whether this call may reduce the host expiration time.</param> public void Renew(int timeSpan, bool canMakeShorter) { if (this._firstRenewing) { this._firstRenewing = false; canMakeShorter = true; } lock (this.DisposeLock) { if (this.IsDisposed) { throw OperationException.WrapException(this.DisposeReason); } lock (this._accessToLocalMembers) { int proposedTime = GenuineUtility.GetTimeout(timeSpan); if (canMakeShorter || GenuineUtility.IsTimeoutExpired(this._expireTime, proposedTime)) { this._expireTime = proposedTime; } } } }
/// <summary> /// Encrypts the message data and put a result into the specified output stream. /// </summary> /// <param name="input">The stream containing the serialized message.</param> /// <param name="output">The result stream with the data being sent to the remote host.</param> public override void Encrypt(Stream input, GenuineChunkedStream output) { // there are two good approaches here: either encrypt the stream directly into the target lock (this._encryptor) GenuineUtility.CopyStreamToStream(new CryptoStream(new FinishReadingStream(input), this._encryptor, CryptoStreamMode.Read), output); // or create separate encryptor instance for encrypting at run-time // stream.WriteStream(new ResettableCryptoStream(input, this.SymmetricAlgorithm.CreateEncryptor())); }
/// <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> /// Attaches the client. /// </summary> /// <param name="nickname">Nickname.</param> public void AttachClient(string nickname) { string receiverUri = GenuineUtility.FetchCurrentRemoteUri() + "/MessageReceiver.rem"; IMessageReceiver iMessageReceiver = (IMessageReceiver)Activator.GetObject(typeof(IMessageReceiver), receiverUri); this._dispatcher.Add((MarshalByRefObject)iMessageReceiver); GenuineUtility.CurrentSession["Nickname"] = nickname; Console.WriteLine("Client with nickname \"{0}\" has been registered.", nickname); }
/// <summary> /// Reads settings. /// </summary> /// <param name="properties">Settings container to read from.</param> protected virtual void ReadSettings(IDictionary properties) { // retrieve settings foreach (DictionaryEntry entry in properties) { if (string.Compare(entry.Key.ToString(), "name", true) == 0) { this._channelName = entry.Value.ToString(); } if (string.Compare(entry.Key.ToString(), "priority", true) == 0) { this._channelPriority = GenuineUtility.SafeConvertToInt32(entry.Value, this._channelPriority); } if (string.Compare(entry.Key.ToString(), "prefix", true) == 0) { this._urlPrefix = entry.Value.ToString(); if (!this._urlPrefix.StartsWith("g") || this._urlPrefix.Length < 4 || this._urlPrefix.Length > 8) { GenuineExceptions.Get_Channel_InvalidParameter("prefix"); } } } // enable compresion if such an option is specified if ((bool)this.ITransportContext.IParameterProvider[GenuineParameter.Compression]) { this.SecuritySessionParameters = SecuritySessionServices.DefaultContextWithCompression; } #if DEBUG try { // enable logging if (this.ITransportContext.IParameterProvider[GenuineParameter.EnableGlobalLoggingToFile] is string && ((string)this.ITransportContext.IParameterProvider[GenuineParameter.EnableGlobalLoggingToFile]).Length > 0) { GenuineLoggingServices.SetUpLoggingToFile(this.ITransportContext.IParameterProvider[GenuineParameter.EnableGlobalLoggingToFile] as string, this.ITransportContext.IParameterProvider[GenuineParameter.LoggingParameters] as string); } else if (this.ITransportContext.IParameterProvider[GenuineParameter.EnableGlobalLoggingToMemory] is int && ((int)this.ITransportContext.IParameterProvider[GenuineParameter.EnableGlobalLoggingToMemory]) > 0) { GenuineLoggingServices.SetUpLoggingToMemory((int)this.ITransportContext.IParameterProvider[GenuineParameter.EnableGlobalLoggingToMemory], this.ITransportContext.IParameterProvider[GenuineParameter.LoggingParameters] as string); } } catch { } #endif }
/// <summary> /// Initiates the HTTP web request. /// </summary> /// <param name="httpWebRequest">The HttpWebRequest.</param> /// <param name="asyncCallback">The callback.</param> /// <param name="state">The additional parameter to the request.</param> /// <param name="timeoutSpan">The timeout of the operation.</param> public HttpWebRequestCop(HttpWebRequest httpWebRequest, AsyncCallback asyncCallback, object state, int timeoutSpan) { this._httpWebRequest = httpWebRequest; this._asyncCallback = asyncCallback; this._state = state; this._timeoutExpiresAt = GenuineUtility.GetTimeout(timeoutSpan); // asyncCallback this._httpWebRequest.BeginGetResponse(new AsyncCallback(this.HandleWebResponse), state); TimerProvider.Attach(this); }
/// <summary> /// Sends the stream to the remote host. /// </summary> /// <param name="message">The message.</param> public void SendMessage(Message message) { int availableConnectionEntry = 0; HttpWebRequest httpWebRequest = null; try { // serialize the message GenuineChunkedStream stream = new GenuineChunkedStream(false); using (BufferKeeper bufferKeeper = new BufferKeeper(0)) { MessageCoder.FillInLabelledStream(message, null, null, stream, bufferKeeper.Buffer, (int)this.ITransportContext.IParameterProvider[GenuineParameter.HttpRecommendedPacketSize]); } // add the header GenuineChunkedStream resultStream = new GenuineChunkedStream(false); BinaryWriter binaryWriter = new BinaryWriter(resultStream); HttpMessageCoder.WriteRequestHeader(binaryWriter, MessageCoder.PROTOCOL_VERSION, GenuineConnectionType.Invocation, this.ITransportContext.BinaryHostIdentifier, HttpPacketType.Usual, message.MessageId, string.Empty, this.Remote.LocalHostUniqueIdentifier); if (stream.CanSeek) { resultStream.WriteStream(stream); } else { GenuineUtility.CopyStreamToStream(stream, resultStream); } // get a connection availableConnectionEntry = FindAvailableConnectionEntry(); httpWebRequest = this.InitializeRequest("__GC_INVC_" + availableConnectionEntry.ToString(), this._keepalive); this.InitiateSending(new ConnectionInfo(httpWebRequest, availableConnectionEntry, message), resultStream, this._httpAsynchronousRequestTimeout); } catch { try { if (httpWebRequest != null) { httpWebRequest.Abort(); } } catch { } this.ReleaseConnectionEntry(availableConnectionEntry); throw; } }
/// <summary> /// Creates and returns a stream containing decrypted data. /// </summary> /// <param name="input">A stream containing encrypted data.</param> /// <returns>A stream with decrypted data.</returns> public override Stream Decrypt(Stream input) { // check on view whether it's session's packet if (input.ReadByte() == 0) { // continue the Security Session establishing Stream outputStream = this.EstablishSession(input, false); if (outputStream != null) { GenuineThreadPool.QueueUserWorkItem(new WaitCallback(this.SendMessage), outputStream, false); } return(null); } lock (this) { GenuineChunkedStream output = new GenuineChunkedStream(false); byte[] sign = null; int signSize = 0; if (this.KeyedHashAlgorithm != null) { signSize = this.KeyedHashAlgorithm.HashSize / 8; } // decrypt the content and fetch the sign if (this._decryptor != null) { CryptoStream cryptoStream = new CryptoStream(new FinishReadingStream(output), this._decryptor, CryptoStreamMode.Write); sign = GenuineUtility.CopyStreamToStreamExceptSign(input, cryptoStream, signSize); cryptoStream.FlushFinalBlock(); } else { sign = GenuineUtility.CopyStreamToStreamExceptSign(input, output, signSize); } // check the sign if (this.KeyedHashAlgorithm != null) { if (!ZeroProofAuthorizationUtility.CompareBuffers(sign, this.KeyedHashAlgorithm.ComputeHash(output), sign.Length)) { throw GenuineExceptions.Get_Security_WrongSignature(); } output.Position = 0; } output.ReleaseOnReadMode = true; return(output); } }
/// <summary> /// Returns a channel message sink that delivers messages to the specified URL or channel data object. /// </summary> /// <param name="url">The url.</param> /// <param name="remoteChannelData">The information associated with the channel.</param> /// <param name="objectURI">The uri of the target.</param> /// <returns>A channel message sink that delivers messages to the specified URL or channel data object.</returns> public IMessageSink CreateMessageSink(string url, object remoteChannelData, out string objectURI) { objectURI = null; string channelUri = null; // if it's a well-known object if (url == null && remoteChannelData is IChannelDataStore) { url = ((IChannelDataStore)remoteChannelData).ChannelUris[0]; } if (url == null) { return(null); } // check whether we can service this url string[] channelPrefixes = this._possibleChannelPrefixes; int i = 0; for ( ; i < channelPrefixes.Length; i++) { if (url.StartsWith(channelPrefixes[i])) { break; } } // if the requested url wasn't recognized, it should be // directed to another channel if (i == channelPrefixes.Length) { return(null); } channelUri = GenuineUtility.Parse(url, out objectURI); // if the provided URI is not registered at common URI Storage, nothing will be able // to send anything there // if it's registered, it does not matter whose sink services the connection. if (!GenuineUtility.CheckUrlOnConnectivity(url) && UriStorage.GetTransportContext(channelUri) == null) { return(null); } if (channelUri == null) { return(null); } return(this._iClientChannelSinkProvider.CreateSink(this, url, remoteChannelData) as IMessageSink); }
/// <summary> /// Checks on whether the specified GUID has been registered before. /// Automatically registers GUID if it wasn't registered. /// </summary> /// <param name="guid">The GUID to check.</param> /// <returns>True if the specified GUID has been registered before.</returns> public bool WasGuidRegistered(string guid) { lock (this) { if (_guids.Contains(guid)) { return(true); } _guids[guid] = GenuineUtility.GetTimeout(_timeSpanToRememberCallInMilliseconds); return(false); } }
/// <summary> /// Creates and returns a stream containing decrypted data. /// </summary> /// <param name="input">A stream containing encrypted data.</param> /// <returns>A stream with decrypted data.</returns> public override Stream Decrypt(Stream input) { // the first approach lock (this._decryptor) { GenuineChunkedStream output = new GenuineChunkedStream(true); GenuineUtility.CopyStreamToStream(new CryptoStream(new FinishReadingStream(input), this._decryptor, CryptoStreamMode.Read), output); return(output); } // the second approach // return new CryptoStream(new FinishReadingStream(input), this.SymmetricAlgorithm.CreateDecryptor(), CryptoStreamMode.Read); }
/// <summary> /// Constructs an instance of the GenuineTcpClientTransportSink class. /// </summary> /// <param name="url">The Url of the remote object.</param> /// <param name="iTransportContext">The transport context.</param> public GenuineTcpClientTransportSink(string url, ITransportContext iTransportContext) { this.ITransportContext = iTransportContext; string objectURI; this._recipientUri = GenuineUtility.Parse(url, out objectURI); this._properties["GC_URI"] = this._recipientUri; this._properties["GC_TC"] = iTransportContext; // it's rather a trick, but works well this._properties["GC_TS"] = this; }
/// <summary> /// Encrypts the stream under current security conditions. /// </summary> /// <param name="messageStream">Data to be encrypted.</param> /// <param name="outputStream">Stream to write encrypted content to.</param> /// <param name="sspiFeatureFlags">Requested features.</param> public void EncryptMessage(Stream messageStream, GenuineChunkedStream outputStream, SspiFeatureFlags sspiFeatureFlags) { // get package sizes lock (_secPkgContext_SizesLock) { if (!_secPkgContext_SizesInitialized) { SspiApi.QueryContextSizes(this._phContext, ref this._secPkgContext_Sizes); _secPkgContext_SizesInitialized = true; } } byte[] chunk = null; int position = 0; BinaryWriter outputWriter = new BinaryWriter(outputStream); if ((sspiFeatureFlags & SspiFeatureFlags.Encryption) != 0) { // it'll write signature automatically as well as encrypt content SspiApi.EncryptMessage(this._phContext, messageStream, outputWriter, ref this._secPkgContext_Sizes); } else if ((sspiFeatureFlags & SspiFeatureFlags.Signing) != 0) { // remember position to write signature size later outputStream.WriteInt32AndRememberItsLocation(0, out chunk, out position); long currentLength = outputStream.Length; // anyway will have to read this into buffer byte[] contentBuffer = new byte[(int)messageStream.Length]; GenuineUtility.ReadDataFromStream(messageStream, contentBuffer, 0, contentBuffer.Length); // write signature SspiApi.MakeSignature(this._phContext, contentBuffer, outputWriter, ref this._secPkgContext_Sizes); // update signature size MessageCoder.WriteInt32(chunk, position, (int)(outputStream.Length - currentLength)); // write the content outputWriter.Write((int)contentBuffer.Length); outputWriter.Write(contentBuffer, 0, contentBuffer.Length); } else { // just copy the source content //outputWriter.Write( (int) messageStream.Length ); GenuineUtility.CopyStreamToStream(messageStream, outputStream); } }
/// <summary> /// Constructs an instance of the BasicChannelWithSecurity class. /// </summary> /// <param name="properties">Channel properties.</param> protected void InitializeInstance(IDictionary properties) { // properties if (properties == null) { this._properties = new Hashtable(); } else { this._properties = properties; } this.ReadSettings(properties); // create default client formatter sink if (this._iClientChannelSinkProvider == null) { this._iClientChannelSinkProvider = new BinaryClientFormatterSinkProvider(); } // connect client sink provider to the end IClientChannelSinkProvider currentProvider = this._iClientChannelSinkProvider; while (currentProvider.Next != null) { currentProvider = currentProvider.Next; } currentProvider.Next = new GenuineTcpClientTransportSinkProvider(this.ITransportContext); // create default server formatter sink if (this._iServerChannelSinkProvider == null) { this._iServerChannelSinkProvider = GenuineUtility.GetDefaultServerSinkChain(); } // collect sink providers' cookies IServerChannelSinkProvider sinkProvider = this._iServerChannelSinkProvider; while (sinkProvider != null) { sinkProvider.GetChannelData((IChannelDataStore)this.ChannelData); sinkProvider = sinkProvider.Next; } // register channel sink this._iServerChannelSink = new GenuineUniversalServerTransportSink(this, ChannelServices.CreateServerChannelSinkChain(this._iServerChannelSinkProvider, this), this.ITransportContext); }
/// <summary> /// Indicates whether this message processor still waits for the response(s). /// </summary> /// <param name="now">The current time elapsed since the system started.</param> /// <returns>True if the message processor still waits for the response.</returns> public bool IsExpired(int now) { lock (this) { if (this._isDispatched) { return(true); } } if (GenuineUtility.IsTimeoutExpired(this._message.FinishTime, now)) { return(true); } return(false); }
private static void RunSplitToHostAndPortWithInputDictionary(Dictionary <string, Tuple <string, int> > testDict) { foreach (var entry in testDict) { try { int port; Assert.AreEqual(entry.Value.Item1, GenuineUtility.SplitToHostAndPort(entry.Key, out port), true, "-> Host name of Entry Key: {0}", entry.Key); Assert.AreEqual(entry.Value.Item2, port, "-> Port of Entry Key: {0}", entry.Key); } catch (Exception ex) { Assert.Fail("{0}: {1} -> Port of Entry Key: {2}", ex.GetType().Name, ex.Message, entry.Key); } } }