Browse Source

enhanced session handling (verifying securechannel etc)

FlorianPalm 10 years ago
parent
commit
d9ef36ca74

+ 10 - 10
src/ua_services.h

@@ -34,7 +34,7 @@
  * the configuration information required to establish a SecureChannel and a
  * Session.
  */
-UA_Int32 Service_GetEndpoints(UA_Session session, const UA_GetEndpointsRequest* request, UA_GetEndpointsResponse *response);
+UA_Int32 Service_GetEndpoints(SL_secureChannel channel, const UA_GetEndpointsRequest* request, UA_GetEndpointsResponse *response);
 // Service_RegisterServer
 /** @} */
 
@@ -58,7 +58,7 @@ UA_Int32 Service_OpenSecureChannel(SL_secureChannel channel,const UA_OpenSecureC
 /**
  * @brief This Service is used to terminate a SecureChannel.
  */
-UA_Int32 Service_CloseSecureChannel(UA_Session session, const UA_CloseSecureChannelRequest *request, UA_CloseSecureChannelResponse *response);
+UA_Int32 Service_CloseSecureChannel(const UA_CloseSecureChannelRequest *request, UA_CloseSecureChannelResponse *response);
 /** @} */
 
 /**
@@ -77,7 +77,7 @@ UA_Int32 Service_CloseSecureChannel(UA_Session session, const UA_CloseSecureChan
  * logs and in the Server’s address space. The second is the authenticationToken
  * which is used to associate an incoming request with a Session.
  */
-UA_Int32 Service_CreateSession(UA_Session session, const UA_CreateSessionRequest *request, UA_CreateSessionResponse *response);
+UA_Int32 Service_CreateSession(UA_Session *session, const UA_CreateSessionRequest *request, UA_CreateSessionResponse *response);
 
 /**
  * @brief This Service is used by the Client to submit its SoftwareCertificates
@@ -86,12 +86,12 @@ UA_Int32 Service_CreateSession(UA_Session session, const UA_CreateSessionRequest
  * Client before it issues any other Service request after CreateSession.
  * Failure to do so shall cause the Server to close the Session.
  */
-UA_Int32 Service_ActivateSession(UA_Session session, const UA_ActivateSessionRequest *request, UA_ActivateSessionResponse *response);
+UA_Int32 Service_ActivateSession(SL_secureChannel channel, UA_Session *session, const UA_ActivateSessionRequest *request, UA_ActivateSessionResponse *response);
 
 /**
  * @brief This Service is used to terminate a Session.
  */
-UA_Int32 Service_CloseSession(UA_Session session, const UA_CloseSessionRequest *request, UA_CloseSessionResponse *response);
+UA_Int32 Service_CloseSession(UA_Session *session, const UA_CloseSessionRequest *request, UA_CloseSessionResponse *response);
 // Service_Cancel
 /** @} */
 
@@ -108,7 +108,7 @@ UA_Int32 Service_CloseSession(UA_Session session, const UA_CloseSessionRequest *
 /**
  * @brief This Service is used to add one or more Nodes into the AddressSpace hierarchy.
  */
-UA_Int32 Service_AddNodes(UA_Session session, const UA_AddNodesRequest *request, UA_AddNodesResponse *response);
+UA_Int32 Service_AddNodes(UA_Session *session, const UA_AddNodesRequest *request, UA_AddNodesResponse *response);
 // Service_AddReferences
 // Service_DeleteNodes
 // Service_DeleteReferences
@@ -128,12 +128,12 @@ UA_Int32 Service_AddNodes(UA_Session session, const UA_AddNodesRequest *request,
  * The browse can be further limited by the use of a View. This Browse Service
  * also supports a primitive filtering capability.
  */ 
-UA_Int32 Service_Browse(UA_Session session, const UA_BrowseRequest *request, UA_BrowseResponse *response);
+UA_Int32 Service_Browse(UA_Session *session, const UA_BrowseRequest *request, UA_BrowseResponse *response);
 
 /**
  * @brief This Service is used to translate textual node paths to their respective ids.
  */
-UA_Int32 Service_TranslateBrowsePathsToNodeIds(UA_Session session,  const UA_TranslateBrowsePathsToNodeIdsRequest *request, UA_TranslateBrowsePathsToNodeIdsResponse *response);
+UA_Int32 Service_TranslateBrowsePathsToNodeIds(UA_Session *session,  const UA_TranslateBrowsePathsToNodeIdsRequest *request, UA_TranslateBrowsePathsToNodeIdsResponse *response);
 // Service_BrowseNext
 // Service_TranslateBrowsePathsToNodeIds
 // Service_RegisterNodes
@@ -176,7 +176,7 @@ UA_Int32 Service_TranslateBrowsePathsToNodeIds(UA_Session session,  const UA_Tra
  * values as a composite, to read individual elements or to read ranges of
  * elements of the composite.
  */
-UA_Int32 Service_Read(UA_Session session, const UA_ReadRequest *request, UA_ReadResponse *response);
+UA_Int32 Service_Read(UA_Session *session, const UA_ReadRequest *request, UA_ReadResponse *response);
 // Service_HistoryRead
 // Service_Write
 // Service_HistoryUpdate
@@ -210,7 +210,7 @@ a component of an Object.
  * triggered item links to be deleted, but has no effect on the MonitoredItems
  * referenced by the triggered items.
  */
-UA_Int32 Service_CreateMonitoredItems(UA_Session session, const UA_CreateMonitoredItemsRequest *request, UA_CreateMonitoredItemsResponse *response);
+UA_Int32 Service_CreateMonitoredItems(UA_Session *session, const UA_CreateMonitoredItemsRequest *request, UA_CreateMonitoredItemsResponse *response);
 // Service_ModifyMonitoredItems
 // Service_SetMonitoringMode
 // Service_SetTriggering

+ 2 - 2
src/ua_services_attribute.c

@@ -185,7 +185,7 @@ static UA_DataValue *service_read_node(Application * app, const UA_ReadValueId *
 	return v;
 }
 
-UA_Int32 Service_Read(UA_Session session, const UA_ReadRequest * request, UA_ReadResponse * response) {
+UA_Int32 Service_Read(UA_Session *session, const UA_ReadRequest * request, UA_ReadResponse * response) {
 	if(session)
 	{
 
@@ -206,7 +206,7 @@ UA_Int32 Service_Read(UA_Session session, const UA_ReadRequest * request, UA_Rea
 			DBG_VERBOSE(printf("service_read - attributeId=%d\n",request->nodesToRead[i]->attributeId));
 			DBG_VERBOSE(UA_NodeId_printf("service_read - nodeId=",&(request->nodesToRead[i]->nodeId)));
 
-			UA_Session_getApplicationPointer(session,&application);
+			UA_Session_getApplicationPointer(*session,&application);
 			if(application){
 				response->results[i] = service_read_node(application, request->nodesToRead[i]);
 			}

+ 1 - 1
src/ua_services_discovery.c

@@ -1,5 +1,5 @@
 #include "ua_services.h"
-UA_Int32 Service_GetEndpoints(UA_Session session, const UA_GetEndpointsRequest* request, UA_GetEndpointsResponse *response) {
+UA_Int32 Service_GetEndpoints(SL_secureChannel channel, const UA_GetEndpointsRequest* request, UA_GetEndpointsResponse *response) {
 	UA_String_printx("endpointUrl=", &request->endpointUrl);
 	response->endpointsSize = 1;
 	UA_Array_new((void***) &response->endpoints,response->endpointsSize,UA_ENDPOINTDESCRIPTION);

+ 2 - 2
src/ua_services_nodemanagement.c

@@ -66,11 +66,11 @@ static UA_AddNodesResult * addSingleNode(Application *app, UA_AddNodesItem *item
 	return result;
 }
 
-UA_Int32 Service_AddNodes(UA_Session session, const UA_AddNodesRequest *request, UA_AddNodesResponse *response) {
+UA_Int32 Service_AddNodes(UA_Session *session, const UA_AddNodesRequest *request, UA_AddNodesResponse *response) {
 //TODO GET SESSION HERE	if(channel->session == UA_NULL || channel->session->application == UA_NULL)
 //		return UA_ERROR;	// TODO: Return error message
 
-	int nodestoaddsize = request->nodesToAddSize;
+	UA_Int32 nodestoaddsize = request->nodesToAddSize;
 	if(nodestoaddsize <= 0) {
 		response->responseHeader.serviceResult = UA_STATUSCODE_BADNOTHINGTODO;
 		response->resultsSize = 0;

+ 1 - 1
src/ua_services_securechannel.c

@@ -18,7 +18,7 @@ UA_Int32 Service_OpenSecureChannel(SL_secureChannel channel,
 	return retval;
 }
 
-UA_Int32 Service_CloseSecureChannel(UA_Session session, const UA_CloseSecureChannelRequest *request,
+UA_Int32 Service_CloseSecureChannel(const UA_CloseSecureChannelRequest *request,
 		UA_CloseSecureChannelResponse *response)
 {
 	UA_Int32 retval = UA_SUCCESS;

+ 5 - 9
src/ua_services_session.c

@@ -7,7 +7,7 @@ Session sessionMockup = {
 		&appMockup
 };
 
-UA_Int32 Service_CreateSession(UA_Session session, const UA_CreateSessionRequest *request, UA_CreateSessionResponse *response) {
+UA_Int32 Service_CreateSession(UA_Session *session, const UA_CreateSessionRequest *request, UA_CreateSessionResponse *response) {
 	UA_String_printf("CreateSession Service - endpointUrl=", &(request->endpointUrl));
 
 	UA_Session *newSession;
@@ -28,25 +28,21 @@ UA_Int32 Service_CreateSession(UA_Session session, const UA_CreateSessionRequest
 	return UA_SUCCESS;
 }
 
-UA_Int32 Service_ActivateSession(UA_Session session, const UA_ActivateSessionRequest *request, UA_ActivateSessionResponse *response) {
+UA_Int32 Service_ActivateSession(SL_secureChannel channel, UA_Session *session, const UA_ActivateSessionRequest *request, UA_ActivateSessionResponse *response) {
 
-	// FIXME: activate session
-
-	//UA_Session_bind(session,)
 
+	UA_Session_bind(*session,channel);
+	UA_Session_setApplicationPointer(*session,&appMockup);
 
 	UA_NodeId_printf("ActivateSession - authToken=", &(request->requestHeader.authenticationToken));
 	// 321 == AnonymousIdentityToken_Encoding_DefaultBinary
 	UA_NodeId_printf("ActivateSession - uIdToken.type=", &(request->userIdentityToken.typeId));
 	UA_ByteString_printx_hex("ActivateSession - uIdToken.body=", &(request->userIdentityToken.body));
-	UA_Session_setApplicationPointer(session,&appMockup);
 
-	// FIXME: channel->session->application = <Application Ptr>
-	//FIXME channel->session = &sessionMockup;
 	return UA_SUCCESS;
 }
 
-UA_Int32 Service_CloseSession(UA_Session session, const UA_CloseSessionRequest *request, UA_CloseSessionResponse *response) {
+UA_Int32 Service_CloseSession(UA_Session *session, const UA_CloseSessionRequest *request, UA_CloseSessionResponse *response) {
 	//FIXME channel->session = UA_NULL;
 	// FIXME: set response
 	return UA_SUCCESS;

+ 2 - 2
src/ua_services_view.c

@@ -1,7 +1,7 @@
 #include "ua_services.h"
 #include "ua_statuscodes.h"
 
-UA_Int32 Service_Browse(UA_Session session, const UA_BrowseRequest *request, UA_BrowseResponse *response) {
+UA_Int32 Service_Browse(UA_Session *session, const UA_BrowseRequest *request, UA_BrowseResponse *response) {
 	UA_Int32 retval = UA_SUCCESS;
 	DBG_VERBOSE(UA_NodeId_printf("BrowseService - view=",&(request->view.viewId)));
 	UA_Int32 i = 0;
@@ -11,7 +11,7 @@ UA_Int32 Service_Browse(UA_Session session, const UA_BrowseRequest *request, UA_
 	return retval;
 }
 
-UA_Int32 Service_TranslateBrowsePathsToNodeIds(UA_Session session, const UA_TranslateBrowsePathsToNodeIdsRequest *request, UA_TranslateBrowsePathsToNodeIdsResponse *response)
+UA_Int32 Service_TranslateBrowsePathsToNodeIds(UA_Session *session, const UA_TranslateBrowsePathsToNodeIdsRequest *request, UA_TranslateBrowsePathsToNodeIdsResponse *response)
 {
 	UA_Int32 retval = UA_SUCCESS;
 

+ 3 - 2
src/ua_stack_channel.c

@@ -182,9 +182,10 @@ UA_Int32 SL_Channel_generateNonce(UA_ByteString *nonce)
 	return UA_SUCCESS;
 }
 
-_Bool SL_Channel_equal(void* channel1, void* channel2)
+UA_Boolean SL_Channel_compare(SL_secureChannel channel1, SL_secureChannel channel2)
 {
-	return (((SL_Channel1*)channel1)->channelId == ((SL_Channel1*)channel2)->channelId);
+	return (((SL_Channel1*)channel1)->channelId == ((SL_Channel1*)channel2)->channelId)
+			? UA_EQUAL : UA_NOT_EQUAL;
 }
 
 UA_Int32 SL_Channel_new(SL_secureChannel **channel,

+ 1 - 1
src/ua_stack_channel.h

@@ -64,7 +64,7 @@ UA_Int32 SL_Channel_registerChannelIdProvider(SL_ChannelIdProvider provider);
 UA_Int32 SL_Channel_checkRequestId(SL_secureChannel channel, UA_UInt32 requestId);
 
 UA_Int32 SL_Channel_checkSequenceNumber(SL_secureChannel channel, UA_UInt32 sequenceNumber);
-UA_Boolean SL_Channel_equal(void* channel1, void* channel2);
+UA_Boolean SL_Channel_compare(SL_secureChannel channel1, SL_secureChannel channel2);
 //getters
 UA_Int32 SL_Channel_getChannelId(SL_secureChannel channel, UA_UInt32 *channelId);
 UA_Int32 SL_Channel_getTokenId(SL_secureChannel channel, UA_UInt32 *tokenlId);

+ 2 - 1
src/ua_stack_channel_manager.c

@@ -167,7 +167,8 @@ UA_Int32 SL_ChannelManager_removeChannel(UA_Int32 channelId)
 	SL_secureChannel channel;
 	UA_Int32 retval = UA_SUCCESS;
 	SL_ChannelManager_getChannel(channelId, &channel);
-	UA_list_Element *element =  UA_list_search(&channelManager->channels, SL_Channel_equal, &channel);
+
+	UA_list_Element *element =  UA_list_search(&channelManager->channels, (UA_list_PayloadComparer)SL_Channel_compare, &channel);
 	if(element){
 		retval |= UA_list_removeElement(element,(UA_list_PayloadVisitor)SL_Channel_delete);
 		return retval;

+ 14 - 4
src/ua_stack_session.c

@@ -105,9 +105,9 @@ UA_Boolean UA_Session_compare(UA_Session session1, UA_Session session2)
 {
 	if(session1 && session2){
 		return UA_NodeId_compare(&((UA_SessionType*)session1)->sessionId,
-				&((UA_SessionType*)session2)->sessionId) == 0;
+				&((UA_SessionType*)session2)->sessionId);
 	}
-	return UA_FALSE;
+	return UA_NOT_EQUAL;
 }
 
 UA_Boolean UA_Session_compareByToken(UA_Session session, UA_NodeId *token)
@@ -115,7 +115,7 @@ UA_Boolean UA_Session_compareByToken(UA_Session session, UA_NodeId *token)
 	if(session && token){
 		return UA_NodeId_compare(&((UA_SessionType*)session)->authenticationToken, token);
 	}
-	return UA_FALSE;
+	return UA_NOT_EQUAL;
 }
 
 UA_Boolean UA_Session_compareById(UA_Session session, UA_NodeId *sessionId)
@@ -123,7 +123,7 @@ UA_Boolean UA_Session_compareById(UA_Session session, UA_NodeId *sessionId)
 	if(session && sessionId){
 		return UA_NodeId_compare(&((UA_SessionType*)session)->sessionId, sessionId);
 	}
-	return UA_FALSE;
+	return UA_NOT_EQUAL;
 }
 
 UA_Int32 UA_Session_getId(UA_Session session, UA_NodeId *sessionId)
@@ -154,6 +154,16 @@ UA_Int32 UA_Session_getChannel(UA_Session session, SL_secureChannel *channel)
 	return UA_ERROR;
 }
 
+UA_Boolean UA_Session_verifyChannel(UA_Session session, SL_secureChannel channel)
+{
+	if(session && channel)
+	{
+		if(SL_Channel_compare(((UA_SessionType*)session)->channel, channel) == UA_EQUAL) {
+				return UA_TRUE;
+		}
+	}
+	return UA_FALSE;
+}
 UA_Int32 UA_Session_getApplicationPointer(UA_Session session, Application** application)
 {
 	if(session)

+ 5 - 0
src/ua_stack_session.h

@@ -26,10 +26,15 @@ UA_Boolean UA_Session_compare(UA_Session session1, UA_Session session2);
 UA_Boolean UA_Session_compareByToken(UA_Session session, UA_NodeId *token);
 UA_Boolean UA_Session_compareById(UA_Session session, UA_NodeId *sessionId);
 UA_Int32 UA_Session_bind(UA_Session session, SL_secureChannel channel);
+UA_Boolean UA_Session_verifyChannel(UA_Session session, SL_secureChannel channel);
+
 UA_Int32 UA_Session_getId(UA_Session session, UA_NodeId *sessionId);
 UA_Int32 UA_Session_getToken(UA_Session session, UA_NodeId *authenticationToken);
 UA_Int32 UA_Session_getChannel(UA_Session session, SL_secureChannel *channel);
+
 UA_Int32 UA_Session_getApplicationPointer(UA_Session session, Application** application);
 
 UA_Int32 UA_Session_setApplicationPointer(UA_Session session, Application* application);
+
+
 #endif /* UA_STACK_SESSION_H_ */

+ 57 - 25
src/ua_transport_binary_secure.c

@@ -133,6 +133,15 @@ static void init_response_header(UA_RequestHeader const * p,
 	r->stringTableSize = 0;
 	r->timestamp = UA_DateTime_now();
 }
+#define RESPONSE_PREPARE(TYPE) \
+	UA_##TYPE##Request p; \
+	UA_##TYPE##Response r; \
+	UA_Session session = UA_NULL; \
+	UA_##TYPE##Request_decodeBinary(msg, pos, &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; \
@@ -150,7 +159,19 @@ static void init_response_header(UA_RequestHeader const * p,
 	UA_##TYPE##Response_encodeBinary(&r, pos, &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)); \
+	*pos = 0; \
+	UA_ByteString_newMembers(&response_msg, UA_##TYPE##Response_calcSize(&r)); \
+	UA_##TYPE##Response_encodeBinary(&r, pos, &response_msg); \
+	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_Int32 *pos)
@@ -169,58 +190,69 @@ UA_Int32 SL_handleRequest(SL_secureChannel channel, const UA_ByteString* msg,
 	UA_ByteString response_msg;
 	UA_Int32 serviceid = serviceRequestType.identifier.numeric - 2; // binary encoding has 2 added to the id
 	UA_Int32 responsetype;
+	//services which need a channel as parameter
 	if (serviceid == UA_GETENDPOINTSREQUEST_NS0)
 	{
-		INVOKE_SERVICE(GetEndpoints);
+		RESPONSE_PREPARE(GetEndpoints);
+		Service_GetEndpoints(channel,&p, &r);
+		RESPONSE_CLEANUP(GetEndpoints);
+		//INVOKE_SERVICE(GetEndpoints);
 		responsetype = UA_GETENDPOINTSRESPONSE_NS0;
 	}
 	else if (serviceid == UA_OPENSECURECHANNELREQUEST_NS0)
 	{
-		//I see at the moment no other way to handle this
-		UA_OpenSecureChannelRequest p;
-		UA_OpenSecureChannelResponse r;
-		UA_OpenSecureChannelRequest_decodeBinary(msg, pos, &p);
-		UA_OpenSecureChannelResponse_init(&r);
-		init_response_header(&p.requestHeader, &r.responseHeader);
-		DBG_VERBOSE(printf("Invoke Service: %s\n", #TYPE));
+		RESPONSE_PREPARE(OpenSecureChannel);
 		Service_OpenSecureChannel(channel,&p, &r);
-		DBG_VERBOSE(printf("Finished Service: %s\n", #TYPE));
-	    *pos = 0; \
-		UA_ByteString_newMembers(&response_msg, UA_OpenSecureChannelResponse_calcSize(&r));
-		UA_OpenSecureChannelResponse_encodeBinary(&r, pos, &response_msg);
-		UA_OpenSecureChannelRequest_deleteMembers(&p);
-		UA_OpenSecureChannelResponse_deleteMembers(&r);
-
-		//INVOKE_SERVICE(OpenSecureChannel);
+		RESPONSE_CLEANUP(OpenSecureChannel);
 		responsetype = UA_OPENSECURECHANNELRESPONSE_NS0;
 	}
 	else if (serviceid == UA_CLOSESECURECHANNELREQUEST_NS0)
 	{
-		INVOKE_SERVICE(CloseSecureChannel);
+		RESPONSE_PREPARE(CloseSecureChannel);
+		Service_CloseSecureChannel(&p,&r);
+		RESPONSE_CLEANUP(CloseSecureChannel);
 		responsetype = UA_CLOSESECURECHANNELRESPONSE_NS0;
 	}
 	else if (serviceid == UA_CREATESESSIONREQUEST_NS0)
 	{
-		//TODO prepare userdefined implementation
-		INVOKE_SERVICE(CreateSession);
+		RESPONSE_PREPARE(CreateSession);
+		Service_CreateSession(&session,&p, &r);
+		RESPONSE_CLEANUP(CreateSession);
 		responsetype = UA_CREATESESSIONRESPONSE_NS0;
 	}
 	else if (serviceid == UA_ACTIVATESESSIONREQUEST_NS0)
 	{
-		//TODO prepare userdefined implementation
-		INVOKE_SERVICE(ActivateSession);
+		RESPONSE_PREPARE(ActivateSession);
+		Service_ActivateSession(channel,&session,&p, &r);
+		RESPONSE_CLEANUP(ActivateSession);
+
 		responsetype = UA_ACTIVATESESSIONRESPONSE_NS0;
 	}
 	else if (serviceid == UA_CLOSESESSIONREQUEST_NS0)
 	{
-		//TODO prepare userdefined implementation
-		INVOKE_SERVICE(CloseSession);
+		RESPONSE_PREPARE(CloseSession);
+		Service_CloseSession(&session,&p, &r);
+		RESPONSE_CLEANUP(CloseSession);
+
 		responsetype = UA_CLOSESESSIONRESPONSE_NS0;
 	}
 	else if (serviceid == UA_READREQUEST_NS0)
 	{
+
+		RESPONSE_PREPARE(Read);
+		DBG_VERBOSE(printf("Finished Service: %s\n", Read));
+		if (UA_Session_verifyChannel(session,channel)){
+			Service_Read(&session,&p, &r);
+		}
+		else
+		{
+			DBG_VERBOSE(printf("Finished Service: %s\n", Read));
+			//TODO return error, session does not belong to channel or vice versa
+		}
+		DBG_VERBOSE(printf("Finished Service: %s\n", Read));
+		RESPONSE_CLEANUP(Read);
 		//TODO prepare userdefined implementation
-		INVOKE_SERVICE(Read);
+	//	INVOKE_SERVICE(Read);
 		responsetype = UA_READRESPONSE_NS0;
 	}
 	else