Переглянути джерело

cleanup of the session and securechannel service

Julius Pfrommer 9 роки тому
батько
коміт
0f88ed7f56

+ 8 - 15
src/server/ua_securechannel_manager.c

@@ -43,16 +43,8 @@ UA_StatusCode
 UA_SecureChannelManager_open(UA_SecureChannelManager *cm, UA_Connection *conn,
                              const UA_OpenSecureChannelRequest *request,
                              UA_OpenSecureChannelResponse *response) {
-    switch(request->securityMode) {
-    case UA_MESSAGESECURITYMODE_NONE:
-        break;
-    case UA_MESSAGESECURITYMODE_INVALID:
-    case UA_MESSAGESECURITYMODE_SIGN:
-    case UA_MESSAGESECURITYMODE_SIGNANDENCRYPT:
-    default:
-        response->responseHeader.serviceResult = UA_STATUSCODE_BADSECURITYMODEREJECTED;
-        return response->responseHeader.serviceResult;
-    }
+    if(request->securityMode != UA_MESSAGESECURITYMODE_NONE)
+        return UA_STATUSCODE_BADSECURITYMODEREJECTED;
 
     channel_list_entry *entry = UA_malloc(sizeof(channel_list_entry));
     if(!entry)
@@ -63,9 +55,9 @@ UA_SecureChannelManager_open(UA_SecureChannelManager *cm, UA_Connection *conn,
     response->responseHeader.timestamp = UA_DateTime_now();
     response->serverProtocolVersion = 0;
 
-    entry->channel.securityToken.channelId       = cm->lastChannelId++;
-    entry->channel.securityToken.tokenId         = cm->lastTokenId++;
-    entry->channel.securityToken.createdAt       = UA_DateTime_now();
+    entry->channel.securityToken.channelId = cm->lastChannelId++;
+    entry->channel.securityToken.tokenId = cm->lastTokenId++;
+    entry->channel.securityToken.createdAt = UA_DateTime_now();
     entry->channel.securityToken.revisedLifetime = (request->requestedLifetime > cm->maxChannelLifetime) ?
                                                    cm->maxChannelLifetime : request->requestedLifetime;
     /* pragmatic workaround to get clients requesting lifetime of 0 working */
@@ -82,7 +74,6 @@ UA_SecureChannelManager_open(UA_SecureChannelManager *cm, UA_Connection *conn,
 
     UA_Connection_attachSecureChannel(conn, &entry->channel);
     LIST_INSERT_HEAD(&cm->channels, entry, pointers);
-
     return UA_STATUSCODE_GOOD;
 }
 
@@ -91,7 +82,7 @@ UA_SecureChannelManager_renew(UA_SecureChannelManager *cm, UA_Connection *conn,
                               const UA_OpenSecureChannelRequest *request,
                               UA_OpenSecureChannelResponse *response) {
     UA_SecureChannel *channel = conn->channel;
-    if(channel == UA_NULL)
+    if(!channel)
         return UA_STATUSCODE_BADINTERNALERROR;
 
     /* if no security token is already issued */
@@ -108,8 +99,10 @@ UA_SecureChannelManager_renew(UA_SecureChannelManager *cm, UA_Connection *conn,
         if(channel->nextSecurityToken.revisedLifetime == 0)
             channel->nextSecurityToken.revisedLifetime = cm->maxChannelLifetime;
     }
+
     if(channel->clientNonce.data)
         UA_ByteString_deleteMembers(&channel->clientNonce);
+
     UA_ByteString_copy(&request->clientNonce, &channel->clientNonce);
     UA_ByteString_copy(&channel->serverNonce, &response->serverNonce);
     UA_ChannelSecurityToken_copy(&channel->nextSecurityToken, &response->securityToken);

+ 22 - 11
src/server/ua_securechannel_manager.h

@@ -21,18 +21,29 @@ typedef struct UA_SecureChannelManager {
     UA_UInt32   lastTokenId;
 } UA_SecureChannelManager;
 
-UA_StatusCode UA_SecureChannelManager_init(UA_SecureChannelManager *cm, UA_UInt32 maxChannelCount,
-                                           UA_UInt32 tokenLifetime, UA_UInt32 startChannelId,
-                                           UA_UInt32 startTokenId);
+UA_StatusCode
+UA_SecureChannelManager_init(UA_SecureChannelManager *cm, UA_UInt32 maxChannelCount,
+                             UA_UInt32 tokenLifetime, UA_UInt32 startChannelId,
+                             UA_UInt32 startTokenId);
+
 void UA_SecureChannelManager_deleteMembers(UA_SecureChannelManager *cm);
+
 void UA_SecureChannelManager_cleanupTimedOut(UA_SecureChannelManager *cm, UA_DateTime now);
-UA_StatusCode UA_SecureChannelManager_open(UA_SecureChannelManager *cm, UA_Connection *conn,
-                                           const UA_OpenSecureChannelRequest *request,
-                                           UA_OpenSecureChannelResponse *response);
-UA_StatusCode UA_SecureChannelManager_renew(UA_SecureChannelManager *cm, UA_Connection *conn,
-                                            const UA_OpenSecureChannelRequest *request,
-                                            UA_OpenSecureChannelResponse *response);
-UA_SecureChannel * UA_SecureChannelManager_get(UA_SecureChannelManager *cm, UA_UInt32 channelId);
-UA_StatusCode UA_SecureChannelManager_close(UA_SecureChannelManager *cm, UA_UInt32 channelId);
+
+UA_StatusCode
+UA_SecureChannelManager_open(UA_SecureChannelManager *cm, UA_Connection *conn,
+                             const UA_OpenSecureChannelRequest *request,
+                             UA_OpenSecureChannelResponse *response);
+
+UA_StatusCode
+UA_SecureChannelManager_renew(UA_SecureChannelManager *cm, UA_Connection *conn,
+                              const UA_OpenSecureChannelRequest *request,
+                              UA_OpenSecureChannelResponse *response);
+
+UA_SecureChannel *
+UA_SecureChannelManager_get(UA_SecureChannelManager *cm, UA_UInt32 channelId);
+
+UA_StatusCode
+UA_SecureChannelManager_close(UA_SecureChannelManager *cm, UA_UInt32 channelId);
 
 #endif /* UA_CHANNEL_MANAGER_H_ */

+ 7 - 3
src/server/ua_services_securechannel.c

@@ -7,7 +7,9 @@ void Service_OpenSecureChannel(UA_Server *server, UA_Connection *connection,
                                UA_OpenSecureChannelResponse *response) {
     // todo: if(request->clientProtocolVersion != protocolVersion)
     if(request->requestType == UA_SECURITYTOKENREQUESTTYPE_ISSUE) {
-        UA_SecureChannelManager_open(&server->secureChannelManager, connection, request, response);
+        response->responseHeader.serviceResult =
+            UA_SecureChannelManager_open(&server->secureChannelManager, connection, request, response);
+
         if(response->responseHeader.serviceResult == UA_STATUSCODE_GOOD)
             UA_LOG_DEBUG(server->logger, UA_LOGCATEGORY_SECURECHANNEL,
                          "Opened SecureChannel %i on Connection %i",
@@ -16,7 +18,9 @@ void Service_OpenSecureChannel(UA_Server *server, UA_Connection *connection,
             UA_LOG_DEBUG(server->logger, UA_LOGCATEGORY_SECURECHANNEL,
                          "Opening SecureChannel on Connection %i failed", connection->sockfd);
     } else {
-        UA_SecureChannelManager_renew(&server->secureChannelManager, connection, request, response);
+        response->responseHeader.serviceResult =
+            UA_SecureChannelManager_renew(&server->secureChannelManager, connection, request, response);
+
         if(response->responseHeader.serviceResult == UA_STATUSCODE_GOOD)
             UA_LOG_DEBUG(server->logger, UA_LOGCATEGORY_SECURECHANNEL,
                          "Renewed SecureChannel %i on Connection %i",
@@ -27,9 +31,9 @@ void Service_OpenSecureChannel(UA_Server *server, UA_Connection *connection,
     }
 }
 
+/* The server does not send a CloseSecureChannel response */
 void Service_CloseSecureChannel(UA_Server *server, UA_Int32 channelId) {
     UA_LOG_DEBUG(server->logger, UA_LOGCATEGORY_SECURECHANNEL,
                  "Closing SecureChannel %i", channelId);
     UA_SecureChannelManager_close(&server->secureChannelManager, channelId);
-    // 62451 Part 6 Chapter 7.1.4 - The server does not send a CloseSecureChannel response
 }

+ 25 - 19
src/server/ua_session_manager.c

@@ -2,8 +2,9 @@
 #include "ua_statuscodes.h"
 #include "ua_util.h"
 
-UA_StatusCode UA_SessionManager_init(UA_SessionManager *sessionManager, UA_UInt32 maxSessionCount,
-                                    UA_UInt32 maxSessionLifeTime, UA_UInt32 startSessionId) {
+UA_StatusCode
+UA_SessionManager_init(UA_SessionManager *sessionManager, UA_UInt32 maxSessionCount,
+                       UA_UInt32 maxSessionLifeTime, UA_UInt32 startSessionId) {
     LIST_INIT(&sessionManager->sessions);
     sessionManager->maxSessionCount = maxSessionCount;
     sessionManager->lastSessionId   = startSessionId;
@@ -21,36 +22,35 @@ void UA_SessionManager_deleteMembers(UA_SessionManager *sessionManager, UA_Serve
     }
 }
 
-void UA_SessionManager_cleanupTimedOut(UA_SessionManager *sessionManager, UA_Server* server, UA_DateTime now) {
-    session_list_entry *sentry = LIST_FIRST(&sessionManager->sessions);
-    while(sentry) {
+void UA_SessionManager_cleanupTimedOut(UA_SessionManager *sessionManager,
+                                       UA_Server* server, UA_DateTime now) {
+    session_list_entry *sentry, *temp;
+    LIST_FOREACH_SAFE(sentry, &sessionManager->sessions, pointers, temp) {
         if(sentry->session.validTill < now) {
-            session_list_entry *next = LIST_NEXT(sentry, pointers);
-            LIST_REMOVE(sentry, pointers);
             UA_Session_deleteMembersCleanup(&sentry->session, server);
             UA_free(sentry);
             sessionManager->currentSessionCount--;
-            sentry = next;
-        } else {
-            sentry = LIST_NEXT(sentry, pointers);
         }
     }
 }
 
-UA_Session * UA_SessionManager_getSession(UA_SessionManager *sessionManager, const UA_NodeId *token) {
+UA_Session *
+UA_SessionManager_getSession(UA_SessionManager *sessionManager, const UA_NodeId *token) {
     session_list_entry *current = UA_NULL;
     LIST_FOREACH(current, &sessionManager->sessions, pointers) {
-        if(UA_NodeId_equal(&current->session.authenticationToken, token))
-            break;
+        if(UA_NodeId_equal(&current->session.authenticationToken, token)) {
+            if(UA_DateTime_now() > current->session.validTill)
+                return UA_NULL;
+            return &current->session;
+        }
     }
-    if(!current || UA_DateTime_now() > current->session.validTill)
-        return UA_NULL;
-    return &current->session;
+    return UA_NULL;
 }
 
 /** Creates and adds a session. But it is not yet attached to a secure channel. */
-UA_StatusCode UA_SessionManager_createSession(UA_SessionManager *sessionManager, UA_SecureChannel *channel,
-                                              const UA_CreateSessionRequest *request, UA_Session **session) {
+UA_StatusCode
+UA_SessionManager_createSession(UA_SessionManager *sessionManager, UA_SecureChannel *channel,
+                                const UA_CreateSessionRequest *request, UA_Session **session) {
     if(sessionManager->currentSessionCount >= sessionManager->maxSessionCount)
         return UA_STATUSCODE_BADTOOMANYSESSIONS;
 
@@ -63,25 +63,31 @@ UA_StatusCode UA_SessionManager_createSession(UA_SessionManager *sessionManager,
     newentry->session.sessionId = UA_NODEID_NUMERIC(1, sessionManager->lastSessionId++);
     UA_UInt32 randSeed = (UA_UInt32)(sessionManager->lastSessionId + UA_DateTime_now());
     newentry->session.authenticationToken = UA_NODEID_GUID(1, UA_Guid_random(&randSeed));
+
     if(request->requestedSessionTimeout <= sessionManager->maxSessionLifeTime &&
        request->requestedSessionTimeout > 0)
         newentry->session.timeout = (UA_Int64)request->requestedSessionTimeout;
     else
         newentry->session.timeout = sessionManager->maxSessionLifeTime; // todo: remove when the CTT is fixed
+
     UA_Session_updateLifetime(&newentry->session);
     LIST_INSERT_HEAD(&sessionManager->sessions, newentry, pointers);
     *session = &newentry->session;
     return UA_STATUSCODE_GOOD;
 }
 
-UA_StatusCode UA_SessionManager_removeSession(UA_SessionManager *sessionManager, UA_Server* server, const UA_NodeId *token) {
+UA_StatusCode
+UA_SessionManager_removeSession(UA_SessionManager *sessionManager,
+                                UA_Server* server, const UA_NodeId *token) {
     session_list_entry *current;
     LIST_FOREACH(current, &sessionManager->sessions, pointers) {
         if(UA_NodeId_equal(&current->session.authenticationToken, token))
             break;
     }
+
     if(!current)
         return UA_STATUSCODE_BADSESSIONIDINVALID;
+
     LIST_REMOVE(current, pointers);
     UA_Session_deleteMembersCleanup(&current->session, server);
     UA_free(current);

+ 13 - 9
src/server/ua_session_manager.h

@@ -1,7 +1,7 @@
 #ifndef UA_SESSION_MANAGER_H_
 #define UA_SESSION_MANAGER_H_
 
-#include "../deps/queue.h"
+#include "queue.h"
 #include "ua_server.h"
 #include "ua_util.h"
 #include "ua_session.h"
@@ -19,20 +19,24 @@ typedef struct UA_SessionManager {
     UA_DateTime  maxSessionLifeTime;    // time in [ms]
 } UA_SessionManager;
 
-UA_StatusCode UA_SessionManager_init(UA_SessionManager *sessionManager, UA_UInt32 maxSessionCount,
-                                    UA_UInt32 maxSessionLifeTime, UA_UInt32 startSessionId);
+UA_StatusCode
+UA_SessionManager_init(UA_SessionManager *sessionManager, UA_UInt32 maxSessionCount,
+                       UA_UInt32 maxSessionLifeTime, UA_UInt32 startSessionId);
 
 void UA_SessionManager_deleteMembers(UA_SessionManager *sessionManager, UA_Server *server);
 
 void UA_SessionManager_cleanupTimedOut(UA_SessionManager *sessionManager, UA_Server *server, UA_DateTime now);
 
-UA_StatusCode UA_SessionManager_createSession(UA_SessionManager *sessionManager,
-                                              UA_SecureChannel *channel, const UA_CreateSessionRequest *request,
-                                              UA_Session **session);
+UA_StatusCode
+UA_SessionManager_createSession(UA_SessionManager *sessionManager,
+                                UA_SecureChannel *channel, const UA_CreateSessionRequest *request,
+                                UA_Session **session);
 
-UA_StatusCode UA_SessionManager_removeSession(UA_SessionManager *sessionManager, UA_Server *server, const UA_NodeId *token);
+UA_StatusCode
+UA_SessionManager_removeSession(UA_SessionManager *sessionManager,
+                                UA_Server *server, const UA_NodeId *token);
 
-/** Finds the session which is identified by the authentication token */
-UA_Session * UA_SessionManager_getSession(UA_SessionManager *sessionManager, const UA_NodeId *token);
+UA_Session *
+UA_SessionManager_getSession(UA_SessionManager *sessionManager, const UA_NodeId *token);
 
 #endif /* UA_SESSION_MANAGER_H_ */