Esempio n. 1
0
UA_Int32 UA_AsymmetricAlgorithmSecurityHeader_deleteMembers(UA_AsymmetricAlgorithmSecurityHeader* p) {
	UA_Int32 retval = UA_SUCCESS;
	retval |= UA_ByteString_deleteMembers(&(p->securityPolicyUri));
	retval |= UA_ByteString_deleteMembers(&(p->senderCertificate));
	retval |= UA_ByteString_deleteMembers(&(p->receiverCertificateThumbprint));
	return retval;
}
Esempio n. 2
0
/** Accesses only the sockfd in the handle. Can be run from parallel threads. */
static UA_StatusCode sendUDP(UA_Connection *connection, UA_ByteString *buf) {
    UDPConnection *udpc = (UDPConnection*)connection;
    ServerNetworkLayerUDP *layer = (ServerNetworkLayerUDP*)connection->handle;
	size_t nWritten = 0;
	struct sockaddr_in *sin = NULL;

	if (udpc->from.sa_family == AF_INET) {
#if ((__GNUC__ == 4 && __GNUC_MINOR__ >= 6) || __GNUC__ > 4 || defined(__clang__))
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wcast-align"
#endif
	    sin = (struct sockaddr_in *) &udpc->from;
#if ((__GNUC__ == 4 && __GNUC_MINOR__ >= 6) || __GNUC__ > 4 || defined(__clang__))
#pragma GCC diagnostic pop
#endif
	} else {
        UA_ByteString_deleteMembers(buf);
		return UA_STATUSCODE_BADINTERNALERROR;
    }

	while (nWritten < (size_t)buf->length) {
		UA_Int32 n = sendto(layer->serversockfd, buf->data, buf->length, 0,
                            (struct sockaddr*)sin, sizeof(struct sockaddr_in));
        if(n == -1L) {
            UA_LOG_WARNING(layer->layer.logger, UA_LOGCATEGORY_COMMUNICATION, "UDP send error %i", errno);
            UA_ByteString_deleteMembers(buf);
            return UA_STATUSCODE_BADINTERNALERROR;
        }
        nWritten += n;
	}
    UA_ByteString_deleteMembers(buf);
    return UA_STATUSCODE_GOOD;
}
Esempio n. 3
0
static UA_StatusCode
socket_write(UA_Connection *connection, UA_ByteString *buf) {
    size_t nWritten = 0;
    while(buf->length > 0 && nWritten < (size_t)buf->length) {
        UA_Int32 n = 0;
        do {
#ifdef _WIN32
            n = send((SOCKET)connection->sockfd, (const char*)buf->data, (size_t)buf->length, 0);
            const int last_error = WSAGetLastError();
            if(n < 0 && last_error != WSAEINTR && last_error != WSAEWOULDBLOCK) {
                connection->close(connection);
                socket_close(connection);
                UA_ByteString_deleteMembers(buf);
                return UA_STATUSCODE_BADCONNECTIONCLOSED;
            }
#else
            n = send(connection->sockfd, (const char*)buf->data, (size_t)buf->length, MSG_NOSIGNAL);
            if(n == -1L && errno != EINTR && errno != EAGAIN) {
                connection->close(connection);
                socket_close(connection);
                UA_ByteString_deleteMembers(buf);
                return UA_STATUSCODE_BADCONNECTIONCLOSED;
            }
#endif
        } while (n == -1L);
        nWritten += n;
    }
    UA_ByteString_deleteMembers(buf);
    return UA_STATUSCODE_GOOD;
}
void UA_SecureChannel_deleteMembers(UA_SecureChannel *channel) {
    UA_AsymmetricAlgorithmSecurityHeader_deleteMembers(&channel->serverAsymAlgSettings);
    UA_ByteString_deleteMembers(&channel->serverNonce);
    UA_AsymmetricAlgorithmSecurityHeader_deleteMembers(&channel->clientAsymAlgSettings);
    UA_ByteString_deleteMembers(&channel->clientNonce);
    UA_ChannelSecurityToken_deleteMembers(&channel->securityToken);
}
Esempio n. 5
0
END_TEST

