Beispiel #1
0
        /// <summary>
        /// Gets a Security Session.
        /// </summary>
        /// <param name="securitySessionName">The name of the Security Session.</param>
        /// <param name="keyStore">The store of all keys.</param>
        /// <returns>An object implementing ISecuritySession interface.</returns>
        public SecuritySession GetSecuritySession(string securitySessionName, IKeyStore keyStore)
        {
            lock (this.DisposeLock)
            {
                if (this.IsDisposed)
                {
                    throw OperationException.WrapException(this.DisposeReason);
                }

                lock (_securitySessions)
                {
                    SecuritySession iSecuritySession = _securitySessions[securitySessionName] as SecuritySession;
                    if (iSecuritySession == null)
                    {
                        IKeyProvider iKeyProvider = keyStore.GetKey(securitySessionName);
                        if (iKeyProvider == null)
                        {
                            throw GenuineExceptions.Get_Security_ContextNotFound(securitySessionName);
                        }
                        iSecuritySession = iKeyProvider.CreateSecuritySession(securitySessionName, this);
                        _securitySessions[securitySessionName] = iSecuritySession;
                    }

                    return(iSecuritySession);
                }
            }
        }
Beispiel #2
0
        /// <summary>
        /// Puts down detailed information about the specified instance of the HostInformation class.
        /// </summary>
        /// <param name="author">The author.</param>
        /// <param name="type">The type of the event(Subcategory).</param>
        /// <param name="exception">The exception associated with the event.</param>
        /// <param name="remote">The remote host participating in the event.</param>
        /// <param name="sourceThreadId">The id of the thread where the invocation was made.</param>
        /// <param name="sourceThreadName">The name of the thread.</param>
        /// <param name="securitySession">The Security Session.</param>
        /// <param name="securitySessionName">The name of the Security Session</param>
        /// <param name="connectionId">The connection identifier.</param>
        /// <param name="description">The description of the event.</param>
        /// <param name="parameters">Parameters to the description.</param>
        public void WriteHostInformationEvent(string author, LogMessageType type, Exception exception,
                                              HostInformation remote, int sourceThreadId, string sourceThreadName,
                                              SecuritySession securitySession, string securitySessionName, int connectionId,
                                              string description, params object[] parameters)
        {
            if (remote == null)
            {
                this.WriteImplementationWarningEvent("BinaryLogWriter.WriteHostInformationCreatedEvent", LogMessageType.Error, null,
                                                     sourceThreadId, sourceThreadName, "The reference is null. Stack trace: " + Environment.StackTrace);
                return;
            }

            lock (this._streamLock)
            {
                this.WriteRecordHeader(BinaryRecordVersion.HostInformationInfo, LogCategory.HostInformation, type, author);
                this.WriteException(exception);

                this.WriteHostInformation(remote);

                this.BinaryWriter.Write((int)sourceThreadId);
                this.WriteString(sourceThreadName);

                this.WriteSecuritySessionId(securitySession);
                this.WriteString(securitySessionName);

                this.BinaryWriter.Write((int)connectionId);
                this.WriteStringWithParameters(description, parameters);

                this.BinaryWriter.Flush();
            }
        }
Beispiel #3
0
 /// <summary>
 /// Puts down the Security Session Identifier.
 /// </summary>
 /// <param name="securitySession">The Security Session.</param>
 private void WriteSecuritySessionId(SecuritySession securitySession)
 {
     this.BinaryWriter.Write((bool)(securitySession != null));
     if (securitySession != null)
     {
         this.BinaryWriter.Write((int)securitySession.SecuritySessionId);
     }
 }
