Exemplo n.º 1
0
        private void OnReceiveCStoreRequest(object sender, CStoreRequestReceivedEventArgs request)
        {
            try
            {
                if (__CurrentRequest != null && __MovedInstances != null)
                {
                    if (CanMoveCStoreRequest(request))
                    {
                        GatewaySession.Log(__Client, DicomCommandType.CMove, LogType.Debug, MessageDirection.Output, null,
                                           "[Gateway] Sending C-Move response to client \"" + __ClientAE + "\"");

                        lock ( _storeLock )
                        {
                            OnMoveDataSet(request.RequestDataSet);


                            GatewaySession.Log(__Client, DicomCommandType.CMove, LogType.Debug, MessageDirection.Output, null,
                                               "[Gateway] C-Move response sent successfully to client \"" + __ClientAE + "\"");
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                GatewaySession.Log(__Client, DicomCommandType.CMove, LogType.Error, MessageDirection.Output, null,
                                   "[Gateway] Failed to send C-Move response to client \"" + __ClientAE + "\"\n"
                                   + ex.Message);

                __CurrentStatus = DicomCommandStatusType.Failure;
            }
        }
Exemplo n.º 2
0
        private QueryRetrieveScu GetScu(AeInfo server)
        {
            QueryRetrieveScu scu           = null;
            bool             useSecurePort = (server.Port == 0) && (server.SecurePort != 0);
            int port = useSecurePort ? server.SecurePort : server.Port;

            if (useSecurePort)
            {
                GatewaySession.InitializeDicomSecurity(false);
                scu = new QueryRetrieveScu(string.Empty, DicomNetSecurityMode.Tls, GatewaySession._openSslOptions);
                scu.UseSecureHost = true;
                GatewaySession.SetCiphers(scu);
            }

            if (scu == null)
            {
                scu = new QueryRetrieveScu();
            }

            scu.AETitle     = server.AETitle;
            scu.HostAddress = IPAddress.Parse(server.Address);
            scu.HostPort    = port;

            return(scu);
        }
Exemplo n.º 3
0
        private void Find_AfterSecureLinkReady(object sender, AfterSecureLinkReadyEventArgs e)
        {
            DicomConnection connection = sender as DicomConnection;

            if (e.Error == DicomExceptionCode.Success)
            {
                DicomTlsCipherSuiteType cipher = connection.GetTlsCipherSuite();
                GatewaySession.Log(LogType.Information, String.Format(SECURE_LINK_READY_CIPHERSUITE, cipher.GetCipherFriendlyName()));
            }
            else
            {
                GatewaySession.Log(LogType.Information, String.Format(SECURE_LINK_FAILED, e.Error));
            }
        }
Exemplo n.º 4
0
        public bool IsAbstractSyntaxSupported(string abstractSyntax)
        {
            if (abstractSyntax == DicomUidType.PatientRootQueryFind || abstractSyntax == DicomUidType.PatientStudyQueryFind ||
                abstractSyntax == DicomUidType.StudyRootQueryFind)
            {
                if (!GatewaySession.HasGetwayLicense)
                {
                    string message = "[Gateway] Valid license for gateway server not found.  Abstract syntax not accepted by gateway server";

                    GatewaySession.Log(_Client, DicomCommandType.CFind, LogType.Error, MessageDirection.Input, null, message);
                }
                return(GatewaySession.HasGetwayLicense);
            }
            return(false);
        }
        /// <inheritdoc/>
        public virtual RequestContextModel GetContext(RequestHeader requestHeader,
                                                      RequestType requestType)
        {
            if (requestHeader == null)
            {
                throw new ArgumentNullException(nameof(requestHeader));
            }
            GatewaySession session = null;

            try {
                lock (_lock) {
                    // check for create / activate session request which are handled differently.
                    if (requestType == RequestType.CreateSession)
                    {
                        return(new RequestContextModel(requestHeader, requestType));
                    }
                    // find session.
                    if (_sessions.TryGetValue(requestHeader.AuthenticationToken, out session))
                    {
                        // validate request header in context of this session.
                        session.ValidateRequest(requestHeader, requestType);
                        return(new RequestContextModel(requestHeader, requestType, session));
                    }
                    // No session, validate the request as a session less request
                    var identity = ValidateSessionLessRequest(requestHeader.AuthenticationToken,
                                                              requestType);
                    return(new RequestContextModel(requestHeader, requestType, identity));
                }
            }
            catch (Exception e) {
                if (e is ServiceResultException sre &&
                    sre.StatusCode == StatusCodes.BadSessionNotActivated)
                {
                    if (session != null)
                    {
                        CloseSession(session.Id);
                    }
                }
                throw new ServiceResultException(e, StatusCodes.BadUnexpectedError);
            }
        }
Exemplo n.º 6
0
        private void OnMatchFound(DicomDataSet response)
        {
            try
            {
                if (null != MatchFound)
                {
                    try
                    {
                        GatewaySession.Log(__Client, DicomCommandType.CFind, LogType.Debug, MessageDirection.Output, null,
                                           "[Gateway] Sending C-Find response to client \"" + (__Client.IsAssociated() ? __Client.Association.Calling : string.Empty) + "\"");

                        DicomElement element = response.FindFirstElement(null, DicomTag.RetrieveAETitle, true);

                        if (null != element)
                        {
                            response.DeleteElement(element);
                        }

                        response.InsertElementAndSetValue(DicomTag.InstanceAvailability, "NEARLINE");

                        MatchFound(this, new MatchFoundEventArgs(response));

                        GatewaySession.Log(__Client, DicomCommandType.CFind, LogType.Debug, MessageDirection.Output, null,
                                           "[Gateway] C-Find response sent successfully to client \"" + (__Client.IsAssociated() ? __Client.Association.Calling : string.Empty) + "\"");
                    }
                    catch (Exception exception)
                    {
                        GatewaySession.Log(__Client, DicomCommandType.CFind, LogType.Error, MessageDirection.Output, null,
                                           "[Gateway] Faild to send C-Find response to client \"" + (__Client.IsAssociated() ? __Client.Association.Calling : string.Empty) + "\"\n"
                                           + exception.Message);
                    }
                }
            }
            finally
            {
                response.Dispose();
            }
        }
        /// <inheritdoc/>
        public virtual bool ActivateSession(RequestContextModel context,
                                            NodeId authenticationToken, SignatureData clientSignature,
                                            List <SoftwareCertificate> clientSoftwareCertificates,
                                            ExtensionObject userIdentityToken, SignatureData userTokenSignature,
                                            StringCollection localeIds, out byte[] serverNonce)
        {
            // find session.
            GatewaySession session = null;

            lock (_lock) {
                if (!_sessions.TryGetValue(authenticationToken, out session))
                {
                    throw new ServiceResultException(StatusCodes.BadSessionClosed);
                }
            }

            if (session.IsClosed)
            {
                throw new ServiceResultException(StatusCodes.BadSessionClosed);
            }

            // Activate session.
            var nonceLength = (uint)_configuration.NonceLength;

            serverNonce = Utils.Nonce.CreateNonce(nonceLength);
            var contextChanged = session.Activate(context, clientSignature,
                                                  clientSoftwareCertificates, userIdentityToken, userTokenSignature,
                                                  serverNonce);

            if (contextChanged)
            {
                _sessionActivated?.Invoke(session, null);
            }

            // indicates that the identity context for the session has changed.
            return(contextChanged);
        }
Exemplo n.º 8
0
        //[PresentationContext(DicomUidType.PatientRootQueryFind, new byte[] {1,0,1},DicomUidType.ImplicitVRLittleEndian)]
        //[PresentationContext(DicomUidType.PatientStudyQueryFind, DicomUidType.ImplicitVRLittleEndian)]
        //[PresentationContext(DicomUidType.StudyRootQueryFind, DicomUidType.ImplicitVRLittleEndian)]
        public DicomCommandStatusType OnFind
        (
            DicomClient client,
            byte presentationId,
            int messageId,
            string affectedClass,
            DicomCommandPriorityType priority,
            DicomDataSet request
        )
        {
            int countOfServersConnection;


            try
            {
                __Client = client;

                if (null == __ServersManager)
                {
                    GatewaySession.Log(string.Empty, string.Empty, -1, DicomCommandType.CFind, LogType.Error, MessageDirection.None, null, "[Gateway] Gateway server not available");

                    return(DicomCommandStatusType.ProcessingFailure);
                }

                countOfServersConnection = 0;

                //make sure to break the loop on success or normal failure
                while (countOfServersConnection < __ServersManager.Servers.Count)
                {
                    AeInfo           currentRemoteServer;
                    DicomScp         remoteScp;
                    QueryRetrieveScu cFindScu;


                    countOfServersConnection++;

                    currentRemoteServer = __ServersManager.GetRemoteServer();

                    remoteScp = GetScp(currentRemoteServer);
                    cFindScu  = GetScu(__ServersManager.Gateway.Server);

                    try
                    {
                        RegisterEvents(cFindScu);

                        if (cFindScu.SecurityMode == DicomNetSecurityMode.Tls)
                        {
                            GatewaySession.InitializeDicomSecurity(false);
                            GatewaySession.SetCiphers(cFindScu);
                            GatewaySession.SetSecurityCertificates(cFindScu);
                        }

                        __CFindScu = cFindScu;

                        __CurrentStatus = DicomCommandStatusType.Success;

                        GatewaySession.Log(client, DicomCommandType.CFind, LogType.Information, MessageDirection.Output, request,
                                           "[Gateway] Sending C-Find request to remote server \"" + currentRemoteServer.AETitle + "\"");

                        cFindScu.Find(remoteScp, request);

                        GatewaySession.Log(client, DicomCommandType.CFind, LogType.Information, MessageDirection.None, null,
                                           "[Gateway] C-Find request sent successfully \"" + currentRemoteServer.AETitle + "\"");

                        break;
                    }
                    catch (ClientConnectionException exception)
                    {
                        GatewaySession.Log(client, DicomCommandType.CFind, LogType.Warning, MessageDirection.None, null, "[Gateway] Connecting to server failed \"" + currentRemoteServer.AETitle + "\"\n" + exception.Message);

                        __ServersManager.SetRemoteServerConnectionFailure();

                        __CurrentStatus = DicomCommandStatusType.Failure;
                    }
                    catch (ClientCommunicationException exception)
                    {
                        __CurrentStatus = exception.Status;

                        GatewaySession.Log(client, DicomCommandType.CFind, LogType.Error, MessageDirection.None, null, "[Gateway] Communicating with server failed \"" + currentRemoteServer.AETitle + "\"\n" + exception.Message);

                        break;
                    }
                    catch (DicomException exception)
                    {
                        if (__CurrentStatus == DicomCommandStatusType.Success)
                        {
                            __CurrentStatus = DicomCommandStatusType.Failure;
                        }

                        GatewaySession.Log(client, DicomCommandType.CFind, LogType.Error, MessageDirection.None, null, "[Gateway] Forwarding to server failed \"" + currentRemoteServer.AETitle + "\"\n" + exception.Message);

                        break;
                    }
                    catch (Exception exception)
                    {
                        if (__CurrentStatus == DicomCommandStatusType.Success)
                        {
                            __CurrentStatus = DicomCommandStatusType.ProcessingFailure;
                        }

                        GatewaySession.Log(client, DicomCommandType.CFind, LogType.Error, MessageDirection.None, null, "[Gateway] Forwarding to server failed \"" + currentRemoteServer.AETitle + "\"\n" + exception.Message);

                        break;
                    }
                    finally
                    {
                        UnregisterEvents(cFindScu);

                        cFindScu.Dispose();

                        __CFindScu = null;
                    }
                }

                return(__CurrentStatus);
            }
            finally
            {
                request.Dispose();
            }
        }
        /// <inheritdoc/>
        public IServerSession CreateSession(RequestContextModel context,
                                            EndpointDescription endpoint, X509Certificate2 serverCertificate,
                                            byte[] clientNonce, X509Certificate2 clientCertificate, double requestedTimeout,
                                            out NodeId sessionId, out NodeId authenticationToken,
                                            out byte[] serverNonce, out double revisedTimeout)
        {
            GatewaySession session = null;

            lock (_lock) {
                // check session count.
                if (_configuration.MaxSessionCount > 0 &&
                    _sessions.Count >= _configuration.MaxSessionCount)
                {
                    throw new ServiceResultException(StatusCodes.BadTooManySessions);
                }

                // check for same Nonce in another session
                if (clientNonce != null)
                {
                    foreach (var sessionIterator in _sessions.Values)
                    {
                        if (Utils.CompareNonce(sessionIterator.ClientNonce, clientNonce))
                        {
                            throw new ServiceResultException(StatusCodes.BadNonceInvalid);
                        }
                    }
                }

                // Create session
                sessionId           = new NodeId(Guid.NewGuid());
                authenticationToken = new NodeId(Utils.Nonce.CreateNonce(kDefaultNonceLength));
                var nonceLength = (uint)_configuration.NonceLength;
                serverNonce = Utils.Nonce.CreateNonce(nonceLength == 0 ? kDefaultNonceLength :
                                                      nonceLength);

                var maxSessionTimeout = _configuration.MaxSessionTimeout.TotalMilliseconds;
                var minSessionTimeout = _configuration.MinSessionTimeout.TotalMilliseconds;
                if (requestedTimeout > maxSessionTimeout)
                {
                    revisedTimeout = maxSessionTimeout;
                }
                else if (requestedTimeout < minSessionTimeout)
                {
                    revisedTimeout = minSessionTimeout;
                }
                else
                {
                    revisedTimeout = requestedTimeout;
                }

                // Add session to list
                session = new GatewaySession(this, context, sessionId, endpoint,
                                             clientCertificate, clientNonce, serverCertificate, serverNonce,
                                             TimeSpan.FromMilliseconds(revisedTimeout), _configuration.MaxRequestAge,
                                             _validateUser);
                if (!_sessions.TryAdd(authenticationToken, session))
                {
                    throw new ServiceResultException(StatusCodes.BadInternalError);
                }
            }

            _sessionCreated?.Invoke(session, null);
            return(session);
        }
Exemplo n.º 10
0
        //[PresentationContext(DicomUidType.PatientRootQueryMove, new byte[] {1,0,1},DicomUidType.ImplicitVRLittleEndian)]
        //[PresentationContext(DicomUidType.PatientStudyQueryMove, DicomUidType.ImplicitVRLittleEndian)]
        //[PresentationContext(DicomUidType.StudyRootQueryMove, DicomUidType.ImplicitVRLittleEndian)]
        public DicomCommandStatusType OnMove
        (
            DicomClient client,
            byte presentationId,
            int messageId,
            string affectedClass,
            DicomCommandPriorityType priority,
            string moveAE,
            DicomDataSet request
        )
        {
            try
            {
                int countOfServersConnection;


                __Client   = client;
                __ClientAE = client.AETitle;

                if (null == __ServersManager)
                {
                    GatewaySession.Log(string.Empty, string.Empty, -1, DicomCommandType.CMove, LogType.Error, MessageDirection.None, null, "[Gateway] Gateway server not available");

                    return(DicomCommandStatusType.ProcessingFailure);
                }

                countOfServersConnection = 0;

                //make sure to break the loop on success or normal failure
                while (countOfServersConnection < __ServersManager.Servers.Count)
                {
                    AeInfo           currentRemoteServer;
                    DicomScp         remoteScp;
                    QueryRetrieveScu cMoveScu;


                    countOfServersConnection++;

                    currentRemoteServer = __ServersManager.GetRemoteServer( );
                    remoteScp           = GetScp(currentRemoteServer);

                    cMoveScu = GetScu(__ServersManager.Gateway.Server);

                    try
                    {
                        RegisterEvents(cMoveScu);

                        if (cMoveScu.SecurityMode == DicomNetSecurityMode.Tls)
                        {
                            // Set the TLS certificate
                            cMoveScu.SetTlsClientCertificate(
                                GatewaySession.DicomSecurityAgent.CertificateFileName,
                                GatewaySession.DicomSecurityAgent.CertificateType,
                                GatewaySession.DicomSecurityAgent.KeyFileName.Length > 0 ? GatewaySession.DicomSecurityAgent.KeyFileName : null);
                        }

                        __CMoveScu = cMoveScu;

                        __CurrentStatus = DicomCommandStatusType.Success;

                        __CurrentRequest     = new MoveRequestInformation(request);
                        __MovedInstances     = new List <string> ( );
                        __ForwardedInstances = new List <string> ( );

                        ServerEventBroker.Instance.Subscribe <CStoreRequestReceivedEventArgs> (OnReceiveCStoreRequest);
                        ServerEventBroker.Instance.Subscribe <CStoreResponseSentEventArgs>    (OnSendCStoreResponse);

                        try
                        {
                            GatewaySession.Log(client, DicomCommandType.CMove, LogType.Information, MessageDirection.Output, request,
                                               "[Gateway] Sending C-Move request to remote server \"" + currentRemoteServer.AETitle + "\"");

                            cMoveScu.Move(remoteScp, __ServersManager.Gateway.Server.AETitle, request);

                            GatewaySession.Log(client, DicomCommandType.CMove, LogType.Information, MessageDirection.Output, request,
                                               "[Gateway] C-Move request sent successfully \"" + currentRemoteServer.AETitle + "\"");
                        }
                        finally
                        {
                            ServerEventBroker.Instance.Unsubscribe <CStoreRequestReceivedEventArgs> (OnReceiveCStoreRequest);
                            ServerEventBroker.Instance.Unsubscribe <CStoreResponseSentEventArgs>    (OnSendCStoreResponse);
                        }

                        break;
                    }
                    catch (ClientConnectionException exception)
                    {
                        GatewaySession.Log(client, DicomCommandType.CMove, LogType.Warning, MessageDirection.None, null, "[Gateway] Connecting to server failed \"" + currentRemoteServer.AETitle + "\"\n" + exception.Message);

                        __ServersManager.SetRemoteServerConnectionFailure( );

                        if (countOfServersConnection >= __ServersManager.Servers.Count)
                        {
                            __CurrentStatus = DicomCommandStatusType.Failure;
                        }
                    }
                    catch (ClientCommunicationException exception)
                    {
                        //Don't update the status, just log a message here
                        //__CurrentStatus = exception.Status ;

                        GatewaySession.Log(client, DicomCommandType.CMove, LogType.Warning, MessageDirection.None, null, "[Gateway] Problem occured moving from server \"" + currentRemoteServer.AETitle + "\"\n" + exception.Message);

                        break;
                    }
                    catch (DicomException exception)
                    {
                        if (__CurrentStatus == DicomCommandStatusType.Success)
                        {
                            __CurrentStatus = DicomCommandStatusType.Failure;
                        }

                        GatewaySession.Log(client, DicomCommandType.CMove, LogType.Error, MessageDirection.None, null, "[Gateway] Sending to server failed \"" + currentRemoteServer.AETitle + "\"\n" + exception.Message);

                        break;
                    }
                    catch (Exception exception)
                    {
                        if (__CurrentStatus == DicomCommandStatusType.Success)
                        {
                            __CurrentStatus = DicomCommandStatusType.ProcessingFailure;
                        }

                        GatewaySession.Log(client, DicomCommandType.CMove, LogType.Error, MessageDirection.None, null, "[Gateway] Sending to server failed \"" + currentRemoteServer.AETitle + "\"\n" + exception.Message);

                        break;
                    }
                    finally
                    {
                        UnregisterEvents(cMoveScu);

                        cMoveScu.Dispose( );

                        __CMoveScu = null;
                    }
                }

                return(__CurrentStatus);
            }
            finally
            {
                request.Dispose( );
            }
        }
Exemplo n.º 11
0
        private void OnSendCStoreResponse(object sender, CStoreResponseSentEventArgs response)
        {
            try
            {
                bool process = false;


                lock ( _instancesListLock )
                {
                    process = (__MovedInstances.Contains(response.Instance) && !__ForwardedInstances.Contains(response.Instance));
                }

                if (process && response.Status == DicomCommandStatusType.Success)
                {
                    if (ServiceLocator.IsRegistered <ForwardOptions> ( ) && DataAccessServices.IsDataAccessServiceRegistered <IForwardDataAccessAgent> ( ))
                    {
                        ForwardOptions          forwardOptions = ServiceLocator.Retrieve <ForwardOptions> ( );
                        IForwardDataAccessAgent dataAccess     = DataAccessServices.GetDataAccessService <IForwardDataAccessAgent> ( );

                        if (null != forwardOptions && null != dataAccess)
                        {
                            DateTime?expires     = null;
                            DateTime forwardDate = DateTime.Now;


                            if (dataAccess.IsForwarded(response.Instance))
                            {
                                return;
                            }

                            if (forwardOptions.ImageHold != null && forwardOptions.ImageHold != 0)
                            {
                                switch (forwardOptions.HoldInterval)
                                {
                                case HoldInterval.Days:
                                {
                                    expires = forwardDate.AddDays(forwardOptions.ImageHold.Value);
                                }
                                break;

                                case HoldInterval.Months:
                                {
                                    expires = forwardDate.AddMonths(forwardOptions.ImageHold.Value);
                                }
                                break;

                                default:
                                {
                                    expires = forwardDate.AddYears(forwardOptions.ImageHold.Value);
                                }

                                break;
                                }
                            }

                            dataAccess.SetInstanceForwarded(response.Instance, forwardDate, expires);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                GatewaySession.Log(__Client, DicomCommandType.CMove, LogType.Error, MessageDirection.Output, null, "[Gateway] Failed to set instance forwarding.\n" + ex.Message);
            }
        }