open62541 icon indicating copy to clipboard operation
open62541 copied to clipboard

When the Client connection fails, the Session on the Server is not closed.

Open yirongliang opened this issue 1 year ago • 2 comments

Description

I use UA.NET's Quickstarts.ReferenceServer as the test server and open62541 as the client test.

I'm testing that the Server returns the BadIdentityTokenRejected error status. When the connection has been closed, the Session is still retained on the Server side. This causes every time I re-establish a connection, the Server side will continue to generate new Sessions until the Server can no longer accept new connections. I used UaExpert to conduct the same BadIdentityTokenRejected test, and it can close the Server-side Session normally.

The following is the message from my single connection:

[2024-06-26 17:29:28.527 (UTC+0800)] info/securitypolicy The Basic128Rsa15 security policy with openssl is added. [2024-06-26 17:29:28.528 (UTC+0800)] info/securitypolicy The basic256 security policy with openssl is added. [2024-06-26 17:29:28.528 (UTC+0800)] info/securitypolicy The Aes256Sha256RsaPss security policy with openssl is added. [2024-06-26 17:29:28.528 (UTC+0800)] info/securitypolicy The basic256sha256 security policy with openssl is added. [2024-06-26 17:29:28.529 (UTC+0800)] info/securitypolicy The Aes128Sha256RsaOaep security policy with openssl is added. [2024-06-26 17:29:28.529 (UTC+0800)] info/securitypolicy The Basic128Rsa15 security policy with openssl is added. [2024-06-26 17:29:28.529 (UTC+0800)] info/securitypolicy The basic256 security policy with openssl is added. [2024-06-26 17:29:28.530 (UTC+0800)] info/securitypolicy The Aes256Sha256RsaPss security policy with openssl is added. [2024-06-26 17:29:28.531 (UTC+0800)] info/securitypolicy The basic256sha256 security policy with openssl is added. [2024-06-26 17:29:28.532 (UTC+0800)] info/securitypolicy The Aes128Sha256RsaOaep security policy with openssl is added. [2024-06-26 17:29:28.533 (UTC+0800)] info/eventloop Starting the EventLoop [2024-06-26 17:29:28.533 (UTC+0800)] warn/client skip verifying ApplicationURI for the SecurityPolicy http://opcfoundation.org/UA/SecurityPolicy#None [2024-06-26 17:29:28.537 (UTC+0800)] info/network TCP 1696 | Opening a connection to "localhost" on port 62541 [2024-06-26 17:29:28.539 (UTC+0800)] info/channel TCP 1696 | SC 33 | SecureChannel opened with SecurityPolicy http://opcfoundation.org/UA/SecurityPolicy#None and a revised lifetime of 600.00s [2024-06-26 17:29:28.540 (UTC+0800)] info/client Client Status: ChannelState: Open, SessionState: Closed, ConnectStatus: Good [2024-06-26 17:29:28.542 (UTC+0800)] info/client Use the EndpointURL opc.tcp://localhost:62541/Quickstarts/ReferenceServer returned from FindServers [2024-06-26 17:29:28.544 (UTC+0800)] info/channel TCP 1696 | SC 33 | SecureChannel closed [2024-06-26 17:29:28.546 (UTC+0800)] warn/client skip verifying ApplicationURI for the SecurityPolicy http://opcfoundation.org/UA/SecurityPolicy#None [2024-06-26 17:29:28.551 (UTC+0800)] info/network TCP 1688 | Opening a connection to "localhost" on port 62541 [2024-06-26 17:29:28.552 (UTC+0800)] info/network TCP 1696 | Socket closed [2024-06-26 17:29:28.553 (UTC+0800)] info/channel TCP 1688 | SC 34 | SecureChannel opened with SecurityPolicy http://opcfoundation.org/UA/SecurityPolicy#None and a revised lifetime of 600.00s [2024-06-26 17:29:28.553 (UTC+0800)] info/client Client Status: ChannelState: Open, SessionState: Closed, ConnectStatus: Good [2024-06-26 17:29:28.555 (UTC+0800)] warn/client The server returned Endpoints with a different EndpointUrl opc.https://localhost:62540/Quickstarts/ReferenceServer than was used to initialize the connection: opc.tcp://localhost:62541/Quickstarts/ReferenceServer. Some servers require a complete match of the EndpointUrl/DiscoveryUrl (including the path) to return all endpoints. [2024-06-26 17:29:28.556 (UTC+0800)] info/client Rejecting endpoint 1: security mode doesn't match [2024-06-26 17:29:28.557 (UTC+0800)] info/client Rejecting endpoint 2: security mode doesn't match [2024-06-26 17:29:28.557 (UTC+0800)] info/client Rejecting endpoint 3: security mode doesn't match [2024-06-26 17:29:28.558 (UTC+0800)] info/client Rejecting endpoint 4: security mode doesn't match [2024-06-26 17:29:28.559 (UTC+0800)] info/client Rejecting UserTokenPolicy 0 (anonymous) in endpoint 5: configuration doesn't match [2024-06-26 17:29:28.561 (UTC+0800)] info/client Rejecting UserTokenPolicy 1 (username) in endpoint 5: configuration doesn't match [2024-06-26 17:29:28.563 (UTC+0800)] info/client Rejecting endpoint 6: security policy doesn't match. [2024-06-26 17:29:28.565 (UTC+0800)] info/client Rejecting endpoint 7: security policy doesn't match. [2024-06-26 17:29:28.568 (UTC+0800)] info/client Selected endpoint 5 in URL opc.tcp://localhost:62541/Quickstarts/ReferenceServer with SecurityMode SignAndEncrypt and SecurityPolicy http://opcfoundation.org/UA/SecurityPolicy#Basic256Sha256 [2024-06-26 17:29:28.573 (UTC+0800)] info/client Selected UserTokenPolicy 15 with UserTokenType Certificate and SecurityPolicy http://opcfoundation.org/UA/SecurityPolicy#Basic256Sha256 [2024-06-26 17:29:28.576 (UTC+0800)] info/channel TCP 1688 | SC 34 | SecureChannel closed [2024-06-26 17:29:28.577 (UTC+0800)] warn/client skip verifying ApplicationURI for the SecurityPolicy http://opcfoundation.org/UA/SecurityPolicy#None [2024-06-26 17:29:28.580 (UTC+0800)] info/securitypolicy The basic256sha256 security policy channel with openssl is created. [2024-06-26 17:29:28.584 (UTC+0800)] info/network TCP 1300 | Opening a connection to "localhost" on port 62541 [2024-06-26 17:29:28.589 (UTC+0800)] info/network TCP 1688 | Socket closed [2024-06-26 17:29:28.620 (UTC+0800)] warn/userland No certificate store configured. Accepting the certificate. [2024-06-26 17:29:28.630 (UTC+0800)] info/channel TCP 1300 | SC 35 | SecureChannel opened with SecurityPolicy http://opcfoundation.org/UA/SecurityPolicy#Basic256Sha256 and a revised lifetime of 600.00s [2024-06-26 17:29:28.631 (UTC+0800)] info/client Client Status: ChannelState: Open, SessionState: Closed, ConnectStatus: Good [2024-06-26 17:29:28.648 (UTC+0800)] info/securitypolicy The basic256sha256 security policy channel with openssl is created. [2024-06-26 17:29:28.669 (UTC+0800)] info/securitypolicy The basic256sha256 security policy channel with openssl is deleted. [2024-06-26 17:29:28.671 (UTC+0800)] info/client Client Status: ChannelState: Open, SessionState: Created, ConnectStatus: Good [2024-06-26 17:29:28.682 (UTC+0800)] info/client Received a ServiceFault response [2024-06-26 17:29:28.697 (UTC+0800)] error/client Session cannot be activated with StatusCode BadIdentityTokenRejected. The client cannot recover from this, closing the connection. [2024-06-26 17:29:28.700 (UTC+0800)] info/client Client Status: ChannelState: Closing, SessionState: Closed, ConnectStatus: BadIdentityTokenRejected [2024-06-26 17:29:28.705 (UTC+0800)] info/channel TCP 1300 | SC 35 | SecureChannel closed [2024-06-26 17:29:28.708 (UTC+0800)] info/securitypolicy The basic256sha256 security policy channel with openssl is deleted. [2024-06-26 17:29:28.711 (UTC+0800)] info/client Client Status: ChannelState: Fresh, SessionState: Closed, ConnectStatus: BadIdentityTokenRejected [2024-06-26 17:29:28.714 (UTC+0800)] info/network TCP 1300 | Socket closed [2024-06-26 17:29:33.964 (UTC+0800)] info/eventloop Stopping the EventLoop [2024-06-26 17:29:33.964 (UTC+0800)] info/network UDP | Shutting down the ConnectionManager [2024-06-26 17:29:33.965 (UTC+0800)] info/network TCP | Shutting down the ConnectionManager [2024-06-26 17:29:33.965 (UTC+0800)] info/eventloop The EventLoop has stopped

