ua_services_session.c 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. #include "ua_services.h"
  2. #include "ua_server_internal.h"
  3. #include "ua_session_manager.h"
  4. #include "ua_statuscodes.h"
  5. #include "ua_util.h"
  6. void Service_CreateSession(UA_Server *server, UA_SecureChannel *channel,
  7. const UA_CreateSessionRequest *request,
  8. UA_CreateSessionResponse *response) {
  9. response->responseHeader.serviceResult =
  10. UA_Array_copy(server->endpointDescriptions, (void**)&response->serverEndpoints,
  11. &UA_TYPES[UA_TYPES_ENDPOINTDESCRIPTION], server->endpointDescriptionsSize);
  12. if(response->responseHeader.serviceResult != UA_STATUSCODE_GOOD)
  13. return;
  14. response->serverEndpointsSize = server->endpointDescriptionsSize;
  15. UA_Session *newSession;
  16. response->responseHeader.serviceResult = UA_SessionManager_createSession(&server->sessionManager,
  17. channel, request, &newSession);
  18. if(response->responseHeader.serviceResult != UA_STATUSCODE_GOOD)
  19. return;
  20. //TODO get maxResponseMessageSize internally
  21. newSession->maxResponseMessageSize = request->maxResponseMessageSize;
  22. response->sessionId = newSession->sessionId;
  23. response->revisedSessionTimeout = newSession->timeout;
  24. response->authenticationToken = newSession->authenticationToken;
  25. response->responseHeader.serviceResult = UA_String_copy(&request->sessionName, &newSession->sessionName);
  26. if(server->endpointDescriptions)
  27. response->responseHeader.serviceResult |=
  28. UA_ByteString_copy(&server->endpointDescriptions->serverCertificate, &response->serverCertificate);
  29. if(response->responseHeader.serviceResult != UA_STATUSCODE_GOOD) {
  30. UA_SessionManager_removeSession(&server->sessionManager, server, &newSession->authenticationToken);
  31. return;
  32. }
  33. }
  34. void Service_ActivateSession(UA_Server *server, UA_SecureChannel *channel,
  35. const UA_ActivateSessionRequest *request,
  36. UA_ActivateSessionResponse *response) {
  37. // make the channel know about the session
  38. UA_Session *foundSession =
  39. UA_SessionManager_getSession(&server->sessionManager,
  40. (const UA_NodeId*)&request->requestHeader.authenticationToken);
  41. if(foundSession == UA_NULL) {
  42. response->responseHeader.serviceResult = UA_STATUSCODE_BADSESSIONIDINVALID;
  43. return;
  44. } else if(foundSession->validTill < UA_DateTime_now()) {
  45. response->responseHeader.serviceResult = UA_STATUSCODE_BADSESSIONIDINVALID;
  46. return;
  47. }
  48. UA_UserIdentityToken token;
  49. UA_UserIdentityToken_init(&token);
  50. size_t offset = 0;
  51. UA_UserIdentityToken_decodeBinary(&request->userIdentityToken.body, &offset, &token);
  52. UA_UserNameIdentityToken username_token;
  53. UA_UserNameIdentityToken_init(&username_token);
  54. UA_String ap = UA_STRING(ANONYMOUS_POLICY);
  55. UA_String up = UA_STRING(USERNAME_POLICY);
  56. //(Compatibility notice)
  57. //Siemens OPC Scout v10 provides an empty policyId, this is not okay
  58. //For compatibility we will assume that empty policyId == ANONYMOUS_POLICY
  59. //if(token.policyId.data == UA_NULL) {
  60. // /* 1) no policy defined */
  61. // response->responseHeader.serviceResult = UA_STATUSCODE_BADIDENTITYTOKENINVALID;
  62. //} else
  63. //(End Compatibility notice)
  64. if(server->config.Login_enableAnonymous && (token.policyId.data == UA_NULL || UA_String_equal(&token.policyId, &ap))) {
  65. /* 2) anonymous logins */
  66. if(foundSession->channel && foundSession->channel != channel)
  67. UA_SecureChannel_detachSession(foundSession->channel, foundSession);
  68. UA_SecureChannel_attachSession(channel, foundSession);
  69. foundSession->activated = UA_TRUE;
  70. UA_Session_updateLifetime(foundSession);
  71. } else if(server->config.Login_enableUsernamePassword && UA_String_equal(&token.policyId, &up)) {
  72. /* 3) username logins */
  73. offset = 0;
  74. UA_UserNameIdentityToken_decodeBinary(&request->userIdentityToken.body, &offset, &username_token);
  75. if(username_token.encryptionAlgorithm.data != UA_NULL) {
  76. /* 3.1) we only support encryption */
  77. response->responseHeader.serviceResult = UA_STATUSCODE_BADIDENTITYTOKENINVALID;
  78. } else if(username_token.userName.length == -1 && username_token.password.length == -1){
  79. /* 3.2) empty username and password */
  80. response->responseHeader.serviceResult = UA_STATUSCODE_BADIDENTITYTOKENINVALID;
  81. } else {
  82. /* 3.3) ok, trying to match the username */
  83. UA_UInt32 i = 0;
  84. for(; i < server->config.Login_loginsCount; ++i) {
  85. UA_String user = UA_STRING(server->config.Login_usernames[i]);
  86. UA_String pw = UA_STRING(server->config.Login_passwords[i]);
  87. if(UA_String_equal(&username_token.userName, &user) &&
  88. UA_String_equal(&username_token.password, &pw)) {
  89. /* success - activate */
  90. if(foundSession->channel && foundSession->channel != channel)
  91. UA_SecureChannel_detachSession(foundSession->channel, foundSession);
  92. UA_SecureChannel_attachSession(channel, foundSession);
  93. foundSession->activated = UA_TRUE;
  94. UA_Session_updateLifetime(foundSession);
  95. break;
  96. }
  97. }
  98. /* no username/pass matched */
  99. if(i >= server->config.Login_loginsCount)
  100. response->responseHeader.serviceResult = UA_STATUSCODE_BADUSERACCESSDENIED;
  101. }
  102. } else {
  103. response->responseHeader.serviceResult = UA_STATUSCODE_BADIDENTITYTOKENINVALID;
  104. }
  105. UA_UserIdentityToken_deleteMembers(&token);
  106. UA_UserNameIdentityToken_deleteMembers(&username_token);
  107. return;
  108. }
  109. void Service_CloseSession(UA_Server *server, UA_Session *session, const UA_CloseSessionRequest *request,
  110. UA_CloseSessionResponse *response) {
  111. UA_Session *foundSession =
  112. UA_SessionManager_getSession(&server->sessionManager,
  113. (const UA_NodeId*)&request->requestHeader.authenticationToken);
  114. if(foundSession == UA_NULL)
  115. response->responseHeader.serviceResult = UA_STATUSCODE_BADSESSIONIDINVALID;
  116. else
  117. response->responseHeader.serviceResult =
  118. UA_SessionManager_removeSession(&server->sessionManager, server, &session->authenticationToken);
  119. }