123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153 |
- #include "ua_services.h"
- #include "ua_server_internal.h"
- #include "ua_session_manager.h"
- #include "ua_statuscodes.h"
- #include "ua_util.h"
- void Service_CreateSession(UA_Server *server, UA_SecureChannel *channel,
- const UA_CreateSessionRequest *request,
- UA_CreateSessionResponse *response) {
- response->serverEndpoints = UA_malloc(sizeof(UA_EndpointDescription));
- if(!response->serverEndpoints || (response->responseHeader.serviceResult =
- UA_EndpointDescription_copy(server->endpointDescriptions, response->serverEndpoints)) !=
- UA_STATUSCODE_GOOD)
- return;
- response->serverEndpointsSize = 1;
- // creates a session and adds a pointer to the channel. Only when the
- // session is activated will the channel point to the session as well
- UA_Session *newSession;
- response->responseHeader.serviceResult = UA_SessionManager_createSession(&server->sessionManager,
- channel, request, &newSession);
- if(response->responseHeader.serviceResult != UA_STATUSCODE_GOOD)
- return;
- //bind session to channel
- channel->session = newSession;
- //TODO get maxResponseMessageSize internally
- newSession->maxResponseMessageSize = request->maxResponseMessageSize;
- response->sessionId = newSession->sessionId;
- response->revisedSessionTimeout = newSession->timeout;
- response->authenticationToken = newSession->authenticationToken;
- response->responseHeader.serviceResult = UA_String_copy(&request->sessionName, &newSession->sessionName);
- if(server->endpointDescriptions)
- response->responseHeader.serviceResult |=
- UA_ByteString_copy(&server->endpointDescriptions->serverCertificate, &response->serverCertificate);
- if(response->responseHeader.serviceResult != UA_STATUSCODE_GOOD) {
- UA_SessionManager_removeSession(&server->sessionManager, &newSession->sessionId);
- return;
- }
- }
- #ifdef RETURN
- #undef RETURN
- #endif
- #define RETURN UA_UserIdentityToken_deleteMembers(&token); \
- UA_UserNameIdentityToken_deleteMembers(&username_token); \
- return
- void Service_ActivateSession(UA_Server *server,UA_SecureChannel *channel,
- const UA_ActivateSessionRequest *request,
- UA_ActivateSessionResponse *response) {
- // make the channel know about the session
- UA_Session *foundSession;
- UA_SessionManager_getSessionByToken(&server->sessionManager,
- (const UA_NodeId*)&request->requestHeader.authenticationToken,
- &foundSession);
- if(foundSession == UA_NULL){
- response->responseHeader.serviceResult = UA_STATUSCODE_BADSESSIONIDINVALID;
- return;
- }
- if(foundSession->validTill < UA_DateTime_now()){
- response->responseHeader.serviceResult = UA_STATUSCODE_BADSESSIONIDINVALID;
- //TODO: maybe delete session? or wait for a recurring cleanup?
- return;
- }
- UA_UserIdentityToken token;
- UA_UserIdentityToken_init(&token);
- size_t offset = 0;
- UA_UserIdentityToken_decodeBinary(&request->userIdentityToken.body, &offset, &token);
- UA_UserNameIdentityToken username_token;
- UA_UserNameIdentityToken_init(&username_token);
- //check policies
- if(token.policyId.data == UA_NULL){ //user identity token is NULL
- response->responseHeader.serviceResult = UA_STATUSCODE_BADIDENTITYTOKENINVALID;
- //todo cleanup session
- RETURN;
- }
- //anonymous logins
- if(server->config.Login_enableAnonymous && UA_String_equalchars(&token.policyId, ANONYMOUS_POLICY)){
- //success - activate
- channel->session = foundSession;
- channel->session->activated = UA_TRUE;
- //TODO: not sure if we have to do this, tests seem to work
- //if(foundSession->channel) //in case session is being rebound
- // foundSession->channel->session = UA_NULL;
- foundSession->channel=channel;
- RETURN;
- //username logins
- }else if(server->config.Login_enableUsernamePassword && UA_String_equalchars(&token.policyId, USERNAME_POLICY)){
- offset = 0;
- UA_UserNameIdentityToken_decodeBinary(&request->userIdentityToken.body, &offset, &username_token);
- if(username_token.encryptionAlgorithm.data != UA_NULL){
- //we only support encryption
- response->responseHeader.serviceResult = UA_STATUSCODE_BADIDENTITYTOKENINVALID;
- //todo cleanup session
- RETURN;
- }
- if(username_token.userName.length == -1 && username_token.password.length == -1){
- //empty username and password
- response->responseHeader.serviceResult = UA_STATUSCODE_BADIDENTITYTOKENINVALID;
- //todo cleanup session
- RETURN;
- }
- for(UA_UInt32 i=0;i<server->config.Login_loginsCount;++i){
- if(UA_String_equalchars(&username_token.userName, server->config.Login_usernames[i])
- && UA_String_equalchars(&username_token.password, server->config.Login_passwords[i])){
- //success - activate
- channel->session = foundSession;
- channel->session->activated = UA_TRUE;
- //TODO: not sure if we have to do this, tests seem to work
- //if(foundSession->channel) //in case session is being rebound
- // foundSession->channel->session = UA_NULL;
- foundSession->channel=channel;
- RETURN;
- }
- }
- //no username/pass matched
- response->responseHeader.serviceResult = UA_STATUSCODE_BADUSERACCESSDENIED;
- //todo cleanup session
- RETURN;
- }
- //default case - no login
- response->responseHeader.serviceResult = UA_STATUSCODE_BADIDENTITYTOKENINVALID;
- //todo cleanup session
- RETURN;
- }
- #undef RETURN
- void Service_CloseSession(UA_Server *server, UA_Session *session, const UA_CloseSessionRequest *request,
- UA_CloseSessionResponse *response) {
- UA_Session *foundSession;
- UA_SessionManager_getSessionByToken(&server->sessionManager,
- (const UA_NodeId*)&request->requestHeader.authenticationToken, &foundSession);
- if(foundSession == UA_NULL){
- response->responseHeader.serviceResult = UA_STATUSCODE_BADSESSIONIDINVALID;
- return;
- }
- response->responseHeader.serviceResult =
- UA_SessionManager_removeSession(&server->sessionManager, &session->sessionId);
- }
|