ua_securechannel_manager.c 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. #include "ua_securechannel_manager.h"
  2. #include "ua_session.h"
  3. #include "ua_statuscodes.h"
  4. UA_StatusCode UA_SecureChannelManager_init(UA_SecureChannelManager *cm, UA_UInt32 maxChannelCount,
  5. UA_UInt32 tokenLifetime, UA_UInt32 startChannelId,
  6. 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. return UA_STATUSCODE_GOOD;
  13. }
  14. void UA_SecureChannelManager_deleteMembers(UA_SecureChannelManager *cm) {
  15. channel_list_entry *current, *next = LIST_FIRST(&cm->channels);
  16. while(next) {
  17. current = next;
  18. next = LIST_NEXT(current, pointers);
  19. LIST_REMOVE(current, pointers);
  20. if(current->channel.session)
  21. current->channel.session->channel = UA_NULL;
  22. if(current->channel.connection)
  23. current->channel.connection->channel = UA_NULL;
  24. UA_SecureChannel_deleteMembers(&current->channel);
  25. UA_free(current);
  26. }
  27. }
  28. UA_StatusCode UA_SecureChannelManager_open(UA_SecureChannelManager *cm, UA_Connection *conn,
  29. const UA_OpenSecureChannelRequest *request,
  30. UA_OpenSecureChannelResponse *response)
  31. {
  32. switch(request->securityMode) {
  33. case UA_MESSAGESECURITYMODE_INVALID:
  34. response->responseHeader.serviceResult = UA_STATUSCODE_BADSECURITYMODEREJECTED;
  35. return response->responseHeader.serviceResult;
  36. // fall through and handle afterwards
  37. /* case UA_MESSAGESECURITYMODE_NONE: */
  38. /* UA_ByteString_copy(&request->clientNonce, &entry->channel.clientNonce); */
  39. /* break; */
  40. case UA_MESSAGESECURITYMODE_SIGN:
  41. case UA_MESSAGESECURITYMODE_SIGNANDENCRYPT:
  42. response->responseHeader.serviceResult = UA_STATUSCODE_BADSECURITYMODEREJECTED;
  43. return response->responseHeader.serviceResult;
  44. default:
  45. // do nothing
  46. break;
  47. }
  48. channel_list_entry *entry = UA_malloc(sizeof(channel_list_entry));
  49. if(!entry) return UA_STATUSCODE_BADOUTOFMEMORY;
  50. UA_SecureChannel_init(&entry->channel);
  51. response->responseHeader.stringTableSize = 0;
  52. response->responseHeader.timestamp = UA_DateTime_now();
  53. entry->channel.connection = conn;
  54. conn->channel = &entry->channel;
  55. entry->channel.securityToken.channelId = cm->lastChannelId++;
  56. entry->channel.securityToken.tokenId = cm->lastTokenId++;
  57. entry->channel.securityToken.createdAt = UA_DateTime_now();
  58. entry->channel.securityToken.revisedLifetime = (request->requestedLifetime > cm->maxChannelLifetime) ?
  59. cm->maxChannelLifetime : request->requestedLifetime;
  60. UA_ByteString_copy(&request->clientNonce, &entry->channel.clientNonce);
  61. entry->channel.serverAsymAlgSettings.securityPolicyUri =
  62. UA_STRING_ALLOC("http://opcfoundation.org/UA/SecurityPolicy#None");
  63. LIST_INSERT_HEAD(&cm->channels, entry, pointers);
  64. response->serverProtocolVersion = 0;
  65. UA_SecureChannel_generateNonce(&entry->channel.serverNonce);
  66. UA_ByteString_copy(&entry->channel.serverNonce, &response->serverNonce);
  67. UA_ChannelSecurityToken_copy(&entry->channel.securityToken, &response->securityToken);
  68. conn->channel = &entry->channel;
  69. return UA_STATUSCODE_GOOD;
  70. }
  71. UA_StatusCode UA_SecureChannelManager_renew(UA_SecureChannelManager *cm, UA_Connection *conn,
  72. const UA_OpenSecureChannelRequest *request,
  73. UA_OpenSecureChannelResponse *response)
  74. {
  75. UA_SecureChannel *channel = conn->channel;
  76. if(channel == UA_NULL)
  77. return UA_STATUSCODE_BADINTERNALERROR;
  78. channel->securityToken.tokenId = cm->lastTokenId++;
  79. channel->securityToken.createdAt = UA_DateTime_now(); // todo: is wanted?
  80. channel->securityToken.revisedLifetime = (request->requestedLifetime > cm->maxChannelLifetime) ?
  81. cm->maxChannelLifetime : request->requestedLifetime;
  82. if(channel->serverNonce.data != UA_NULL)
  83. UA_ByteString_deleteMembers(&channel->serverNonce);
  84. UA_SecureChannel_generateNonce(&channel->serverNonce);
  85. UA_ByteString_copy(&channel->serverNonce, &response->serverNonce);
  86. UA_ChannelSecurityToken_copy(&channel->securityToken, &response->securityToken);
  87. return UA_STATUSCODE_GOOD;
  88. }
  89. UA_SecureChannel * UA_SecureChannelManager_get(UA_SecureChannelManager *cm, UA_UInt32 channelId) {
  90. channel_list_entry *entry;
  91. LIST_FOREACH(entry, &cm->channels, pointers) {
  92. if(entry->channel.securityToken.channelId == channelId)
  93. return &entry->channel;
  94. }
  95. return UA_NULL;
  96. }
  97. UA_StatusCode UA_SecureChannelManager_close(UA_SecureChannelManager *cm, UA_UInt32 channelId) {
  98. // TODO lock access
  99. channel_list_entry *entry;
  100. LIST_FOREACH(entry, &cm->channels, pointers) {
  101. if(entry->channel.securityToken.channelId == channelId) {
  102. UA_Connection *c = entry->channel.connection;
  103. if(c) {
  104. UA_Connection_detachSecureChannel(c);
  105. c->close(c);
  106. }
  107. entry->channel.session = UA_NULL;
  108. UA_SecureChannel_deleteMembers(&entry->channel);
  109. LIST_REMOVE(entry, pointers);
  110. UA_free(entry);
  111. return UA_STATUSCODE_GOOD;
  112. }
  113. }
  114. return UA_STATUSCODE_BADINTERNALERROR;
  115. }