ua_securechannel_manager.c 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. #include "ua_securechannel_manager.h"
  2. #include "ua_session.h"
  3. #include "ua_util.h"
  4. #include "ua_statuscodes.h"
  5. struct channel_list_entry {
  6. UA_SecureChannel channel;
  7. LIST_ENTRY(channel_list_entry) pointers;
  8. };
  9. struct UA_SecureChannelManager {
  10. UA_Int32 maxChannelCount;
  11. UA_DateTime maxChannelLifetime;
  12. LIST_HEAD(channel_list, channel_list_entry) channels;
  13. UA_MessageSecurityMode securityMode;
  14. UA_String endpointUrl;
  15. UA_DateTime channelLifeTime;
  16. UA_Int32 lastChannelId;
  17. UA_UInt32 lastTokenId;
  18. };
  19. UA_StatusCode UA_SecureChannelManager_new(UA_SecureChannelManager **cm, UA_UInt32 maxChannelCount,
  20. UA_UInt32 tokenLifetime, UA_UInt32 startChannelId,
  21. UA_UInt32 startTokenId, UA_String *endpointUrl) {
  22. if(!(*cm = UA_alloc(sizeof(UA_SecureChannelManager))))
  23. return UA_STATUSCODE_BADOUTOFMEMORY;
  24. UA_SecureChannelManager *channelManager = *cm;
  25. LIST_INIT(&channelManager->channels);
  26. channelManager->lastChannelId = startChannelId;
  27. channelManager->lastTokenId = startTokenId;
  28. UA_String_copy(endpointUrl, &channelManager->endpointUrl);
  29. channelManager->maxChannelLifetime = tokenLifetime;
  30. channelManager->maxChannelCount = maxChannelCount;
  31. return UA_STATUSCODE_GOOD;
  32. }
  33. void UA_SecureChannelManager_delete(UA_SecureChannelManager *cm) {
  34. struct channel_list_entry *entry = LIST_FIRST(&cm->channels);
  35. while(entry) {
  36. LIST_REMOVE(entry, pointers);
  37. if(entry->channel.session)
  38. entry->channel.session->channel = UA_NULL;
  39. if(entry->channel.connection)
  40. entry->channel.connection->channel = UA_NULL;
  41. UA_SecureChannel_deleteMembers(&entry->channel);
  42. UA_free(entry);
  43. entry = LIST_FIRST(&cm->channels);
  44. }
  45. UA_String_deleteMembers(&cm->endpointUrl);
  46. UA_free(cm);
  47. }
  48. UA_StatusCode UA_SecureChannelManager_open(UA_SecureChannelManager *cm,
  49. UA_Connection *conn,
  50. const UA_OpenSecureChannelRequest *request,
  51. UA_OpenSecureChannelResponse *response) {
  52. struct channel_list_entry *entry = UA_alloc(sizeof(struct channel_list_entry));
  53. if(!entry)
  54. return UA_STATUSCODE_BADOUTOFMEMORY;
  55. UA_SecureChannel_init(&entry->channel);
  56. entry->channel.connection = conn;
  57. entry->channel.securityToken.channelId = cm->lastChannelId++;
  58. entry->channel.securityToken.tokenId = cm->lastTokenId++;
  59. entry->channel.securityToken.createdAt = UA_DateTime_now();
  60. entry->channel.securityToken.revisedLifetime =
  61. request->requestedLifetime > cm->maxChannelLifetime ?
  62. cm->maxChannelLifetime : request->requestedLifetime;
  63. switch(request->securityMode) {
  64. case UA_MESSAGESECURITYMODE_INVALID:
  65. printf("UA_SecureChannel_processOpenRequest - client demands invalid \n");
  66. break;
  67. case UA_MESSAGESECURITYMODE_NONE:
  68. UA_ByteString_copy(&request->clientNonce, &entry->channel.clientNonce);
  69. break;
  70. case UA_MESSAGESECURITYMODE_SIGN:
  71. case UA_MESSAGESECURITYMODE_SIGNANDENCRYPT:
  72. printf("UA_SecureChannel_processOpenRequest - client demands signed & encrypted \n");
  73. //TODO check if senderCertificate and ReceiverCertificateThumbprint are present
  74. break;
  75. }
  76. UA_String_copycstring("http://opcfoundation.org/UA/SecurityPolicy#None",
  77. (UA_String *)&entry->channel.serverAsymAlgSettings.securityPolicyUri);
  78. LIST_INSERT_HEAD(&cm->channels, entry, pointers);
  79. response->serverProtocolVersion = 0;
  80. UA_SecureChannel_generateNonce(&entry->channel.serverNonce);
  81. UA_ByteString_copy(&entry->channel.serverNonce, &response->serverNonce);
  82. UA_ChannelSecurityToken_copy(&entry->channel.securityToken, &response->securityToken);
  83. conn->channel = &entry->channel;
  84. return UA_STATUSCODE_GOOD;
  85. }
  86. UA_StatusCode UA_SecureChannelManager_renew(UA_SecureChannelManager *cm,
  87. UA_Connection *conn,
  88. const UA_OpenSecureChannelRequest *request,
  89. UA_OpenSecureChannelResponse *response) {
  90. UA_SecureChannel *channel = conn->channel;
  91. if(channel == UA_NULL)
  92. return UA_STATUSCODE_BADINTERNALERROR;
  93. channel->securityToken.tokenId = cm->lastTokenId++;
  94. channel->securityToken.createdAt = UA_DateTime_now(); // todo: is wanted?
  95. channel->securityToken.revisedLifetime = request->requestedLifetime > cm->maxChannelLifetime ?
  96. cm->maxChannelLifetime : request->requestedLifetime;
  97. UA_SecureChannel_generateNonce(&channel->serverNonce);
  98. UA_ByteString_copy(&channel->serverNonce, &response->serverNonce);
  99. UA_ChannelSecurityToken_copy(&channel->securityToken, &response->securityToken);
  100. return UA_STATUSCODE_GOOD;
  101. }
  102. UA_StatusCode UA_SecureChannelManager_get(UA_SecureChannelManager *cm, UA_UInt32 channelId,
  103. UA_SecureChannel **channel) {
  104. struct channel_list_entry *entry;
  105. LIST_FOREACH(entry, &cm->channels, pointers) {
  106. if(entry->channel.securityToken.channelId == channelId) {
  107. *channel = &entry->channel;
  108. return UA_STATUSCODE_GOOD;
  109. }
  110. }
  111. *channel = UA_NULL;
  112. return UA_STATUSCODE_BADINTERNALERROR;
  113. }
  114. UA_StatusCode UA_SecureChannelManager_close(UA_SecureChannelManager *cm, UA_UInt32 channelId) {
  115. //TODO lock access
  116. // TODO: close the binaryconnection if it is still open. So we dö not have stray pointers..
  117. struct channel_list_entry *entry;
  118. LIST_FOREACH(entry, &cm->channels, pointers) {
  119. if(entry->channel.securityToken.channelId == channelId) {
  120. UA_SecureChannel_deleteMembers(&entry->channel);
  121. LIST_REMOVE(entry, pointers);
  122. UA_free(entry);
  123. return UA_STATUSCODE_GOOD;
  124. }
  125. }
  126. //TODO notify server application that secureChannel has been closed part 6 - §7.1.4
  127. return UA_STATUSCODE_BADINTERNALERROR;
  128. }