ua_server_binary.c 17 KB

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