ua_server_binary.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391
  1. #include "ua_server_internal.h"
  2. #include "ua_services.h"
  3. #include "ua_statuscodes.h"
  4. #include "ua_namespace_0.h"
  5. #include "ua_securechannel_manager.h"
  6. #include "ua_session_manager.h"
  7. #include "ua_util.h"
  8. static UA_StatusCode UA_ByteStringArray_deleteMembers(UA_ByteStringArray *stringarray) {
  9. if(!stringarray)
  10. return UA_STATUSCODE_BADINTERNALERROR;
  11. for(UA_UInt32 i = 0;i < stringarray->stringsSize;i++)
  12. UA_String_deleteMembers(&stringarray->strings[i]);
  13. return UA_STATUSCODE_GOOD;
  14. }
  15. static void processHello(UA_Connection *connection, const UA_ByteString *msg,
  16. UA_UInt32 *pos) {
  17. UA_TcpHelloMessage helloMessage;
  18. if(UA_TcpHelloMessage_decodeBinary(msg, pos, &helloMessage) != UA_STATUSCODE_GOOD) {
  19. connection->close(connection->callbackHandle);
  20. return;
  21. }
  22. connection->remoteConf.maxChunkCount = helloMessage.maxChunkCount;
  23. connection->remoteConf.maxMessageSize = helloMessage.maxMessageSize;
  24. connection->remoteConf.protocolVersion = helloMessage.protocolVersion;
  25. connection->remoteConf.recvBufferSize = helloMessage.receiveBufferSize;
  26. connection->remoteConf.sendBufferSize = helloMessage.sendBufferSize;
  27. connection->state = UA_CONNECTION_ESTABLISHED;
  28. // build acknowledge response
  29. UA_TcpAcknowledgeMessage ackMessage;
  30. ackMessage.protocolVersion = connection->localConf.protocolVersion;
  31. ackMessage.receiveBufferSize = connection->localConf.recvBufferSize;
  32. ackMessage.sendBufferSize = connection->localConf.sendBufferSize;
  33. ackMessage.maxMessageSize = connection->localConf.maxMessageSize;
  34. ackMessage.maxChunkCount = connection->localConf.maxChunkCount;
  35. UA_TcpMessageHeader ackHeader;
  36. ackHeader.messageType = UA_MESSAGETYPE_ACK;
  37. ackHeader.isFinal = 'F';
  38. ackHeader.messageSize = UA_TcpAcknowledgeMessage_calcSizeBinary(&ackMessage) +
  39. UA_TcpMessageHeader_calcSizeBinary(&ackHeader);
  40. UA_ByteString ack_msg;
  41. UA_UInt32 tmpPos = 0;
  42. UA_ByteString_newMembers(&ack_msg, ackHeader.messageSize);
  43. UA_TcpMessageHeader_encodeBinary(&ackHeader, &ack_msg, &tmpPos);
  44. UA_TcpAcknowledgeMessage_encodeBinary(&ackMessage, &ack_msg, &tmpPos);
  45. UA_ByteStringArray answer_buf = { .stringsSize = 1, .strings = &ack_msg };
  46. connection->write(connection->callbackHandle, answer_buf); // the string is freed internall in the (asynchronous) write
  47. UA_TcpHelloMessage_deleteMembers(&helloMessage);
  48. }
  49. static void processOpen(UA_Connection *connection, UA_Server *server, const UA_ByteString *msg, UA_UInt32 *pos) {
  50. if(connection->state != UA_CONNECTION_ESTABLISHED) {
  51. // was hello exchanged before?
  52. if(connection->state == UA_CONNECTION_OPENING)
  53. connection->close(connection->callbackHandle);
  54. return;
  55. }
  56. UA_UInt32 secureChannelId;
  57. UA_UInt32_decodeBinary(msg, pos, &secureChannelId);
  58. UA_AsymmetricAlgorithmSecurityHeader asymHeader;
  59. UA_AsymmetricAlgorithmSecurityHeader_decodeBinary(msg, pos, &asymHeader);
  60. UA_SequenceHeader seqHeader;
  61. UA_SequenceHeader_decodeBinary(msg, pos, &seqHeader);
  62. UA_ExpandedNodeId requestType;
  63. UA_ExpandedNodeId_decodeBinary(msg, pos, &requestType);
  64. if(requestType.nodeId.identifier.numeric != 446) {
  65. // todo: handle error
  66. }
  67. UA_OpenSecureChannelRequest r;
  68. UA_OpenSecureChannelRequest_decodeBinary(msg, pos, &r);
  69. // perform request
  70. UA_OpenSecureChannelResponse p;
  71. UA_OpenSecureChannelResponse_init(&p);
  72. Service_OpenSecureChannel(server, connection, &r, &p);
  73. // response
  74. UA_TcpMessageHeader respHeader;
  75. respHeader.messageType = UA_MESSAGETYPE_OPN;
  76. respHeader.isFinal = 'F';
  77. respHeader.messageSize = 8+4; //header + securechannelid
  78. UA_ExpandedNodeId responseType;
  79. NS0EXPANDEDNODEID(responseType, 449);
  80. respHeader.messageSize += UA_AsymmetricAlgorithmSecurityHeader_calcSizeBinary(&asymHeader);
  81. respHeader.messageSize += UA_SequenceHeader_calcSizeBinary(&seqHeader);
  82. respHeader.messageSize += UA_ExpandedNodeId_calcSizeBinary(&responseType);
  83. respHeader.messageSize += UA_OpenSecureChannelResponse_calcSizeBinary(&p);
  84. UA_ByteString resp_msg;
  85. UA_UInt32 tmpPos = 0;
  86. UA_ByteString_newMembers(&resp_msg, respHeader.messageSize);
  87. UA_TcpMessageHeader_encodeBinary(&respHeader, &resp_msg, &tmpPos);
  88. UA_UInt32_encodeBinary(&p.securityToken.channelId, &resp_msg, &tmpPos);
  89. UA_AsymmetricAlgorithmSecurityHeader_encodeBinary(&asymHeader, &resp_msg, &tmpPos); // just mirror back
  90. UA_SequenceHeader_encodeBinary(&seqHeader, &resp_msg, &tmpPos); // just mirror back
  91. UA_ExpandedNodeId_encodeBinary(&responseType, &resp_msg, &tmpPos);
  92. UA_OpenSecureChannelResponse_encodeBinary(&p, &resp_msg, &tmpPos);
  93. UA_OpenSecureChannelRequest_deleteMembers(&r);
  94. UA_OpenSecureChannelResponse_deleteMembers(&p);
  95. UA_AsymmetricAlgorithmSecurityHeader_deleteMembers(&asymHeader);
  96. UA_ByteStringArray answer_buf = { .stringsSize = 1, .strings = &resp_msg };
  97. connection->write(connection->callbackHandle, answer_buf);
  98. }
  99. static void init_response_header(const UA_RequestHeader *p, UA_ResponseHeader *r) {
  100. r->requestHandle = p->requestHandle;
  101. r->serviceResult = UA_STATUSCODE_GOOD;
  102. r->stringTableSize = 0;
  103. r->timestamp = UA_DateTime_now();
  104. }
  105. #define CHECK_PROCESS(CODE, CLEANUP) \
  106. do { if(CODE != UA_STATUSCODE_GOOD) { \
  107. CLEANUP; \
  108. return; \
  109. } } while(0)
  110. #define INVOKE_SERVICE(TYPE) do { \
  111. UA_##TYPE##Request p; \
  112. UA_##TYPE##Response r; \
  113. CHECK_PROCESS(UA_##TYPE##Request_decodeBinary(msg, pos, &p),; ); \
  114. UA_##TYPE##Response_init(&r); \
  115. init_response_header(&p.requestHeader, &r.responseHeader); \
  116. DBG_VERBOSE(printf("Invoke Service: %s\n", # TYPE)); \
  117. Service_##TYPE(server, channel->session, &p, &r); \
  118. DBG_VERBOSE(printf("Finished Service: %s\n", # TYPE)); \
  119. UA_ByteString_newMembers(message, UA_##TYPE##Response_calcSizeBinary(&r)); \
  120. UA_##TYPE##Response_encodeBinary(&r, message, &sendOffset); \
  121. UA_##TYPE##Request_deleteMembers(&p); \
  122. UA_##TYPE##Response_deleteMembers(&r); \
  123. responseType = requestType.nodeId.identifier.numeric + 3; \
  124. } while(0)
  125. static void processMessage(UA_Connection *connection, UA_Server *server, const UA_ByteString *msg, UA_UInt32 *pos) {
  126. // 1) Read in the securechannel
  127. UA_UInt32 secureChannelId;
  128. UA_UInt32_decodeBinary(msg, pos, &secureChannelId);
  129. UA_SecureChannel *channel;
  130. UA_SecureChannelManager_get(&server->secureChannelManager, secureChannelId, &channel);
  131. // 2) Read the security header
  132. UA_UInt32 tokenId;
  133. UA_UInt32_decodeBinary(msg, pos, &tokenId);
  134. UA_SequenceHeader sequenceHeader;
  135. CHECK_PROCESS(UA_SequenceHeader_decodeBinary(msg, pos, &sequenceHeader),; );
  136. channel->sequenceNumber = sequenceHeader.sequenceNumber;
  137. channel->requestId = sequenceHeader.requestId;
  138. // todo
  139. //UA_SecureChannel_checkSequenceNumber(channel,sequenceHeader.sequenceNumber);
  140. //UA_SecureChannel_checkRequestId(channel,sequenceHeader.requestId);
  141. // 3) Read the nodeid of the request
  142. UA_ExpandedNodeId requestType;
  143. CHECK_PROCESS(UA_ExpandedNodeId_decodeBinary(msg, pos, &requestType),; );
  144. if(requestType.nodeId.identifierType != UA_NODEIDTYPE_NUMERIC) {
  145. UA_ExpandedNodeId_deleteMembers(&requestType); // if the nodeidtype is numeric, we do not have to free anything
  146. return;
  147. }
  148. // 4) process the request
  149. UA_ByteString responseBufs[2]; // 0->header, 1->response payload
  150. UA_UInt32 responseType;
  151. UA_ByteString *header = &responseBufs[0];
  152. UA_ByteString *message = &responseBufs[1];
  153. UA_UInt32 sendOffset = 0;
  154. //subtract UA_ENCODINGOFFSET_BINARY for binary encoding
  155. switch(requestType.nodeId.identifier.numeric - UA_ENCODINGOFFSET_BINARY) {
  156. case UA_GETENDPOINTSREQUEST_NS0: {
  157. UA_GetEndpointsRequest p;
  158. UA_GetEndpointsResponse r;
  159. CHECK_PROCESS(UA_GetEndpointsRequest_decodeBinary(msg, pos, &p),; );
  160. UA_GetEndpointsResponse_init(&r);
  161. init_response_header(&p.requestHeader, &r.responseHeader);
  162. Service_GetEndpoints(server, &p, &r);
  163. UA_ByteString_newMembers(message, UA_GetEndpointsResponse_calcSizeBinary(&r));
  164. UA_GetEndpointsResponse_encodeBinary(&r, message, &sendOffset);
  165. UA_GetEndpointsRequest_deleteMembers(&p);
  166. UA_GetEndpointsResponse_deleteMembers(&r);
  167. responseType = requestType.nodeId.identifier.numeric + 3;
  168. break;
  169. }
  170. case UA_CREATESESSIONREQUEST_NS0: {
  171. UA_CreateSessionRequest p;
  172. UA_CreateSessionResponse r;
  173. CHECK_PROCESS(UA_CreateSessionRequest_decodeBinary(msg, pos, &p),; );
  174. UA_CreateSessionResponse_init(&r);
  175. init_response_header(&p.requestHeader, &r.responseHeader);
  176. Service_CreateSession(server, channel, &p, &r);
  177. UA_ByteString_newMembers(message, UA_CreateSessionResponse_calcSizeBinary(&r));
  178. UA_CreateSessionResponse_encodeBinary(&r, message, &sendOffset);
  179. UA_CreateSessionRequest_deleteMembers(&p);
  180. UA_CreateSessionResponse_deleteMembers(&r);
  181. responseType = requestType.nodeId.identifier.numeric + 3;
  182. break;
  183. }
  184. case UA_ACTIVATESESSIONREQUEST_NS0: {
  185. UA_ActivateSessionRequest p;
  186. UA_ActivateSessionResponse r;
  187. CHECK_PROCESS(UA_ActivateSessionRequest_decodeBinary(msg, pos, &p),; );
  188. UA_ActivateSessionResponse_init(&r);
  189. init_response_header(&p.requestHeader, &r.responseHeader);
  190. Service_ActivateSession(server, channel, &p, &r);
  191. UA_ByteString_newMembers(message, UA_ActivateSessionResponse_calcSizeBinary(&r));
  192. UA_ActivateSessionResponse_encodeBinary(&r, message, &sendOffset);
  193. UA_ActivateSessionRequest_deleteMembers(&p);
  194. UA_ActivateSessionResponse_deleteMembers(&r);
  195. responseType = requestType.nodeId.identifier.numeric + 3;
  196. break;
  197. }
  198. case UA_CLOSESESSIONREQUEST_NS0: {
  199. UA_CloseSessionRequest p;
  200. UA_CloseSessionResponse r;
  201. CHECK_PROCESS(UA_CloseSessionRequest_decodeBinary(msg, pos, &p),; );
  202. UA_CloseSessionResponse_init(&r);
  203. init_response_header(&p.requestHeader, &r.responseHeader);
  204. Service_CloseSession(server, &p, &r);
  205. UA_ByteString_newMembers(message, UA_CloseSessionResponse_calcSizeBinary(&r));
  206. UA_CloseSessionResponse_encodeBinary(&r, message, &sendOffset);
  207. UA_CloseSessionRequest_deleteMembers(&p);
  208. UA_CloseSessionResponse_deleteMembers(&r);
  209. responseType = requestType.nodeId.identifier.numeric + 3;
  210. break;
  211. }
  212. case UA_READREQUEST_NS0:
  213. INVOKE_SERVICE(Read);
  214. break;
  215. case UA_WRITEREQUEST_NS0:
  216. INVOKE_SERVICE(Write);
  217. break;
  218. case UA_BROWSEREQUEST_NS0:
  219. INVOKE_SERVICE(Browse);
  220. break;
  221. /* case UA_CREATESUBSCRIPTIONREQUEST_NS0: */
  222. /* INVOKE_SERVICE(CreateSubscription); */
  223. /* break; */
  224. case UA_TRANSLATEBROWSEPATHSTONODEIDSREQUEST_NS0:
  225. INVOKE_SERVICE(TranslateBrowsePathsToNodeIds);
  226. break;
  227. /* case UA_PUBLISHREQUEST_NS0: */
  228. /* INVOKE_SERVICE(Publish); */
  229. /* break; */
  230. /* case UA_CREATEMONITOREDITEMSREQUEST_NS0: */
  231. /* INVOKE_SERVICE(CreateMonitoredItems); */
  232. /* break; */
  233. /* case UA_SETPUBLISHINGMODEREQUEST_NS0: */
  234. /* INVOKE_SERVICE(SetPublishingMode); */
  235. /* break; */
  236. default: {
  237. printf("SL_processMessage - unknown request, namespace=%d, request=%d\n",
  238. requestType.nodeId.namespaceIndex, requestType.nodeId.identifier.numeric);
  239. UA_RequestHeader p;
  240. UA_ResponseHeader r;
  241. CHECK_PROCESS(UA_RequestHeader_decodeBinary(msg, pos, &p),; );
  242. UA_ResponseHeader_init(&r);
  243. r.requestHandle = p.requestHandle;
  244. r.serviceResult = UA_STATUSCODE_BADSERVICEUNSUPPORTED;
  245. UA_ByteString_newMembers(message, UA_ResponseHeader_calcSizeBinary(&r));
  246. UA_ResponseHeader_encodeBinary(&r, message, &sendOffset);
  247. UA_RequestHeader_deleteMembers(&p);
  248. UA_ResponseHeader_deleteMembers(&r);
  249. responseType = UA_RESPONSEHEADER_NS0 + 2;
  250. }
  251. break;
  252. }
  253. // 5) Build the header
  254. UA_NodeId response_nodeid = { .namespaceIndex = 0, .identifierType = UA_NODEIDTYPE_NUMERIC,
  255. .identifier.numeric = responseType }; // add 2 for binary encoding
  256. UA_ByteString_newMembers(header,
  257. 8 + 16 + // message header + 4*32bit secure channel information
  258. UA_NodeId_calcSizeBinary(&response_nodeid));
  259. // header
  260. UA_TcpMessageHeader respHeader;
  261. respHeader.messageType = UA_MESSAGETYPE_MSG;
  262. respHeader.isFinal = 'F';
  263. respHeader.messageSize = header->length + message->length;
  264. UA_UInt32 rpos = 0;
  265. UA_TcpMessageHeader_encodeBinary(&respHeader, header, &rpos);
  266. UA_UInt32_encodeBinary(&channel->securityToken.channelId, header, &rpos); // channel id
  267. UA_UInt32_encodeBinary(&channel->securityToken.tokenId, header, &rpos); // algorithm security header
  268. UA_UInt32_encodeBinary(&channel->sequenceNumber, header, &rpos); // encode sequence header
  269. UA_UInt32_encodeBinary(&channel->requestId, header, &rpos);
  270. UA_NodeId_encodeBinary(&response_nodeid, header, &rpos); // add payload type
  271. // sign data
  272. // encrypt data
  273. // 6) Send it over the wire.
  274. UA_ByteStringArray responseBufArray;
  275. responseBufArray.strings = responseBufs; // the content is deleted in the write function (asynchronous)
  276. responseBufArray.stringsSize = 2;
  277. connection->write(connection->callbackHandle, responseBufArray);
  278. }
  279. static void processClose(UA_Connection *connection, UA_Server *server, const UA_ByteString *msg, UA_UInt32 *pos) {
  280. // just read in the sequenceheader
  281. UA_UInt32 secureChannelId;
  282. UA_UInt32_decodeBinary(msg, pos, &secureChannelId);
  283. //the two last parameter is ignored since no answer is needed
  284. Service_CloseSecureChannel(server, secureChannelId);
  285. }
  286. void UA_Server_processBinaryMessage(UA_Server *server, UA_Connection *connection, const UA_ByteString *msg) {
  287. UA_Int32 retval = UA_STATUSCODE_GOOD;
  288. UA_UInt32 pos = 0;
  289. UA_TcpMessageHeader tcpMessageHeader;
  290. // todo: test how far pos advanced must be equal to what is said in the messageheader
  291. do {
  292. retval = UA_TcpMessageHeader_decodeBinary(msg, &pos, &tcpMessageHeader);
  293. UA_UInt32 targetpos = pos - 8 + tcpMessageHeader.messageSize;
  294. if(retval == UA_STATUSCODE_GOOD) {
  295. // none of the process-functions returns an error its all contained inside.
  296. switch(tcpMessageHeader.messageType) {
  297. case UA_MESSAGETYPE_HEL:
  298. processHello(connection, msg, &pos);
  299. break;
  300. case UA_MESSAGETYPE_OPN:
  301. processOpen(connection, server, msg, &pos);
  302. break;
  303. case UA_MESSAGETYPE_MSG:
  304. //no break
  305. // if this fails, the connection is closed (no break on the case)
  306. if(connection->state == UA_CONNECTION_ESTABLISHED &&
  307. connection->channel != NULL) {
  308. processMessage(connection, server, msg, &pos);
  309. break;
  310. }
  311. case UA_MESSAGETYPE_CLO:
  312. connection->state = UA_CONNECTION_CLOSING;
  313. processClose(connection, server, msg, &pos);
  314. connection->close(connection->callbackHandle);
  315. return;
  316. }
  317. UA_TcpMessageHeader_deleteMembers(&tcpMessageHeader);
  318. } else {
  319. printf("TL_Process - ERROR: decoding of header failed \n");
  320. connection->state = UA_CONNECTION_CLOSING;
  321. //processClose(connection, server, msg, &pos);
  322. connection->close(connection->callbackHandle);
  323. }
  324. // todo: more than one message at once..
  325. if(pos != targetpos) {
  326. printf("The message size was not as announced or an error occurred while processing, skipping to the end of the message.\n");
  327. pos = targetpos;
  328. }
  329. } while(msg->length > (UA_Int32)pos);
  330. }