ua_securechannel_manager.c 6.0 KB

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