|
@@ -1,74 +1,106 @@
|
|
#include <stdio.h>
|
|
#include <stdio.h>
|
|
#include <memory.h> // memcpy
|
|
#include <memory.h> // memcpy
|
|
|
|
+
|
|
#include "ua_transport_binary.h"
|
|
#include "ua_transport_binary.h"
|
|
#include "ua_transport_binary_secure.h"
|
|
#include "ua_transport_binary_secure.h"
|
|
#include "ua_transport.h"
|
|
#include "ua_transport.h"
|
|
#include "ua_statuscodes.h"
|
|
#include "ua_statuscodes.h"
|
|
#include "ua_services.h"
|
|
#include "ua_services.h"
|
|
|
|
+#include "ua_stack_session_manager.h"
|
|
|
|
+#include "ua_stack_session.h"
|
|
|
|
|
|
#define SIZE_SECURECHANNEL_HEADER 12
|
|
#define SIZE_SECURECHANNEL_HEADER 12
|
|
#define SIZE_SEQHEADER_HEADER 8
|
|
#define SIZE_SEQHEADER_HEADER 8
|
|
|
|
|
|
-SL_Channel slc;
|
|
|
|
|
|
+static UA_Int32 SL_Send(SL_Channel channel,
|
|
|
|
+ const UA_ByteString * responseMessage, UA_Int32 type)
|
|
|
|
+{
|
|
|
|
+ UA_UInt32 pos = 0;
|
|
|
|
+ UA_Int32 isAsym = (type == UA_OPENSECURECHANNELRESPONSE_NS0); // FIXME: this is a to dumb method to determine asymmetric algorithm setting
|
|
|
|
+ UA_UInt32 channelId;
|
|
|
|
+ UA_UInt32 sequenceNumber;
|
|
|
|
+ UA_UInt32 requestId;
|
|
|
|
+ UA_TL_Connection connection;
|
|
|
|
+ UA_NodeId resp_nodeid;
|
|
|
|
+ UA_AsymmetricAlgorithmSecurityHeader *asymAlgSettings = UA_NULL;
|
|
|
|
|
|
-static UA_Int32 SL_Send(SL_Channel *channel, const UA_ByteString *responseMessage, UA_Int32 type) {
|
|
|
|
- UA_UInt32 offset = 0;
|
|
|
|
- // FIXME: this is a to dumb method to determine asymmetric algorithm setting
|
|
|
|
- UA_Int32 isAsym = (type == UA_OPENSECURECHANNELRESPONSE_NS0);
|
|
|
|
|
|
+ resp_nodeid.encodingByte = UA_NODEIDTYPE_FOURBYTE;
|
|
|
|
+ resp_nodeid.namespace = 0;
|
|
|
|
+ resp_nodeid.identifier.numeric = type + 2; // binary encoding
|
|
|
|
|
|
- UA_NodeId resp_nodeid;
|
|
|
|
- resp_nodeid.encodingByte = UA_NODEIDTYPE_FOURBYTE;
|
|
|
|
- resp_nodeid.namespace = 0;
|
|
|
|
- resp_nodeid.identifier.numeric = type+2; // binary encoding
|
|
|
|
-
|
|
|
|
- const UA_ByteString *response_gather[2];
|
|
|
|
- UA_alloc((void **)&response_gather[0], sizeof(UA_ByteString));
|
|
|
|
- if(isAsym) {
|
|
|
|
- UA_ByteString_newMembers(
|
|
|
|
- (UA_ByteString *)response_gather[0], SIZE_SECURECHANNEL_HEADER + SIZE_SEQHEADER_HEADER +
|
|
|
|
- UA_AsymmetricAlgorithmSecurityHeader_calcSizeBinary(&channel->localAsymAlgSettings) +
|
|
|
|
- UA_NodeId_calcSizeBinary(&resp_nodeid));
|
|
|
|
- }else {
|
|
|
|
- UA_ByteString_newMembers((UA_ByteString *)response_gather[0], 8 +
|
|
|
|
- 16 + // normal header + 4*32bit secure channel information
|
|
|
|
- UA_NodeId_calcSizeBinary(&resp_nodeid));
|
|
|
|
- }
|
|
|
|
|
|
+ const UA_ByteString *response_gather[2]; // securechannel_header, seq_header, security_encryption_header, message_length (eventually + padding + size_signature);
|
|
|
|
+ UA_alloc((void ** )&response_gather[0], sizeof(UA_ByteString));
|
|
|
|
+ if (isAsym)
|
|
|
|
+ {
|
|
|
|
|
|
|
|
+ SL_Channel_getLocalAsymAlgSettings(channel, &asymAlgSettings);
|
|
|
|
+ UA_ByteString_newMembers((UA_ByteString *) response_gather[0],
|
|
|
|
+ SIZE_SECURECHANNEL_HEADER + SIZE_SEQHEADER_HEADER
|
|
|
|
+ + UA_AsymmetricAlgorithmSecurityHeader_calcSizeBinary(
|
|
|
|
+ asymAlgSettings)
|
|
|
|
+ + UA_NodeId_calcSizeBinary(&resp_nodeid));
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ UA_ByteString_newMembers((UA_ByteString *) response_gather[0], 8 + 16 + // normal header + 4*32bit secure channel information
|
|
|
|
+ UA_NodeId_calcSizeBinary(&resp_nodeid));
|
|
|
|
+ }
|
|
|
|
|
|
// sizePadding = 0;
|
|
// sizePadding = 0;
|
|
// sizeSignature = 0;
|
|
// sizeSignature = 0;
|
|
- UA_ByteString *header = (UA_ByteString *)response_gather[0];
|
|
|
|
|
|
+ UA_ByteString *header = (UA_ByteString *) response_gather[0];
|
|
|
|
|
|
- /*---encode Secure Conversation Message Header ---*/
|
|
|
|
- if(isAsym) {
|
|
|
|
|
|
+ /*---encode Secure Conversation Message Header ---*/
|
|
|
|
+ if (isAsym)
|
|
|
|
+ {
|
|
header->data[0] = 'O';
|
|
header->data[0] = 'O';
|
|
header->data[1] = 'P';
|
|
header->data[1] = 'P';
|
|
header->data[2] = 'N';
|
|
header->data[2] = 'N';
|
|
- } else {
|
|
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
header->data[0] = 'M';
|
|
header->data[0] = 'M';
|
|
header->data[1] = 'S';
|
|
header->data[1] = 'S';
|
|
header->data[2] = 'G';
|
|
header->data[2] = 'G';
|
|
}
|
|
}
|
|
- offset += 3;
|
|
|
|
- header->data[offset] = 'F';
|
|
|
|
- offset += 1;
|
|
|
|
|
|
+ pos += 3;
|
|
|
|
+ header->data[pos] = 'F';
|
|
|
|
+ pos += 1;
|
|
|
|
|
|
UA_Int32 packetSize = response_gather[0]->length + responseMessage->length;
|
|
UA_Int32 packetSize = response_gather[0]->length + responseMessage->length;
|
|
- UA_Int32_encodeBinary(&packetSize, header, &offset);
|
|
|
|
- UA_UInt32_encodeBinary(&channel->securityToken.secureChannelId, header, &offset);
|
|
|
|
|
|
+ UA_Int32_encodeBinary(&packetSize, header,&pos);
|
|
|
|
+
|
|
|
|
+ //use get accessor to read the channel Id
|
|
|
|
+ SL_Channel_getChannelId(channel, &channelId);
|
|
|
|
+
|
|
|
|
+ UA_UInt32_encodeBinary(&channelId, header,&pos);
|
|
|
|
|
|
/*---encode Algorithm Security Header ---*/
|
|
/*---encode Algorithm Security Header ---*/
|
|
- if(isAsym)
|
|
|
|
- UA_AsymmetricAlgorithmSecurityHeader_encodeBinary(&channel->localAsymAlgSettings, header, &offset);
|
|
|
|
|
|
+ if (isAsym)
|
|
|
|
+ {
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ UA_AsymmetricAlgorithmSecurityHeader_encodeBinary(asymAlgSettings,
|
|
|
|
+ header,&pos);
|
|
|
|
+ UA_free(asymAlgSettings);
|
|
|
|
+ }
|
|
else
|
|
else
|
|
- UA_SymmetricAlgorithmSecurityHeader_encodeBinary(&channel->securityToken.tokenId, header, &offset);
|
|
|
|
|
|
+ {
|
|
|
|
+
|
|
|
|
+ UA_UInt32 tokenId = 0;
|
|
|
|
+ SL_Channel_getTokenId(channel, &tokenId);
|
|
|
|
+
|
|
|
|
+ UA_UInt32_encodeBinary(&tokenId, header,&pos);
|
|
|
|
+ }
|
|
|
|
|
|
/*---encode Sequence Header ---*/
|
|
/*---encode Sequence Header ---*/
|
|
- UA_UInt32_encodeBinary(&channel->sequenceHeader.sequenceNumber, header, &offset);
|
|
|
|
- UA_UInt32_encodeBinary(&channel->sequenceHeader.requestId, header, &offset);
|
|
|
|
|
|
+ SL_Channel_getSequenceNumber(channel, &sequenceNumber);
|
|
|
|
+ UA_UInt32_encodeBinary(&sequenceNumber, header, &pos);
|
|
|
|
+ SL_Channel_getRequestId(channel, &requestId);
|
|
|
|
+ UA_UInt32_encodeBinary(&requestId, header,&pos);
|
|
|
|
|
|
/*---add payload type---*/
|
|
/*---add payload type---*/
|
|
- UA_NodeId_encodeBinary(&resp_nodeid, header, &offset);
|
|
|
|
|
|
+ UA_NodeId_encodeBinary(&resp_nodeid, header,&pos);
|
|
|
|
|
|
/*---add encoded Message ---*/
|
|
/*---add encoded Message ---*/
|
|
response_gather[1] = responseMessage; // is deleted in the calling function
|
|
response_gather[1] = responseMessage; // is deleted in the calling function
|
|
@@ -78,180 +110,357 @@ static UA_Int32 SL_Send(SL_Channel *channel, const UA_ByteString *responseMessag
|
|
/* encrypt Data*/
|
|
/* encrypt Data*/
|
|
|
|
|
|
/* send Data */
|
|
/* send Data */
|
|
- TL_Send(channel->tlConnection, response_gather, 2);
|
|
|
|
|
|
+ SL_Channel_getConnection(channel, &connection);
|
|
|
|
+ TL_Send(connection, response_gather, 2);
|
|
|
|
|
|
- UA_ByteString_delete((UA_ByteString *)response_gather[0]);
|
|
|
|
|
|
+ UA_ByteString_delete((UA_ByteString *) response_gather[0]);
|
|
return UA_SUCCESS;
|
|
return UA_SUCCESS;
|
|
}
|
|
}
|
|
|
|
|
|
-static void init_response_header(UA_RequestHeader const *p, UA_ResponseHeader *r) {
|
|
|
|
- memset((void *)r, 0, sizeof(UA_ResponseHeader));
|
|
|
|
- r->requestHandle = p->requestHandle;
|
|
|
|
- r->serviceResult = UA_STATUSCODE_GOOD;
|
|
|
|
|
|
+static void init_response_header(UA_RequestHeader const * p,
|
|
|
|
+ UA_ResponseHeader * r)
|
|
|
|
+{
|
|
|
|
+ memset((void*) r, 0, sizeof(UA_ResponseHeader));
|
|
|
|
+ r->requestHandle = p->requestHandle;
|
|
|
|
+ r->serviceResult = UA_STATUSCODE_GOOD;
|
|
r->stringTableSize = 0;
|
|
r->stringTableSize = 0;
|
|
- r->timestamp = UA_DateTime_now();
|
|
|
|
|
|
+ r->timestamp = UA_DateTime_now();
|
|
}
|
|
}
|
|
-
|
|
|
|
-#define INVOKE_SERVICE(TYPE) \
|
|
|
|
- UA_##TYPE##Request p; \
|
|
|
|
- UA_##TYPE##Response r; \
|
|
|
|
- UA_##TYPE##Request_decodeBinary(msg, offset, &p); \
|
|
|
|
- UA_##TYPE##Response_init(&r); \
|
|
|
|
- init_response_header(&p.requestHeader, &r.responseHeader); \
|
|
|
|
- DBG_VERBOSE(printf("Invoke Service: %s\n", # TYPE)); \
|
|
|
|
- Service_##TYPE(channel, &p, &r); \
|
|
|
|
- DBG_VERBOSE(printf("Finished Service: %s\n", # TYPE)); \
|
|
|
|
- UA_UInt32 sending_offset = 0; \
|
|
|
|
- UA_ByteString_newMembers(&response_msg, UA_##TYPE##Response_calcSizeBinary(&r)); \
|
|
|
|
- UA_##TYPE##Response_encodeBinary(&r, &response_msg, &sending_offset); \
|
|
|
|
- UA_##TYPE##Request_deleteMembers(&p); \
|
|
|
|
- UA_##TYPE##Response_deleteMembers(&r); \
|
|
|
|
-
|
|
|
|
-/** this function manages all the generic stuff for the request-response game */
|
|
|
|
-UA_Int32 SL_handleRequest(SL_Channel *channel, const UA_ByteString *msg, UA_UInt32 *offset) {
|
|
|
|
|
|
+#define RESPONSE_PREPARE(TYPE) \
|
|
|
|
+ UA_##TYPE##Request p; \
|
|
|
|
+ UA_##TYPE##Response r; \
|
|
|
|
+ UA_Session session = UA_NULL; \
|
|
|
|
+ UA_##TYPE##Request_decodeBinary(msg, &recvOffset, &p); \
|
|
|
|
+ UA_##TYPE##Response_init(&r); \
|
|
|
|
+ init_response_header(&p.requestHeader, &r.responseHeader); \
|
|
|
|
+ UA_SessionManager_getSessionByToken(&p.requestHeader.authenticationToken, &session); \
|
|
|
|
+ DBG_VERBOSE(printf("Invoke Service: %s\n", #TYPE)); \
|
|
|
|
+
|
|
|
|
+#define INVOKE_SERVICE(TYPE) \
|
|
|
|
+ UA_##TYPE##Request p; \
|
|
|
|
+ UA_##TYPE##Response r; \
|
|
|
|
+ UA_Session session = UA_NULL; \
|
|
|
|
+ UA_##TYPE##Request_decodeBinary(msg, &recvOffset, &p); \
|
|
|
|
+ UA_##TYPE##Response_init(&r); \
|
|
|
|
+ init_response_header(&p.requestHeader, &r.responseHeader); \
|
|
|
|
+ UA_SessionManager_getSessionByToken(&p.requestHeader.authenticationToken, &session); \
|
|
|
|
+ DBG_VERBOSE(printf("Invoke Service: %s\n", #TYPE)); \
|
|
|
|
+ Service_##TYPE(session, &p, &r); \
|
|
|
|
+ DBG_VERBOSE(printf("Finished Service: %s\n", #TYPE)); \
|
|
|
|
+ sendOffset = 0; \
|
|
|
|
+ UA_ByteString_newMembers(&response_msg, UA_##TYPE##Response_calcSizeBinary(&r)); \
|
|
|
|
+ UA_##TYPE##Response_encodeBinary(&r, &sendOffset, &response_msg); \
|
|
|
|
+ UA_##TYPE##Request_deleteMembers(&p); \
|
|
|
|
+ UA_##TYPE##Response_deleteMembers(&r); \
|
|
|
|
+/*
|
|
|
|
+#define INVOKE_SERVICE(TYPE) \
|
|
|
|
+ DBG_VERBOSE(printf("Invoke Service: %s\n", #TYPE)); \
|
|
|
|
+ Service_##TYPE(session, &p, &r); \
|
|
|
|
+ DBG_VERBOSE(printf("Finished Service: %s\n", #TYPE)); \
|
|
|
|
+*/
|
|
|
|
+#define RESPONSE_CLEANUP(TYPE) \
|
|
|
|
+ DBG_VERBOSE(printf("Finished Service: %s\n", #TYPE)); \
|
|
|
|
+ sendOffset = 0; \
|
|
|
|
+ UA_ByteString_newMembers(&response_msg, UA_##TYPE##Response_calcSizeBinary(&r)); \
|
|
|
|
+ UA_##TYPE##Response_encodeBinary(&r, &response_msg,&sendOffset); \
|
|
|
|
+ UA_##TYPE##Request_deleteMembers(&p); \
|
|
|
|
+ UA_##TYPE##Response_deleteMembers(&r); \
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+UA_Int32 SL_handleRequest(SL_Channel channel, const UA_ByteString* msg,
|
|
|
|
+ UA_UInt32 *pos)
|
|
|
|
+{
|
|
UA_Int32 retval = UA_SUCCESS;
|
|
UA_Int32 retval = UA_SUCCESS;
|
|
-
|
|
|
|
|
|
+ UA_UInt32 recvOffset = *pos;
|
|
|
|
+ UA_UInt32 sendOffset = 0;
|
|
// Every Message starts with a NodeID which names the serviceRequestType
|
|
// Every Message starts with a NodeID which names the serviceRequestType
|
|
UA_NodeId serviceRequestType;
|
|
UA_NodeId serviceRequestType;
|
|
- UA_NodeId_decodeBinary(msg, offset, &serviceRequestType);
|
|
|
|
|
|
+ UA_NodeId_decodeBinary(msg, &recvOffset,&serviceRequestType);
|
|
#ifdef DEBUG
|
|
#ifdef DEBUG
|
|
- UA_NodeId_printf("SL_processMessage - serviceRequestType=", &serviceRequestType);
|
|
|
|
|
|
+ UA_NodeId_printf("SL_processMessage - serviceRequestType=",
|
|
|
|
+ &serviceRequestType);
|
|
#endif
|
|
#endif
|
|
-
|
|
|
|
UA_ByteString response_msg;
|
|
UA_ByteString response_msg;
|
|
- int serviceid = serviceRequestType.identifier.numeric-2; // binary encoding has 2 added to the id
|
|
|
|
- UA_Int32 responsetype;
|
|
|
|
- if(serviceid == UA_GETENDPOINTSREQUEST_NS0) {
|
|
|
|
- INVOKE_SERVICE(GetEndpoints);
|
|
|
|
|
|
+ UA_Int32 serviceid = serviceRequestType.identifier.numeric - 2; // binary encoding has 2 added to the id
|
|
|
|
+ UA_Int32 responsetype;
|
|
|
|
+/* stack related services which only need information about the secure Channel */
|
|
|
|
+ if (serviceid == UA_GETENDPOINTSREQUEST_NS0)
|
|
|
|
+ {
|
|
|
|
+ RESPONSE_PREPARE(GetEndpoints);
|
|
|
|
+ Service_GetEndpoints(channel,&p, &r);
|
|
|
|
+ RESPONSE_CLEANUP(GetEndpoints);
|
|
|
|
+ //INVOKE_SERVICE(GetEndpoints);
|
|
responsetype = UA_GETENDPOINTSRESPONSE_NS0;
|
|
responsetype = UA_GETENDPOINTSRESPONSE_NS0;
|
|
- }else if(serviceid == UA_OPENSECURECHANNELREQUEST_NS0) {
|
|
|
|
- INVOKE_SERVICE(OpenSecureChannel);
|
|
|
|
|
|
+ }
|
|
|
|
+ else if (serviceid == UA_OPENSECURECHANNELREQUEST_NS0)
|
|
|
|
+ {
|
|
|
|
+ RESPONSE_PREPARE(OpenSecureChannel);
|
|
|
|
+ Service_OpenSecureChannel(channel,&p, &r);
|
|
|
|
+ RESPONSE_CLEANUP(OpenSecureChannel);
|
|
responsetype = UA_OPENSECURECHANNELRESPONSE_NS0;
|
|
responsetype = UA_OPENSECURECHANNELRESPONSE_NS0;
|
|
- }else if(serviceid == UA_CLOSESECURECHANNELREQUEST_NS0) {
|
|
|
|
- INVOKE_SERVICE(CloseSecureChannel);
|
|
|
|
|
|
+ }
|
|
|
|
+ else if (serviceid == UA_CLOSESECURECHANNELREQUEST_NS0)
|
|
|
|
+ {
|
|
|
|
+ RESPONSE_PREPARE(CloseSecureChannel);
|
|
|
|
+ Service_CloseSecureChannel(channel,&p,&r);
|
|
|
|
+ RESPONSE_CLEANUP(CloseSecureChannel);
|
|
responsetype = UA_CLOSESECURECHANNELRESPONSE_NS0;
|
|
responsetype = UA_CLOSESECURECHANNELRESPONSE_NS0;
|
|
- }else if(serviceid == UA_CREATESESSIONREQUEST_NS0) {
|
|
|
|
- INVOKE_SERVICE(CreateSession);
|
|
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ else if (serviceid == UA_CREATESESSIONREQUEST_NS0)
|
|
|
|
+ {
|
|
|
|
+ RESPONSE_PREPARE(CreateSession);
|
|
|
|
+ Service_CreateSession(channel,&p, &r);
|
|
|
|
+ RESPONSE_CLEANUP(CreateSession);
|
|
responsetype = UA_CREATESESSIONRESPONSE_NS0;
|
|
responsetype = UA_CREATESESSIONRESPONSE_NS0;
|
|
- }else if(serviceid == UA_ACTIVATESESSIONREQUEST_NS0) {
|
|
|
|
- INVOKE_SERVICE(ActivateSession);
|
|
|
|
|
|
+ }
|
|
|
|
+/* services which need a session object */
|
|
|
|
+ else if (serviceid == UA_ACTIVATESESSIONREQUEST_NS0)
|
|
|
|
+ {
|
|
|
|
+ RESPONSE_PREPARE(ActivateSession);
|
|
|
|
+ UA_Session_updateLifetime(session); //renew session timeout
|
|
|
|
+ Service_ActivateSession(channel, session,&p, &r);
|
|
|
|
+ RESPONSE_CLEANUP(ActivateSession);
|
|
|
|
+
|
|
responsetype = UA_ACTIVATESESSIONRESPONSE_NS0;
|
|
responsetype = UA_ACTIVATESESSIONRESPONSE_NS0;
|
|
- }else if(serviceid == UA_CLOSESESSIONREQUEST_NS0) {
|
|
|
|
- INVOKE_SERVICE(CloseSession);
|
|
|
|
|
|
+ }
|
|
|
|
+ else if (serviceid == UA_CLOSESESSIONREQUEST_NS0)
|
|
|
|
+ {
|
|
|
|
+ RESPONSE_PREPARE(CloseSession);
|
|
|
|
+ if (UA_Session_verifyChannel(session,channel)){
|
|
|
|
+ UA_Session_updateLifetime(session); //renew session timeout
|
|
|
|
+ Service_CloseSession(session,&p, &r);
|
|
|
|
+ RESPONSE_CLEANUP(CloseSession);
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ DBG_VERBOSE(printf("session does not match secure channel"));
|
|
|
|
+ }
|
|
responsetype = UA_CLOSESESSIONRESPONSE_NS0;
|
|
responsetype = UA_CLOSESESSIONRESPONSE_NS0;
|
|
- }else if(serviceid == UA_READREQUEST_NS0) {
|
|
|
|
- INVOKE_SERVICE(Read);
|
|
|
|
|
|
+ }
|
|
|
|
+ else if (serviceid == UA_READREQUEST_NS0)
|
|
|
|
+ {
|
|
|
|
+
|
|
|
|
+ RESPONSE_PREPARE(Read);
|
|
|
|
+ UA_Session_updateLifetime(session); //renew session timeout
|
|
|
|
+ DBG_VERBOSE(printf("Finished Service: %s\n", Read));
|
|
|
|
+ if (UA_Session_verifyChannel(session,channel)){
|
|
|
|
+ UA_Session_updateLifetime(session); //renew session timeout
|
|
|
|
+ Service_Read(session,&p, &r);
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ DBG_VERBOSE(printf("session does not match secure channel"));
|
|
|
|
+ }
|
|
|
|
+ DBG_VERBOSE(printf("Finished Service: %s\n", Read));
|
|
|
|
+ RESPONSE_CLEANUP(Read);
|
|
|
|
+
|
|
responsetype = UA_READRESPONSE_NS0;
|
|
responsetype = UA_READRESPONSE_NS0;
|
|
- }else if(serviceid == UA_WRITEREQUEST_NS0)
|
|
|
|
|
|
+ }
|
|
|
|
+ else if (serviceid == UA_WRITEREQUEST_NS0)
|
|
{
|
|
{
|
|
- INVOKE_SERVICE(Write);
|
|
|
|
|
|
+
|
|
|
|
+ RESPONSE_PREPARE(Write);
|
|
|
|
+ DBG_VERBOSE(printf("Finished Service: %s\n", Write));
|
|
|
|
+ if (UA_Session_verifyChannel(session,channel)){
|
|
|
|
+ UA_Session_updateLifetime(session); //renew session timeout
|
|
|
|
+ Service_Write(session,&p, &r);
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ DBG_VERBOSE(printf("session does not match secure channel"));
|
|
|
|
+ }
|
|
|
|
+ DBG_VERBOSE(printf("Finished Service: %s\n", Write));
|
|
|
|
+ RESPONSE_CLEANUP(Write);
|
|
|
|
+
|
|
|
|
+
|
|
responsetype = UA_WRITERESPONSE_NS0;
|
|
responsetype = UA_WRITERESPONSE_NS0;
|
|
- }else if(serviceid == UA_TRANSLATEBROWSEPATHSTONODEIDSREQUEST_NS0) {
|
|
|
|
- INVOKE_SERVICE(TranslateBrowsePathsToNodeIds);
|
|
|
|
- responsetype = UA_TRANSLATEBROWSEPATHSTONODEIDSRESPONSE_NS0;
|
|
|
|
- }else if(serviceid == UA_BROWSEREQUEST_NS0) {
|
|
|
|
- INVOKE_SERVICE(Browse);
|
|
|
|
|
|
+ }
|
|
|
|
+ else if (serviceid == UA_BROWSEREQUEST_NS0)
|
|
|
|
+ {
|
|
|
|
+
|
|
|
|
+ RESPONSE_PREPARE(Browse);
|
|
|
|
+ DBG_VERBOSE(printf("Finished Service: %s\n", Browse));
|
|
|
|
+ if (UA_Session_verifyChannel(session,channel)){
|
|
|
|
+ Service_Browse(session,&p, &r);
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ DBG_VERBOSE(printf("session does not match secure channel"));
|
|
|
|
+ }
|
|
|
|
+ DBG_VERBOSE(printf("Finished Service: %s\n", Browse));
|
|
|
|
+ RESPONSE_CLEANUP(Browse);
|
|
|
|
+
|
|
|
|
+
|
|
responsetype = UA_BROWSERESPONSE_NS0;
|
|
responsetype = UA_BROWSERESPONSE_NS0;
|
|
- }else if(serviceid == UA_CREATESUBSCRIPTIONREQUEST_NS0) {
|
|
|
|
- INVOKE_SERVICE(CreateSubscription);
|
|
|
|
|
|
+ }
|
|
|
|
+ else if (serviceid == UA_CREATESUBSCRIPTIONREQUEST_NS0)
|
|
|
|
+ {
|
|
|
|
+
|
|
|
|
+ RESPONSE_PREPARE(CreateSubscription);
|
|
|
|
+ DBG_VERBOSE(printf("Finished Service: %s\n", CreateSubscription));
|
|
|
|
+ if (UA_Session_verifyChannel(session,channel)){
|
|
|
|
+ Service_CreateSubscription(session, &p, &r);
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ DBG_VERBOSE(printf("session does not match secure channel"));
|
|
|
|
+ }
|
|
|
|
+ DBG_VERBOSE(printf("Finished Service: %s\n", CreateSubscription));
|
|
|
|
+ RESPONSE_CLEANUP(CreateSubscription);
|
|
responsetype = UA_CREATESUBSCRIPTIONRESPONSE_NS0;
|
|
responsetype = UA_CREATESUBSCRIPTIONRESPONSE_NS0;
|
|
- }else if(serviceid == UA_CREATEMONITOREDITEMSREQUEST_NS0) {
|
|
|
|
- INVOKE_SERVICE(CreateMonitoredItems);
|
|
|
|
- responsetype = UA_CREATEMONITOREDITEMSRESPONSE_NS0;
|
|
|
|
- }else if(serviceid == UA_PUBLISHREQUEST_NS0) {
|
|
|
|
- INVOKE_SERVICE(Publish);
|
|
|
|
|
|
+ }
|
|
|
|
+ else if (serviceid == UA_TRANSLATEBROWSEPATHSTONODEIDSREQUEST_NS0)
|
|
|
|
+ {
|
|
|
|
+
|
|
|
|
+ RESPONSE_PREPARE(TranslateBrowsePathsToNodeIds);
|
|
|
|
+ DBG_VERBOSE(printf("Finished Service: %s\n", TranslateBrowsePathsToNodeIds));
|
|
|
|
+ if (UA_Session_verifyChannel(session,channel)){
|
|
|
|
+ Service_TranslateBrowsePathsToNodeIds(session, &p, &r);
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ DBG_VERBOSE(printf("session does not match secure channel"));
|
|
|
|
+ }
|
|
|
|
+ DBG_VERBOSE(printf("Finished Service: %s\n", TranslateBrowsePathsToNodeIds));
|
|
|
|
+ RESPONSE_CLEANUP(TranslateBrowsePathsToNodeIds);
|
|
|
|
+ responsetype = UA_TRANSLATEBROWSEPATHSTONODEIDSRESPONSE_NS0;
|
|
|
|
+ }
|
|
|
|
+ else if (serviceid == UA_PUBLISHREQUEST_NS0)
|
|
|
|
+ {
|
|
|
|
+
|
|
|
|
+ RESPONSE_PREPARE(Publish);
|
|
|
|
+ DBG_VERBOSE(printf("Finished Service: %s\n", Publish));
|
|
|
|
+ if (UA_Session_verifyChannel(session,channel)){
|
|
|
|
+ Service_Publish(session, &p, &r);
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ DBG_VERBOSE(printf("session does not match secure channel"));
|
|
|
|
+ }
|
|
|
|
+ DBG_VERBOSE(printf("Finished Service: %s\n", Publish));
|
|
|
|
+ RESPONSE_CLEANUP(Publish);
|
|
responsetype = UA_PUBLISHRESPONSE_NS0;
|
|
responsetype = UA_PUBLISHRESPONSE_NS0;
|
|
- }else{
|
|
|
|
- printf("SL_processMessage - unknown request, namespace=%d, request=%d\n",
|
|
|
|
- serviceRequestType.namespace,
|
|
|
|
- serviceRequestType.identifier.numeric);
|
|
|
|
|
|
+ }
|
|
|
|
+ else if (serviceid == UA_CREATEMONITOREDITEMSREQUEST_NS0)
|
|
|
|
+ {
|
|
|
|
+ RESPONSE_PREPARE(CreateMonitoredItems);
|
|
|
|
+ DBG_VERBOSE(printf("Finished Service: %s\n", CreateMonitoredItems));
|
|
|
|
+ if (UA_Session_verifyChannel(session,channel)){
|
|
|
|
+ Service_CreateMonitoredItems(session, &p, &r);
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ DBG_VERBOSE(printf("session does not match secure channel"));
|
|
|
|
+ }
|
|
|
|
+ DBG_VERBOSE(printf("Finished Service: %s\n", CreateMonitoredItems));
|
|
|
|
+ RESPONSE_CLEANUP(CreateMonitoredItems);
|
|
|
|
+ responsetype = UA_CREATEMONITOREDITEMSRESPONSE_NS0;
|
|
|
|
+ }
|
|
|
|
+ else if (serviceid == UA_SETPUBLISHINGMODEREQUEST_NS0)
|
|
|
|
+ {
|
|
|
|
+ RESPONSE_PREPARE(SetPublishingMode);
|
|
|
|
+ DBG_VERBOSE(printf("Finished Service: %s\n",SetPublishingMode));
|
|
|
|
+ if (UA_Session_verifyChannel(session,channel)){
|
|
|
|
+ Service_SetPublishingMode(session, &p, &r);
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ DBG_VERBOSE(printf("session does not match secure channel"));
|
|
|
|
+ }
|
|
|
|
+ DBG_VERBOSE(printf("Finished Service: %s\n", SetPublishingMode));
|
|
|
|
+ RESPONSE_CLEANUP(SetPublishingMode);
|
|
|
|
+ responsetype = UA_SETPUBLISHINGMODERESPONSE_NS0;
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ printf(
|
|
|
|
+ "SL_processMessage - unknown request, namespace=%d, request=%d\n",
|
|
|
|
+ serviceRequestType.namespace,
|
|
|
|
+ serviceRequestType.identifier.numeric);
|
|
retval = UA_ERROR;
|
|
retval = UA_ERROR;
|
|
- UA_RequestHeader p;
|
|
|
|
|
|
+ UA_RequestHeader p;
|
|
UA_ResponseHeader r;
|
|
UA_ResponseHeader r;
|
|
- UA_RequestHeader_decodeBinary(msg, offset, &p);
|
|
|
|
|
|
+
|
|
|
|
+ UA_RequestHeader_decodeBinary(msg, &recvOffset, &p);
|
|
UA_ResponseHeader_init(&r);
|
|
UA_ResponseHeader_init(&r);
|
|
r.requestHandle = p.requestHandle;
|
|
r.requestHandle = p.requestHandle;
|
|
r.serviceResult = UA_STATUSCODE_BADSERVICEUNSUPPORTED;
|
|
r.serviceResult = UA_STATUSCODE_BADSERVICEUNSUPPORTED;
|
|
- *offset = 0;
|
|
|
|
|
|
+ sendOffset = 0;
|
|
UA_ByteString_newMembers(&response_msg, UA_ResponseHeader_calcSizeBinary(&r));
|
|
UA_ByteString_newMembers(&response_msg, UA_ResponseHeader_calcSizeBinary(&r));
|
|
- UA_ResponseHeader_encodeBinary(&r, &response_msg, offset);
|
|
|
|
|
|
+ UA_ResponseHeader_encodeBinary(&r, &response_msg,&sendOffset);
|
|
responsetype = UA_RESPONSEHEADER_NS0;
|
|
responsetype = UA_RESPONSEHEADER_NS0;
|
|
}
|
|
}
|
|
-
|
|
|
|
- SL_Send(channel, &response_msg, responsetype);
|
|
|
|
|
|
+ if(serviceid != UA_CLOSESECURECHANNELREQUEST_NS0){
|
|
|
|
+ SL_Send(channel, &response_msg, responsetype);
|
|
|
|
+ }
|
|
UA_ByteString_deleteMembers(&response_msg);
|
|
UA_ByteString_deleteMembers(&response_msg);
|
|
-
|
|
|
|
|
|
+ *pos = recvOffset;
|
|
return retval;
|
|
return retval;
|
|
}
|
|
}
|
|
-/**
|
|
|
|
- *
|
|
|
|
- * @param connection
|
|
|
|
- * @param msg
|
|
|
|
- * @param offset
|
|
|
|
- * @return
|
|
|
|
- */
|
|
|
|
-UA_Int32 SL_Channel_new(TL_Connection *connection, const UA_ByteString *msg, UA_UInt32 *offset) {
|
|
|
|
- DBG_VERBOSE(printf("SL_Channel_new - entered\n"));
|
|
|
|
- UA_Int32 retval = UA_SUCCESS;
|
|
|
|
|
|
|
|
- /* Create New Channel*/
|
|
|
|
- SL_Channel *channel = &slc; // FIXME: generate new secure channel
|
|
|
|
- UA_AsymmetricAlgorithmSecurityHeader_init(&(channel->localAsymAlgSettings));
|
|
|
|
- UA_ByteString_copy(&UA_ByteString_securityPoliceNone,
|
|
|
|
- &(channel->localAsymAlgSettings.securityPolicyUri));
|
|
|
|
- UA_alloc((void **)&(channel->localNonce.data), sizeof(UA_Byte));
|
|
|
|
- channel->localNonce.length = 1;
|
|
|
|
- channel->connectionState = CONNECTIONSTATE_CLOSED; // the state of the channel will be opened in the service
|
|
|
|
- channel->sequenceHeader.requestId = 0;
|
|
|
|
- channel->sequenceHeader.sequenceNumber = 1;
|
|
|
|
- UA_String_init(&(channel->secureChannelId));
|
|
|
|
- channel->securityMode = UA_SECURITYMODE_INVALID;
|
|
|
|
- channel->securityToken.secureChannelId = 25; //TODO set a valid start secureChannelId number
|
|
|
|
- channel->securityToken.tokenId.tokenId = 1; //TODO set a valid start TokenId
|
|
|
|
-
|
|
|
|
- connection->secureChannel = channel;
|
|
|
|
- connection->secureChannel->tlConnection = connection;
|
|
|
|
-
|
|
|
|
- /* Read the OPN message headers */
|
|
|
|
- *offset += 4; // skip the securechannelid
|
|
|
|
- UA_AsymmetricAlgorithmSecurityHeader_decodeBinary(
|
|
|
|
- msg, offset, &connection->secureChannel->remoteAsymAlgSettings);
|
|
|
|
- UA_SequenceHeader_decodeBinary(msg, offset, &connection->secureChannel->sequenceHeader);
|
|
|
|
- //TODO check that the sequence number is smaller than MaxUInt32 - 1024
|
|
|
|
- //TODO check if a OpenSecureChannelRequest follows
|
|
|
|
-
|
|
|
|
- retval |= SL_handleRequest(channel, msg, offset);
|
|
|
|
- return retval;
|
|
|
|
-
|
|
|
|
- // FIXME: reject
|
|
|
|
|
|
+UA_Int32 SL_ProcessOpenChannel(SL_Channel channel, const UA_ByteString* msg,
|
|
|
|
+ UA_UInt32 *pos)
|
|
|
|
+{
|
|
|
|
+ UA_Int32 retval = UA_SUCCESS;
|
|
|
|
+ UA_SequenceHeader sequenceHeader;
|
|
|
|
+ UA_AsymmetricAlgorithmSecurityHeader asymHeader;
|
|
|
|
+ *pos+=4; //skip secure channel id
|
|
|
|
+ UA_AsymmetricAlgorithmSecurityHeader_decodeBinary(msg,pos,&asymHeader);
|
|
|
|
+ UA_SequenceHeader_decodeBinary(msg,pos,&sequenceHeader);
|
|
|
|
+
|
|
|
|
+ //init remote security settings from the security header
|
|
|
|
+ SL_Channel_setRemoteSecuritySettings(channel,&asymHeader,&sequenceHeader);
|
|
|
|
+ return SL_handleRequest(channel, msg, pos) | retval;
|
|
}
|
|
}
|
|
-
|
|
|
|
-/**
|
|
|
|
- * process the rest of the header. TL already processed MessageType
|
|
|
|
- * (OPN,MSG,...), isFinal and MessageSize. SL_process cares for
|
|
|
|
- * secureChannelId, XASHeader and sequenceHeader
|
|
|
|
- * */
|
|
|
|
-UA_Int32 SL_Process(SL_Channel *connection, const UA_ByteString *msg, UA_UInt32 *offset) {
|
|
|
|
|
|
+UA_Int32 SL_ProcessCloseChannel(SL_Channel channel, const UA_ByteString* msg,
|
|
|
|
+ UA_UInt32 *pos)
|
|
|
|
+{
|
|
|
|
+ return SL_handleRequest(channel, msg, pos);
|
|
|
|
+}
|
|
|
|
+UA_Int32 SL_Process(const UA_ByteString* msg,
|
|
|
|
+ UA_UInt32* pos)
|
|
|
|
+{
|
|
|
|
|
|
DBG_VERBOSE(printf("SL_process - entered \n"));
|
|
DBG_VERBOSE(printf("SL_process - entered \n"));
|
|
UA_UInt32 secureChannelId;
|
|
UA_UInt32 secureChannelId;
|
|
|
|
+ UA_UInt32 foundChannelId;
|
|
|
|
+ SL_Channel channel;
|
|
|
|
+ UA_SequenceHeader sequenceHeader;
|
|
|
|
|
|
- if(connection->connectionState == CONNECTIONSTATE_ESTABLISHED) {
|
|
|
|
- UA_UInt32_decodeBinary(msg, offset, &secureChannelId);
|
|
|
|
-
|
|
|
|
- //FIXME: we assume SAS, need to check if AAS or SAS
|
|
|
|
- UA_SymmetricAlgorithmSecurityHeader symAlgSecHeader;
|
|
|
|
- // if (connection->securityMode == UA_MESSAGESECURITYMODE_NONE) {
|
|
|
|
- UA_SymmetricAlgorithmSecurityHeader_decodeBinary(msg, offset, &symAlgSecHeader);
|
|
|
|
-
|
|
|
|
- printf("SL_process - securityToken received=%d, expected=%d\n", secureChannelId,
|
|
|
|
- connection->securityToken.secureChannelId);
|
|
|
|
- if(secureChannelId == connection->securityToken.secureChannelId) {
|
|
|
|
- UA_SequenceHeader_decodeBinary(msg, offset, &(connection->sequenceHeader));
|
|
|
|
- SL_handleRequest(&slc, msg, offset);
|
|
|
|
- } else {
|
|
|
|
- //TODO generate ERROR_Bad_SecureChannelUnkown
|
|
|
|
- }
|
|
|
|
|
|
+
|
|
|
|
+ UA_UInt32_decodeBinary(msg, pos, &secureChannelId);
|
|
|
|
+
|
|
|
|
+ //FIXME: we assume SAS, need to check if AAS or SAS
|
|
|
|
+ UA_SymmetricAlgorithmSecurityHeader symAlgSecHeader;
|
|
|
|
+ // if (connection->securityMode == UA_MESSAGESECURITYMODE_NONE) {
|
|
|
|
+ UA_SymmetricAlgorithmSecurityHeader_decodeBinary(msg, pos,
|
|
|
|
+ &symAlgSecHeader);
|
|
|
|
+
|
|
|
|
+ if (SL_ChannelManager_getChannel(secureChannelId,
|
|
|
|
+ &channel) == UA_SUCCESS)
|
|
|
|
+ {
|
|
|
|
+
|
|
|
|
+ SL_Channel_getChannelId(channel, &foundChannelId);
|
|
|
|
+ printf("SL_process - received msg, with channel id: %i \n",
|
|
|
|
+ foundChannelId);
|
|
|
|
+
|
|
|
|
+ //sequence number processing
|
|
|
|
+ UA_SequenceHeader_decodeBinary(msg, pos,
|
|
|
|
+ &sequenceHeader);
|
|
|
|
+ SL_Channel_checkSequenceNumber(channel,sequenceHeader.sequenceNumber);
|
|
|
|
+ SL_Channel_checkRequestId(channel,sequenceHeader.requestId);
|
|
|
|
+ //request id processing
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ SL_handleRequest(channel, msg, pos);
|
|
}
|
|
}
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ printf("SL_process - ERROR could not find channel with id: %i \n",
|
|
|
|
+ secureChannelId);
|
|
|
|
+ //TODO generate ERROR_Bad_SecureChannelUnkown
|
|
|
|
+ }
|
|
|
|
+
|
|
return UA_SUCCESS;
|
|
return UA_SUCCESS;
|
|
}
|
|
}
|