ua_securechannel_manager.c 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. #include "ua_securechannel_manager.h"
  2. #include "ua_session.h"
  3. #include "ua_statuscodes.h"
  4. UA_StatusCode
  5. UA_SecureChannelManager_init(UA_SecureChannelManager *cm, size_t maxChannelCount, UA_UInt32 tokenLifetime,
  6. UA_UInt32 startChannelId, UA_UInt32 startTokenId) {
  7. LIST_INIT(&cm->channels);
  8. cm->lastChannelId = startChannelId;
  9. cm->lastTokenId = startTokenId;
  10. cm->maxChannelLifetime = tokenLifetime;
  11. cm->maxChannelCount = maxChannelCount;
  12. cm->currentChannelCount = 0;
  13. return UA_STATUSCODE_GOOD;
  14. }
  15. void UA_SecureChannelManager_deleteMembers(UA_SecureChannelManager *cm) {
  16. channel_list_entry *entry, *temp;
  17. LIST_FOREACH_SAFE(entry, &cm->channels, pointers, temp) {
  18. LIST_REMOVE(entry, pointers);
  19. UA_SecureChannel_deleteMembersCleanup(&entry->channel);
  20. UA_free(entry);
  21. }
  22. }
  23. /* remove channels that were not renewed or who have no connection attached */
  24. void UA_SecureChannelManager_cleanupTimedOut(UA_SecureChannelManager *cm, UA_DateTime now) {
  25. channel_list_entry *entry, *temp;
  26. LIST_FOREACH_SAFE(entry, &cm->channels, pointers, temp) {
  27. UA_DateTime timeout =
  28. entry->channel.securityToken.createdAt +
  29. ((UA_DateTime)entry->channel.securityToken.revisedLifetime * 10000);
  30. if(timeout < now || !entry->channel.connection) {
  31. LIST_REMOVE(entry, pointers);
  32. UA_SecureChannel_deleteMembersCleanup(&entry->channel);
  33. #ifndef UA_MULTITHREADING
  34. cm->currentChannelCount--;
  35. #else
  36. cm->currentChannelCount = uatomic_add_return(
  37. &cm->currentChannelCount, -1);
  38. #endif
  39. UA_free(entry);
  40. } else if(entry->channel.nextSecurityToken.tokenId > 0) {
  41. UA_SecureChannel_revolveTokens(&entry->channel);
  42. }
  43. }
  44. }
  45. UA_StatusCode
  46. UA_SecureChannelManager_open(UA_SecureChannelManager *cm, UA_Connection *conn,
  47. const UA_OpenSecureChannelRequest *request,
  48. UA_OpenSecureChannelResponse *response) {
  49. if(request->securityMode != UA_MESSAGESECURITYMODE_NONE)
  50. return UA_STATUSCODE_BADSECURITYMODEREJECTED;
  51. if(cm->currentChannelCount >= cm->maxChannelCount)
  52. return UA_STATUSCODE_BADOUTOFMEMORY;
  53. channel_list_entry *entry = UA_malloc(sizeof(channel_list_entry));
  54. if(!entry)
  55. return UA_STATUSCODE_BADOUTOFMEMORY;
  56. #ifndef UA_MULTITHREADING
  57. cm->currentChannelCount++;
  58. #else
  59. cm->currentChannelCount = uatomic_add_return(&cm->currentChannelCount, 1);
  60. #endif
  61. UA_SecureChannel_init(&entry->channel);
  62. response->responseHeader.stringTableSize = 0;
  63. response->responseHeader.timestamp = UA_DateTime_now();
  64. response->serverProtocolVersion = 0;
  65. entry->channel.securityToken.channelId = cm->lastChannelId++;
  66. entry->channel.securityToken.tokenId = cm->lastTokenId++;
  67. entry->channel.securityToken.createdAt = UA_DateTime_now();
  68. entry->channel.securityToken.revisedLifetime =
  69. (request->requestedLifetime > cm->maxChannelLifetime) ?
  70. cm->maxChannelLifetime : request->requestedLifetime;
  71. /* pragmatic workaround to get clients requesting lifetime of 0 working */
  72. if(entry->channel.securityToken.revisedLifetime == 0)
  73. entry->channel.securityToken.revisedLifetime = cm->maxChannelLifetime;
  74. UA_ByteString_copy(&request->clientNonce, &entry->channel.clientNonce);
  75. entry->channel.serverAsymAlgSettings.securityPolicyUri = UA_STRING_ALLOC(
  76. "http://opcfoundation.org/UA/SecurityPolicy#None");
  77. UA_SecureChannel_generateNonce(&entry->channel.serverNonce);
  78. UA_ByteString_copy(&entry->channel.serverNonce, &response->serverNonce);
  79. UA_ChannelSecurityToken_copy(&entry->channel.securityToken,
  80. &response->securityToken);
  81. UA_Connection_attachSecureChannel(conn, &entry->channel);
  82. LIST_INSERT_HEAD(&cm->channels, entry, pointers);
  83. return UA_STATUSCODE_GOOD;
  84. }
  85. UA_StatusCode
  86. UA_SecureChannelManager_renew(UA_SecureChannelManager *cm, UA_Connection *conn,
  87. const UA_OpenSecureChannelRequest *request,
  88. UA_OpenSecureChannelResponse *response) {
  89. UA_SecureChannel *channel = conn->channel;
  90. if(!channel)
  91. return UA_STATUSCODE_BADINTERNALERROR;
  92. /* if no security token is already issued */
  93. if(channel->nextSecurityToken.tokenId == 0) {
  94. channel->nextSecurityToken.channelId = channel->securityToken.channelId;
  95. //FIXME: UaExpert seems not to use the new tokenid
  96. channel->nextSecurityToken.tokenId = cm->lastTokenId++;
  97. //channel->nextSecurityToken.tokenId = channel->securityToken.tokenId;
  98. channel->nextSecurityToken.createdAt = UA_DateTime_now();
  99. channel->nextSecurityToken.revisedLifetime =
  100. (request->requestedLifetime > cm->maxChannelLifetime) ?
  101. cm->maxChannelLifetime : request->requestedLifetime;
  102. /* pragmatic workaround to get clients requesting lifetime of 0 working */
  103. if(channel->nextSecurityToken.revisedLifetime == 0)
  104. channel->nextSecurityToken.revisedLifetime = cm->maxChannelLifetime;
  105. }
  106. if(channel->clientNonce.data)
  107. UA_ByteString_deleteMembers(&channel->clientNonce);
  108. UA_ByteString_copy(&request->clientNonce, &channel->clientNonce);
  109. UA_ByteString_copy(&channel->serverNonce, &response->serverNonce);
  110. UA_ChannelSecurityToken_copy(&channel->nextSecurityToken, &response->securityToken);
  111. return UA_STATUSCODE_GOOD;
  112. }
  113. UA_SecureChannel * UA_SecureChannelManager_get(UA_SecureChannelManager *cm, UA_UInt32 channelId) {
  114. channel_list_entry *entry;
  115. LIST_FOREACH(entry, &cm->channels, pointers) {
  116. if(entry->channel.securityToken.channelId == channelId)
  117. return &entry->channel;
  118. }
  119. return NULL;
  120. }
  121. UA_StatusCode UA_SecureChannelManager_close(UA_SecureChannelManager *cm, UA_UInt32 channelId) {
  122. channel_list_entry *entry;
  123. LIST_FOREACH(entry, &cm->channels, pointers) {
  124. if(entry->channel.securityToken.channelId == channelId) {
  125. LIST_REMOVE(entry, pointers);
  126. UA_SecureChannel_deleteMembersCleanup(&entry->channel);
  127. UA_free(entry);
  128. #ifndef UA_MULTITHREADING
  129. cm->currentChannelCount--;
  130. #else
  131. cm->currentChannelCount = uatomic_add_return(&cm->currentChannelCount, -1);
  132. #endif
  133. return UA_STATUSCODE_GOOD;
  134. }
  135. }
  136. return UA_STATUSCODE_BADINTERNALERROR;
  137. }