ua_services_session.c 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  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. //bind session to channel
  23. channel->session = newSession;
  24. //TODO get maxResponseMessageSize internally
  25. newSession->maxResponseMessageSize = request->maxResponseMessageSize;
  26. response->sessionId = newSession->sessionId;
  27. response->revisedSessionTimeout = newSession->timeout;
  28. response->authenticationToken = newSession->authenticationToken;
  29. response->responseHeader.serviceResult = UA_String_copy(&request->sessionName, &newSession->sessionName);
  30. if(server->endpointDescriptions)
  31. response->responseHeader.serviceResult |=
  32. UA_ByteString_copy(&server->endpointDescriptions->serverCertificate, &response->serverCertificate);
  33. if(response->responseHeader.serviceResult != UA_STATUSCODE_GOOD) {
  34. UA_SessionManager_removeSession(&server->sessionManager, &newSession->sessionId);
  35. return;
  36. }
  37. }
  38. #ifdef RETURN
  39. #undef RETURN
  40. #endif
  41. #define RETURN UA_UserIdentityToken_deleteMembers(&token); \
  42. UA_UserNameIdentityToken_deleteMembers(&username_token); \
  43. return
  44. void Service_ActivateSession(UA_Server *server,UA_SecureChannel *channel,
  45. const UA_ActivateSessionRequest *request,
  46. UA_ActivateSessionResponse *response) {
  47. // make the channel know about the session
  48. UA_Session *foundSession;
  49. UA_SessionManager_getSessionByToken(&server->sessionManager,
  50. (const UA_NodeId*)&request->requestHeader.authenticationToken,
  51. &foundSession);
  52. if(foundSession == UA_NULL){
  53. response->responseHeader.serviceResult = UA_STATUSCODE_BADSESSIONIDINVALID;
  54. return;
  55. }
  56. if(foundSession->validTill < UA_DateTime_now()){
  57. response->responseHeader.serviceResult = UA_STATUSCODE_BADSESSIONIDINVALID;
  58. //TODO: maybe delete session? or wait for a recurring cleanup?
  59. return;
  60. }
  61. UA_UserIdentityToken token;
  62. UA_UserIdentityToken_init(&token);
  63. size_t offset = 0;
  64. UA_UserIdentityToken_decodeBinary(&request->userIdentityToken.body, &offset, &token);
  65. UA_UserNameIdentityToken username_token;
  66. UA_UserNameIdentityToken_init(&username_token);
  67. //check policies
  68. if(token.policyId.data == UA_NULL){ //user identity token is NULL
  69. response->responseHeader.serviceResult = UA_STATUSCODE_BADIDENTITYTOKENINVALID;
  70. //todo cleanup session
  71. RETURN;
  72. }
  73. //anonymous logins
  74. if(server->config.Login_enableAnonymous && UA_String_equalchars(&token.policyId, ANONYMOUS_POLICY)){
  75. //success - activate
  76. channel->session = foundSession;
  77. channel->session->activated = UA_TRUE;
  78. //TODO: not sure if we have to do this, tests seem to work
  79. //if(foundSession->channel) //in case session is being rebound
  80. // foundSession->channel->session = UA_NULL;
  81. foundSession->channel=channel;
  82. RETURN;
  83. //username logins
  84. }else if(server->config.Login_enableUsernamePassword && UA_String_equalchars(&token.policyId, USERNAME_POLICY)){
  85. offset = 0;
  86. UA_UserNameIdentityToken_decodeBinary(&request->userIdentityToken.body, &offset, &username_token);
  87. if(username_token.encryptionAlgorithm.data != UA_NULL){
  88. //we only support encryption
  89. response->responseHeader.serviceResult = UA_STATUSCODE_BADIDENTITYTOKENINVALID;
  90. //todo cleanup session
  91. RETURN;
  92. }
  93. if(username_token.userName.length == -1 && username_token.password.length == -1){
  94. //empty username and password
  95. response->responseHeader.serviceResult = UA_STATUSCODE_BADIDENTITYTOKENINVALID;
  96. //todo cleanup session
  97. RETURN;
  98. }
  99. for(UA_UInt32 i=0;i<server->config.Login_loginsCount;++i){
  100. if(UA_String_equalchars(&username_token.userName, server->config.Login_usernames[i])
  101. && UA_String_equalchars(&username_token.password, server->config.Login_passwords[i])){
  102. //success - activate
  103. channel->session = foundSession;
  104. channel->session->activated = UA_TRUE;
  105. //TODO: not sure if we have to do this, tests seem to work
  106. //if(foundSession->channel) //in case session is being rebound
  107. // foundSession->channel->session = UA_NULL;
  108. foundSession->channel=channel;
  109. RETURN;
  110. }
  111. }
  112. //no username/pass matched
  113. response->responseHeader.serviceResult = UA_STATUSCODE_BADUSERACCESSDENIED;
  114. //todo cleanup session
  115. RETURN;
  116. }
  117. //default case - no login
  118. response->responseHeader.serviceResult = UA_STATUSCODE_BADIDENTITYTOKENINVALID;
  119. //todo cleanup session
  120. RETURN;
  121. }
  122. #undef RETURN
  123. void Service_CloseSession(UA_Server *server, UA_Session *session, const UA_CloseSessionRequest *request,
  124. UA_CloseSessionResponse *response) {
  125. UA_Session *foundSession;
  126. UA_SessionManager_getSessionByToken(&server->sessionManager,
  127. (const UA_NodeId*)&request->requestHeader.authenticationToken, &foundSession);
  128. if(foundSession == UA_NULL){
  129. response->responseHeader.serviceResult = UA_STATUSCODE_BADSESSIONIDINVALID;
  130. return;
  131. }
  132. response->responseHeader.serviceResult =
  133. UA_SessionManager_removeSession(&server->sessionManager, &session->sessionId);
  134. }