Beispiel #4
0
        /// <summary>
        /// Checks if the user has multiple roles and/or patients.
        /// If the user has 1 or more Patients and no additional roles, the PatientProxy role is automatically selected and Authentication/Login is automatically completed. It is up to the website to determine which Patient the user is using/wants to use.
        /// If the user has only 1 Role, this Role is automatically selected for the user and Authentication/Login is automatically completed.
        /// If the user has more then 1 Role or 1 Role in addition to the patients. These roles are in the Strings variable and the User has to select which Role to use.
        /// </summary>
        /// <param name="userName">The username of the user. If the username is null, the current authenticated User for the session is used instead.</param>
        /// <returns>An operationResult inidicating success or failure. The Strings variable is filled with Role Name(s) the user has access to.</returns>
        public OperationResultAsLists UserHasMultipleRoles(string userName)
        {
            try
            {
                userName = userName == null ? WcfUserSessionSecurity.Current.User.UserName : userName;
                User user = this.handler.UserManager.FindByName(userName == null ? WcfUserSessionSecurity.Current.User.UserName : userName);
                if (user == null)
                {
                    throw this.handler.MessageManager.GetError(ErrorCodes.USER_SESSION_EXPIRED);
                }
                if (WcfUserSessionSecurity.Current.User != null && !WcfUserSessionSecurity.Current.VerifyNameOrIdWithSession(userName: userName))
                {
                    throw this.handler.MessageManager.GetError(ErrorCodes.USER_UNKNOWN);
                }

                SecuritySession.SetCurrentSession(WcfUserSessionSecurity.Current.SessionId, user);

                List <string>  userRoles          = this.handler.UserManager.GetRoles(user.Id).ToList();
                List <Patient> patients           = this.handler.UserManager.GetPatientsForUser(userId: user.Id);
                Dictionary <string, string> roles = new Dictionary <string, string>();
                if (userRoles.Count == 1 /*&& patients.Count == 0*/)
                {
                    var result = this.SelectRole(user.UserName, userRoles[0]);
                    if (!result.Succeeded)
                    {
                        throw new PCHIError(result.ErrorCode, result.ErrorMessages);
                    }
                }

                /*else if (patients.Count > 0 && userRoles.Count == 0)
                 * {
                 *  var result = this.SelectRole(user.UserName, "PatientProxy");
                 *  if (!result.Succeeded) throw new PCHIError(result.ErrorCode, result.ErrorMessages);
                 * }*/

                /*
                 * if (patients.Count > 0)
                 * {
                 *  userRoles.Add("PatientProxy");
                 * }*/

                return(new OperationResultAsLists(null)
                {
                    Strings = userRoles
                });
            }
            catch (Exception ex)
            {
                return(new OperationResultAsLists(ex));
            }
        }
Beispiel #5
0
        /// <summary>
        /// Puts down a record describing a general Genuine Channels event.
        /// </summary>
        /// <param name="logCategory">The category of the event.</param>
        /// <param name="author">The author.</param>
        /// <param name="type">The type of the event(Subcategory).</param>
        /// <param name="exception">The exception associated with the event.</param>
        /// <param name="message">The message associated with the event.</param>
        /// <param name="remote">The remote host participating in the event.</param>
        /// <param name="content">The content associated with the record.</param>
        /// <param name="sourceThreadId">The id of the thread where the invocation was made.</param>
        /// <param name="sourceThreadName">The name of the thread.</param>
        /// <param name="securitySession">The Security Session.</param>
        /// <param name="securitySessionName">The name of the Security Session</param>
        /// <param name="writeDispatcherSettings">A value indicating whether it is necessary to put down broadcast dispatcher's settings.</param>
        /// <param name="dispatcher">The broadcast dispatcher.</param>
        /// <param name="resultCollector">The broadcast result collector.</param>
        /// <param name="writeReceiverInfoSettings">A value indicating whether it is necessary to put down information about the specified broadcast recipient.</param>
        /// <param name="receiverInfo">The broadcast recipient.</param>
        /// <param name="string1">The first string that elaborates the current event.</param>
        /// <param name="string2">The second string that elaborates the current event.</param>
        /// <param name="description">The description of the event.</param>
        /// <param name="parameters">Parameters to the description.</param>
        public void WriteBroadcastEngineEvent(LogCategory logCategory, string author, LogMessageType type, Exception exception,
                                              Message message, HostInformation remote, Stream content, int sourceThreadId, string sourceThreadName,
                                              SecuritySession securitySession, string securitySessionName,
                                              bool writeDispatcherSettings, Dispatcher dispatcher, ResultCollector resultCollector, bool writeReceiverInfoSettings,
                                              ReceiverInfo receiverInfo, string string1, string string2, string description, params object[] parameters)
        {
            if (dispatcher == null)
            {
                this.WriteImplementationWarningEvent("BinaryLogWriter.WriteBroadcastEngineEvent", LogMessageType.Error, null,
                                                     sourceThreadId, sourceThreadName, "The reference is null. Stack trace: " + Environment.StackTrace);
                return;
            }

            lock (this._streamLock)
            {
                this.WriteRecordHeader(BinaryRecordVersion.TransportBroadcastEngineRecord, logCategory, type, author);
                this.WriteException(exception);

                this.WriteMessageSeqNo(message);
                this.WriteHostInformationId(remote);
                this.WriteBinaryContent(content);

                this.BinaryWriter.Write((int)sourceThreadId);
                this.WriteString(sourceThreadName);

                this.WriteSecuritySessionId(securitySession);
                this.WriteString(securitySessionName);

                this.WriteResultCollectorId(resultCollector);
                this.WriteDispatcherSettings(writeDispatcherSettings, dispatcher);
                this.WriteReceiverInfo(writeReceiverInfoSettings, receiverInfo);

                this.WriteString(string1);
                this.WriteString(string2);
                this.WriteStringWithParameters(description, parameters);

                this.BinaryWriter.Flush();
            }
        }