START_TEST(encodeShallYieldDecode) {
    /* floating point types may change the representaton due to several possible NaN values. */
    if(_i != UA_TYPES_FLOAT || _i != UA_TYPES_DOUBLE ||
       _i != UA_TYPES_CREATESESSIONREQUEST || _i != UA_TYPES_CREATESESSIONRESPONSE ||
       _i != UA_TYPES_VARIABLEATTRIBUTES || _i != UA_TYPES_READREQUEST ||
       _i != UA_TYPES_MONITORINGPARAMETERS || _i != UA_TYPES_MONITOREDITEMCREATERESULT ||
       _i != UA_TYPES_CREATESUBSCRIPTIONREQUEST || _i != UA_TYPES_CREATESUBSCRIPTIONRESPONSE)
        return;

    // given
    UA_ByteString msg1, msg2;
    void *obj1 = UA_new(&UA_TYPES[_i]);
    UA_StatusCode retval = UA_ByteString_allocBuffer(&msg1, 65000); // fixed buf size
    ck_assert_int_eq(retval, UA_STATUSCODE_GOOD);
    UA_Byte *pos = msg1.data;
    const UA_Byte *end = &msg1.data[msg1.length];
    retval = UA_encodeBinary(obj1, &UA_TYPES[_i],
                             &pos, &end, NULL, NULL);
    if(retval != UA_STATUSCODE_GOOD) {
        UA_delete(obj1, &UA_TYPES[_i]);
        UA_ByteString_deleteMembers(&msg1);
        return;
    }

    // when
    void *obj2 = UA_new(&UA_TYPES[_i]);
    size_t offset = 0;
    retval = UA_decodeBinary(&msg1, &offset, obj2, &UA_TYPES[_i], 0, NULL); 
    ck_assert_msg(retval == UA_STATUSCODE_GOOD, "could not decode idx=%d,nodeid=%i",
                  _i, UA_TYPES[_i].typeId.identifier.numeric);
    ck_assert(!memcmp(obj1, obj2, UA_TYPES[_i].memSize)); // bit identical decoding
    retval = UA_ByteString_allocBuffer(&msg2, 65000);
    ck_assert_int_eq(retval, UA_STATUSCODE_GOOD);
    pos = msg2.data;
    end = &msg2.data[msg2.length];
    retval = UA_encodeBinary(obj2, &UA_TYPES[_i], &pos, &end, NULL, NULL);
    ck_assert_int_eq(retval, UA_STATUSCODE_GOOD);

    // then
    msg1.length = offset;
    msg2.length = offset;
    ck_assert_msg(UA_ByteString_equal(&msg1, &msg2) == true, "messages differ idx=%d,nodeid=%i", _i,
                  UA_TYPES[_i].typeId.identifier.numeric);

    // finally
    UA_delete(obj1, &UA_TYPES[_i]);
    UA_delete(obj2, &UA_TYPES[_i]);
    UA_ByteString_deleteMembers(&msg1);
    UA_ByteString_deleteMembers(&msg2);
}
Esempio n. 6
0
int main(int argc, char* argv[]) {
    signal(SIGINT, stopHandler);
    signal(SIGTERM, stopHandler);

    if(argc < 3) {
        UA_LOG_FATAL(UA_Log_Stdout, UA_LOGCATEGORY_USERLAND,
                     "Missing arguments. Arguments are "
                     "<server-certificate.der> <private-key.der> "
                     "[<trustlist1.crl>, ...]");
        return 1;
    }

    /* Load certificate and private key */
    UA_ByteString certificate = loadFile(argv[1]);
    UA_ByteString privateKey = loadFile(argv[2]);

    /* Load the trustlist */
    size_t trustListSize = 0;
    if(argc > 3)
        trustListSize = (size_t)argc-3;
    UA_STACKARRAY(UA_ByteString, trustList, trustListSize);
    for(size_t i = 0; i < trustListSize; i++)
        trustList[i] = loadFile(argv[i+3]);

    /* Loading of a revocation list currently unsupported */
    UA_ByteString *revocationList = NULL;
    size_t revocationListSize = 0;

    UA_ServerConfig *config =
        UA_ServerConfig_new_basic128rsa15(4840, &certificate, &privateKey,
                                          trustList, trustListSize,
                                          revocationList, revocationListSize);
    UA_ByteString_deleteMembers(&certificate);
    UA_ByteString_deleteMembers(&privateKey);
    for(size_t i = 0; i < trustListSize; i++)
        UA_ByteString_deleteMembers(&trustList[i]);

    if(!config) {
        UA_LOG_FATAL(UA_Log_Stdout, UA_LOGCATEGORY_USERLAND,
                     "Could not create the server config");
        return 1;
    }

    UA_Server *server = UA_Server_new(config);
    UA_StatusCode retval = UA_Server_run(server, &running);
    UA_Server_delete(server);
    UA_ServerConfig_delete(config);
    return (int)retval;
}
Esempio n. 7
0
static void
checkSignature(const UA_Server *server,
               const UA_SecureChannel *channel,
               UA_Session *session,
               const UA_ActivateSessionRequest *request,
               UA_ActivateSessionResponse *response) {
    if(channel->securityMode == UA_MESSAGESECURITYMODE_SIGN ||
       channel->securityMode == UA_MESSAGESECURITYMODE_SIGNANDENCRYPT) {
        const UA_SecurityPolicy *const securityPolicy = channel->securityPolicy;
        const UA_ByteString *const localCertificate = &securityPolicy->localCertificate;

        UA_ByteString dataToVerify;
        UA_StatusCode retval = UA_ByteString_allocBuffer(&dataToVerify,
                                                         localCertificate->length + session->serverNonce.length);
        if(retval != UA_STATUSCODE_GOOD) {
            response->responseHeader.serviceResult = retval;
            UA_LOG_DEBUG_SESSION(server->config.logger, session,
                                 "Failed to allocate buffer for signature verification! %#10x", retval);
            return;
        }

        memcpy(dataToVerify.data, localCertificate->data, localCertificate->length);
        memcpy(dataToVerify.data + localCertificate->length,
               session->serverNonce.data, session->serverNonce.length);

        retval = securityPolicy->asymmetricModule.cryptoModule.
            verify(securityPolicy, channel->channelContext, &dataToVerify,
                   &request->clientSignature.signature);
        if(retval != UA_STATUSCODE_GOOD) {
            response->responseHeader.serviceResult = retval;
            UA_LOG_DEBUG_SESSION(server->config.logger, session,
                                 "Failed to verify the client signature! %#10x", retval);
            UA_ByteString_deleteMembers(&dataToVerify);
            return;
        }

        retval  = UA_SecureChannel_generateNonce(channel, 32, &response->serverNonce);
        retval |= UA_ByteString_copy(&response->serverNonce, &session->serverNonce);
        if(retval != UA_STATUSCODE_GOOD) {
            response->responseHeader.serviceResult = retval;
            UA_LOG_DEBUG_SESSION(server->config.logger, session,
                                 "Failed to generate a new nonce! %#10x", retval);
            UA_ByteString_deleteMembers(&dataToVerify);
            return;
        }

        UA_ByteString_deleteMembers(&dataToVerify);
    }
}
Esempio n. 8
0
static UA_StatusCode
socket_recv(UA_Connection *connection, UA_ByteString *response, UA_UInt32 timeout) {
    response->data = malloc(connection->localConf.recvBufferSize);
    if(!response->data) {
        response->length = 0;
        return UA_STATUSCODE_BADOUTOFMEMORY; /* not enough memory retry */
    }

    if(timeout > 0) {
        /* currently, only the client uses timeouts */
#ifndef _WIN32
        int timeout_usec = timeout * 1000;
        struct timeval tmptv = {timeout_usec / 1000000, timeout_usec % 1000000};
        int ret = setsockopt(connection->sockfd, SOL_SOCKET, SO_RCVTIMEO, (const char *)&tmptv, sizeof(struct timeval));
#else
        DWORD timeout_dw = timeout;
        int ret = setsockopt(connection->sockfd, SOL_SOCKET, SO_RCVTIMEO, (const char*)&timeout_dw, sizeof(DWORD));
#endif
        if(0 != ret) {
            UA_ByteString_deleteMembers(response);
            socket_close(connection);
            return UA_STATUSCODE_BADCONNECTIONCLOSED;
        }
    }

    int ret = recv(connection->sockfd, (char*)response->data, connection->localConf.recvBufferSize, 0);
	if(ret == 0) {
        /* server has closed the connection */
        UA_ByteString_deleteMembers(response);
        socket_close(connection);
        return UA_STATUSCODE_BADCONNECTIONCLOSED;
	} else if(ret < 0) {
        UA_ByteString_deleteMembers(response);
#ifdef _WIN32
        const int last_error = WSAGetLastError();
        #define TEST_RETRY (last_error == WSAEINTR || last_error == WSAEWOULDBLOCK)
#else
        #define TEST_RETRY (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK)
#endif
        if (TEST_RETRY)
            return UA_STATUSCODE_GOOD; /* retry */
        else {
            socket_close(connection);
            return UA_STATUSCODE_BADCONNECTIONCLOSED;
        }
    }
    response->length = ret;
    return UA_STATUSCODE_GOOD;
}
Esempio n. 9
0
/* loadFile parses the certificate file.
 *
 * @param  path               specifies the file name given in argv[]
 * @return Returns the file content after parsing */
