refactor(core): Move ConnectionConfig into SecureChannel

This commit is contained in:
Julius Pfrommer 2020-01-12 00:32:15 +01:00 committed by Julius Pfrommer
parent fd998e4ad9
commit a25bb75393
22 changed files with 110 additions and 139 deletions

View File

@ -1,6 +1,7 @@
SET(SOURCE_GROUP ${SOURCE_GROUP}\\arch)
ua_include_directories(${CMAKE_CURRENT_SOURCE_DIR}) #to have access to ua_network_tcp.h
ua_include_directories(${CMAKE_CURRENT_SOURCE_DIR}) # to have access to ua_network_tcp.h
ua_include_directories(${CMAKE_SOURCE_DIR}/src) # to have access to ua_securechannel.h
add_subdirectory(posix)
add_subdirectory(win32)

View File

@ -15,6 +15,7 @@
#include <open62541/util.h>
#include "open62541_queue.h"
#include "ua_securechannel.h"
#include <string.h> // memset
@ -29,7 +30,8 @@
static UA_StatusCode
connection_getsendbuffer(UA_Connection *connection,
size_t length, UA_ByteString *buf) {
if(length > connection->config.sendBufferSize)
UA_SecureChannel *channel = connection->channel;
if(channel && channel->config.sendBufferSize < length)
return UA_STATUSCODE_BADCOMMUNICATIONERROR;
return UA_ByteString_allocBuffer(buf, length);
}
@ -115,8 +117,8 @@ connection_recv(UA_Connection *connection, UA_ByteString *response,
if(internallyAllocated) {
size_t bufferSize = 16384; /* Use as default for a new SecureChannel */
UA_SecureChannel *channel = connection->channel;
if(channel && connection->config.recvBufferSize > 0)
bufferSize = connection->config.recvBufferSize;
if(channel && channel->config.recvBufferSize > 0)
bufferSize = channel->config.recvBufferSize;
UA_StatusCode res = UA_ByteString_allocBuffer(response, bufferSize);
if(res != UA_STATUSCODE_GOOD)
return res;
@ -236,7 +238,6 @@ ServerNetworkLayerTCP_add(UA_ServerNetworkLayer *nl, ServerNetworkLayerTCP *laye
memset(c, 0, sizeof(UA_Connection));
c->sockfd = newsockfd;
c->handle = layer;
c->config = nl->localConnectionConfig;
c->send = connection_write;
c->close = ServerNetworkLayerTCP_close;
c->free = ServerNetworkLayerTCP_freeConnection;
@ -751,7 +752,6 @@ UA_ClientConnectionTCP_init(UA_ConnectionConfig config, const UA_String endpoint
memset(&connection, 0, sizeof(UA_Connection));
connection.state = UA_CONNECTION_OPENING;
connection.config = config;
connection.send = connection_write;
connection.recv = connection_recv;
connection.close = ClientNetworkLayerTCP_close;
@ -813,7 +813,6 @@ UA_ClientConnectionTCP(UA_ConnectionConfig config, const UA_String endpointUrl,
UA_Connection connection;
memset(&connection, 0, sizeof(UA_Connection));
connection.state = UA_CONNECTION_CLOSED;
connection.config = config;
connection.send = connection_write;
connection.recv = connection_recv;
connection.close = ClientNetworkLayerTCP_close;

View File

@ -12,6 +12,7 @@
#include <open62541/plugin/log_stdout.h>
#include <open62541/util.h>
#include "open62541_queue.h"
#include "ua_securechannel.h"
#include <libwebsockets.h>
#include <string.h>
@ -49,7 +50,8 @@ typedef struct {
static UA_StatusCode
connection_getsendbuffer(UA_Connection *connection, size_t length, UA_ByteString *buf) {
if(length > connection->config.sendBufferSize)
UA_SecureChannel *channel = connection->channel;
if(channel && channel->config.sendBufferSize < length)
return UA_STATUSCODE_BADCOMMUNICATIONERROR;
return UA_ByteString_allocBuffer(buf, length);
}
@ -101,7 +103,6 @@ freeConnection(UA_Connection *connection) {
}
UA_free(connection->handle);
}
UA_Connection_clear(connection);
UA_free(connection);
}
@ -133,7 +134,6 @@ callback_opcua(struct lws *wsi, enum lws_callback_reasons reason, void *user, vo
memset(c, 0, sizeof(UA_Connection));
c->sockfd = 0;
c->handle = buffer;
c->config = layer->config;
c->send = connection_send;
c->close = ServerNetworkLayerWS_close;
c->free = freeConnection;
@ -188,34 +188,17 @@ callback_opcua(struct lws *wsi, enum lws_callback_reasons reason, void *user, vo
}
break;
case LWS_CALLBACK_RECEIVE:
case LWS_CALLBACK_RECEIVE: {
if(!vhd->context)
break;
layer =
(ServerNetworkLayerWS *)lws_context_user(vhd->context);
layer = (ServerNetworkLayerWS *)lws_context_user(vhd->context);
if(!layer->server)
break;
if(pss->connection->incompleteChunk.length == 0) {
UA_ByteString message = {len, (UA_Byte *)in};
UA_Server_processBinaryMessage(layer->server, pss->connection, &message);
} else {
UA_ByteString message = pss->connection->incompleteChunk;
pss->connection->incompleteChunk = UA_BYTESTRING_NULL;
UA_Byte *t = (UA_Byte*)UA_realloc(message.data, message.length + len);
if(!t) {
UA_ByteString_deleteMembers(&message);
return -1;
}
memcpy(&t[message.length], in, len);
message.data = t;
message.length += len;
UA_Server_processBinaryMessage(layer->server, pss->connection, &message);
connection_releaserecvbuffer(pss->connection, &message);
}
UA_ByteString message = {len, (UA_Byte *)in};
UA_Server_processBinaryMessage(layer->server, pss->connection, &message);
break;
}
default:
break;

View File

@ -55,12 +55,10 @@ typedef enum {
* is not done */
UA_CONNECTION_ESTABLISHED /* The socket is open and the connection
* configured */
} UA_ConnectionState;
struct UA_Connection {
UA_ConnectionState state;
UA_ConnectionConfig config;
UA_SecureChannel *channel; /* The securechannel that is attached to
* this connection */
UA_SOCKET sockfd; /* Most connectivity solutions run on

View File

@ -24,20 +24,16 @@ mqtt_pal_sendall(mqtt_pal_socket_handle fd, const void* buf, size_t len, int fla
ssize_t
mqtt_pal_recvall(mqtt_pal_socket_handle fd, void* buf, size_t bufsz, int flags) {
UA_Connection *connection = (UA_Connection*) fd->connection;
connection->config.recvBufferSize = (UA_UInt32) bufsz;
UA_Connection *connection = (UA_Connection*)fd->connection;
UA_ByteString inBuffer;
inBuffer.data = (UA_Byte*)buf;
inBuffer.length = bufsz;
UA_StatusCode ret = connection->recv(connection, &inBuffer, fd->timeout);
if(ret == UA_STATUSCODE_GOOD ){
// Buffer received, copy to recv buffer
memcpy(buf, inBuffer.data, inBuffer.length);
ssize_t bytesReceived = (ssize_t)inBuffer.length;
/* free recv buffer */
connection->releaseRecvBuffer(connection, &inBuffer);
return bytesReceived;
}else if(ret == UA_STATUSCODE_GOODNONCRITICALTIMEOUT){
if(ret == UA_STATUSCODE_GOOD ) {
return (ssize_t)inBuffer.length;
} else if(ret == UA_STATUSCODE_GOODNONCRITICALTIMEOUT) {
return 0;
}else{
} else {
return -1; //error case, no free necessary
}
}

View File

@ -31,7 +31,7 @@
static void
UA_Client_init(UA_Client* client) {
UA_SecureChannel_init(&client->channel);
UA_SecureChannel_init(&client->channel, &client->config.localConnectionConfig);
if(client->config.stateCallback)
client->config.stateCallback(client, client->state);
/* Catch error during async connection */

View File

@ -59,8 +59,7 @@ processACKResponse(void *application, UA_SecureChannel *channel,
UA_LOG_DEBUG(&client->config.logger, UA_LOGCATEGORY_NETWORK, "Received ACK message");
/* Process the ACK message */
retval = UA_Connection_processHELACK(channel->connection, &client->config.localConnectionConfig,
(const UA_ConnectionConfig*)&ackMessage);
retval = UA_SecureChannel_processHELACK(channel, (const UA_ConnectionConfig*)&ackMessage);
if(retval != UA_STATUSCODE_GOOD) {
UA_LOG_ERROR(&client->config.logger, UA_LOGCATEGORY_NETWORK,
"Processing the ACK message failed with StatusCode %s",
@ -734,6 +733,7 @@ UA_Client_connectTCPSecureChannel(UA_Client *client, const UA_String endpointUrl
client->channel.state = UA_SECURECHANNELSTATE_FRESH;
client->channel.sendSequenceNumber = 0;
client->requestId = 0;
client->channel.config = client->config.localConnectionConfig;
/* Set the channel SecurityMode */
client->channel.securityMode = client->config.endpoint.securityMode;
@ -788,7 +788,7 @@ UA_Client_connectTCPSecureChannel(UA_Client *client, const UA_String endpointUrl
UA_Connection_attachSecureChannel(&client->connection, &client->channel);
/* Perform the HEL/ACK handshake */
client->connection.config = client->config.localConnectionConfig;
client->channel.config = client->config.localConnectionConfig;
retval = HelAckHandshake(client, endpointUrl);
if(retval != UA_STATUSCODE_GOOD) {
UA_LOG_ERROR(&client->config.logger, UA_LOGCATEGORY_CLIENT,

View File

@ -63,8 +63,7 @@ processACKResponseAsync(void *application, UA_SecureChannel *channel,
}
client->connectStatus =
UA_Connection_processHELACK(channel->connection, &client->config.localConnectionConfig,
(const UA_ConnectionConfig*)&ackMessage);
UA_SecureChannel_processHELACK(channel, (const UA_ConnectionConfig*)&ackMessage);
if(client->connectStatus != UA_STATUSCODE_GOOD) {
UA_LOG_ERROR(&client->config.logger, UA_LOGCATEGORY_NETWORK,
"Processing the ACK message failed with StatusCode %s",
@ -607,6 +606,7 @@ UA_Client_connect_async(UA_Client *client, const char *endpointUrl,
client->channel.state = UA_SECURECHANNELSTATE_FRESH;
client->channel.sendSequenceNumber = 0;
client->requestId = 0;
client->channel.config = client->config.localConnectionConfig;
UA_String_deleteMembers(&client->endpointUrl);
client->endpointUrl = UA_STRING_ALLOC(endpointUrl);

View File

@ -127,7 +127,9 @@ UA_SecureChannelManager_create(UA_SecureChannelManager *cm, UA_Connection *conne
return UA_STATUSCODE_BADOUTOFMEMORY;
/* Channel state is fresh (0) */
UA_SecureChannel_init(&entry->channel);
/* TODO: Use the connection config from the correct network layer */
UA_SecureChannel_init(&entry->channel,
&cm->server->config.networkLayers[0].localConnectionConfig);
entry->channel.securityToken.channelId = 0;
entry->channel.securityToken.createdAt = UA_DateTime_now();
entry->channel.securityToken.revisedLifetime = cm->server->config.maxSecurityTokenLifetime;

View File

@ -20,6 +20,7 @@
#include <open62541/transport_generated_handling.h>
#include <open62541/types_generated_encoding_binary.h>
#include <open62541/types_generated_handling.h>
#include "open62541/plugin/network.h"
#include "ua_securechannel_manager.h"
#include "ua_server_internal.h"
@ -279,7 +280,7 @@ getServicePointers(UA_UInt32 requestTypeId, const UA_DataType **requestType,
/* HEL -> Open up the connection */
static UA_StatusCode
processHEL(UA_Server *server, UA_Connection *connection, const UA_ByteString *msg) {
processHEL(UA_Server *server, UA_SecureChannel *channel, const UA_ByteString *msg) {
size_t offset = 8; /* Go to the beginning of the TcpHelloMessage */
UA_TcpHelloMessage helloMessage;
UA_StatusCode retval = UA_TcpHelloMessage_decodeBinary(msg, &offset, &helloMessage);
@ -289,11 +290,6 @@ processHEL(UA_Server *server, UA_Connection *connection, const UA_ByteString *ms
/* Currently not checked */
UA_String_clear(&helloMessage.endpointUrl);
/* TODO: Use the config of the exact NetworkLayer */
if(server->config.networkLayersSize == 0)
return UA_STATUSCODE_BADOUTOFMEMORY;
const UA_ConnectionConfig *localConfig = &server->config.networkLayers[0].localConnectionConfig;
/* Parameterize the connection */
UA_ConnectionConfig remoteConfig;
remoteConfig.protocolVersion = helloMessage.protocolVersion;
@ -301,32 +297,33 @@ processHEL(UA_Server *server, UA_Connection *connection, const UA_ByteString *ms
remoteConfig.recvBufferSize = helloMessage.receiveBufferSize;
remoteConfig.maxMessageSize = helloMessage.maxMessageSize;
remoteConfig.maxChunkCount = helloMessage.maxChunkCount;
retval = UA_Connection_processHELACK(connection, localConfig, &remoteConfig);
retval = UA_SecureChannel_processHELACK(channel, &remoteConfig);
if(retval != UA_STATUSCODE_GOOD) {
UA_LOG_INFO(&server->config.logger, UA_LOGCATEGORY_NETWORK,
"Connection %i | Error during the HEL/ACK handshake",
(int)(connection->sockfd));
(int)(channel->connection->sockfd));
return retval;
}
/* Build acknowledge response */
UA_TcpAcknowledgeMessage ackMessage;
memcpy(&ackMessage, &connection->config, sizeof(UA_TcpAcknowledgeMessage)); /* Same struct layout.. */
memcpy(&ackMessage, &channel->config, sizeof(UA_TcpAcknowledgeMessage)); /* Same struct layout.. */
UA_TcpMessageHeader ackHeader;
ackHeader.messageTypeAndChunkType = UA_MESSAGETYPE_ACK + UA_CHUNKTYPE_FINAL;
ackHeader.messageSize = 8 + 20; /* ackHeader + ackMessage */
UA_Connection *connection = channel->connection;
/* Get the send buffer from the network layer */
UA_ByteString ack_msg;
UA_ByteString_init(&ack_msg);
retval = connection->getSendBuffer(connection, connection->config.sendBufferSize, &ack_msg);
retval = connection->getSendBuffer(connection, channel->config.sendBufferSize, &ack_msg);
if(retval != UA_STATUSCODE_GOOD)
return retval;
/* Encode and send the response */
UA_Byte *bufPos = ack_msg.data;
const UA_Byte *bufEnd = &ack_msg.data[ack_msg.length];
retval = UA_TcpMessageHeader_encodeBinary(&ackHeader, &bufPos, bufEnd);
if(retval != UA_STATUSCODE_GOOD) {
connection->releaseSendBuffer(connection, &ack_msg);
@ -732,7 +729,7 @@ processSecureChannelMessage(void *application, UA_SecureChannel *channel,
switch(messagetype) {
case UA_MESSAGETYPE_HEL:
UA_LOG_TRACE_CHANNEL(&server->config.logger, channel, "Process a HEL message");
retval = processHEL(server, channel->connection, message);
retval = processHEL(server, channel, message);
break;
case UA_MESSAGETYPE_OPN:
UA_LOG_TRACE_CHANNEL(&server->config.logger, channel, "Process an OPN message");

View File

@ -164,8 +164,7 @@ Service_CreateSession(UA_Server *server, UA_SecureChannel *channel,
/* Fill the session information */
newSession->maxResponseMessageSize = request->maxResponseMessageSize;
newSession->maxRequestMessageSize =
channel->connection->config.maxMessageSize;
newSession->maxRequestMessageSize = channel->config.maxMessageSize;
response->responseHeader.serviceResult |=
UA_ApplicationDescription_copy(&request->clientDescription,
&newSession->clientDescription);

View File

@ -20,37 +20,6 @@
#include "ua_types_encoding_binary.h"
#include "ua_util_internal.h"
UA_StatusCode
UA_Connection_processHELACK(UA_Connection *connection,
const UA_ConnectionConfig *localConfig,
const UA_ConnectionConfig *remoteConfig) {
connection->config = *remoteConfig;
/* The lowest common version is used by both sides */
if(connection->config.protocolVersion > localConfig->protocolVersion)
connection->config.protocolVersion = localConfig->protocolVersion;
/* Can we receive the max send size? */
if(connection->config.sendBufferSize > localConfig->recvBufferSize)
connection->config.sendBufferSize = localConfig->recvBufferSize;
/* Can we send the max receive size? */
if(connection->config.recvBufferSize > localConfig->sendBufferSize)
connection->config.recvBufferSize = localConfig->sendBufferSize;
/* Chunks of at least 8192 bytes must be permissible.
* See Part 6, Clause 6.7.1 */
if(connection->config.recvBufferSize < 8192 ||
connection->config.sendBufferSize < 8192 ||
(connection->config.maxMessageSize != 0 &&
connection->config.maxMessageSize < 8192))
return UA_STATUSCODE_BADINTERNALERROR;
connection->state = UA_CONNECTION_ESTABLISHED;
return UA_STATUSCODE_GOOD;
}
/* Hides some errors before sending them to a client according to the
* standard. */
static void

View File

@ -16,13 +16,6 @@
_UA_BEGIN_DECLS
/* Process the remote configuration in the HEL/ACK handshake. The connection
* config is initialized with the local settings. */
UA_StatusCode
UA_Connection_processHELACK(UA_Connection *connection,
const UA_ConnectionConfig *localConfig,
const UA_ConnectionConfig *remoteConfig);
/* When a fatal error occurs the Server shall send an Error Message to the
* Client and close the socket. When a Client encounters one of these errors, it
* shall also close the socket but does not send an Error Message. After the

View File

@ -31,12 +31,13 @@ UA_StatusCode sendAsym_sendFailure;
UA_StatusCode processSym_seqNumberFailure;
#endif
void
UA_SecureChannel_init(UA_SecureChannel *channel) {
void UA_SecureChannel_init(UA_SecureChannel *channel,
const UA_ConnectionConfig *config) {
/* Linked lists are also initialized by zeroing out */
memset(channel, 0, sizeof(UA_SecureChannel));
channel->state = UA_SECURECHANNELSTATE_FRESH;
TAILQ_INIT(&channel->messages);
channel->config = *config;
}
UA_StatusCode
@ -143,7 +144,8 @@ UA_SecureChannel_deleteMembers(UA_SecureChannel *channel) {
/* Remove the buffered messages */
UA_SecureChannel_deleteMessages(channel);
UA_ByteString_clear(&channel->incompleteChunk);
UA_SecureChannel_init(channel);
UA_ConnectionConfig oldConfig = channel->config;
UA_SecureChannel_init(channel, &oldConfig);
}
void
@ -166,6 +168,36 @@ UA_SecureChannel_close(UA_SecureChannel *channel) {
}
}
UA_StatusCode
UA_SecureChannel_processHELACK(UA_SecureChannel *channel,
const UA_ConnectionConfig *remoteConfig) {
channel->config = *remoteConfig;
/* The lowest common version is used by both sides */
if(channel->config.protocolVersion > remoteConfig->protocolVersion)
channel->config.protocolVersion = remoteConfig->protocolVersion;
/* Can we receive the max send size? */
if(channel->config.sendBufferSize > channel->config.recvBufferSize)
channel->config.sendBufferSize = channel->config.recvBufferSize;
/* Can we send the max receive size? */
if(channel->config.recvBufferSize > channel->config.sendBufferSize)
channel->config.recvBufferSize = channel->config.sendBufferSize;
/* Chunks of at least 8192 bytes must be permissible.
* See Part 6, Clause 6.7.1 */
if(channel->config.recvBufferSize < 8192 ||
channel->config.sendBufferSize < 8192 ||
(channel->config.maxMessageSize != 0 &&
channel->config.maxMessageSize < 8192))
return UA_STATUSCODE_BADINTERNALERROR;
channel->connection->state = UA_CONNECTION_ESTABLISHED;
return UA_STATUSCODE_GOOD;
}
UA_SessionHeader *
UA_SecureChannel_getSession(UA_SecureChannel *channel,
const UA_NodeId *authenticationToken) {
@ -191,7 +223,7 @@ UA_SecureChannel_sendAsymmetricOPNMessage(UA_SecureChannel *channel,
/* Allocate the message buffer */
UA_ByteString buf = UA_BYTESTRING_NULL;
UA_StatusCode retval =
connection->getSendBuffer(connection, connection->config.sendBufferSize, &buf);
connection->getSendBuffer(connection, channel->config.sendBufferSize, &buf);
if(retval != UA_STATUSCODE_GOOD)
return retval;
@ -253,25 +285,22 @@ error:
return retval;
}
/* Will this chunk surpass the capacity of the SecureChannel for the message? */
static UA_StatusCode
checkLimitsSym(UA_MessageContext *const messageContext, size_t *const bodyLength) {
/* Will this chunk surpass the capacity of the SecureChannel for the message? */
UA_Connection *const connection = messageContext->channel->connection;
if(!connection)
return UA_STATUSCODE_BADINTERNALERROR;
UA_Byte *buf_body_start = messageContext->messageBuffer.data + UA_SECURE_MESSAGE_HEADER_LENGTH;
const UA_Byte *buf_body_end = messageContext->buf_pos;
checkLimitsSym(UA_MessageContext *const mc, size_t *const bodyLength) {
UA_Byte *buf_body_start = mc->messageBuffer.data + UA_SECURE_MESSAGE_HEADER_LENGTH;
const UA_Byte *buf_body_end = mc->buf_pos;
*bodyLength = (uintptr_t)buf_body_end - (uintptr_t)buf_body_start;
messageContext->messageSizeSoFar += *bodyLength;
messageContext->chunksSoFar++;
mc->messageSizeSoFar += *bodyLength;
mc->chunksSoFar++;
if(messageContext->messageSizeSoFar > connection->config.maxMessageSize &&
connection->config.maxMessageSize != 0)
UA_SecureChannel *channel = mc->channel;
if(mc->messageSizeSoFar > channel->config.maxMessageSize &&
channel->config.maxMessageSize != 0)
return UA_STATUSCODE_BADRESPONSETOOLARGE;
if(messageContext->chunksSoFar > connection->config.maxChunkCount &&
connection->config.maxChunkCount != 0)
if(mc->chunksSoFar > channel->config.maxChunkCount &&
channel->config.maxChunkCount != 0)
return UA_STATUSCODE_BADRESPONSETOOLARGE;
return UA_STATUSCODE_GOOD;
@ -340,7 +369,7 @@ sendSymmetricChunk(UA_MessageContext *messageContext) {
total_length += securityPolicy->symmetricModule.cryptoModule.signatureAlgorithm.
getLocalSignatureSize(securityPolicy, channel->channelContext);
/* Space for the padding and the signature have been reserved in setBufPos() */
UA_assert(total_length <= connection->config.sendBufferSize);
UA_assert(total_length <= channel->config.sendBufferSize);
/* For giving the buffer to the network layer */
messageContext->messageBuffer.length = total_length;
@ -386,7 +415,7 @@ sendSymmetricEncodingCallback(void *data, UA_Byte **buf_pos, const UA_Byte **buf
if(!connection)
return UA_STATUSCODE_BADINTERNALERROR;
retval = connection->getSendBuffer(connection, connection->config.sendBufferSize,
retval = connection->getSendBuffer(connection, mc->channel->config.sendBufferSize,
&mc->messageBuffer);
if(retval != UA_STATUSCODE_GOOD)
return retval;
@ -419,7 +448,7 @@ UA_MessageContext_begin(UA_MessageContext *mc, UA_SecureChannel *channel,
/* Allocate the message buffer */
UA_StatusCode retval =
connection->getSendBuffer(connection, connection->config.sendBufferSize,
connection->getSendBuffer(connection, channel->config.sendBufferSize,
&mc->messageBuffer);
if(retval != UA_STATUSCODE_GOOD)
return retval;
@ -518,9 +547,7 @@ addChunkPayload(UA_SecureChannel *channel, UA_UInt32 requestId,
}
/* Test against the connection settings */
const UA_ConnectionConfig *config = &channel->connection->config;
UA_assert(config != NULL); /* clang-analyzer false positive */
const UA_ConnectionConfig *config = &channel->config;
if(config->maxChunkCount > 0 &&
config->maxChunkCount <= latest->chunkPayloadsSize)
return UA_STATUSCODE_BADRESPONSETOOLARGE;
@ -781,14 +808,14 @@ processChunk(UA_SecureChannel *channel, const UA_ByteString *packet,
UA_TcpMessageHeader hdr;
UA_TcpMessageHeader_decodeBinary(packet, &initial_offset, &hdr);
UA_MessageType msgType = (UA_MessageType)
hdr.messageTypeAndChunkType & UA_BITMASK_MESSAGETYPE;
(hdr.messageTypeAndChunkType & UA_BITMASK_MESSAGETYPE);
UA_ChunkType chunkType = (UA_ChunkType)
(hdr.messageTypeAndChunkType & UA_BITMASK_CHUNKTYPE);
/* The message size is not allowed */
if(hdr.messageSize < 16)
return UA_STATUSCODE_BADTCPMESSAGETYPEINVALID;
if(hdr.messageSize > channel->connection->config.recvBufferSize)
if(hdr.messageSize > channel->config.recvBufferSize)
return UA_STATUSCODE_BADTCPMESSAGETOOLARGE;
/* Incomplete chunk */

View File

@ -73,6 +73,7 @@ typedef TAILQ_HEAD(UA_MessageQueue, UA_Message) UA_MessageQueue;
struct UA_SecureChannel {
UA_SecureChannelState state;
UA_MessageSecurityMode securityMode;
UA_ConnectionConfig config;
/* Rules for revolving the token with a renew OPN request: The client is
* allowed to accept messages with the old token until the OPN response has
@ -110,10 +111,17 @@ struct UA_SecureChannel {
* messages */
};
void UA_SecureChannel_init(UA_SecureChannel *channel);
void UA_SecureChannel_init(UA_SecureChannel *channel,
const UA_ConnectionConfig *config);
void UA_SecureChannel_close(UA_SecureChannel *channel);
/* Process the remote configuration in the HEL/ACK handshake. The connection
* config is initialized with the local settings. */
UA_StatusCode
UA_SecureChannel_processHELACK(UA_SecureChannel *channel,
const UA_ConnectionConfig *remoteConfig);
UA_StatusCode
UA_SecureChannel_setSecurityPolicy(UA_SecureChannel *channel,
const UA_SecurityPolicy *securityPolicy,

View File

@ -7,6 +7,7 @@
#include <open62541/transport_generated_handling.h>
#include <open62541/types_generated.h>
#include <open62541/types_generated_encoding_binary.h>
#include <open62541/server_config_default.h>
#include "ua_securechannel.h"
#include <ua_types_encoding_binary.h>
@ -41,7 +42,7 @@ static key_sizes keySizes;
static void
setup_secureChannel(void) {
TestingPolicy(&dummyPolicy, dummyCertificate, &fCalled, &keySizes);
UA_SecureChannel_init(&testChannel);
UA_SecureChannel_init(&testChannel, &UA_ConnectionConfig_default);
UA_SecureChannel_setSecurityPolicy(&testChannel, &dummyPolicy, &dummyCertificate);
testingConnection = createDummyConnection(65535, &sentData);
@ -95,7 +96,7 @@ START_TEST(SecureChannel_initAndDelete) {
UA_StatusCode retval;
UA_SecureChannel channel;
UA_SecureChannel_init(&channel);
UA_SecureChannel_init(&channel, &UA_ConnectionConfig_default);
retval = UA_SecureChannel_setSecurityPolicy(&channel, &dummyPolicy, &dummyCertificate);
ck_assert_msg(retval == UA_STATUSCODE_GOOD, "Expected StatusCode to be good");

View File

@ -179,7 +179,7 @@ START_TEST(Client_renewSecureChannel) {
UA_Variant val;
UA_NodeId nodeId = UA_NODEID_STRING(1, "my.variable");
retval = UA_Client_readValueAttribute(client, nodeId, &val);
ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD);
ck_assert_msg(retval == UA_STATUSCODE_GOOD, UA_StatusCode_name(retval));
UA_Variant_deleteMembers(&val);
UA_Client_disconnect(client);

View File

@ -62,6 +62,5 @@ LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
UA_Server_run_shutdown(server);
UA_Server_delete(server);
c.close(&c);
UA_Connection_clear(&c);
return 0;
}

View File

@ -112,7 +112,7 @@ LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
if (status >= 0) {
if (write(sockfd, data, size) != size) {
UA_LOG_FATAL(UA_Log_Stdout, UA_LOGCATEGORY_CLIENT,
"Did not write %d bytes", size);
"Did not write %lu bytes", (long unsigned)size);
retCode = EXIT_FAILURE;
}
} else {

View File

@ -28,7 +28,7 @@ static void setup(void) {
UA_ServerConfig_setDefault(UA_Server_getConfig(server));
TestingPolicy(&dummyPolicy, UA_BYTESTRING_NULL, &funcsCalled, &keySizes);
UA_SecureChannel_init(&testChannel);
UA_SecureChannel_init(&testChannel, &UA_ConnectionConfig_default);
UA_SecureChannel_setSecurityPolicy(&testChannel, &dummyPolicy, &UA_BYTESTRING_NULL);
testingConnection = createDummyConnection(65535, NULL);

View File

@ -27,7 +27,7 @@ static void setup(void) {
server = UA_Server_new();
UA_ServerConfig_setDefault(UA_Server_getConfig(server));
TestingPolicy(&dummyPolicy, UA_BYTESTRING_NULL, &funcsCalled, &keySizes);
UA_SecureChannel_init(&testChannel);
UA_SecureChannel_init(&testChannel, &UA_ConnectionConfig_default);
UA_SecureChannel_setSecurityPolicy(&testChannel, &dummyPolicy, &UA_BYTESTRING_NULL);
testingConnection = createDummyConnection(65535, NULL);
UA_Connection_attachSecureChannel(&testingConnection, &testChannel);

View File

@ -59,7 +59,6 @@ UA_Connection createDummyConnection(size_t sendBufferSize,
UA_Connection c;
c.state = UA_CONNECTION_ESTABLISHED;
c.config = UA_ConnectionConfig_default;
c.channel = NULL;
c.sockfd = 0;
c.handle = NULL;