ua_client_connect.c 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765
  1. /* This Source Code Form is subject to the terms of the Mozilla Public
  2. * License, v. 2.0. If a copy of the MPL was not distributed with this
  3. * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  4. *
  5. * Copyright 2017 (c) Mark Giraud, Fraunhofer IOSB
  6. * Copyright 2017-2018 (c) Thomas Stalder, Blue Time Concept SA
  7. * Copyright 2017 (c) Fraunhofer IOSB (Author: Julius Pfrommer)
  8. * Copyright 2017 (c) Stefan Profanter, fortiss GmbH
  9. * Copyright 2018 (c) Kalycito Infotech Private Limited
  10. */
  11. #include "ua_client_internal.h"
  12. #include "ua_transport_generated.h"
  13. #include "ua_transport_generated_handling.h"
  14. #include "ua_transport_generated_encoding_binary.h"
  15. #include "ua_types_encoding_binary.h"
  16. #include "ua_types_generated_encoding_binary.h"
  17. /* Size are refered in bytes */
  18. #define UA_MINMESSAGESIZE 8192
  19. #define UA_SESSION_LOCALNONCELENGTH 32
  20. #define MAX_DATA_SIZE 4096
  21. /********************/
  22. /* Set client state */
  23. /********************/
  24. void
  25. setClientState(UA_Client *client, UA_ClientState state) {
  26. if(client->state != state) {
  27. client->state = state;
  28. if(client->config.stateCallback)
  29. client->config.stateCallback(client, client->state);
  30. }
  31. }
  32. /***********************/
  33. /* Open the Connection */
  34. /***********************/
  35. #define UA_BITMASK_MESSAGETYPE 0x00ffffff
  36. #define UA_BITMASK_CHUNKTYPE 0xff000000
  37. static UA_StatusCode
  38. processACKResponse(void *application, UA_Connection *connection, UA_ByteString *chunk) {
  39. UA_Client *client = (UA_Client*)application;
  40. /* Decode the message */
  41. size_t offset = 0;
  42. UA_StatusCode retval;
  43. UA_TcpMessageHeader messageHeader;
  44. UA_TcpAcknowledgeMessage ackMessage;
  45. retval = UA_TcpMessageHeader_decodeBinary(chunk, &offset, &messageHeader);
  46. if(retval != UA_STATUSCODE_GOOD) {
  47. UA_LOG_INFO(&client->config.logger, UA_LOGCATEGORY_NETWORK,
  48. "Decoding ACK message failed");
  49. return retval;
  50. }
  51. // check if we got an error response from the server
  52. UA_MessageType messageType = (UA_MessageType)
  53. (messageHeader.messageTypeAndChunkType & UA_BITMASK_MESSAGETYPE);
  54. UA_ChunkType chunkType = (UA_ChunkType)
  55. (messageHeader.messageTypeAndChunkType & UA_BITMASK_CHUNKTYPE);
  56. if (messageType == UA_MESSAGETYPE_ERR) {
  57. // Header + ErrorMessage (error + reasonLength_field + length)
  58. UA_StatusCode error = *(UA_StatusCode*)(&chunk->data[offset]);
  59. UA_UInt32 len = *((UA_UInt32*)&chunk->data[offset + 4]);
  60. UA_Byte *data = (UA_Byte*)&chunk->data[offset + 4+4];
  61. UA_LOG_ERROR(&client->config.logger, UA_LOGCATEGORY_NETWORK,
  62. "Received ERR response. %s - %.*s", UA_StatusCode_name(error), len, data);
  63. return error;
  64. }
  65. if (chunkType != UA_CHUNKTYPE_FINAL) {
  66. return UA_STATUSCODE_BADTCPMESSAGETYPEINVALID;
  67. }
  68. /* Decode the ACK message */
  69. retval = UA_TcpAcknowledgeMessage_decodeBinary(chunk, &offset, &ackMessage);
  70. if(retval != UA_STATUSCODE_GOOD) {
  71. UA_LOG_INFO(&client->config.logger, UA_LOGCATEGORY_NETWORK,
  72. "Decoding ACK message failed");
  73. return retval;
  74. }
  75. UA_LOG_DEBUG(&client->config.logger, UA_LOGCATEGORY_NETWORK, "Received ACK message");
  76. /* Process the ACK message */
  77. return UA_Connection_processHELACK(connection, &client->config.localConnectionConfig,
  78. (const UA_ConnectionConfig*)&ackMessage);
  79. }
  80. static UA_StatusCode
  81. HelAckHandshake(UA_Client *client) {
  82. /* Get a buffer */
  83. UA_ByteString message;
  84. UA_Connection *conn = &client->connection;
  85. UA_StatusCode retval = conn->getSendBuffer(conn, UA_MINMESSAGESIZE, &message);
  86. if(retval != UA_STATUSCODE_GOOD)
  87. return retval;
  88. /* Prepare the HEL message and encode at offset 8 */
  89. UA_TcpHelloMessage hello;
  90. UA_String_copy(&client->endpointUrl, &hello.endpointUrl); /* must be less than 4096 bytes */
  91. memcpy(&hello, &client->config.localConnectionConfig, sizeof(UA_ConnectionConfig)); /* same struct layout */
  92. UA_Byte *bufPos = &message.data[8]; /* skip the header */
  93. const UA_Byte *bufEnd = &message.data[message.length];
  94. retval = UA_TcpHelloMessage_encodeBinary(&hello, &bufPos, bufEnd);
  95. UA_TcpHelloMessage_deleteMembers(&hello);
  96. if(retval != UA_STATUSCODE_GOOD) {
  97. conn->releaseSendBuffer(conn, &message);
  98. return retval;
  99. }
  100. /* Encode the message header at offset 0 */
  101. UA_TcpMessageHeader messageHeader;
  102. messageHeader.messageTypeAndChunkType = UA_CHUNKTYPE_FINAL + UA_MESSAGETYPE_HEL;
  103. messageHeader.messageSize = (UA_UInt32)((uintptr_t)bufPos - (uintptr_t)message.data);
  104. bufPos = message.data;
  105. retval = UA_TcpMessageHeader_encodeBinary(&messageHeader, &bufPos, bufEnd);
  106. if(retval != UA_STATUSCODE_GOOD) {
  107. conn->releaseSendBuffer(conn, &message);
  108. return retval;
  109. }
  110. /* Send the HEL message */
  111. message.length = messageHeader.messageSize;
  112. retval = conn->send(conn, &message);
  113. if(retval != UA_STATUSCODE_GOOD) {
  114. UA_LOG_INFO(&client->config.logger, UA_LOGCATEGORY_NETWORK,
  115. "Sending HEL failed");
  116. return retval;
  117. }
  118. UA_LOG_DEBUG(&client->config.logger, UA_LOGCATEGORY_NETWORK,
  119. "Sent HEL message");
  120. /* Loop until we have a complete chunk */
  121. retval = UA_Connection_receiveChunksBlocking(conn, client, processACKResponse,
  122. client->config.timeout);
  123. if(retval != UA_STATUSCODE_GOOD) {
  124. UA_LOG_INFO(&client->config.logger, UA_LOGCATEGORY_NETWORK,
  125. "Receiving ACK message failed with %s", UA_StatusCode_name(retval));
  126. if(retval == UA_STATUSCODE_BADCONNECTIONCLOSED)
  127. client->state = UA_CLIENTSTATE_DISCONNECTED;
  128. UA_Client_disconnect(client);
  129. }
  130. return retval;
  131. }
  132. static void
  133. processDecodedOPNResponse(UA_Client *client, UA_OpenSecureChannelResponse *response, UA_Boolean renew) {
  134. /* Replace the token */
  135. if (renew)
  136. client->channel.nextSecurityToken = response->securityToken; // Set the next token
  137. else
  138. client->channel.securityToken = response->securityToken; // Set initial token
  139. /* Replace the nonce */
  140. UA_ByteString_deleteMembers(&client->channel.remoteNonce);
  141. client->channel.remoteNonce = response->serverNonce;
  142. UA_ByteString_init(&response->serverNonce);
  143. if(client->channel.state == UA_SECURECHANNELSTATE_OPEN)
  144. UA_LOG_DEBUG(&client->config.logger, UA_LOGCATEGORY_SECURECHANNEL,
  145. "SecureChannel in the server renewed");
  146. else
  147. UA_LOG_DEBUG(&client->config.logger, UA_LOGCATEGORY_SECURECHANNEL,
  148. "Opened SecureChannel acknowledged by the server");
  149. /* Response.securityToken.revisedLifetime is UInt32 we need to cast it to
  150. * DateTime=Int64 we take 75% of lifetime to start renewing as described in
  151. * standard */
  152. client->channel.state = UA_SECURECHANNELSTATE_OPEN;
  153. client->nextChannelRenewal = UA_DateTime_nowMonotonic() + (UA_DateTime)
  154. (client->channel.securityToken.revisedLifetime * (UA_Double)UA_DATETIME_MSEC * 0.75);
  155. }
  156. UA_StatusCode
  157. openSecureChannel(UA_Client *client, UA_Boolean renew) {
  158. /* Check if sc is still valid */
  159. if(renew && client->nextChannelRenewal > UA_DateTime_nowMonotonic())
  160. return UA_STATUSCODE_GOOD;
  161. UA_Connection *conn = &client->connection;
  162. if(conn->state != UA_CONNECTION_ESTABLISHED)
  163. return UA_STATUSCODE_BADSERVERNOTCONNECTED;
  164. /* Prepare the OpenSecureChannelRequest */
  165. UA_OpenSecureChannelRequest opnSecRq;
  166. UA_OpenSecureChannelRequest_init(&opnSecRq);
  167. opnSecRq.requestHeader.timestamp = UA_DateTime_now();
  168. opnSecRq.requestHeader.authenticationToken = client->authenticationToken;
  169. if(renew) {
  170. opnSecRq.requestType = UA_SECURITYTOKENREQUESTTYPE_RENEW;
  171. UA_LOG_DEBUG(&client->config.logger, UA_LOGCATEGORY_SECURECHANNEL,
  172. "Requesting to renew the SecureChannel");
  173. } else {
  174. opnSecRq.requestType = UA_SECURITYTOKENREQUESTTYPE_ISSUE;
  175. UA_LOG_DEBUG(&client->config.logger, UA_LOGCATEGORY_SECURECHANNEL,
  176. "Requesting to open a SecureChannel");
  177. }
  178. /* Set the securityMode to input securityMode from client data */
  179. opnSecRq.securityMode = client->channel.securityMode;
  180. opnSecRq.clientNonce = client->channel.localNonce;
  181. opnSecRq.requestedLifetime = client->config.secureChannelLifeTime;
  182. /* Send the OPN message */
  183. UA_UInt32 requestId = ++client->requestId;
  184. UA_StatusCode retval =
  185. UA_SecureChannel_sendAsymmetricOPNMessage(&client->channel, requestId, &opnSecRq,
  186. &UA_TYPES[UA_TYPES_OPENSECURECHANNELREQUEST]);
  187. if(retval != UA_STATUSCODE_GOOD) {
  188. UA_LOG_ERROR(&client->config.logger, UA_LOGCATEGORY_SECURECHANNEL,
  189. "Sending OPN message failed with error %s", UA_StatusCode_name(retval));
  190. UA_Client_disconnect(client);
  191. return retval;
  192. }
  193. UA_LOG_DEBUG(&client->config.logger, UA_LOGCATEGORY_SECURECHANNEL, "OPN message sent");
  194. /* Increase nextChannelRenewal to avoid that we re-start renewal when
  195. * publish responses are received before the OPN response arrives. */
  196. client->nextChannelRenewal = UA_DateTime_nowMonotonic() +
  197. (2 * ((UA_DateTime)client->config.timeout * UA_DATETIME_MSEC));
  198. /* Receive / decrypt / decode the OPN response. Process async services in
  199. * the background until the OPN response arrives. */
  200. UA_OpenSecureChannelResponse response;
  201. retval = receiveServiceResponse(client, &response,
  202. &UA_TYPES[UA_TYPES_OPENSECURECHANNELRESPONSE],
  203. UA_DateTime_nowMonotonic() +
  204. ((UA_DateTime)client->config.timeout * UA_DATETIME_MSEC),
  205. &requestId);
  206. if(retval != UA_STATUSCODE_GOOD) {
  207. UA_Client_disconnect(client);
  208. return retval;
  209. }
  210. processDecodedOPNResponse(client, &response, renew);
  211. UA_OpenSecureChannelResponse_deleteMembers(&response);
  212. return retval;
  213. }
  214. /* Function to verify the signature corresponds to ClientNonce
  215. * using the local certificate.
  216. *
  217. * @param channel current channel in which the client runs
  218. * @param response create session response from the server
  219. * @return Returns an error code or UA_STATUSCODE_GOOD. */
  220. UA_StatusCode
  221. checkClientSignature(const UA_SecureChannel *channel, const UA_CreateSessionResponse *response) {
  222. if(channel == NULL || response == NULL)
  223. return UA_STATUSCODE_BADINTERNALERROR;
  224. if(channel->securityMode != UA_MESSAGESECURITYMODE_SIGN &&
  225. channel->securityMode != UA_MESSAGESECURITYMODE_SIGNANDENCRYPT)
  226. return UA_STATUSCODE_GOOD;
  227. if(!channel->securityPolicy)
  228. return UA_STATUSCODE_BADINTERNALERROR;
  229. const UA_SecurityPolicy* securityPolicy = channel->securityPolicy;
  230. const UA_ByteString* localCertificate = &securityPolicy->localCertificate;
  231. size_t dataToVerifySize = localCertificate->length + channel->localNonce.length;
  232. UA_ByteString dataToVerify = UA_BYTESTRING_NULL;
  233. UA_StatusCode retval = UA_ByteString_allocBuffer(&dataToVerify, dataToVerifySize);
  234. if(retval != UA_STATUSCODE_GOOD)
  235. return retval;
  236. memcpy(dataToVerify.data, localCertificate->data, localCertificate->length);
  237. memcpy(dataToVerify.data + localCertificate->length,
  238. channel->localNonce.data, channel->localNonce.length);
  239. retval = securityPolicy->
  240. certificateSigningAlgorithm.verify(securityPolicy,
  241. channel->channelContext,
  242. &dataToVerify,
  243. &response->serverSignature.signature);
  244. UA_ByteString_deleteMembers(&dataToVerify);
  245. return retval;
  246. }
  247. /* Function to create a signature using remote certificate and nonce
  248. *
  249. * @param channel current channel in which the client runs
  250. * @param request activate session request message to server
  251. * @return Returns an error or UA_STATUSCODE_GOOD */
  252. UA_StatusCode
  253. signActivateSessionRequest(UA_SecureChannel *channel,
  254. UA_ActivateSessionRequest *request) {
  255. if(channel == NULL || request == NULL)
  256. return UA_STATUSCODE_BADINTERNALERROR;
  257. if(channel->securityMode != UA_MESSAGESECURITYMODE_SIGN &&
  258. channel->securityMode != UA_MESSAGESECURITYMODE_SIGNANDENCRYPT)
  259. return UA_STATUSCODE_GOOD;
  260. const UA_SecurityPolicy *const securityPolicy = channel->securityPolicy;
  261. UA_SignatureData *signatureData = &request->clientSignature;
  262. /* Prepare the signature */
  263. size_t signatureSize = securityPolicy->certificateSigningAlgorithm.
  264. getLocalSignatureSize(securityPolicy, channel->channelContext);
  265. UA_StatusCode retval = UA_String_copy(&securityPolicy->certificateSigningAlgorithm.uri,
  266. &signatureData->algorithm);
  267. if(retval != UA_STATUSCODE_GOOD)
  268. return retval;
  269. retval = UA_ByteString_allocBuffer(&signatureData->signature, signatureSize);
  270. if(retval != UA_STATUSCODE_GOOD)
  271. return retval;
  272. /* Allocate a temporary buffer */
  273. size_t dataToSignSize = channel->remoteCertificate.length + channel->remoteNonce.length;
  274. /* Prevent stack-smashing. TODO: Compute MaxSenderCertificateSize */
  275. if(dataToSignSize > MAX_DATA_SIZE)
  276. return UA_STATUSCODE_BADINTERNALERROR;
  277. UA_ByteString dataToSign;
  278. retval = UA_ByteString_allocBuffer(&dataToSign, dataToSignSize);
  279. if(retval != UA_STATUSCODE_GOOD)
  280. return retval; /* signatureData->signature is cleaned up with the response */
  281. /* Sign the signature */
  282. memcpy(dataToSign.data, channel->remoteCertificate.data, channel->remoteCertificate.length);
  283. memcpy(dataToSign.data + channel->remoteCertificate.length,
  284. channel->remoteNonce.data, channel->remoteNonce.length);
  285. retval = securityPolicy->certificateSigningAlgorithm.
  286. sign(securityPolicy, channel->channelContext, &dataToSign,
  287. &signatureData->signature);
  288. /* Clean up */
  289. UA_ByteString_deleteMembers(&dataToSign);
  290. return retval;
  291. }
  292. static UA_StatusCode
  293. activateSession(UA_Client *client) {
  294. UA_ActivateSessionRequest request;
  295. UA_ActivateSessionRequest_init(&request);
  296. request.requestHeader.requestHandle = ++client->requestHandle;
  297. request.requestHeader.timestamp = UA_DateTime_now();
  298. request.requestHeader.timeoutHint = 600000;
  299. //manual ExtensionObject encoding of the identityToken
  300. if(client->authenticationMethod == UA_CLIENTAUTHENTICATION_NONE) {
  301. UA_AnonymousIdentityToken* identityToken = UA_AnonymousIdentityToken_new();
  302. UA_AnonymousIdentityToken_init(identityToken);
  303. UA_String_copy(&client->token.policyId, &identityToken->policyId);
  304. request.userIdentityToken.encoding = UA_EXTENSIONOBJECT_DECODED;
  305. request.userIdentityToken.content.decoded.type = &UA_TYPES[UA_TYPES_ANONYMOUSIDENTITYTOKEN];
  306. request.userIdentityToken.content.decoded.data = identityToken;
  307. } else {
  308. UA_UserNameIdentityToken* identityToken = UA_UserNameIdentityToken_new();
  309. UA_UserNameIdentityToken_init(identityToken);
  310. UA_String_copy(&client->token.policyId, &identityToken->policyId);
  311. UA_String_copy(&client->username, &identityToken->userName);
  312. UA_String_copy(&client->password, &identityToken->password);
  313. request.userIdentityToken.encoding = UA_EXTENSIONOBJECT_DECODED;
  314. request.userIdentityToken.content.decoded.type = &UA_TYPES[UA_TYPES_USERNAMEIDENTITYTOKEN];
  315. request.userIdentityToken.content.decoded.data = identityToken;
  316. }
  317. /* This function call is to prepare a client signature */
  318. if(client->channel.securityMode == UA_MESSAGESECURITYMODE_SIGN ||
  319. client->channel.securityMode == UA_MESSAGESECURITYMODE_SIGNANDENCRYPT) {
  320. signActivateSessionRequest(&client->channel, &request);
  321. }
  322. UA_ActivateSessionResponse response;
  323. __UA_Client_Service(client, &request, &UA_TYPES[UA_TYPES_ACTIVATESESSIONREQUEST],
  324. &response, &UA_TYPES[UA_TYPES_ACTIVATESESSIONRESPONSE]);
  325. if(response.responseHeader.serviceResult != UA_STATUSCODE_GOOD) {
  326. UA_LOG_ERROR(&client->config.logger, UA_LOGCATEGORY_CLIENT,
  327. "ActivateSession failed with error code %s",
  328. UA_StatusCode_name(response.responseHeader.serviceResult));
  329. }
  330. UA_StatusCode retval = response.responseHeader.serviceResult;
  331. UA_ActivateSessionRequest_deleteMembers(&request);
  332. UA_ActivateSessionResponse_deleteMembers(&response);
  333. return retval;
  334. }
  335. /* Gets a list of endpoints. Memory is allocated for endpointDescription array */
  336. UA_StatusCode
  337. UA_Client_getEndpointsInternal(UA_Client *client, size_t* endpointDescriptionsSize,
  338. UA_EndpointDescription** endpointDescriptions) {
  339. UA_GetEndpointsRequest request;
  340. UA_GetEndpointsRequest_init(&request);
  341. request.requestHeader.timestamp = UA_DateTime_now();
  342. request.requestHeader.timeoutHint = 10000;
  343. // assume the endpointurl outlives the service call
  344. request.endpointUrl = client->endpointUrl;
  345. UA_GetEndpointsResponse response;
  346. __UA_Client_Service(client, &request, &UA_TYPES[UA_TYPES_GETENDPOINTSREQUEST],
  347. &response, &UA_TYPES[UA_TYPES_GETENDPOINTSRESPONSE]);
  348. if(response.responseHeader.serviceResult != UA_STATUSCODE_GOOD) {
  349. UA_StatusCode retval = response.responseHeader.serviceResult;
  350. UA_LOG_ERROR(&client->config.logger, UA_LOGCATEGORY_CLIENT,
  351. "GetEndpointRequest failed with error code %s",
  352. UA_StatusCode_name(retval));
  353. UA_GetEndpointsResponse_deleteMembers(&response);
  354. return retval;
  355. }
  356. *endpointDescriptions = response.endpoints;
  357. *endpointDescriptionsSize = response.endpointsSize;
  358. response.endpoints = NULL;
  359. response.endpointsSize = 0;
  360. UA_GetEndpointsResponse_deleteMembers(&response);
  361. return UA_STATUSCODE_GOOD;
  362. }
  363. static UA_StatusCode
  364. getEndpoints(UA_Client *client) {
  365. UA_EndpointDescription* endpointArray = NULL;
  366. size_t endpointArraySize = 0;
  367. UA_StatusCode retval =
  368. UA_Client_getEndpointsInternal(client, &endpointArraySize, &endpointArray);
  369. if(retval != UA_STATUSCODE_GOOD)
  370. return retval;
  371. UA_Boolean endpointFound = false;
  372. UA_Boolean tokenFound = false;
  373. UA_String securityNone = UA_STRING("http://opcfoundation.org/UA/SecurityPolicy#None");
  374. UA_String binaryTransport = UA_STRING("http://opcfoundation.org/UA-Profile/"
  375. "Transport/uatcp-uasc-uabinary");
  376. // TODO: compare endpoint information with client->endpointUri
  377. for(size_t i = 0; i < endpointArraySize; ++i) {
  378. UA_EndpointDescription* endpoint = &endpointArray[i];
  379. /* look out for binary transport endpoints */
  380. /* Note: Siemens returns empty ProfileUrl, we will accept it as binary */
  381. if(endpoint->transportProfileUri.length != 0 &&
  382. !UA_String_equal(&endpoint->transportProfileUri, &binaryTransport))
  383. continue;
  384. /* look for an endpoint corresponding to the client security policy */
  385. if(!UA_String_equal(&endpoint->securityPolicyUri, &client->securityPolicy.policyUri))
  386. continue;
  387. endpointFound = true;
  388. /* look for a user token policy with an anonymous token */
  389. for(size_t j = 0; j < endpoint->userIdentityTokensSize; ++j) {
  390. UA_UserTokenPolicy* userToken = &endpoint->userIdentityTokens[j];
  391. /* Usertokens also have a security policy... */
  392. if(userToken->securityPolicyUri.length > 0 &&
  393. !UA_String_equal(&userToken->securityPolicyUri, &securityNone))
  394. continue;
  395. /* UA_CLIENTAUTHENTICATION_NONE == UA_USERTOKENTYPE_ANONYMOUS
  396. * UA_CLIENTAUTHENTICATION_USERNAME == UA_USERTOKENTYPE_USERNAME
  397. * TODO: Check equivalence for other types when adding the support */
  398. if((int)client->authenticationMethod != (int)userToken->tokenType)
  399. continue;
  400. /* Endpoint with matching usertokenpolicy found */
  401. tokenFound = true;
  402. UA_UserTokenPolicy_deleteMembers(&client->token);
  403. UA_UserTokenPolicy_copy(userToken, &client->token);
  404. break;
  405. }
  406. }
  407. UA_Array_delete(endpointArray, endpointArraySize,
  408. &UA_TYPES[UA_TYPES_ENDPOINTDESCRIPTION]);
  409. if(!endpointFound) {
  410. UA_LOG_ERROR(&client->config.logger, UA_LOGCATEGORY_CLIENT,
  411. "No suitable endpoint found");
  412. retval = UA_STATUSCODE_BADINTERNALERROR;
  413. } else if(!tokenFound) {
  414. UA_LOG_ERROR(&client->config.logger, UA_LOGCATEGORY_CLIENT,
  415. "No suitable UserTokenPolicy found for the possible endpoints");
  416. retval = UA_STATUSCODE_BADINTERNALERROR;
  417. }
  418. return retval;
  419. }
  420. static UA_StatusCode
  421. createSession(UA_Client *client) {
  422. UA_CreateSessionRequest request;
  423. UA_CreateSessionRequest_init(&request);
  424. UA_StatusCode retval = UA_STATUSCODE_GOOD;
  425. if(client->channel.securityMode == UA_MESSAGESECURITYMODE_SIGN ||
  426. client->channel.securityMode == UA_MESSAGESECURITYMODE_SIGNANDENCRYPT) {
  427. if(client->channel.localNonce.length != UA_SESSION_LOCALNONCELENGTH) {
  428. UA_ByteString_deleteMembers(&client->channel.localNonce);
  429. retval = UA_ByteString_allocBuffer(&client->channel.localNonce,
  430. UA_SESSION_LOCALNONCELENGTH);
  431. if(retval != UA_STATUSCODE_GOOD)
  432. return retval;
  433. }
  434. retval = client->channel.securityPolicy->symmetricModule.
  435. generateNonce(client->channel.securityPolicy, &client->channel.localNonce);
  436. if(retval != UA_STATUSCODE_GOOD)
  437. return retval;
  438. }
  439. request.requestHeader.timestamp = UA_DateTime_now();
  440. request.requestHeader.timeoutHint = 10000;
  441. UA_ByteString_copy(&client->channel.localNonce, &request.clientNonce);
  442. request.requestedSessionTimeout = client->config.requestedSessionTimeout;
  443. request.maxResponseMessageSize = UA_INT32_MAX;
  444. UA_String_copy(&client->endpointUrl, &request.endpointUrl);
  445. if(client->channel.securityMode == UA_MESSAGESECURITYMODE_SIGN ||
  446. client->channel.securityMode == UA_MESSAGESECURITYMODE_SIGNANDENCRYPT) {
  447. UA_ByteString_copy(&client->channel.securityPolicy->localCertificate,
  448. &request.clientCertificate);
  449. }
  450. UA_CreateSessionResponse response;
  451. __UA_Client_Service(client, &request, &UA_TYPES[UA_TYPES_CREATESESSIONREQUEST],
  452. &response, &UA_TYPES[UA_TYPES_CREATESESSIONRESPONSE]);
  453. if(response.responseHeader.serviceResult == UA_STATUSCODE_GOOD &&
  454. (client->channel.securityMode == UA_MESSAGESECURITYMODE_SIGN ||
  455. client->channel.securityMode == UA_MESSAGESECURITYMODE_SIGNANDENCRYPT)) {
  456. UA_ByteString_deleteMembers(&client->channel.remoteNonce);
  457. UA_ByteString_copy(&response.serverNonce, &client->channel.remoteNonce);
  458. if(!UA_ByteString_equal(&response.serverCertificate,
  459. &client->channel.remoteCertificate)) {
  460. return UA_STATUSCODE_BADCERTIFICATEINVALID;
  461. }
  462. /* Verify the client signature */
  463. retval = checkClientSignature(&client->channel, &response);
  464. if(retval != UA_STATUSCODE_GOOD)
  465. return retval;
  466. }
  467. UA_NodeId_copy(&response.authenticationToken, &client->authenticationToken);
  468. retval = response.responseHeader.serviceResult;
  469. UA_CreateSessionRequest_deleteMembers(&request);
  470. UA_CreateSessionResponse_deleteMembers(&response);
  471. return retval;
  472. }
  473. UA_StatusCode
  474. UA_Client_connectInternal(UA_Client *client, const char *endpointUrl,
  475. UA_Boolean endpointsHandshake, UA_Boolean createNewSession) {
  476. if(client->state >= UA_CLIENTSTATE_CONNECTED)
  477. return UA_STATUSCODE_GOOD;
  478. UA_ChannelSecurityToken_init(&client->channel.securityToken);
  479. client->channel.state = UA_SECURECHANNELSTATE_FRESH;
  480. client->channel.sendSequenceNumber = 0;
  481. client->requestId = 0;
  482. UA_StatusCode retval = UA_STATUSCODE_GOOD;
  483. client->connection =
  484. client->config.connectionFunc(client->config.localConnectionConfig,
  485. UA_STRING((char*)(uintptr_t)endpointUrl),
  486. client->config.timeout, &client->config.logger);
  487. if(client->connection.state != UA_CONNECTION_OPENING) {
  488. retval = UA_STATUSCODE_BADCONNECTIONCLOSED;
  489. goto cleanup;
  490. }
  491. UA_String_deleteMembers(&client->endpointUrl);
  492. client->endpointUrl = UA_STRING_ALLOC(endpointUrl);
  493. if(!client->endpointUrl.data) {
  494. retval = UA_STATUSCODE_BADOUTOFMEMORY;
  495. goto cleanup;
  496. }
  497. /* Set the channel SecurityMode if not done so far */
  498. if(client->channel.securityMode == UA_MESSAGESECURITYMODE_INVALID)
  499. client->channel.securityMode = UA_MESSAGESECURITYMODE_NONE;
  500. /* Set the channel SecurityPolicy if not done so far */
  501. if(!client->channel.securityPolicy) {
  502. UA_ByteString remoteCertificate = UA_BYTESTRING_NULL;
  503. retval = UA_SecureChannel_setSecurityPolicy(&client->channel,
  504. &client->securityPolicy,
  505. &remoteCertificate);
  506. if(retval != UA_STATUSCODE_GOOD)
  507. return retval;
  508. }
  509. /* Local nonce set and generate sym keys */
  510. retval = UA_SecureChannel_generateLocalNonce(&client->channel);
  511. if(retval != UA_STATUSCODE_GOOD)
  512. return retval;
  513. /* Open a TCP connection */
  514. client->connection.config = client->config.localConnectionConfig;
  515. retval = HelAckHandshake(client);
  516. if(retval != UA_STATUSCODE_GOOD)
  517. goto cleanup;
  518. setClientState(client, UA_CLIENTSTATE_CONNECTED);
  519. /* Open a SecureChannel. TODO: Select with endpoint */
  520. client->channel.connection = &client->connection;
  521. retval = openSecureChannel(client, false);
  522. if(retval != UA_STATUSCODE_GOOD)
  523. goto cleanup;
  524. setClientState(client, UA_CLIENTSTATE_SECURECHANNEL);
  525. /* Delete async service. TODO: Move this from connect to the disconnect/cleanup phase */
  526. UA_Client_AsyncService_removeAll(client, UA_STATUSCODE_BADSHUTDOWN);
  527. #ifdef UA_ENABLE_SUBSCRIPTIONS
  528. client->currentlyOutStandingPublishRequests = 0;
  529. #endif
  530. // TODO: actually, reactivate an existing session is working, but currently republish is not implemented
  531. // This option is disabled until we have a good implementation of the subscription recovery.
  532. #ifdef UA_SESSION_RECOVERY
  533. /* Try to activate an existing Session for this SecureChannel */
  534. if((!UA_NodeId_equal(&client->authenticationToken, &UA_NODEID_NULL)) && (createNewSession)) {
  535. retval = activateSession(client);
  536. if(retval == UA_STATUSCODE_BADSESSIONIDINVALID) {
  537. /* Could not recover an old session. Remove authenticationToken */
  538. UA_NodeId_deleteMembers(&client->authenticationToken);
  539. } else {
  540. if(retval != UA_STATUSCODE_GOOD)
  541. goto cleanup;
  542. setClientState(client, UA_CLIENTSTATE_SESSION_RENEWED);
  543. return retval;
  544. }
  545. } else {
  546. UA_NodeId_deleteMembers(&client->authenticationToken);
  547. }
  548. #else
  549. UA_NodeId_deleteMembers(&client->authenticationToken);
  550. #endif /* UA_SESSION_RECOVERY */
  551. /* Generate new local and remote key */
  552. retval = UA_SecureChannel_generateNewKeys(&client->channel);
  553. if(retval != UA_STATUSCODE_GOOD)
  554. return retval;
  555. /* Get Endpoints */
  556. if(endpointsHandshake) {
  557. retval = getEndpoints(client);
  558. if(retval != UA_STATUSCODE_GOOD)
  559. goto cleanup;
  560. }
  561. /* Create the Session for this SecureChannel */
  562. if(createNewSession) {
  563. retval = createSession(client);
  564. if(retval != UA_STATUSCODE_GOOD)
  565. goto cleanup;
  566. #ifdef UA_ENABLE_SUBSCRIPTIONS
  567. /* A new session has been created. We need to clean up the subscriptions */
  568. UA_Client_Subscriptions_clean(client);
  569. #endif
  570. retval = activateSession(client);
  571. if(retval != UA_STATUSCODE_GOOD)
  572. goto cleanup;
  573. setClientState(client, UA_CLIENTSTATE_SESSION);
  574. }
  575. return retval;
  576. cleanup:
  577. UA_Client_disconnect(client);
  578. return retval;
  579. }
  580. UA_StatusCode
  581. UA_Client_connect(UA_Client *client, const char *endpointUrl) {
  582. return UA_Client_connectInternal(client, endpointUrl, true, true);
  583. }
  584. UA_StatusCode
  585. UA_Client_connect_noSession(UA_Client *client, const char *endpointUrl) {
  586. return UA_Client_connectInternal(client, endpointUrl, true, false);
  587. }
  588. UA_StatusCode
  589. UA_Client_connect_username(UA_Client *client, const char *endpointUrl,
  590. const char *username, const char *password) {
  591. client->authenticationMethod = UA_CLIENTAUTHENTICATION_USERNAME;
  592. client->username = UA_STRING_ALLOC(username);
  593. client->password = UA_STRING_ALLOC(password);
  594. return UA_Client_connect(client, endpointUrl);
  595. }
  596. /************************/
  597. /* Close the Connection */
  598. /************************/
  599. static void
  600. sendCloseSession(UA_Client *client) {
  601. UA_CloseSessionRequest request;
  602. UA_CloseSessionRequest_init(&request);
  603. request.requestHeader.timestamp = UA_DateTime_now();
  604. request.requestHeader.timeoutHint = 10000;
  605. request.deleteSubscriptions = true;
  606. UA_CloseSessionResponse response;
  607. __UA_Client_Service(client, &request, &UA_TYPES[UA_TYPES_CLOSESESSIONREQUEST],
  608. &response, &UA_TYPES[UA_TYPES_CLOSESESSIONRESPONSE]);
  609. UA_CloseSessionRequest_deleteMembers(&request);
  610. UA_CloseSessionResponse_deleteMembers(&response);
  611. }
  612. static void
  613. sendCloseSecureChannel(UA_Client *client) {
  614. UA_SecureChannel *channel = &client->channel;
  615. UA_CloseSecureChannelRequest request;
  616. UA_CloseSecureChannelRequest_init(&request);
  617. request.requestHeader.requestHandle = ++client->requestHandle;
  618. request.requestHeader.timestamp = UA_DateTime_now();
  619. request.requestHeader.timeoutHint = 10000;
  620. request.requestHeader.authenticationToken = client->authenticationToken;
  621. UA_SecureChannel_sendSymmetricMessage(channel, ++client->requestId,
  622. UA_MESSAGETYPE_CLO, &request,
  623. &UA_TYPES[UA_TYPES_CLOSESECURECHANNELREQUEST]);
  624. UA_CloseSecureChannelRequest_deleteMembers(&request);
  625. UA_SecureChannel_close(&client->channel);
  626. UA_SecureChannel_deleteMembers(&client->channel);
  627. }
  628. UA_StatusCode
  629. UA_Client_disconnect(UA_Client *client) {
  630. /* Is a session established? */
  631. if(client->state >= UA_CLIENTSTATE_SESSION) {
  632. client->state = UA_CLIENTSTATE_SECURECHANNEL;
  633. sendCloseSession(client);
  634. }
  635. UA_NodeId_deleteMembers(&client->authenticationToken);
  636. client->requestHandle = 0;
  637. /* Is a secure channel established? */
  638. if(client->state >= UA_CLIENTSTATE_SECURECHANNEL) {
  639. client->state = UA_CLIENTSTATE_CONNECTED;
  640. sendCloseSecureChannel(client);
  641. }
  642. /* Close the TCP connection */
  643. if(client->connection.state != UA_CONNECTION_CLOSED
  644. && client->connection.state != UA_CONNECTION_OPENING)
  645. /*UA_ClientConnectionTCP_init sets initial state to opening */
  646. if(client->connection.close != NULL)
  647. client->connection.close(&client->connection);
  648. #ifdef UA_ENABLE_SUBSCRIPTIONS
  649. // TODO REMOVE WHEN UA_SESSION_RECOVERY IS READY
  650. /* We need to clean up the subscriptions */
  651. UA_Client_Subscriptions_clean(client);
  652. #endif
  653. setClientState(client, UA_CLIENTSTATE_DISCONNECTED);
  654. return UA_STATUSCODE_GOOD;
  655. }