static UA_ByteString loadFile(const char *const path) {
    UA_ByteString fileContents = UA_BYTESTRING_NULL;
    if (path == NULL)
        return fileContents;

    /* Open the file */
    FILE *fp = fopen(path, "rb");
    if (!fp) {
        errno = 0; /* We read errno also from the tcp layer */
        return fileContents;
    }

    /* Get the file length, allocate the data and read */
    fseek(fp, 0, SEEK_END);
    fileContents.length = (size_t) ftell(fp);
    fileContents.data = (UA_Byte *) UA_malloc(fileContents.length * sizeof(UA_Byte));
    if (fileContents.data) {
        fseek(fp, 0, SEEK_SET);
        size_t read = fread(fileContents.data, sizeof(UA_Byte), fileContents.length, fp);
        if (read != fileContents.length)
            UA_ByteString_deleteMembers(&fileContents);
    } else {
        fileContents.length = 0;
    }

    fclose(fp);
    return fileContents;
}
Esempio n. 10
0
END_TEST

START_TEST(calcSizeBinaryShallBeCorrect) {
    /* Empty variants (with no type defined) cannot be encoded. This is intentional. Discovery configuration is just a base class and void * */
    if(_i == UA_TYPES_VARIANT ||
       _i == UA_TYPES_VARIABLEATTRIBUTES ||
       _i == UA_TYPES_VARIABLETYPEATTRIBUTES ||
       _i == UA_TYPES_FILTEROPERAND ||
       _i == UA_TYPES_MONITORINGFILTER ||
       _i == UA_TYPES_DISCOVERYCONFIGURATION ||
       _i == UA_TYPES_UNION ||
       _i == UA_TYPES_HISTORYREADDETAILS ||
       _i == UA_TYPES_NOTIFICATIONDATA ||
       _i == UA_TYPES_MONITORINGFILTERRESULT)
        return;
    void *obj = UA_new(&UA_TYPES[_i]);
    size_t predicted_size = UA_calcSizeBinary(obj, &UA_TYPES[_i]);
    ck_assert_int_ne(predicted_size, 0);
    UA_ByteString msg;
    UA_StatusCode retval = UA_ByteString_allocBuffer(&msg, predicted_size);
    ck_assert_int_eq(retval, UA_STATUSCODE_GOOD);
    UA_Byte *pos = msg.data;
    const UA_Byte *end = &msg.data[msg.length];
    retval = UA_encodeBinary(obj, &UA_TYPES[_i], &pos, &end, NULL, NULL);
    if(retval)
        printf("%i\n",_i);
    ck_assert_int_eq(retval, UA_STATUSCODE_GOOD);
    ck_assert_int_eq((uintptr_t)(pos - msg.data), predicted_size);
    UA_delete(obj, &UA_TYPES[_i]);
    UA_ByteString_deleteMembers(&msg);
}
Esempio n. 11
0
END_TEST

