static UA_StatusCode requestActivateSession (UA_Client *client, UA_UInt32 *requestId) { UA_ActivateSessionRequest request; UA_ActivateSessionRequest_init(&request); request.requestHeader.requestHandle = ++client->requestHandle; request.requestHeader.timestamp = UA_DateTime_now (); request.requestHeader.timeoutHint = 600000; UA_StatusCode retval = UA_ExtensionObject_copy(&client->config.userIdentityToken, &request.userIdentityToken); if(retval != UA_STATUSCODE_GOOD) return retval; /* If not token is set, use anonymous */ if(request.userIdentityToken.encoding == UA_EXTENSIONOBJECT_ENCODED_NOBODY) { UA_AnonymousIdentityToken *t = UA_AnonymousIdentityToken_new(); if(!t) { UA_ActivateSessionRequest_deleteMembers(&request); return UA_STATUSCODE_BADOUTOFMEMORY; } request.userIdentityToken.content.decoded.data = t; request.userIdentityToken.content.decoded.type = &UA_TYPES[UA_TYPES_ANONYMOUSIDENTITYTOKEN]; request.userIdentityToken.encoding = UA_EXTENSIONOBJECT_DECODED; } /* Set the policy-Id from the endpoint. Every IdentityToken starts with a * string. */ retval = UA_String_copy(&client->config.userTokenPolicy.policyId, (UA_String*)request.userIdentityToken.content.decoded.data); #ifdef UA_ENABLE_ENCRYPTION /* Encrypt the UserIdentityToken */ const UA_String *userTokenPolicy = &client->channel.securityPolicy->policyUri; if(client->config.userTokenPolicy.securityPolicyUri.length > 0) userTokenPolicy = &client->config.userTokenPolicy.securityPolicyUri; retval |= encryptUserIdentityToken(client, userTokenPolicy, &request.userIdentityToken); /* This function call is to prepare a client signature */ retval |= signActivateSessionRequest(&client->channel, &request); #endif if(retval != UA_STATUSCODE_GOOD) { UA_ActivateSessionRequest_deleteMembers(&request); client->connectStatus = retval; return retval; } retval = UA_Client_sendAsyncRequest ( client, &request, &UA_TYPES[UA_TYPES_ACTIVATESESSIONREQUEST], (UA_ClientAsyncServiceCallback) responseActivateSession, &UA_TYPES[UA_TYPES_ACTIVATESESSIONRESPONSE], NULL, requestId); UA_ActivateSessionRequest_deleteMembers(&request); client->connectStatus = retval; return retval; }
static UA_StatusCode ActivateSession(UA_Client *client) { UA_ActivateSessionRequest request; UA_ActivateSessionRequest_init(&request); request.requestHeader.requestHandle = 2; //TODO: is it a magic number? request.requestHeader.authenticationToken = client->authenticationToken; request.requestHeader.timestamp = UA_DateTime_now(); request.requestHeader.timeoutHint = 10000; UA_AnonymousIdentityToken identityToken; UA_AnonymousIdentityToken_init(&identityToken); UA_String_copy(&client->token.policyId, &identityToken.policyId); //manual ExtensionObject encoding of the identityToken request.userIdentityToken.encoding = UA_EXTENSIONOBJECT_ENCODINGMASK_BODYISBYTESTRING; request.userIdentityToken.typeId = UA_TYPES[UA_TYPES_ANONYMOUSIDENTITYTOKEN].typeId; request.userIdentityToken.typeId.identifier.numeric+=UA_ENCODINGOFFSET_BINARY; if (identityToken.policyId.length >= 0) UA_ByteString_newMembers(&request.userIdentityToken.body, identityToken.policyId.length+4); else { identityToken.policyId.length = -1; UA_ByteString_newMembers(&request.userIdentityToken.body, 4); } size_t offset = 0; UA_ByteString_encodeBinary(&identityToken.policyId,&request.userIdentityToken.body,&offset); UA_ActivateSessionResponse response; __UA_Client_Service(client, &request, &UA_TYPES[UA_TYPES_ACTIVATESESSIONREQUEST], &response, &UA_TYPES[UA_TYPES_ACTIVATESESSIONRESPONSE]); UA_AnonymousIdentityToken_deleteMembers(&identityToken); UA_ActivateSessionRequest_deleteMembers(&request); UA_ActivateSessionResponse_deleteMembers(&response); return response.responseHeader.serviceResult; // not deleted }
static void processMSG(UA_Connection *connection, UA_Server *server, const UA_ByteString *msg, size_t *pos) { /* Read in the securechannel */ UA_UInt32 secureChannelId; UA_StatusCode retval = UA_UInt32_decodeBinary(msg, pos, &secureChannelId); if(retval != UA_STATUSCODE_GOOD) return; /* the anonymous channel is used e.g. to allow getEndpoints without a channel */ UA_SecureChannel *clientChannel = connection->channel; UA_SecureChannel anonymousChannel; if(!clientChannel) { UA_SecureChannel_init(&anonymousChannel); anonymousChannel.connection = connection; clientChannel = &anonymousChannel; #ifdef EXTENSION_STATELESS anonymousChannel.session = &anonymousSession; #endif } /* Read the security header */ UA_UInt32 tokenId; UA_SequenceHeader sequenceHeader; retval = UA_UInt32_decodeBinary(msg, pos, &tokenId); retval |= UA_SequenceHeader_decodeBinary(msg, pos, &sequenceHeader); if(retval != UA_STATUSCODE_GOOD) return; /* Read the request type */ UA_NodeId requestType; if(UA_NodeId_decodeBinary(msg, pos, &requestType) != UA_STATUSCODE_GOOD) return; if(requestType.identifierType != UA_NODEIDTYPE_NUMERIC) { UA_NodeId_deleteMembers(&requestType); return; } switch(requestType.identifier.numeric - UA_ENCODINGOFFSET_BINARY) { case UA_NS0ID_GETENDPOINTSREQUEST: { UA_GetEndpointsRequest p; UA_GetEndpointsResponse r; if(UA_GetEndpointsRequest_decodeBinary(msg, pos, &p)) return; UA_GetEndpointsResponse_init(&r); init_response_header(&p.requestHeader, &r.responseHeader); Service_GetEndpoints(server, &p, &r); UA_GetEndpointsRequest_deleteMembers(&p); UA_SecureChannel_sendBinaryMessage(clientChannel, sequenceHeader.requestId, &r, &UA_TYPES[UA_TYPES_GETENDPOINTSRESPONSE]); UA_GetEndpointsResponse_deleteMembers(&r); break; } case UA_NS0ID_FINDSERVERSREQUEST: { UA_FindServersRequest p; UA_FindServersResponse r; if(UA_FindServersRequest_decodeBinary(msg, pos, &p)) return; UA_FindServersResponse_init(&r); init_response_header(&p.requestHeader, &r.responseHeader); Service_FindServers(server, &p, &r); UA_FindServersRequest_deleteMembers(&p); UA_SecureChannel_sendBinaryMessage(clientChannel, sequenceHeader.requestId, &r, &UA_TYPES[UA_TYPES_FINDSERVERSRESPONSE]); UA_FindServersResponse_deleteMembers(&r); break; } case UA_NS0ID_CREATESESSIONREQUEST: { UA_CreateSessionRequest p; UA_CreateSessionResponse r; if(UA_CreateSessionRequest_decodeBinary(msg, pos, &p)) return; UA_CreateSessionResponse_init(&r); init_response_header(&p.requestHeader, &r.responseHeader); Service_CreateSession(server, clientChannel, &p, &r); UA_CreateSessionRequest_deleteMembers(&p); UA_SecureChannel_sendBinaryMessage(clientChannel, sequenceHeader.requestId, &r, &UA_TYPES[UA_TYPES_CREATESESSIONRESPONSE]); UA_CreateSessionResponse_deleteMembers(&r); break; } case UA_NS0ID_ACTIVATESESSIONREQUEST: { UA_ActivateSessionRequest p; UA_ActivateSessionResponse r; if(UA_ActivateSessionRequest_decodeBinary(msg, pos, &p)) return; UA_ActivateSessionResponse_init(&r); init_response_header(&p.requestHeader, &r.responseHeader); Service_ActivateSession(server, clientChannel, &p, &r); UA_ActivateSessionRequest_deleteMembers(&p); UA_SecureChannel_sendBinaryMessage(clientChannel, sequenceHeader.requestId, &r, &UA_TYPES[UA_TYPES_ACTIVATESESSIONRESPONSE]); UA_ActivateSessionResponse_deleteMembers(&r); break; } case UA_NS0ID_CLOSESESSIONREQUEST: INVOKE_SERVICE(CloseSession, UA_TYPES_CLOSESESSIONRESPONSE); break; case UA_NS0ID_READREQUEST: INVOKE_SERVICE(Read, UA_TYPES_READRESPONSE); break; case UA_NS0ID_WRITEREQUEST: INVOKE_SERVICE(Write, UA_TYPES_WRITERESPONSE); break; case UA_NS0ID_BROWSEREQUEST: INVOKE_SERVICE(Browse, UA_TYPES_BROWSERESPONSE); break; case UA_NS0ID_BROWSENEXTREQUEST: INVOKE_SERVICE(BrowseNext, UA_TYPES_BROWSENEXTRESPONSE); break; case UA_NS0ID_ADDREFERENCESREQUEST: INVOKE_SERVICE(AddReferences, UA_TYPES_ADDREFERENCESRESPONSE); break; case UA_NS0ID_REGISTERNODESREQUEST: INVOKE_SERVICE(RegisterNodes, UA_TYPES_REGISTERNODESRESPONSE); break; case UA_NS0ID_UNREGISTERNODESREQUEST: INVOKE_SERVICE(UnregisterNodes, UA_TYPES_UNREGISTERNODESRESPONSE); break; case UA_NS0ID_TRANSLATEBROWSEPATHSTONODEIDSREQUEST: INVOKE_SERVICE(TranslateBrowsePathsToNodeIds, UA_TYPES_TRANSLATEBROWSEPATHSTONODEIDSRESPONSE); break; default: { if(requestType.namespaceIndex == 0 && requestType.identifier.numeric==787) UA_LOG_INFO(server->logger, UA_LOGCATEGORY_COMMUNICATION, "Client requested a subscription that are not supported, the message will be skipped"); else UA_LOG_INFO(server->logger, UA_LOGCATEGORY_COMMUNICATION, "Unknown request: NodeId(ns=%d, i=%d)", requestType.namespaceIndex, requestType.identifier.numeric); UA_RequestHeader p; UA_ResponseHeader r; if(UA_RequestHeader_decodeBinary(msg, pos, &p) != UA_STATUSCODE_GOOD) return; UA_ResponseHeader_init(&r); init_response_header(&p, &r); r.serviceResult = UA_STATUSCODE_BADSERVICEUNSUPPORTED; #ifdef EXTENSION_STATELESS if(retval != UA_STATUSCODE_GOOD) r.serviceResult = retval; #endif UA_RequestHeader_deleteMembers(&p); UA_SecureChannel_sendBinaryMessage(clientChannel, sequenceHeader.requestId, &r, &UA_TYPES[UA_TYPES_RESPONSEHEADER]); break; } } }
static void processMSG(UA_Connection *connection, UA_Server *server, const UA_ByteString *msg, size_t *pos) { /* Read in the securechannel */ UA_UInt32 secureChannelId; UA_StatusCode retval = UA_UInt32_decodeBinary(msg, pos, &secureChannelId); if(retval != UA_STATUSCODE_GOOD) return; /* the anonymous channel is used e.g. to allow getEndpoints without a channel */ UA_SecureChannel *clientChannel = connection->channel; UA_SecureChannel anonymousChannel; if(!clientChannel) { UA_SecureChannel_init(&anonymousChannel); anonymousChannel.connection = connection; clientChannel = &anonymousChannel; } /* Read the security header */ UA_UInt32 tokenId = 0; UA_SequenceHeader sequenceHeader; retval = UA_UInt32_decodeBinary(msg, pos, &tokenId); retval |= UA_SequenceHeader_decodeBinary(msg, pos, &sequenceHeader); #ifndef EXTENSION_STATELESS if(retval != UA_STATUSCODE_GOOD || tokenId == 0) // 0 is invalid return; #else if(retval != UA_STATUSCODE_GOOD) return; #endif if(clientChannel != &anonymousChannel && tokenId != clientChannel->securityToken.tokenId) { if(tokenId != clientChannel->nextSecurityToken.tokenId) { /* close the securechannel but keep the connection open */ UA_LOG_INFO(server->logger, UA_LOGCATEGORY_SECURECHANNEL, "Request with a wrong security token. Closing the SecureChannel %i.", clientChannel->securityToken.channelId); Service_CloseSecureChannel(server, clientChannel->securityToken.channelId); return; } UA_SecureChannel_revolveTokens(clientChannel); } /* Read the request type */ UA_NodeId requestType; if(UA_NodeId_decodeBinary(msg, pos, &requestType) != UA_STATUSCODE_GOOD) return; if(requestType.identifierType != UA_NODEIDTYPE_NUMERIC) { UA_NodeId_deleteMembers(&requestType); return; } switch(requestType.identifier.numeric - UA_ENCODINGOFFSET_BINARY) { case UA_NS0ID_GETENDPOINTSREQUEST: { if(clientChannel == &anonymousChannel) UA_LOG_DEBUG(server->logger, UA_LOGCATEGORY_NETWORK, "Processing GetEndpointsRequest on Connection %i", connection->sockfd); else UA_LOG_DEBUG(server->logger, UA_LOGCATEGORY_SECURECHANNEL, "Processing GetEndpointsRequest on SecureChannel %i", clientChannel->securityToken.channelId); UA_GetEndpointsRequest p; UA_GetEndpointsResponse r; if(UA_GetEndpointsRequest_decodeBinary(msg, pos, &p)) return; UA_GetEndpointsResponse_init(&r); init_response_header(&p.requestHeader, &r.responseHeader); Service_GetEndpoints(server, &p, &r); UA_GetEndpointsRequest_deleteMembers(&p); UA_SecureChannel_sendBinaryMessage(clientChannel, sequenceHeader.requestId, &r, &UA_TYPES[UA_TYPES_GETENDPOINTSRESPONSE]); UA_GetEndpointsResponse_deleteMembers(&r); break; } case UA_NS0ID_FINDSERVERSREQUEST: { if(clientChannel == &anonymousChannel) UA_LOG_DEBUG(server->logger, UA_LOGCATEGORY_NETWORK, "Processing FindServerRequest on Connection %i", connection->sockfd); else UA_LOG_DEBUG(server->logger, UA_LOGCATEGORY_SECURECHANNEL, "Processing FindServerRequest on SecureChannel %i", clientChannel->securityToken.channelId); UA_FindServersRequest p; UA_FindServersResponse r; if(UA_FindServersRequest_decodeBinary(msg, pos, &p)) return; UA_FindServersResponse_init(&r); init_response_header(&p.requestHeader, &r.responseHeader); Service_FindServers(server, &p, &r); UA_FindServersRequest_deleteMembers(&p); UA_SecureChannel_sendBinaryMessage(clientChannel, sequenceHeader.requestId, &r, &UA_TYPES[UA_TYPES_FINDSERVERSRESPONSE]); UA_FindServersResponse_deleteMembers(&r); break; } case UA_NS0ID_CREATESESSIONREQUEST: { UA_CreateSessionRequest p; UA_CreateSessionResponse r; if(UA_CreateSessionRequest_decodeBinary(msg, pos, &p)) return; UA_CreateSessionResponse_init(&r); init_response_header(&p.requestHeader, &r.responseHeader); Service_CreateSession(server, clientChannel, &p, &r); UA_CreateSessionRequest_deleteMembers(&p); UA_SecureChannel_sendBinaryMessage(clientChannel, sequenceHeader.requestId, &r, &UA_TYPES[UA_TYPES_CREATESESSIONRESPONSE]); UA_CreateSessionResponse_deleteMembers(&r); break; } case UA_NS0ID_ACTIVATESESSIONREQUEST: { UA_ActivateSessionRequest p; UA_ActivateSessionResponse r; if(UA_ActivateSessionRequest_decodeBinary(msg, pos, &p)) return; UA_ActivateSessionResponse_init(&r); init_response_header(&p.requestHeader, &r.responseHeader); Service_ActivateSession(server, clientChannel, &p, &r); UA_ActivateSessionRequest_deleteMembers(&p); UA_SecureChannel_sendBinaryMessage(clientChannel, sequenceHeader.requestId, &r, &UA_TYPES[UA_TYPES_ACTIVATESESSIONRESPONSE]); UA_ActivateSessionResponse_deleteMembers(&r); break; } case UA_NS0ID_CLOSESESSIONREQUEST: INVOKE_SERVICE(CloseSession, UA_TYPES_CLOSESESSIONRESPONSE); break; case UA_NS0ID_READREQUEST: INVOKE_SERVICE(Read, UA_TYPES_READRESPONSE); break; case UA_NS0ID_WRITEREQUEST: INVOKE_SERVICE(Write, UA_TYPES_WRITERESPONSE); break; case UA_NS0ID_BROWSEREQUEST: INVOKE_SERVICE(Browse, UA_TYPES_BROWSERESPONSE); break; case UA_NS0ID_BROWSENEXTREQUEST: INVOKE_SERVICE(BrowseNext, UA_TYPES_BROWSENEXTRESPONSE); break; case UA_NS0ID_REGISTERNODESREQUEST: INVOKE_SERVICE(RegisterNodes, UA_TYPES_REGISTERNODESRESPONSE); break; case UA_NS0ID_UNREGISTERNODESREQUEST: INVOKE_SERVICE(UnregisterNodes, UA_TYPES_UNREGISTERNODESRESPONSE); break; case UA_NS0ID_TRANSLATEBROWSEPATHSTONODEIDSREQUEST: INVOKE_SERVICE(TranslateBrowsePathsToNodeIds, UA_TYPES_TRANSLATEBROWSEPATHSTONODEIDSRESPONSE); break; #ifdef ENABLE_SUBSCRIPTIONS case UA_NS0ID_CREATESUBSCRIPTIONREQUEST: INVOKE_SERVICE(CreateSubscription, UA_TYPES_CREATESUBSCRIPTIONRESPONSE); break; case UA_NS0ID_PUBLISHREQUEST: INVOKE_SERVICE(Publish, UA_TYPES_PUBLISHRESPONSE); break; case UA_NS0ID_MODIFYSUBSCRIPTIONREQUEST: INVOKE_SERVICE(ModifySubscription, UA_TYPES_MODIFYSUBSCRIPTIONRESPONSE); break; case UA_NS0ID_DELETESUBSCRIPTIONSREQUEST: INVOKE_SERVICE(DeleteSubscriptions, UA_TYPES_DELETESUBSCRIPTIONSRESPONSE); break; case UA_NS0ID_CREATEMONITOREDITEMSREQUEST: INVOKE_SERVICE(CreateMonitoredItems, UA_TYPES_CREATEMONITOREDITEMSRESPONSE); break; case UA_NS0ID_DELETEMONITOREDITEMSREQUEST: INVOKE_SERVICE(DeleteMonitoredItems, UA_TYPES_DELETEMONITOREDITEMSRESPONSE); break; #endif #ifdef ENABLE_METHODCALLS case UA_NS0ID_CALLREQUEST: INVOKE_SERVICE(Call, UA_TYPES_CALLRESPONSE); break; #endif #ifdef ENABLE_NODEMANAGEMENT case UA_NS0ID_ADDNODESREQUEST: INVOKE_SERVICE(AddNodes, UA_TYPES_ADDNODESRESPONSE); break; case UA_NS0ID_ADDREFERENCESREQUEST: INVOKE_SERVICE(AddReferences, UA_TYPES_ADDREFERENCESRESPONSE); break; case UA_NS0ID_DELETENODESREQUEST: INVOKE_SERVICE(DeleteNodes, UA_TYPES_DELETENODESRESPONSE); break; case UA_NS0ID_DELETEREFERENCESREQUEST: INVOKE_SERVICE(DeleteReferences, UA_TYPES_DELETEREFERENCESRESPONSE); break; #endif default: { if(requestType.namespaceIndex == 0 && requestType.identifier.numeric==787) UA_LOG_INFO(server->logger, UA_LOGCATEGORY_NETWORK, "Client requested a subscription that are not supported, the message will be skipped"); else UA_LOG_INFO(server->logger, UA_LOGCATEGORY_NETWORK, "Unknown request: NodeId(ns=%d, i=%d)", requestType.namespaceIndex, requestType.identifier.numeric); UA_RequestHeader p; UA_ServiceFault r; if(UA_RequestHeader_decodeBinary(msg, pos, &p) != UA_STATUSCODE_GOOD) return; UA_ServiceFault_init(&r); init_response_header(&p, &r.responseHeader); r.responseHeader.serviceResult = UA_STATUSCODE_BADSERVICEUNSUPPORTED; UA_SecureChannel_sendBinaryMessage(clientChannel, sequenceHeader.requestId, &r, &UA_TYPES[UA_TYPES_SERVICEFAULT]); UA_RequestHeader_deleteMembers(&p); UA_ServiceFault_deleteMembers(&r); break; } } }