static UA_StatusCode requestSession(UA_Client *client, UA_UInt32 *requestId) { UA_CreateSessionRequest request; UA_CreateSessionRequest_init(&request); UA_StatusCode retval = UA_STATUSCODE_GOOD; if(client->channel.securityMode == UA_MESSAGESECURITYMODE_SIGN || client->channel.securityMode == UA_MESSAGESECURITYMODE_SIGNANDENCRYPT) { if(client->channel.localNonce.length != UA_SESSION_LOCALNONCELENGTH) { UA_ByteString_deleteMembers(&client->channel.localNonce); retval = UA_ByteString_allocBuffer(&client->channel.localNonce, UA_SESSION_LOCALNONCELENGTH); if(retval != UA_STATUSCODE_GOOD) return retval; } retval = client->channel.securityPolicy->symmetricModule. generateNonce(client->channel.securityPolicy, &client->channel.localNonce); if(retval != UA_STATUSCODE_GOOD) return retval; } request.requestHeader.requestHandle = ++client->requestHandle; request.requestHeader.timestamp = UA_DateTime_now(); request.requestHeader.timeoutHint = 10000; UA_ByteString_copy(&client->channel.localNonce, &request.clientNonce); request.requestedSessionTimeout = client->config.requestedSessionTimeout; request.maxResponseMessageSize = UA_INT32_MAX; UA_String_copy(&client->config.endpoint.endpointUrl, &request.endpointUrl); UA_ApplicationDescription_copy(&client->config.clientDescription, &request.clientDescription); retval = UA_Client_sendAsyncRequest ( client, &request, &UA_TYPES[UA_TYPES_CREATESESSIONREQUEST], (UA_ClientAsyncServiceCallback) responseSessionCallback, &UA_TYPES[UA_TYPES_CREATESESSIONRESPONSE], NULL, requestId); UA_CreateSessionRequest_deleteMembers(&request); client->connectStatus = retval; return client->connectStatus; }
void Service_CreateSession(UA_Server *server, UA_SecureChannel *channel, const UA_CreateSessionRequest *request, UA_CreateSessionResponse *response) { if(channel->securityToken.channelId == 0) { response->responseHeader.serviceResult = UA_STATUSCODE_BADSECURECHANNELIDINVALID; return; } /* Allocate the response */ response->serverEndpoints = (UA_EndpointDescription*) UA_Array_new(server->config.endpoints.count, &UA_TYPES[UA_TYPES_ENDPOINTDESCRIPTION]); if(!response->serverEndpoints) { response->responseHeader.serviceResult = UA_STATUSCODE_BADOUTOFMEMORY; return; } response->serverEndpointsSize = server->config.endpoints.count; /* Copy the server's endpointdescriptions into the response */ for(size_t i = 0; i < server->config.endpoints.count; ++i) response->responseHeader.serviceResult |= UA_EndpointDescription_copy(&server->config.endpoints.endpoints[0].endpointDescription, &response->serverEndpoints[i]); /* Mirror back the endpointUrl */ for(size_t i = 0; i < response->serverEndpointsSize; ++i) { UA_String_deleteMembers(&response->serverEndpoints[i].endpointUrl); UA_String_copy(&request->endpointUrl, &response->serverEndpoints[i].endpointUrl); } UA_Session *newSession; response->responseHeader.serviceResult = UA_SessionManager_createSession(&server->sessionManager, channel, request, &newSession); if(response->responseHeader.serviceResult != UA_STATUSCODE_GOOD) { UA_LOG_DEBUG_CHANNEL(server->config.logger, channel, "Processing CreateSessionRequest failed"); return; } /* Fill the session with more information */ newSession->maxResponseMessageSize = request->maxResponseMessageSize; newSession->maxRequestMessageSize = channel->connection->localConf.maxMessageSize; response->responseHeader.serviceResult |= UA_ApplicationDescription_copy(&request->clientDescription, &newSession->clientDescription); /* Prepare the response */ response->sessionId = newSession->sessionId; response->revisedSessionTimeout = (UA_Double)newSession->timeout; response->authenticationToken = newSession->authenticationToken; response->responseHeader.serviceResult = UA_String_copy(&request->sessionName, &newSession->sessionName); if(server->config.endpoints.count > 0) response->responseHeader.serviceResult |= UA_ByteString_copy(&server->config.endpoints.endpoints[0].endpointDescription.serverCertificate, &response->serverCertificate); /* Failure -> remove the session */ if(response->responseHeader.serviceResult != UA_STATUSCODE_GOOD) { UA_SessionManager_removeSession(&server->sessionManager, &newSession->authenticationToken); return; } UA_LOG_DEBUG_CHANNEL(server->config.logger, channel, "Session " UA_PRINTF_GUID_FORMAT " created", UA_PRINTF_GUID_DATA(newSession->sessionId.identifier.guid)); }
void Service_CreateSession(UA_Server *server, UA_SecureChannel *channel, const UA_CreateSessionRequest *request, UA_CreateSessionResponse *response) { if(channel == NULL) { response->responseHeader.serviceResult = UA_STATUSCODE_BADINTERNALERROR; return; } if(channel->connection == NULL) { response->responseHeader.serviceResult = UA_STATUSCODE_BADINTERNALERROR; return; } UA_LOG_DEBUG_CHANNEL(server->config.logger, channel, "Trying to create session"); if(channel->securityMode == UA_MESSAGESECURITYMODE_SIGN || channel->securityMode == UA_MESSAGESECURITYMODE_SIGNANDENCRYPT) { if(!UA_ByteString_equal(&request->clientCertificate, &channel->remoteCertificate)) { response->responseHeader.serviceResult = UA_STATUSCODE_BADCERTIFICATEINVALID; return; } } if(channel->securityToken.channelId == 0) { response->responseHeader.serviceResult = UA_STATUSCODE_BADSECURECHANNELIDINVALID; return; } if(!UA_ByteString_equal(&channel->securityPolicy->policyUri, &UA_SECURITY_POLICY_NONE_URI) && request->clientNonce.length < 32) { response->responseHeader.serviceResult = UA_STATUSCODE_BADNONCEINVALID; return; } ////////////////////// TODO: Compare application URI with certificate uri (decode certificate) /* Allocate the response */ response->serverEndpoints = (UA_EndpointDescription*) UA_Array_new(server->config.endpointsSize, &UA_TYPES[UA_TYPES_ENDPOINTDESCRIPTION]); if(!response->serverEndpoints) { response->responseHeader.serviceResult = UA_STATUSCODE_BADOUTOFMEMORY; return; } response->serverEndpointsSize = server->config.endpointsSize; /* Copy the server's endpointdescriptions into the response */ for(size_t i = 0; i < server->config.endpointsSize; ++i) response->responseHeader.serviceResult |= UA_EndpointDescription_copy(&server->config.endpoints[0].endpointDescription, &response->serverEndpoints[i]); if(response->responseHeader.serviceResult != UA_STATUSCODE_GOOD) return; /* Mirror back the endpointUrl */ for(size_t i = 0; i < response->serverEndpointsSize; ++i) { UA_String_deleteMembers(&response->serverEndpoints[i].endpointUrl); UA_String_copy(&request->endpointUrl, &response->serverEndpoints[i].endpointUrl); } UA_Session *newSession; response->responseHeader.serviceResult = UA_SessionManager_createSession(&server->sessionManager, channel, request, &newSession); if(response->responseHeader.serviceResult != UA_STATUSCODE_GOOD) { UA_LOG_DEBUG_CHANNEL(server->config.logger, channel, "Processing CreateSessionRequest failed"); return; } /* Fill the session with more information */ newSession->maxResponseMessageSize = request->maxResponseMessageSize; newSession->maxRequestMessageSize = channel->connection->localConf.maxMessageSize; response->responseHeader.serviceResult |= UA_ApplicationDescription_copy(&request->clientDescription, &newSession->clientDescription); /* Prepare the response */ response->sessionId = newSession->sessionId; response->revisedSessionTimeout = (UA_Double)newSession->timeout; response->authenticationToken = newSession->authenticationToken; response->responseHeader.serviceResult = UA_String_copy(&request->sessionName, &newSession->sessionName); if(server->config.endpointsSize > 0) response->responseHeader.serviceResult |= UA_ByteString_copy(&channel->securityPolicy->localCertificate, &response->serverCertificate); /* Create a signed nonce */ response->responseHeader.serviceResult = nonceAndSignCreateSessionResponse(server, channel, newSession, request, response); /* Failure -> remove the session */ if(response->responseHeader.serviceResult != UA_STATUSCODE_GOOD) { UA_SessionManager_removeSession(&server->sessionManager, &newSession->authenticationToken); return; } UA_LOG_DEBUG_CHANNEL(server->config.logger, channel, "Session " UA_PRINTF_GUID_FORMAT " created", UA_PRINTF_GUID_DATA(newSession->sessionId.identifier.guid)); }