START_TEST(decodeComplexTypeFromRandomBufferShallSurvive) {
    // given
    UA_ByteString msg1;
    UA_Int32 retval = UA_STATUSCODE_GOOD;
    UA_Int32 buflen = 256;
    retval = UA_ByteString_allocBuffer(&msg1, buflen); // fixed size
#ifdef _WIN32
    srand(42);
#else
    srandom(42);
#endif
    // when
    for(int n = 0;n < RANDOM_TESTS;n++) {
        for(UA_Int32 i = 0;i < buflen;i++) {
#ifdef _WIN32
            UA_UInt32 rnd;
            rnd = rand();
            msg1.data[i] = rnd;
#else
            msg1.data[i] = (UA_Byte)random();  // when
#endif
        }
        size_t pos = 0;
        void *obj1 = UA_new(&UA_TYPES[_i]);
        retval |= UA_decodeBinary(&msg1, &pos, obj1, &UA_TYPES[_i], 0, NULL);
        UA_delete(obj1, &UA_TYPES[_i]);
    }

    // finally
    UA_ByteString_deleteMembers(&msg1);
}
Esempio n. 12
0
static UA_Int32 sendHello(UA_Int32 sock, UA_String *endpointURL) {

	UA_TcpMessageHeader messageHeader;
	messageHeader.messageTypeAndFinal = UA_MESSAGETYPEANDFINAL_HELF;

	UA_TcpHelloMessage hello;
	UA_String_copy(endpointURL, &hello.endpointUrl);
	hello.maxChunkCount = 1;
	hello.maxMessageSize = 16777216;
	hello.protocolVersion = 0;
	hello.receiveBufferSize = 65536;
	hello.sendBufferSize = 65536;

	messageHeader.messageSize = UA_TcpHelloMessage_calcSizeBinary((UA_TcpHelloMessage const*) &hello) +
                                UA_TcpMessageHeader_calcSizeBinary((UA_TcpMessageHeader const*) &messageHeader);
	UA_ByteString message;
	UA_ByteString_newMembers(&message, messageHeader.messageSize);

	size_t offset = 0;
	UA_TcpMessageHeader_encodeBinary((UA_TcpMessageHeader const*) &messageHeader, &message, &offset);
	UA_TcpHelloMessage_encodeBinary((UA_TcpHelloMessage const*) &hello, &message, &offset);

	UA_Int32 sendret = send(sock, message.data, offset, 0);

	UA_ByteString_deleteMembers(&message);
	free(hello.endpointUrl.data);
	if (sendret < 0)
		return 1;
	return 0;
}
Esempio n. 13
0
static void
processJob(UA_Server *server, UA_Job *job) {
    UA_ASSERT_RCU_UNLOCKED();
    UA_RCU_LOCK();
    switch(job->type) {
    case UA_JOBTYPE_NOTHING:
        break;
    case UA_JOBTYPE_DETACHCONNECTION:
        UA_Connection_detachSecureChannel(job->job.closeConnection);
        break;
    case UA_JOBTYPE_BINARYMESSAGE_NETWORKLAYER:
        UA_Server_processBinaryMessage(server, job->job.binaryMessage.connection,
                                       &job->job.binaryMessage.message);
        UA_Connection *connection = job->job.binaryMessage.connection;
        connection->releaseRecvBuffer(connection, &job->job.binaryMessage.message);
        break;
    case UA_JOBTYPE_BINARYMESSAGE_ALLOCATED:
        UA_Server_processBinaryMessage(server, job->job.binaryMessage.connection,
                                       &job->job.binaryMessage.message);
        UA_ByteString_deleteMembers(&job->job.binaryMessage.message);
        break;
    case UA_JOBTYPE_METHODCALL:
    case UA_JOBTYPE_METHODCALL_DELAYED:
        job->job.methodCall.method(server, job->job.methodCall.data);
        break;
    default:
        UA_LOG_WARNING(server->config.logger, UA_LOGCATEGORY_SERVER,
                       "Trying to execute a job of unknown type");
        break;
    }
    UA_RCU_UNLOCK();
}
static UA_StatusCode socket_write(UA_Connection *connection, UA_ByteString *buf, size_t buflen) {
    size_t nWritten = 0;
    while (nWritten < buflen) {
        UA_Int32 n = 0;
        do {
#ifdef _WIN32
            n = send((SOCKET)connection->sockfd, (const char*)buf->data, buflen, 0);
            if(n < 0 && WSAGetLastError() != WSAEINTR && WSAGetLastError() != WSAEWOULDBLOCK){
                connection->close(connection);
                socket_close(connection);
                return UA_STATUSCODE_BADCONNECTIONCLOSED;
            }
#else
            n = send(connection->sockfd, (const char*)buf->data, buflen, MSG_NOSIGNAL);
            if(n == -1L && errno != EINTR && errno != EAGAIN){
                socket_close(connection);
                return UA_STATUSCODE_BADCONNECTIONCLOSED;
            }
#endif
        } while (n == -1L);
        nWritten += n;
    }
#ifdef UA_MULTITHREADING
    UA_ByteString_deleteMembers(buf);
#endif
    return UA_STATUSCODE_GOOD;
}
Esempio n. 15
0
void print_time() {
	UA_DateTime now = UA_DateTime_now();
	UA_ByteString str;
	UA_DateTime_toString(now, &str);
	printf("\"%.*s\"}", str.length, str.data);
	UA_ByteString_deleteMembers(&str);
}
Esempio n. 16
0
static size_t
browseWithMaxResults(UA_Server *server, UA_NodeId nodeId, UA_UInt32 maxResults) {
    UA_BrowseDescription bd;
    UA_BrowseDescription_init(&bd);
    bd.nodeId = nodeId;
    bd.resultMask = UA_BROWSERESULTMASK_ALL;
    bd.browseDirection = UA_BROWSEDIRECTION_FORWARD;
    UA_BrowseResult br = UA_Server_browse(server, maxResults, &bd);
    ck_assert_int_eq(br.statusCode, UA_STATUSCODE_GOOD);
    ck_assert(br.referencesSize > 0);

    size_t total = br.referencesSize;
    UA_ByteString cp = br.continuationPoint;
    br.continuationPoint = UA_BYTESTRING_NULL;
    UA_BrowseResult_deleteMembers(&br);

    while(cp.length > 0) {
        br = UA_Server_browseNext(server, false, &cp);
        ck_assert(br.referencesSize > 0);
        UA_ByteString_deleteMembers(&cp);
        cp = br.continuationPoint;
        br.continuationPoint = UA_BYTESTRING_NULL;
        total += br.referencesSize;
        UA_BrowseResult_deleteMembers(&br);
    }

    return total;
}
Esempio n. 17
0
static void print_time(void) {
	UA_DateTime now = UA_DateTime_now();
	UA_ByteString str;
	UA_DateTime_toString(now, &str);
	printf("%.27s", str.data); //a bit hacky way not to display nanoseconds
	UA_ByteString_deleteMembers(&str);
}
Esempio n. 18
0
/* Create a signed nonce */
static UA_StatusCode
nonceAndSignCreateSessionResponse(UA_Server *server, UA_SecureChannel *channel,
                                  UA_Session *session,
                                  const UA_CreateSessionRequest *request,
                                  UA_CreateSessionResponse *response) {
    if(channel->securityMode != UA_MESSAGESECURITYMODE_SIGN &&
       channel->securityMode != UA_MESSAGESECURITYMODE_SIGNANDENCRYPT)
        return UA_STATUSCODE_GOOD;

    const UA_SecurityPolicy *const securityPolicy = channel->securityPolicy;
    UA_SignatureData *signatureData = &response->serverSignature;

    /* Generate Nonce
     * FIXME: remove magic number??? */
    UA_StatusCode retval = UA_SecureChannel_generateNonce(channel, 32, &response->serverNonce);
    retval |= UA_ByteString_copy(&response->serverNonce, &session->serverNonce);
    if(retval != UA_STATUSCODE_GOOD) {
        UA_SessionManager_removeSession(&server->sessionManager, &session->authenticationToken);
        return retval;
    }

    size_t signatureSize = securityPolicy->asymmetricModule.cryptoModule.
        getLocalSignatureSize(securityPolicy, channel->channelContext);

    retval |= UA_ByteString_allocBuffer(&signatureData->signature, signatureSize);
    if(retval != UA_STATUSCODE_GOOD) {
        UA_SessionManager_removeSession(&server->sessionManager, &session->authenticationToken);
        return retval;
    }

    UA_ByteString dataToSign;
    retval |= UA_ByteString_allocBuffer(&dataToSign,
                                        request->clientCertificate.length +
                                        request->clientNonce.length);
    if(retval != UA_STATUSCODE_GOOD) {
        UA_SignatureData_deleteMembers(signatureData);
        UA_SessionManager_removeSession(&server->sessionManager, &session->authenticationToken);
        return retval;
    }

    memcpy(dataToSign.data, request->clientCertificate.data, request->clientCertificate.length);
    memcpy(dataToSign.data + request->clientCertificate.length,
           request->clientNonce.data, request->clientNonce.length);

    retval |= UA_String_copy(&securityPolicy->asymmetricModule.cryptoModule.
                             signatureAlgorithmUri, &signatureData->algorithm);
    retval |= securityPolicy->asymmetricModule.cryptoModule.
        sign(securityPolicy, channel->channelContext, &dataToSign, &signatureData->signature);

    UA_ByteString_deleteMembers(&dataToSign);
    if(retval != UA_STATUSCODE_GOOD) {
        UA_SignatureData_deleteMembers(signatureData);
        UA_SessionManager_removeSession(&server->sessionManager, &session->authenticationToken);
    }
    return retval;
}
/* run only when the server is stopped */
static void ServerNetworkLayerTCP_deleteMembers(UA_ServerNetworkLayer *nl) {
    ServerNetworkLayerTCP *layer = nl->handle;
#ifndef UA_MULTITHREADING
    UA_ByteString_deleteMembers(&layer->buffer);
#endif
    for(size_t i = 0; i < layer->mappingsSize; i++)
        free(layer->mappings[i].connection);
    free(layer->mappings);
    free(layer);
}
Esempio n. 20
0
void UA_Log_Stdout(UA_LogLevel level, UA_LogCategory category, const char *msg, ...) {
    UA_String t = UA_DateTime_toString(UA_DateTime_now());
    printf("[%.23s] %s/%s\t", t.data, LogLevelNames[level], LogCategoryNames[category]);
    UA_ByteString_deleteMembers(&t);
    va_list ap;
    va_start(ap, msg);
    vprintf(msg, ap);
    va_end(ap);
    printf("\n");
}
Esempio n. 21
0
static UA_Int32 sendCreateSession(UA_Int32 sock, UA_UInt32 channelId, UA_UInt32 tokenId, UA_UInt32 sequenceNumber,
                                  UA_UInt32 requestId, UA_String *endpointUrl) {
    UA_ByteString message;
	UA_ByteString_newMembers(&message, 65536);
	UA_UInt32 tmpChannelId = channelId;
	size_t offset = 0;

	UA_TcpMessageHeader msghdr;
	msghdr.messageTypeAndFinal = UA_MESSAGETYPEANDFINAL_MSGF;

	UA_NodeId type;
	type.identifier.numeric = 461;
	type.identifierType = UA_NODEIDTYPE_NUMERIC;
	type.namespaceIndex = 0;

	UA_CreateSessionRequest rq;
    UA_CreateSessionRequest_init(&rq);
	rq.requestHeader.requestHandle = 1;
	rq.requestHeader.timestamp = UA_DateTime_now();
	rq.requestHeader.timeoutHint = 10000;
	rq.requestHeader.authenticationToken.identifier.numeric = 10;
	rq.requestHeader.authenticationToken.identifierType = UA_NODEIDTYPE_NUMERIC;
	rq.requestHeader.authenticationToken.namespaceIndex = 10;
	UA_String_copy(endpointUrl, &rq.endpointUrl);
	UA_String_copycstring("mysession", &rq.sessionName);
	UA_String_copycstring("abcd", &rq.clientCertificate);
	UA_ByteString_newMembers(&rq.clientNonce, 1);
	rq.clientNonce.data[0] = 0;
	rq.requestedSessionTimeout = 1200000;
	rq.maxResponseMessageSize = UA_INT32_MAX;

	msghdr.messageSize = 16 + UA_TcpMessageHeader_calcSizeBinary(&msghdr) + UA_NodeId_calcSizeBinary(&type) +
                         UA_CreateSessionRequest_calcSizeBinary(&rq);

	UA_TcpMessageHeader_encodeBinary(&msghdr, &message, &offset);
	UA_UInt32_encodeBinary(&tmpChannelId, &message, &offset);
	UA_UInt32_encodeBinary(&tokenId, &message, &offset);
	UA_UInt32_encodeBinary(&sequenceNumber, &message, &offset);
	UA_UInt32_encodeBinary(&requestId, &message, &offset);
	UA_NodeId_encodeBinary(&type, &message, &offset);
	UA_CreateSessionRequest_encodeBinary(&rq, &message, &offset);

	UA_Int32 sendret = send(sock, message.data, offset, 0);
	UA_ByteString_deleteMembers(&message);
	UA_CreateSessionRequest_deleteMembers(&rq);
	if (sendret < 0) {
		printf("send opensecurechannel failed");
		return 1;
	}
	return 0;
}
Esempio n. 22
0
END_TEST