Checklist

Please provide the following information:

  • [X] open62541 Version (release number or git tag): 1.4.0
  • [X] Other OPC UA SDKs used (client or server): Client
  • [X] Operating system: Windows 10
  • [X] Logs (with UA_LOGLEVEL set as low as necessary) attached
  • [ ] Wireshark network dump attached
  • [ ] Self-contained code example attached
  • [ ] Critical issue

yirongliang avatar Jun 26 '24 09:06 yirongliang

In general it is a good idea to keep a session open. The session might have existed prior and we try to activate an existing session for the new client.

But, if we just created the session ourselves and authentication fails, then we can also just delete it. Any work towards this implementation is welcome.

jpfr avatar Jun 26 '24 11:06 jpfr

I added a call to sendCloseSession in the responseActivateSession function. This seems to solve my problem. I don't know if this is the right thing to do.

UA_ActivateSessionResponse *ar = (UA_ActivateSessionResponse*)response;
if(ar->responseHeader.serviceResult != UA_STATUSCODE_GOOD) {
    /* Activating the Session failed */
    /* Configuration option to not create a new Session */
    if(client->config.noNewSession) {
        UA_LOG_ERROR(client->config.logging, UA_LOGCATEGORY_CLIENT,
                     "Session cannot be activated with StatusCode %s. "
                     "The client is configured not to create a new Session.",
                     UA_StatusCode_name(ar->responseHeader.serviceResult));
        client->connectStatus = ar->responseHeader.serviceResult;
        cleanupSession(client);
        closeSecureChannel(client);
        UA_UNLOCK(&client->clientMutex);
        return;
    }

    /* The Session is no longer usable. Create a brand new one. */
    if(ar->responseHeader.serviceResult == UA_STATUSCODE_BADSESSIONIDINVALID ||
       ar->responseHeader.serviceResult == UA_STATUSCODE_BADSESSIONCLOSED) {
        UA_LOG_WARNING(client->config.logging, UA_LOGCATEGORY_CLIENT,
                       "Session to be activated no longer exists. Create a new Session.");
        cleanupSession(client);
        client->connectStatus = createSessionAsync(client);
        UA_UNLOCK(&client->clientMutex);
        return;
    }

    sendCloseSession2(client);
    cleanupSession(client);   

    /* Something else is wrong. Maybe the credentials no longer work. Give up. */
    UA_LOG_ERROR(client->config.logging, UA_LOGCATEGORY_CLIENT,
                 "Session cannot be activated with StatusCode %s. "
                 "The client cannot recover from this, closing the connection.",
                 UA_StatusCode_name(ar->responseHeader.serviceResult));
    client->connectStatus = ar->responseHeader.serviceResult;


    closeSecureChannel(client);
    UA_UNLOCK(&client->clientMutex);
    return;
}

I modified sendCloseSession2 based on sendCloseSession. __Client_Service() cannot be called here because it will check the connection status and cannot send the request.

yirongliang avatar Jun 27 '24 07:06 yirongliang