Beispiel #6
0
        /// <summary>
        /// Destroys the Security Session with the specified name.
        /// Releases all Security Session resources.
        /// </summary>
        /// <param name="securitySessionName">The name of the Security Session.</param>
        public void DestroySecuritySession(string securitySessionName)
        {
            lock (this.DisposeLock)
            {
                if (this.IsDisposed)
                {
                    throw OperationException.WrapException(this.DisposeReason);
                }

                lock (_securitySessions)
                {
                    SecuritySession iSecuritySession = _securitySessions[securitySessionName] as SecuritySession;
                    if (iSecuritySession != null)
                    {
                        IDisposable iDisposable = iSecuritySession as IDisposable;
                        if (iDisposable != null)
                        {
                            iDisposable.Dispose();
                        }

                        // LOG:
                        BinaryLogWriter binaryLogWriter = this.ITransportContext.BinaryLogWriter;
                        if (binaryLogWriter != null && binaryLogWriter[LogCategory.Security] > 0)
                        {
                            binaryLogWriter.WriteEvent(LogCategory.Security, "HostInformation.DestroySecuritySession",
                                                       LogMessageType.SecuritySessionDestroyed, null, null, iSecuritySession.Remote, null,
                                                       GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, iSecuritySession,
                                                       iSecuritySession.Name, -1,
                                                       0, 0, 0, iSecuritySession.GetType().Name, iSecuritySession.Name, null, null,
                                                       "Security Session has been destroyed manually.");
                        }

                        _securitySessions.Remove(securitySessionName);
                    }
                }
            }
        }
Beispiel #7
0
        /// <summary>
        /// Puts down a record describing a general Genuine Channels event.
        /// </summary>
        /// <param name="logCategory">The category of the event.</param>
        /// <param name="author">The author.</param>
        /// <param name="type">The type of the event(Subcategory).</param>
        /// <param name="exception">The exception associated with the event.</param>
        /// <param name="message">The message associated with the event.</param>
        /// <param name="remote">The remote host participating in the event.</param>
        /// <param name="content">The content associated with the record.</param>
        /// <param name="sourceThreadId">The id of the thread where the invocation was made.</param>
        /// <param name="sourceThreadName">The name of the thread.</param>
        /// <param name="securitySession">The Security Session.</param>
        /// <param name="securitySessionName">The name of the Security Session</param>
        /// <param name="connectionId">The identifier of the connection.</param>
        /// <param name="number1">An additional integer parameter.</param>
        /// <param name="number2">An additional integer parameter.</param>
        /// <param name="number3">An additional integer parameter.</param>
        /// <param name="string1">The first string that elaborates the current event.</param>
        /// <param name="string2">The second string that elaborates the current event.</param>
        /// <param name="string3">The third string that elaborates the current event.</param>
        /// <param name="string4">The fourth string that elaborates the current event.</param>
        /// <param name="description">The description of the event.</param>
        /// <param name="parameters">Parameters to the description.</param>
        public void WriteEvent(LogCategory logCategory, string author, LogMessageType type, Exception exception,
                               Message message, HostInformation remote, Stream content, int sourceThreadId, string sourceThreadName,
                               SecuritySession securitySession, string securitySessionName,
                               int connectionId, int number1, int number2, int number3, string string1, string string2, string string3, string string4, string description, params object[] parameters)
        {
            lock (this._streamLock)
            {
                this.WriteRecordHeader(BinaryRecordVersion.GeneralRecord, logCategory, type, author);
                this.WriteException(exception);

                this.WriteMessageSeqNo(message);
                this.WriteHostInformationId(remote);
                this.WriteBinaryContent(content);

                this.BinaryWriter.Write((int)sourceThreadId);
                this.WriteString(sourceThreadName);

                this.WriteSecuritySessionId(securitySession);
                this.WriteString(securitySessionName);

                this.BinaryWriter.Write((int)connectionId);

                this.BinaryWriter.Write((int)number1);
                this.BinaryWriter.Write((int)number2);
                this.BinaryWriter.Write((int)number3);

                this.WriteString(string1);
                this.WriteString(string2);
                this.WriteString(string3);
                this.WriteString(string4);

                this.WriteStringWithParameters(description, parameters);

                this.BinaryWriter.Flush();
            }
        }
 /// <summary>
 /// Sets the CurrentSession of the Business Logic to the WcfUserSessionSecurity current session
 /// </summary>
 /// <param name="sessionId">The Id of the current session</param>
 /// <param name="user">The user to set it to</param>
 /// <param name="header">The Request header that was part of the message</param>
 public static void WcfUserSessionSecurity_SessionUpdated(string sessionId, DSPrima.WcfUserSession.Interfaces.IUser user, RequestHeader header)
 {
     SecuritySession.SetCurrentSession(sessionId, (User)user);
     WcfUserSessionUserManager.SetSessionPermissions();
 }