START_TEST(decodeShallFailWithTruncatedBufferButSurvive) {
    //Skip test for void*
    if (_i == UA_TYPES_DISCOVERYCONFIGURATION ||
            _i == UA_TYPES_FILTEROPERAND ||
            _i == UA_TYPES_MONITORINGFILTER ||
            _i == UA_TYPES_UNION ||
            _i == UA_TYPES_HISTORYREADDETAILS ||
            _i == UA_TYPES_NOTIFICATIONDATA ||
            _i == UA_TYPES_MONITORINGFILTERRESULT)
        return;
    // given
    UA_ByteString msg1;
    void *obj1 = UA_new(&UA_TYPES[_i]);
    UA_StatusCode retval = UA_ByteString_allocBuffer(&msg1, 65000); // fixed buf size
    UA_Byte *pos = msg1.data;
    const UA_Byte *end = &msg1.data[msg1.length];
    retval |= UA_encodeBinary(obj1, &UA_TYPES[_i], &pos, &end, NULL, NULL);
    UA_delete(obj1, &UA_TYPES[_i]);
    if(retval != UA_STATUSCODE_GOOD) {
        UA_ByteString_deleteMembers(&msg1);
        return; // e.g. variants cannot be encoded after an init without failing (no datatype set)
    }

    size_t half = (uintptr_t)(pos - msg1.data) / 2;
    msg1.length = half;

    // when
    void *obj2 = UA_new(&UA_TYPES[_i]);
    size_t offset = 0;
    retval = UA_decodeBinary(&msg1, &offset, obj2, &UA_TYPES[_i], 0, NULL);
    ck_assert_int_ne(retval, UA_STATUSCODE_GOOD);
    UA_delete(obj2, &UA_TYPES[_i]);
    UA_ByteString_deleteMembers(&msg1);
}
Esempio n. 23
0
END_TEST

