Browse Source

fixing renewal in both client and server: added verification of secureChannelID for both the issue and the renewal case, relates #505

Stasik0 9 years ago
parent
commit
d491f9bc66
3 changed files with 21 additions and 5 deletions
  1. 9 4
      src/client/ua_client.c
  2. 1 1
      src/client/ua_client_internal.h
  3. 11 0
      src/server/ua_server_binary.c

+ 9 - 4
src/client/ua_client.c

@@ -33,7 +33,7 @@ static void UA_Client_init(UA_Client* client, UA_ClientConfig config,
 
     client->logger = logger;
     client->config = config;
-    client->scExpiresAt = 0;
+    client->scRenewAt = 0;
 
 #ifdef UA_ENABLE_SUBSCRIPTIONS
     client->monitoredItemHandles = 0;
@@ -169,7 +169,7 @@ static UA_StatusCode HelAckHandshake(UA_Client *c) {
 
 static UA_StatusCode SecureChannelHandshake(UA_Client *client, UA_Boolean renew) {
     /* Check if sc is still valid */
-    if(renew && client->scExpiresAt - UA_DateTime_now() > client->config.timeToRenewSecureChannel * 10000)
+    if(renew && client->scRenewAt - UA_DateTime_now() > client->config.timeToRenewSecureChannel * 10000)
         return UA_STATUSCODE_GOOD;
 
     UA_Connection *c = &client->connection;
@@ -178,7 +178,11 @@ static UA_StatusCode SecureChannelHandshake(UA_Client *client, UA_Boolean renew)
 
     UA_SecureConversationMessageHeader messageHeader;
     messageHeader.messageHeader.messageTypeAndFinal = UA_MESSAGETYPEANDFINAL_OPNF;
-    messageHeader.secureChannelId = 0;
+    if(renew){
+        messageHeader.secureChannelId = client->channel.securityToken.channelId;
+    }else{
+        messageHeader.secureChannelId = 0;
+    }
 
     UA_SequenceHeader seqHeader;
     seqHeader.sequenceNumber = ++client->channel.sequenceNumber;
@@ -283,7 +287,8 @@ static UA_StatusCode SecureChannelHandshake(UA_Client *client, UA_Boolean renew)
     }
 
     //response.securityToken.revisedLifetime is UInt32 we need to cast it to DateTime=Int64
-    client->scExpiresAt = UA_DateTime_now() + (UA_DateTime)response.securityToken.revisedLifetime * 10000;
+    //we take 75% of lifetime to start renewing as described in standard
+    client->scRenewAt = UA_DateTime_now() + (UA_DateTime)response.securityToken.revisedLifetime * 10000 * 0.75;
     retval = response.responseHeader.serviceResult;
 
     if(retval != UA_STATUSCODE_GOOD)

+ 1 - 1
src/client/ua_client_internal.h

@@ -77,7 +77,7 @@ struct UA_Client {
     /* Config */
     UA_Logger logger;
     UA_ClientConfig config;
-    UA_DateTime scExpiresAt;
+    UA_DateTime scRenewAt;
 };
 
 #endif /* UA_CLIENT_INTERNAL_H_ */

+ 11 - 0
src/server/ua_server_binary.c

@@ -62,6 +62,16 @@ static void processOPN(UA_Connection *connection, UA_Server *server, const UA_By
     UA_UInt32 secureChannelId;
     UA_StatusCode retval = UA_UInt32_decodeBinary(msg, pos, &secureChannelId);
 
+    //we can check secureChannelId also here -> if we are asked to isse a token it is 0, otherwise we have to renew
+    //issue
+    if(connection->channel == NULL && secureChannelId != 0){
+        retval |= UA_STATUSCODE_BADREQUESTTYPEINVALID;
+    }
+    //renew
+    if(connection->channel != NULL && secureChannelId != connection->channel->securityToken.channelId){
+        retval |= UA_STATUSCODE_BADREQUESTTYPEINVALID;
+    }
+
     UA_AsymmetricAlgorithmSecurityHeader asymHeader;
     retval |= UA_AsymmetricAlgorithmSecurityHeader_decodeBinary(msg, pos, &asymHeader);
 
@@ -83,6 +93,7 @@ static void processOPN(UA_Connection *connection, UA_Server *server, const UA_By
         return;
     }
 
+
     UA_OpenSecureChannelResponse p;
     UA_OpenSecureChannelResponse_init(&p);
     Service_OpenSecureChannel(server, connection, &r, &p);