Beispiel #9
0
        /// <summary>
        /// Updates the value of the Uri member.
        /// </summary>
        /// <param name="uri">The uri of this host.</param>
        /// <param name="remoteHostUniqueIdentifier">The unique identifier of the HostInformation used by the remote host.</param>
        /// <param name="checkHostInfoVersion">The boolean value that determines whether the host version should be checked.</param>
        /// <returns>The exception explaining why the remote host has lost its state.</returns>
        public Exception UpdateUri(string uri, int remoteHostUniqueIdentifier, bool checkHostInfoVersion)
        {
            Exception       exception       = null;
            BinaryLogWriter binaryLogWriter = GenuineLoggingServices.BinaryLogWriter;

            lock (this._uriLock)
            {
                if (this._uri != uri)
                {
                    if (this._uri != null && this._uri != uri)
                    {
                        exception = GenuineExceptions.Get_Receive_ServerHasBeenRestared();

                        // LOG:
                        if (binaryLogWriter != null && binaryLogWriter[LogCategory.HostInformation] > 0)
                        {
                            binaryLogWriter.WriteEvent(LogCategory.HostInformation, "HostInformation.UpdateUri",
                                                       LogMessageType.HostInformationUriUpdated, exception, null, this,
                                                       null, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name,
                                                       null, null, -1, 0, 0, 0, this._uri, uri, null, null,
                                                       "The URI mismatch has been detected. The remote host has been restarted. Expected uri: \"{0}\". Provided uri: \"{1}\".", this._uri, uri);
                        }

//						if (! (bool) this.ITransportContext.IParameterProvider[GenuineParameter.IgnoreRemoteHostUriChanges])
                        throw exception;
                    }

                    this._uri = uri;
                    UriStorage.RegisterConnection(uri, this.ITransportContext);
                    this.ITransportContext.KnownHosts.UpdateHost(uri, this);

                    // LOG:
                    if (binaryLogWriter != null && binaryLogWriter[LogCategory.HostInformation] > 0)
                    {
                        binaryLogWriter.WriteEvent(LogCategory.HostInformation, "HostInformation.UpdateUri",
                                                   LogMessageType.HostInformationUriUpdated, null, null, this,
                                                   null, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name,
                                                   null, null, -1, 0, 0, 0, this._uri, uri, null, null,
                                                   "The URI of the HostInformation has been updated. Provided uri: \"{0}\".", this._uri);
                    }
                }

                if (checkHostInfoVersion && this.RemoteHostUniqueIdentifier != remoteHostUniqueIdentifier || (this._uri != null && this._uri != uri))
                {
                    if (this.RemoteHostUniqueIdentifier != -1)
                    {
                        exception = GenuineExceptions.Get_Receive_NewSessionDetected();

                        // release all security sessions
                        lock (_securitySessions)
                        {
                            foreach (DictionaryEntry entry in this._securitySessions)
                            {
                                SecuritySession securitySession = (SecuritySession)entry.Value;
                                securitySession.DispatchException(exception);
                            }

                            this._securitySessions = new Hashtable();
                        }

                        this.ITransportContext.IIncomingStreamHandler.DispatchException(this, exception);
                    }

                    this._remoteHostUniqueIdentifier = remoteHostUniqueIdentifier;
                    this.ITransportContext.IGenuineEventProvider.Fire(new GenuineEventArgs(GenuineEventType.GeneralNewSessionDetected, null, this, null));
                }
            }

            return(exception);
        }
        /// <summary>
        /// Sends a message to the remote host.
        /// </summary>
        /// <param name="message">The message to be sent.</param>
        public void Send(Message message)
        {
#if TRIAL
            _messagesBeingSent[message.MessageId] = message;
#endif

            BinaryLogWriter binaryLogWriter = this.ITransportContext.BinaryLogWriter;

            try
            {
                using (new ReaderAutoLocker(this._disposeLock))
                {
                    if (this._disposed)
                    {
                        throw OperationException.WrapException(this._disposeReason);
                    }
                }

                SecuritySession session = null;

                if (this._disposed)
                {
                    throw OperationException.WrapException(this._disposeReason);
                }

                // get the security session descriptor
                if (message.SecuritySessionParameters == null)
                {
                    SecuritySessionParameters securitySessionParameters = SecuritySessionServices.GetCurrentSecurityContext();
                    if (securitySessionParameters == null)
                    {
                        securitySessionParameters = message.Recipient.SecuritySessionParameters;
                    }
                    if (securitySessionParameters == null)
                    {
                        securitySessionParameters = this.ITransportContext.SecuritySessionParameters;
                    }
                    if (securitySessionParameters == null)
                    {
                        securitySessionParameters = SecuritySessionServices.DefaultSecuritySession;
                    }
                    message.SecuritySessionParameters = securitySessionParameters;
                }

                // LOG:
                if (binaryLogWriter != null && binaryLogWriter[LogCategory.MessageProcessing] > 0)
                {
                    binaryLogWriter.WriteSecuritySessionParametersEvent("ConnectionManager.Send",
                                                                        LogMessageType.SecuritySessionParametersAssembled, null, message, message.Recipient,
                                                                        GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name,
                                                                        message.SecuritySessionParameters,
                                                                        "Security Session Parameters have been assembled.");
                }

                // determine the type of sending
                message.IsSynchronous = (message.SecuritySessionParameters.Attributes & SecuritySessionAttributes.ForceSync) != 0 ||
                                        (message.IsSynchronous && (message.SecuritySessionParameters.Attributes & SecuritySessionAttributes.ForceAsync) == 0);

                // the time until invocation times out
                if (!message.FinishTime_Initialized)
                {
                    TimeSpan messageTimeout = message.SecuritySessionParameters.Timeout;
                    if (messageTimeout == TimeSpan.MinValue)
                    {
                        messageTimeout = (TimeSpan)this.ITransportContext.IParameterProvider[GenuineParameter.InvocationTimeout];
                    }
                    message.FinishTime = GenuineUtility.GetTimeout(messageTimeout);

                    message.FinishTime_Initialized = true;
                }

                // checks whether the message has been already processed by Security Session
                if (message.SerializedContent == null)
                {
                    session = message.Recipient.GetSecuritySession(message.SecuritySessionParameters.Name, this.ITransportContext.IKeyStore);
                    if (!session.IsEstablished)
                    {
                        if (binaryLogWriter != null && binaryLogWriter[LogCategory.Security] > 0)
                        {
                            binaryLogWriter.WriteEvent(LogCategory.Security, "ConnectionManager.Send",
                                                       LogMessageType.SecuritySessionHasNotBeenEstablishedYet, null, message, message.Recipient, null,
                                                       GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name,
                                                       session, session.Name, -1, 0, 0, 0, null, null, null, null,
                                                       "The requested Security Session is not established.");
                        }

                        session.InitiateEstablishingSecuritySession(message.SecuritySessionParameters);

                        // if it's a sync sending, then wait until security session will be established
                        if (message.IsSynchronous)
                        {
                            int timeSpanToWait = GenuineUtility.GetMillisecondsLeft(message.FinishTime);
                            if (timeSpanToWait <= 0)
                            {
                                throw GenuineExceptions.Get_Send_ServerDidNotReply();
                            }

                            // wait until Security Session will be established or a failure will be detected
                            int firedEvent = 0;
                            if (message.CancelSending != null)
                            {
                                firedEvent = WaitHandle.WaitAny(new WaitHandle[] { session.IsEstablishedEvent, session.Failed, message.CancelSending }, timeSpanToWait, false);
                            }
                            else
                            {
                                firedEvent = WaitHandle.WaitAny(new WaitHandle[] { session.IsEstablishedEvent, session.Failed }, timeSpanToWait, false);
                            }

                            if (firedEvent == WaitHandle.WaitTimeout)
                            {
                                throw GenuineExceptions.Get_Send_ServerDidNotReply();
                            }

                            // analyze the problem, if any
                            Exception exception = session.ReasonOfFailure;
                            if (firedEvent == 1)
                            {
                                if (exception != null)
                                {
                                    throw OperationException.WrapException(exception);
                                }
                                else
                                {
                                    throw GenuineExceptions.Get_Security_ContextWasNotEstablished(session.Name);
                                }
                            }

                            // if the message has been cancelled, let the sender to understand the reason
                            if (firedEvent == 2)
                            {
                                return;
                            }
                        }
                        else if (!session.IsEstablished)
                        {
                            // it's async and SS still isn't established
                            session.PutMessageToAwaitingQueue(message);
                            return;
                        }
                    }
                }

                // if serialization is necessary
                if (message.SerializedContent == null)
                {
                    // serialize the message
                    GenuineChunkedStream serializedMessageStream = new GenuineChunkedStream(false);
                    MessageCoder.Serialize(serializedMessageStream, message, (message.SecuritySessionParameters.Attributes & SecuritySessionAttributes.EnableCompression) != 0);

                    // save the name of the Security Session
                    GenuineChunkedStream resultStream = new GenuineChunkedStream(false);
                    BinaryWriter         writer       = new BinaryWriter(resultStream);
                    writer.Write(message.SecuritySessionParameters.Name);
                    session.Encrypt(serializedMessageStream, resultStream);
                    message.SerializedContent = resultStream;

                    // LOG: put down the log record
                    if (binaryLogWriter != null && binaryLogWriter[LogCategory.Security] > 0)
                    {
                        binaryLogWriter.WriteEvent(LogCategory.Security, "ConnectionManager.Send",
                                                   LogMessageType.SecuritySessionApplied, null, message, message.Recipient,
                                                   binaryLogWriter[LogCategory.Security] > 1 ? message.SerializedContent : null,
                                                   GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, session,
                                                   session.Name, -1, 0, 0, 0, null, null, null, null,
                                                   "The message has been processed by the established Security Session.");
                    }
                }

#if TRIAL
                if (message.MessageId > 3005)
                {
                    throw GenuineExceptions.Get_Channel_TrialConditionExceeded("The maximum number of messages restriction has been exceeded. You can not send more than 3000 messages using TRIAL version.");
                }
#endif

                message.Sender = this.Local;
                this.InternalSend(message);
            }
            catch (Exception ex)
            {
                if (binaryLogWriter != null && binaryLogWriter[LogCategory.Security] > 0)
                {
                    binaryLogWriter.WriteEvent(LogCategory.MessageProcessing, "ConnectionManager.Send",
                                               LogMessageType.Error, ex, message, message.Recipient, null,
                                               GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name,
                                               null, null, -1, 0, 0, 0, null, null, null, null,
                                               "An exception occurred while processing the message.");
                }

                throw;
            }
        }
        /// <summary>
        /// Accepts an incoming connection.
        /// </summary>
        /// <param name="url">The name of the share.</param>
        /// <param name="localUri">URI of the local host.</param>
        /// <param name="protocolVersion">The version of the protocol supported by the remote host.</param>
        /// <param name="remoteUri">Uri of the remote host.</param>
        /// <param name="remoteHostUniqueIdentifier">The unique identifier of the HostInformation used by the remote host.</param>
        /// <returns>The established connection.</returns>
        private SharedMemoryConnection LowLevel_AcceptConnection_1(string url, string localUri, byte protocolVersion, out string remoteUri, out int remoteHostUniqueIdentifier)
        {
            BinaryLogWriter binaryLogWriter = this.ITransportContext.BinaryLogWriter;

            using (new ReaderAutoLocker(this._disposeLock))
            {
                if (this._disposed)
                {
                    throw OperationException.WrapException(this._disposeReason);
                }
            }

            remoteUri = null;
            Stream inputStream  = null;
            Stream outputStream = null;

            remoteHostUniqueIdentifier = 0;

            // the maximum time during which the connection must be established
            int timeout = GenuineUtility.GetTimeout((TimeSpan)this.ITransportContext.IParameterProvider[GenuineParameter.ConnectTimeout]);

            // open the client's share
            SharedMemoryConnection sharedMemoryConnection = new SharedMemoryConnection(this.ITransportContext, url, false, true);

            // LOG:
            if (binaryLogWriter != null && binaryLogWriter[LogCategory.Connection] > 0)
            {
                binaryLogWriter.WriteConnectionParameterEvent(LogCategory.Connection, "SharedMemoryConnectionManager.LowLevel_AcceptConnection",
                                                              LogMessageType.ConnectionParameters, null, null, this.ITransportContext.IParameterProvider,
                                                              GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, sharedMemoryConnection.DbgConnectionId,
                                                              "The connection is being established to \"{0}\".", url);
            }

            // get the connection-level Security Session
            string          connectionLevelSSName = this.ITransportContext.IParameterProvider[GenuineParameter.SecuritySessionForPersistentConnections] as string;
            SecuritySession securitySession       = null;

            if (connectionLevelSSName != null)
            {
                securitySession = this.ITransportContext.IKeyStore.GetKey(connectionLevelSSName).CreateSecuritySession(connectionLevelSSName, null);
            }

            // establish it
            if (securitySession != null && !securitySession.IsEstablished)
            {
                for ( ; ;)
                {
                    inputStream = Stream.Null;

                    try
                    {
                        // prepare streams
                        inputStream  = sharedMemoryConnection.LowLevel_ReadSync(timeout);
                        outputStream = securitySession.EstablishSession(inputStream, true);

                        if (outputStream == null)
                        {
                            break;
                        }

                        // send a packet to the remote host
                        sharedMemoryConnection.LowLevel_SendSync(outputStream, timeout);
                        if (securitySession.IsEstablished)
                        {
                            break;
                        }
                    }
                    finally
                    {
                        if (inputStream != null)
                        {
                            inputStream.Close();
                        }
                        if (outputStream != null)
                        {
                            outputStream.Close();
                        }
                    }
                }
            }

            sharedMemoryConnection.ConnectionLevelSecurity = securitySession;
            HostInformation remote = null;

            // read remote info
            using (Stream remoteUriStream = sharedMemoryConnection.LowLevel_ReadSync(timeout))
            {
                BinaryReader binaryReader = new BinaryReader(remoteUriStream);
                remoteUri = binaryReader.ReadString();

                remote = this.ITransportContext.KnownHosts[remoteUri];
                if (protocolVersion > 0)
                {
                    remoteHostUniqueIdentifier = binaryReader.ReadInt32();
                }
            }

            // now send connection info through the established connection
            using (GenuineChunkedStream serializedLocalInfo = new GenuineChunkedStream(false))
            {
                // serialize local info
                BinaryWriter binaryWriter = new BinaryWriter(serializedLocalInfo);
                binaryWriter.Write((string)localUri);

                if (protocolVersion > 0)
                {
                    binaryWriter.Write((int)remote.LocalHostUniqueIdentifier);
                }

                // and send it
                sharedMemoryConnection.LowLevel_SendSync(serializedLocalInfo, timeout);
            }

            // LOG:
            if (binaryLogWriter != null && binaryLogWriter[LogCategory.Connection] > 0)
            {
                binaryLogWriter.WriteEvent(LogCategory.Connection, "SharedMemoryConnectionManager.LowLevel_AcceptConnection_1",
                                           LogMessageType.ConnectionEstablished, null, null, remote, null,
                                           GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name,
                                           securitySession, connectionLevelSSName,
                                           sharedMemoryConnection.DbgConnectionId, (int)GenuineConnectionType.Persistent, 0, 0, this.GetType().Name, null, null, null,
                                           "The connection to the remote host has been established.");
            }

            return(sharedMemoryConnection);
        }
        /// <summary>
        /// Opens a connection to the host specified by the url.
        /// </summary>
        /// <param name="remote">The HostInformation of the Remote Host.</param>
        /// <param name="localUri">The uri of the local host.</param>
        /// <param name="remoteUri">The uri of the remote host.</param>
        /// <param name="remoteHostUniqueIdentifier">The unique identifier of the HostInformation used by the remote host.</param>
        /// <returns>The established connection.</returns>
        private SharedMemoryConnection LowLevel_OpenConnection(HostInformation remote, string localUri, out string remoteUri, out int remoteHostUniqueIdentifier)
        {
            using (new ReaderAutoLocker(this._disposeLock))
            {
                if (this._disposed)
                {
                    throw OperationException.WrapException(this._disposeReason);
                }
            }

            remoteUri = null;
            Stream inputStream  = null;
            Stream outputStream = null;
            string url          = remote.Url;

            // the maximum time during which the connection must be established
            int timeout = GenuineUtility.GetTimeout((TimeSpan)this.ITransportContext.IParameterProvider[GenuineParameter.ConnectTimeout]);

            IParameterProvider parameters = this.ITransportContext.IParameterProvider;

            string mutexName = GenuineSharedMemoryChannel.ConstructSharedObjectName(
                "MUTEX" + url, parameters);
            string clientConnected = GenuineSharedMemoryChannel.ConstructSharedObjectName(
                "CC" + url, parameters);
            string clientAccepted = GenuineSharedMemoryChannel.ConstructSharedObjectName(
                "CA" + url, parameters);

            // open the server share
            SharedMemoryConnection serverSharedMemoryConnection = new SharedMemoryConnection(this.ITransportContext, url, false, false);

            // LOG:
            BinaryLogWriter binaryLogWriter = this.ITransportContext.BinaryLogWriter;

            if (binaryLogWriter != null && binaryLogWriter[LogCategory.Connection] > 0)
            {
                binaryLogWriter.WriteConnectionParameterEvent(LogCategory.Connection, "SharedMemoryConnectionManager.LowLevel_OpenConnection",
                                                              LogMessageType.ConnectionParameters, null, remote, this.ITransportContext.IParameterProvider,
                                                              GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, serverSharedMemoryConnection.DbgConnectionId,
                                                              "A Shared Memory connection is being established.");
            }

            // and create the local share
            string shareName = "gshmem://" + Guid.NewGuid().ToString("N");
            SharedMemoryConnection sharedMemoryConnection = new SharedMemoryConnection(this.ITransportContext, shareName, true, true);

            BinaryWriter connectionInformation = MessageCoder.SerializeConnectionHeader(MessageCoder.PROTOCOL_VERSION, GenuineConnectionType.Persistent, "Default");

            connectionInformation.Write(shareName);

            // let the server know that a client's share is ready
            Mutex mutex = null;

            try
            {
                mutex = WindowsAPI.OpenMutex(mutexName);

                NamedEvent _clientConnected = NamedEvent.OpenNamedEvent(clientConnected);
                NamedEvent _clientAccepted  = NamedEvent.OpenNamedEvent(clientAccepted);

                if (!GenuineUtility.WaitOne(mutex, GenuineUtility.GetMillisecondsLeft(timeout)))
                {
                    throw GenuineExceptions.Get_Connect_CanNotConnectToRemoteHost(url, "Can not acquire the lock for the global mutex.");
                }

                // wait until server accepts this client
                _clientAccepted.ManualResetEvent.Reset();
                _clientConnected.ManualResetEvent.Set();

                // copy client's name
                serverSharedMemoryConnection.LowLevel_SendSync(connectionInformation.BaseStream, timeout);

                if (!GenuineUtility.WaitOne(_clientAccepted.ManualResetEvent, GenuineUtility.GetMillisecondsLeft(timeout)))
                {
                    throw GenuineExceptions.Get_Connect_CanNotConnectToRemoteHost(url, "Remote server did not accept a request within the specified time span.");
                }
            }
            finally
            {
                if (mutex != null)
                {
                    try
                    {
                        mutex.ReleaseMutex();
                    }
                    catch
                    {
                    }

                    try
                    {
                        mutex.Close();
                    }
                    catch
                    {
                    }
                }
            }

            // get the connection-level Security Session
            string          connectionLevelSSName = this.ITransportContext.IParameterProvider[GenuineParameter.SecuritySessionForPersistentConnections] as string;
            SecuritySession securitySession       = null;

            if (connectionLevelSSName != null)
            {
                securitySession = this.ITransportContext.IKeyStore.GetKey(connectionLevelSSName).CreateSecuritySession(connectionLevelSSName, null);
            }

            // establish it
            if (securitySession != null && !securitySession.IsEstablished)
            {
                bool firstPass = true;
                for ( ; ;)
                {
                    inputStream = Stream.Null;

                    try
                    {
                        // prepare streams
                        if (!firstPass)
                        {
                            inputStream = sharedMemoryConnection.LowLevel_ReadSync(timeout);
                        }
                        else
                        {
                            firstPass = false;
                        }

                        outputStream = securitySession.EstablishSession(inputStream, true);

                        if (outputStream == null)
                        {
                            break;
                        }

                        // send a packet to the remote host
                        sharedMemoryConnection.LowLevel_SendSync(outputStream, timeout);
                        if (securitySession.IsEstablished)
                        {
                            break;
                        }
                    }
                    finally
                    {
                        if (inputStream != null)
                        {
                            inputStream.Close();
                        }
                        if (outputStream != null)
                        {
                            outputStream.Close();
                        }
                    }
                }
            }

            sharedMemoryConnection.ConnectionLevelSecurity = securitySession;

            // now send connection info through the established connection
            using (GenuineChunkedStream serializedLocalInfo = new GenuineChunkedStream(false))
            {
                // serialize local info
                BinaryWriter binaryWriter = new BinaryWriter(serializedLocalInfo);
                binaryWriter.Write((string)localUri);
                binaryWriter.Write((int)remote.LocalHostUniqueIdentifier);

                // and send it
                sharedMemoryConnection.LowLevel_SendSync(serializedLocalInfo, timeout);

                // read remote info
                using (Stream remoteUriStream = sharedMemoryConnection.LowLevel_ReadSync(timeout))
                {
                    BinaryReader binaryReader = new BinaryReader(remoteUriStream);
                    remoteUri = binaryReader.ReadString();
                    remoteHostUniqueIdentifier = binaryReader.ReadInt32();
                }
            }

            sharedMemoryConnection.Remote = remote;
            sharedMemoryConnection.Remote.UpdateUri(remoteUri, remoteHostUniqueIdentifier);
            sharedMemoryConnection.Remote.GenuinePersistentConnectionState = GenuinePersistentConnectionState.Opened;

            // LOG:
            if (binaryLogWriter != null && binaryLogWriter[LogCategory.HostInformation] > 0)
            {
                binaryLogWriter.WriteHostInformationEvent("SharedMemoryConnectionManager.LowLevel_OpenConnection",
                                                          LogMessageType.HostInformationCreated, null, remote,
                                                          GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, null, null,
                                                          sharedMemoryConnection.DbgConnectionId,
                                                          "HostInformation is ready for actions.");
            }

            // LOG:
            if (binaryLogWriter != null && binaryLogWriter[LogCategory.Connection] > 0)
            {
                binaryLogWriter.WriteEvent(LogCategory.Connection, "SharedMemoryConnectionManager.LowLevel_OpenConnection",
                                           LogMessageType.ConnectionEstablished, null, null, remote, null,
                                           GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name,
                                           securitySession, connectionLevelSSName,
                                           sharedMemoryConnection.DbgConnectionId, (int)GenuineConnectionType.Persistent, 0, 0, this.GetType().Name, null, null, null,
                                           "The connection to the remote host is established.");
            }

            return(sharedMemoryConnection);
        }
Beispiel #13
0
        /// <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);
        }