START_TEST(encodeShallYieldDecode) {
	// given
	UA_ByteString msg1, msg2;
	UA_UInt32     pos = 0;
	void *obj1 = UA_TYPES[_i].new();
	UA_ByteString_newMembers(&msg1, UA_TYPES[_i].encodings[UA_ENCODING_BINARY].calcSize(obj1));
	UA_StatusCode retval = UA_TYPES[_i].encodings[UA_ENCODING_BINARY].encode(obj1, &msg1, &pos);
	if(retval != UA_STATUSCODE_GOOD) {
		// this happens, e.g. when we encode a variant (with UA_TYPES[UA_INVALIDTYPE] in the vtable)
		UA_TYPES[_i].delete(obj1);
		UA_ByteString_deleteMembers(&msg1);
		return;	
	}
Esempio n. 24
0
static UA_Int32 closeSession(ConnectionInfo *connectionInfo) {
	size_t offset = 0;

	UA_ByteString message;
	UA_ByteString_newMembers(&message, 65536);

	UA_CloseSessionRequest rq;
    UA_CloseSessionRequest_init(&rq);

	rq.requestHeader.requestHandle = 1;
	rq.requestHeader.timestamp = UA_DateTime_now();
	rq.requestHeader.timeoutHint = 10000;
	rq.requestHeader.authenticationToken.identifier.numeric = 10;
	rq.requestHeader.authenticationToken.identifierType = UA_NODEIDTYPE_NUMERIC;
	rq.requestHeader.authenticationToken.namespaceIndex = 10;
    rq.deleteSubscriptions = UA_TRUE;

	UA_TcpMessageHeader msghdr;
	msghdr.messageTypeAndFinal = UA_MESSAGETYPEANDFINAL_MSGF;

	UA_NodeId type;
	type.identifier.numeric = 473;
	type.identifierType = UA_NODEIDTYPE_NUMERIC;
	type.namespaceIndex = 0;

	msghdr.messageSize = 16 + UA_TcpMessageHeader_calcSizeBinary(&msghdr) + UA_NodeId_calcSizeBinary(&type) +
                         UA_CloseSessionRequest_calcSizeBinary(&rq);

	UA_TcpMessageHeader_encodeBinary(&msghdr, &message, &offset);
	UA_UInt32_encodeBinary(&connectionInfo->channelId, &message, &offset);
	UA_UInt32_encodeBinary(&connectionInfo->tokenId, &message, &offset);
	UA_UInt32_encodeBinary(&connectionInfo->sequenceHdr.sequenceNumber, &message, &offset);
	UA_UInt32_encodeBinary(&connectionInfo->sequenceHdr.requestId, &message, &offset);
	UA_NodeId_encodeBinary(&type, &message, &offset);
	UA_CloseSessionRequest_encodeBinary(&rq, &message, &offset);

	UA_Int32 sendret = send(connectionInfo->socket, message.data, offset, 0);
	UA_ByteString_deleteMembers(&message);
	UA_CloseSessionRequest_deleteMembers(&rq);
	if(sendret < 0) {
		printf("send closesessionrequest failed");
		return 1;
	}

    return 0;
}
Esempio n. 25
0
/**
 * Called in processCompleteChunk for every complete chunk which is received by the server.
 *
 * It will first try to decode the message to get the name of the called service.
 * When we have a name the message is dumped as binary to that file.
 * If the file already exists a new file will be created with a counter at the end.
 */
void
UA_debug_dumpCompleteChunk(UA_Server *const server, UA_Connection *const connection,
                           UA_ByteString *messageBuffer) {
    struct UA_dump_filename dump_filename;
    dump_filename.messageType = NULL;
    dump_filename.serviceName[0] = 0;

    if(!connection->channel) {
        UA_debug_dump_setName_withoutChannel(server, connection, messageBuffer, &dump_filename);
    } else {
        UA_SecureChannel dummy = *connection->channel;
        TAILQ_INIT(&dummy.messages);
        UA_ByteString messageBufferCopy;
        UA_ByteString_copy(messageBuffer, &messageBufferCopy);
        UA_SecureChannel_decryptAddChunk(&dummy, &messageBufferCopy, UA_TRUE);
        UA_SecureChannel_processCompleteMessages(&dummy, &dump_filename, UA_debug_dump_setName_withChannel);
        UA_SecureChannel_deleteMessages(&dummy);
        UA_ByteString_deleteMembers(&messageBufferCopy);
    }

    char fileName[250];
    snprintf(fileName, 255, "%s/%05d_%s%s", UA_CORPUS_OUTPUT_DIR, ++UA_dump_chunkCount,
             dump_filename.messageType ? dump_filename.messageType : "", dump_filename.serviceName);

    char dumpOutputFile[255];
    snprintf(dumpOutputFile, 255, "%s.bin", fileName);
    // check if file exists and if yes create a counting filename to avoid overwriting
    unsigned cnt = 1;
    while ( access( dumpOutputFile, F_OK ) != -1 ) {
        snprintf(dumpOutputFile, 255, "%s_%d.bin", fileName, cnt);
        cnt++;
    }

    UA_LOG_INFO(&server->config.logger, UA_LOGCATEGORY_SERVER,
                "Dumping package %s", dumpOutputFile);

    FILE *write_ptr = fopen(dumpOutputFile, "ab");
    fwrite(messageBuffer->data, messageBuffer->length, 1, write_ptr); // write 10 bytes from our buffer
    // add the available memory size. See the UA_DUMP_RAM_SIZE define for more info.
    uint32_t ramSize = UA_DUMP_RAM_SIZE;
    fwrite(&ramSize, sizeof(ramSize), 1, write_ptr);
    fclose(write_ptr);
}
Esempio n. 26
0
static UA_StatusCode
requestSession(UA_Client *client, UA_UInt32 *requestId) {
    UA_CreateSessionRequest request;
    UA_CreateSessionRequest_init(&request);

    UA_StatusCode retval = UA_STATUSCODE_GOOD;
    if(client->channel.securityMode == UA_MESSAGESECURITYMODE_SIGN ||
       client->channel.securityMode == UA_MESSAGESECURITYMODE_SIGNANDENCRYPT) {
        if(client->channel.localNonce.length != UA_SESSION_LOCALNONCELENGTH) {
           UA_ByteString_deleteMembers(&client->channel.localNonce);
            retval = UA_ByteString_allocBuffer(&client->channel.localNonce,
                                               UA_SESSION_LOCALNONCELENGTH);
            if(retval != UA_STATUSCODE_GOOD)
                return retval;
        }

        retval = client->channel.securityPolicy->symmetricModule.
                 generateNonce(client->channel.securityPolicy, &client->channel.localNonce);
        if(retval != UA_STATUSCODE_GOOD)
            return retval;
    }

    request.requestHeader.requestHandle = ++client->requestHandle;
    request.requestHeader.timestamp = UA_DateTime_now();
    request.requestHeader.timeoutHint = 10000;
    UA_ByteString_copy(&client->channel.localNonce, &request.clientNonce);
    request.requestedSessionTimeout = client->config.requestedSessionTimeout;
    request.maxResponseMessageSize = UA_INT32_MAX;
    UA_String_copy(&client->config.endpoint.endpointUrl, &request.endpointUrl);

    UA_ApplicationDescription_copy(&client->config.clientDescription,
                                   &request.clientDescription);

    retval = UA_Client_sendAsyncRequest (
            client, &request, &UA_TYPES[UA_TYPES_CREATESESSIONREQUEST],
            (UA_ClientAsyncServiceCallback) responseSessionCallback,
            &UA_TYPES[UA_TYPES_CREATESESSIONRESPONSE], NULL, requestId);
    UA_CreateSessionRequest_deleteMembers(&request);
    client->connectStatus = retval;
    return client->connectStatus;
}
Esempio n. 27
0
int main(int argc, char** argv) {
	signal(SIGINT, stopHandler); /* catches ctrl-c */
#ifdef UA_MULTITHREADING
	pthread_rwlock_init(&writeLock, 0);
#endif

	UA_Server *server = UA_Server_new(UA_ServerConfig_standard);
	logger = Logger_Stdout_new();
	UA_Server_setLogger(server, logger);
    UA_ByteString certificate = loadCertificate();
    UA_Server_setServerCertificate(server, certificate);
    UA_ByteString_deleteMembers(&certificate);
	UA_Server_addNetworkLayer(server, ServerNetworkLayerTCP_new(UA_ConnectionConfig_standard, 16664));

	// add node with the datetime data source
	UA_DataSource dateDataSource = (UA_DataSource)
        {.handle = NULL,
		.read = readTimeData,
		.release = releaseTimeData,
		.write = NULL};
	const UA_QualifiedName dateName = UA_QUALIFIEDNAME(1, "current time");
	UA_Server_addDataSourceVariableNode(server, dateDataSource, dateName, UA_NODEID_NULL,
                                        UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER),
                                        UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES));

	//cpu temperature monitoring for linux machines
	if((temperatureFile = fopen("/sys/class/thermal/thermal_zone0/temp", "r"))){
		// add node with the data source
		UA_DataSource temperatureDataSource = (UA_DataSource)
    	    {.handle = NULL,
			.read = readTemperature,
			.release = releaseTemperature,
			.write = NULL};
		const UA_QualifiedName tempName = UA_QUALIFIEDNAME(1, "cpu temperature");
		UA_Server_addDataSourceVariableNode(server, temperatureDataSource, tempName, UA_NODEID_NULL,
                                            UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER),
                                            UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES));
	}
