ua_services_session.c 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  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->serverEndpoints = UA_malloc(sizeof(UA_EndpointDescription));
  10. if(!response->serverEndpoints || (response->responseHeader.serviceResult =
  11. UA_EndpointDescription_copy(server->endpointDescriptions, response->serverEndpoints)) !=
  12. UA_STATUSCODE_GOOD)
  13. return;
  14. response->serverEndpointsSize = 1;
  15. // creates a session and adds a pointer to the channel. Only when the
  16. // session is activated will the channel point to the session as well
  17. UA_Session *newSession;
  18. response->responseHeader.serviceResult = UA_SessionManager_createSession(&server->sessionManager,
  19. channel, request, &newSession);
  20. if(response->responseHeader.serviceResult != UA_STATUSCODE_GOOD)
  21. return;
  22. //TODO get maxResponseMessageSize internally
  23. newSession->maxResponseMessageSize = request->maxResponseMessageSize;
  24. response->sessionId = newSession->sessionId;
  25. response->revisedSessionTimeout = newSession->timeout;
  26. response->authenticationToken = newSession->authenticationToken;
  27. response->responseHeader.serviceResult = UA_String_copy(&request->sessionName, &newSession->sessionName);
  28. if(server->endpointDescriptions)
  29. response->responseHeader.serviceResult |=
  30. UA_ByteString_copy(&server->endpointDescriptions->serverCertificate, &response->serverCertificate);
  31. if(response->responseHeader.serviceResult != UA_STATUSCODE_GOOD) {
  32. UA_SessionManager_removeSession(&server->sessionManager, &newSession->sessionId);
  33. return;
  34. }
  35. }
  36. #ifdef RETURN
  37. #undef RETURN
  38. #endif
  39. #define RETURN UA_UserIdentityToken_deleteMembers(&token); \
  40. UA_UserNameIdentityToken_deleteMembers(&username_token); \
  41. return
  42. void Service_ActivateSession(UA_Server *server,UA_SecureChannel *channel,
  43. const UA_ActivateSessionRequest *request,
  44. UA_ActivateSessionResponse *response) {
  45. // make the channel know about the session
  46. UA_Session *foundSession;
  47. UA_SessionManager_getSessionByToken(&server->sessionManager,
  48. (const UA_NodeId*)&request->requestHeader.authenticationToken,
  49. &foundSession);
  50. if(foundSession == UA_NULL){
  51. response->responseHeader.serviceResult = UA_STATUSCODE_BADIDENTITYTOKENINVALID;
  52. return;
  53. }
  54. UA_UserIdentityToken token;
  55. UA_UserIdentityToken_init(&token);
  56. size_t offset = 0;
  57. UA_UserIdentityToken_decodeBinary(&request->userIdentityToken.body, &offset, &token);
  58. UA_UserNameIdentityToken username_token;
  59. UA_UserNameIdentityToken_init(&username_token);
  60. //check policies
  61. if(token.policyId.data == UA_NULL){ //user identity token is NULL
  62. response->responseHeader.serviceResult = UA_STATUSCODE_BADIDENTITYTOKENINVALID;
  63. //todo cleanup session
  64. RETURN;
  65. }
  66. //anonymous logins
  67. if(!server->config.Login_enableAnonymous && UA_String_equalchars(&token.policyId, ANONYMOUS_POLICY)){
  68. response->responseHeader.serviceResult = UA_STATUSCODE_BADIDENTITYTOKENINVALID;
  69. UA_UserIdentityToken_deleteMembers(&token);
  70. //todo cleanup session
  71. RETURN;
  72. }
  73. //username logins
  74. else if(UA_String_equalchars(&token.policyId, USERNAME_POLICY)){
  75. if(!server->config.Login_enableUsernamePassword){
  76. response->responseHeader.serviceResult = UA_STATUSCODE_BADIDENTITYTOKENINVALID;
  77. //todo cleanup session
  78. RETURN;
  79. }
  80. offset = 0;
  81. UA_UserNameIdentityToken_decodeBinary(&request->userIdentityToken.body, &offset, &username_token);
  82. if(username_token.encryptionAlgorithm.data != UA_NULL){
  83. //we only support encryption
  84. response->responseHeader.serviceResult = UA_STATUSCODE_BADIDENTITYTOKENINVALID;
  85. //todo cleanup session
  86. RETURN;
  87. }
  88. if(username_token.userName.length == -1 && username_token.password.length == -1){
  89. //empty username and password
  90. response->responseHeader.serviceResult = UA_STATUSCODE_BADIDENTITYTOKENINVALID;
  91. //todo cleanup session
  92. RETURN;
  93. }
  94. UA_Boolean matched = UA_FALSE;
  95. for(UA_UInt32 i=0;i<server->config.Login_loginsCount;++i){
  96. if(UA_String_equalchars(&username_token.userName, server->config.Login_usernames[i])
  97. && UA_String_equalchars(&username_token.password, server->config.Login_passwords[i])){
  98. matched = UA_TRUE;
  99. break;
  100. }
  101. }
  102. if(!matched){
  103. //no username/pass matched
  104. response->responseHeader.serviceResult = UA_STATUSCODE_BADUSERACCESSDENIED;
  105. //todo cleanup session
  106. RETURN;
  107. }
  108. }else{
  109. response->responseHeader.serviceResult = UA_STATUSCODE_BADIDENTITYTOKENINVALID;
  110. //todo cleanup session
  111. RETURN;
  112. }
  113. //success - bind session to the channel
  114. channel->session = foundSession;
  115. RETURN;
  116. }
  117. #undef RETURN
  118. void Service_CloseSession(UA_Server *server, UA_Session *session, const UA_CloseSessionRequest *request,
  119. UA_CloseSessionResponse *response) {
  120. UA_Session *foundSession;
  121. UA_SessionManager_getSessionByToken(&server->sessionManager,
  122. (const UA_NodeId*)&request->requestHeader.authenticationToken, &foundSession);
  123. if(foundSession == UA_NULL){
  124. response->responseHeader.serviceResult = UA_STATUSCODE_BADSESSIONIDINVALID;
  125. return;
  126. }
  127. response->responseHeader.serviceResult =
  128. UA_SessionManager_removeSession(&server->sessionManager, &session->sessionId);
  129. }