Esempio n. 28
0
static UA_ByteString loadCertificate(void) {
    UA_ByteString certificate = UA_STRING_NULL;
    FILE *fp = NULL;
    if(!(fp=fopen("server_cert.der", "rb"))) {
        errno = 0; // we read errno also from the tcp layer...
        return certificate;
    }

    fseek(fp, 0, SEEK_END);
    certificate.length = (size_t)ftell(fp);
    certificate.data = malloc(certificate.length*sizeof(UA_Byte));
    if(!certificate.data){
        fclose(fp);
        return certificate;
    }

    fseek(fp, 0, SEEK_SET);
    if(fread(certificate.data, sizeof(UA_Byte), certificate.length, fp) < (size_t)certificate.length)
        UA_ByteString_deleteMembers(&certificate); // error reading the cert
    fclose(fp);

    return certificate;
}
Esempio n. 29
0
END_TEST

#define RANDOM_TESTS 1000

START_TEST(decodeScalarBasicTypeFromRandomBufferShallSucceed) {
    // given
    void *obj1 = NULL;
    UA_ByteString msg1;
    UA_Int32 retval = UA_STATUSCODE_GOOD;
    UA_Int32 buflen = 256;
    retval = UA_ByteString_allocBuffer(&msg1, buflen); // fixed size
#ifdef _WIN32
    srand(42);
#else
    srandom(42);
#endif
    for(int n = 0;n < RANDOM_TESTS;n++) {
        for(UA_Int32 i = 0;i < buflen;i++) {
#ifdef _WIN32
            UA_UInt32 rnd;
            rnd = rand();
            msg1.data[i] = rnd;
#else
            msg1.data[i] = (UA_Byte)random();  // when
#endif
        }
        size_t pos = 0;
        obj1 = UA_new(&UA_TYPES[_i]);
        retval |= UA_decodeBinary(&msg1, &pos, obj1, &UA_TYPES[_i], 0, NULL);
        //then
        ck_assert_msg(retval == UA_STATUSCODE_GOOD, "Decoding %d from random buffer", UA_TYPES[_i].typeId.identifier.numeric);
        // finally
        UA_delete(obj1, &UA_TYPES[_i]);
    }
    UA_ByteString_deleteMembers(&msg1);
}
Esempio n. 30
0
static UA_Int32 closeSecureChannel(ConnectionInfo *connectionInfo) {
	size_t offset = 0;

	UA_ByteString message;
	UA_ByteString_newMembers(&message, 65536);

	UA_CloseSecureChannelRequest rq;
    UA_CloseSecureChannelRequest_init(&rq);

	rq.requestHeader.requestHandle = 1;
	rq.requestHeader.timestamp = UA_DateTime_now();
	rq.requestHeader.timeoutHint = 10000;
	rq.requestHeader.authenticationToken.identifier.numeric = 10;
	rq.requestHeader.authenticationToken.identifierType = UA_NODEIDTYPE_NUMERIC;
	rq.requestHeader.authenticationToken.namespaceIndex = 10;

	UA_TcpMessageHeader msghdr;
	msghdr.messageTypeAndFinal = UA_MESSAGETYPEANDFINAL_CLOF;

	msghdr.messageSize = 4 + UA_TcpMessageHeader_calcSizeBinary(&msghdr) +
                         UA_CloseSecureChannelRequest_calcSizeBinary(&rq);

	UA_TcpMessageHeader_encodeBinary(&msghdr, &message, &offset);
	UA_UInt32_encodeBinary(&connectionInfo->channelId, &message, &offset);
	UA_CloseSecureChannelRequest_encodeBinary(&rq, &message, &offset);

	UA_Int32 sendret = send(connectionInfo->socket, message.data, offset, 0);
	UA_ByteString_deleteMembers(&message);
	UA_CloseSecureChannelRequest_deleteMembers(&rq);
	if(sendret < 0) {
		printf("send CloseSecureChannelRequest failed");
		return 1;
	}

    return 0;
}