Пример #1
0
END_TEST

START_TEST(test_service_present)
{
    qeo_mgmt_url_ctx_t ctx = NULL;
    char* message = NULL;
    const char *url = NULL;
    qeo_mgmt_client_ctx_t mg_ctx;
    fail_if(s_ctx == NULL);
    message = get_services_messages(0);
    qeo_log_i("Testing message <%s>", message);
    curl_easy_mock_return_data(message, false);
    ctx = qeo_mgmt_url_init(s_ctx);
    mg_ctx.url_ctx = ctx;
    mg_ctx.curl_ctx = s_ctx;
    fail_if(ctx == NULL );
    fail_unless(qeo_mgmt_url_get(&mg_ctx, mock_qeo_mgmt_client_ssl_ctx_cb, NULL, "blabla", QMGMT_URL_ENROLL_DEVICE, &url) == QMGMTCLIENT_OK);
    fail_unless(qeo_mgmt_url_get(&mg_ctx, mock_qeo_mgmt_client_ssl_ctx_cb, NULL, "blabla", QMGMT_URL_CHECK_POLICY, &url) == QMGMTCLIENT_OK);
    fail_unless(qeo_mgmt_url_get(&mg_ctx, mock_qeo_mgmt_client_ssl_ctx_cb, NULL, "blabla", QMGMT_URL_GET_POLICY, &url) == QMGMTCLIENT_OK);
    fail_unless(qeo_mgmt_url_get(&mg_ctx, mock_qeo_mgmt_client_ssl_ctx_cb, NULL, "blabla", QMGMT_URL_REGISTER_FORWARDER, &url) == QMGMTCLIENT_OK);
    qeo_mgmt_url_cleanup(ctx);

    message = get_services_messages(1);
    qeo_log_i("Testing message <%s>", message);
    curl_easy_mock_return_data(message, false);
    ctx = qeo_mgmt_url_init(s_ctx);
    mg_ctx.url_ctx = ctx;
    fail_if(ctx == NULL );
    fail_unless(qeo_mgmt_url_get(&mg_ctx, mock_qeo_mgmt_client_ssl_ctx_cb, NULL, "blabla", QMGMT_URL_ENROLL_DEVICE, &url) == QMGMTCLIENT_OK);
    fail_unless(qeo_mgmt_url_get(&mg_ctx, mock_qeo_mgmt_client_ssl_ctx_cb, NULL, "blabla", QMGMT_URL_CHECK_POLICY, &url) == QMGMTCLIENT_EBADSERVICE);
    fail_unless(qeo_mgmt_url_get(&mg_ctx, mock_qeo_mgmt_client_ssl_ctx_cb, NULL, "blabla", QMGMT_URL_GET_POLICY, &url) == QMGMTCLIENT_OK);
    fail_unless(qeo_mgmt_url_get(&mg_ctx, mock_qeo_mgmt_client_ssl_ctx_cb, NULL, "blabla", QMGMT_URL_REGISTER_FORWARDER, &url) == QMGMTCLIENT_OK);
    qeo_mgmt_url_cleanup(ctx);
}
Пример #2
0
static void my_result_cb(qeo_mgmt_client_retcode_t result, void *cookie){
    qeo_log_i("my_result_cb");
    s_result = result;
    pthread_mutex_lock(&s_mutex);
    pthread_cond_broadcast(&s_cond);
    pthread_mutex_unlock(&s_mutex);
}
Пример #3
0
void fwd_destroy(qeo_factory_t *factory)
{
    lock(&factory->mutex);
    if (true == factory->fwd.rqst_pending) {
        /* Wait untill the fwd request is finished before continuing. */
        qeo_log_i("waiting for the fwd request to finish.");
        pthread_cond_wait(&factory->fwd.wait_rqst_finished, &factory->mutex);
    }
    unlock(&factory->mutex);
    if (factory->flags.is_forwarder) {
        fwd_server_unregister(factory);
        if (FWD_STATE_ENABLED == factory->fwd.u.server.state) {
            if (QEO_OK != fwd_server_instance_remove(factory)) {
                qeo_log_e("failed to remove instance from forwarder topic");
            }
        }
        if (NULL != factory->fwd.u.server.writer) {
            qeocore_writer_close(factory->fwd.u.server.writer);
        }
    }
    if (NULL != factory->fwd.reader) {
        qeocore_reader_close(factory->fwd.reader);
    }
    if (NULL != factory->fwd.timer) {
        DDS_Timer_delete(factory->fwd.timer);
    }
    pthread_cond_destroy(&factory->fwd.wait_rqst_finished);
    fwd_locator_destroy(factory);
}
Пример #4
0
static qeo_retcode_t fwd_server_unregister(qeo_factory_t *factory)
{
    qeo_retcode_t             rc = QEO_OK;

    if (!qeocore_parameter_get_number("FWD_DISABLE_LOCATION_SERVICE")) {
        qeo_security_hndl         qeo_sec = factory->qeo_sec;
        qeo_mgmt_client_retcode_t mgmt_rc = QMGMTCLIENT_EFAIL;
        qeo_mgmt_client_ctx_t     *mgmt_client_ctx = NULL;
        int                       nrOfLocators = 0;


        do {
            if (QEO_OK != (rc = qeo_security_get_mgmt_client_ctx(qeo_sec, &mgmt_client_ctx))) {
                qeo_log_e("unregister_forwarder get security mgmt client failed (rc=%d)", rc);
                break;
            }

            /* Now register the forwarder. */
            qeo_log_i("unregister the forwarder");
            if ((mgmt_rc = qeo_mgmt_client_register_forwarder(mgmt_client_ctx,
                                                              factory->qeo_id.url,
                                                              NULL,
                                                              nrOfLocators,
                                                              ssl_ctx_cb,
                                                              qeo_sec)) != QMGMTCLIENT_OK) {
                qeo_log_e("unregister forwarder failed (rc=%d)", mgmt_rc);
                rc = QEO_EFAIL;
                break;
            }

        } while (0);
    }
    return rc;
}
Пример #5
0
/**
 * This function returns the platform specific storage location as a path.
 * If the path does not exist, it will create one with 0700 mode.
 * The caller is responsible for freeing the string returned in *path.
 * */
const char *get_default_device_storage_path(void)
{
    if (NULL != _default_storage_path) {
        return _default_storage_path;
    }

    do {
        _default_storage_path = get_qeo_dir();
        if (_default_storage_path == NULL){
            qeo_log_e("Could not get qeo storage dir");
            break;
        }

        if (access(_default_storage_path, R_OK | W_OK) != 0) {
            qeo_log_i("Creating storage directory (%s)", strerror(errno));
            if (mkdir(_default_storage_path, 0700) != 0) {
                qeo_log_e("Failed to create storage directory %s", _default_storage_path);
                break;
            }
        }

    } while(0);

    return _default_storage_path;
}
Пример #6
0
static qeo_retcode_t fwd_server_register(qeo_factory_t *factory)
{
    qeo_retcode_t             rc = QEO_OK;

    if (!qeocore_parameter_get_number("FWD_DISABLE_LOCATION_SERVICE")) {
        qeo_security_hndl         qeo_sec = factory->qeo_sec;
        qeo_mgmt_client_retcode_t mgmt_rc = QMGMTCLIENT_EFAIL;
        qeo_mgmt_client_ctx_t     *mgmt_client_ctx = NULL;
        qeo_mgmt_client_locator_t locator={QMGMT_LOCATORTYPE_TCPV4, factory->fwd.locator->address, factory->fwd.locator->port};
        int                       nrOfLocators = 1;

        do {
            if ((rc = qeo_security_get_mgmt_client_ctx(qeo_sec, &mgmt_client_ctx)) != QEO_OK) {
                qeo_log_e("register_forwarder get security mgmt client failed (rc=%d)", rc);
                break;
            }
            /* Now register the forwarder. */
            qeo_log_i("register the forwarder with locator address %s:port %d\n", locator.address, locator.port);
            if ((mgmt_rc = qeo_mgmt_client_register_forwarder(mgmt_client_ctx,
                                                              factory->qeo_id.url,
                                                              &locator,
                                                              nrOfLocators,
                                                              ssl_ctx_cb,
                                                              qeo_sec)) != QMGMTCLIENT_OK) {
                qeo_log_e("register forwarder failed (rc=%d)", mgmt_rc);
                rc = QEO_EFAIL;
                break;
            }

        } while (0);
    }
    return rc;
}
Пример #7
0
static char* get_qeo_dir(void)
{
    char *qeo_dir = NULL;
    const struct passwd *pwd;

    do {
        qeo_dir = qeo_strdup_ret(getenv("QEO_STORAGE_DIR"));
        if (qeo_dir != NULL){
            break;
        }
        
        pwd = getpwuid(getuid());
        if (pwd == NULL || pwd->pw_dir == NULL) {
            qeo_log_e("Failed in getting the home directory");
            break;
        }

        if (asprintf(&qeo_dir, "%s/%s", pwd->pw_dir, LINUX_STORAGE_DIR) == -1){
            qeo_log_e("No mem");
            break;
        }

    } while(0);

    qeo_log_i("Qeo directory is %s", qeo_dir);

    return (char*)qeo_dir;
}
Пример #8
0
void qmc_clean_ongoing_thread(qeo_mgmt_client_ctx_t *ctx){
    if (ctx->join_thread == true){
        qeo_log_i("Waiting for worker thread to shut down");
        if (pthread_join(ctx->worker_thread, NULL) != 0){
            qeo_log_w("Failed to join worker thread");
        }
        ctx->join_thread = false;
    }
}
Пример #9
0
static qeo_retcode_t client_start_timer(qeo_factory_t *factory, bool reset)
{
    qeo_retcode_t rc = QEO_OK;

    if (reset) {
        factory->fwd.timeout = qeocore_parameter_get_number("FWD_LOC_SRV_MIN_TIMEOUT");
    }
    qeo_log_i("retry contacting location service after %ds", factory->fwd.timeout/1000);
    rc = ddsrc_to_qeorc(DDS_Timer_start(factory->fwd.timer, factory->fwd.timeout, (uintptr_t)factory,
                                        fwd_client_discovery_timeout));
    return rc;
}
Пример #10
0
static qeo_platform_device_id qeo_get_device_uuid(const char* platform_storage_filepath, const char* generator_path)
{
    FILE* file = NULL;
    char* result_uuid = NULL;

    do {
        file = fopen(platform_storage_filepath, "r");
        if (file != NULL ) {
            fclose(file);
            qeo_log_i("Fetching the existing UUID");
            result_uuid = get_uuid(platform_storage_filepath);
            break;
        }

        qeo_log_i("Creating a new UUID, because %s not found", platform_storage_filepath);

        result_uuid = get_uuid(generator_path);
        if (NULL == result_uuid) {
            qeo_log_e("Failed to get UUID");
            break;
        }

        FILE* fp = fopen(platform_storage_filepath, "w");

        if (fp != NULL ) {
            qeo_log_i("Writing the new UUID");
            fprintf(fp, "%s", result_uuid);
            fclose(fp);
        }
        else {
            qeo_log_e("Failed to open %s", platform_storage_filepath);
        }
    } while (0);

    qeo_platform_device_id res = char_to_struct(result_uuid);

    free(result_uuid);

    return res;
}
Пример #11
0
/** This callback will be called for each forwarder in the list received from the management client. */
qeo_mgmt_client_retcode_t forwarder_cb(qeo_mgmt_client_forwarder_t* forwarder, void *cookie)
{
    qeo_factory_t             *factory = (qeo_factory_t *) cookie;
    qeo_mgmt_client_locator_t *locator = NULL;
    int                       i = 0;

    /* Get the IP address and port from the qeo_mgmt_client_forwarder_t info. */
    if ((forwarder != NULL) && (forwarder->nrOfLocators > 0)) {
        qeo_log_d("received %d locators", forwarder->nrOfLocators);
        for (i = 0, locator = forwarder->locators; i < forwarder->nrOfLocators; i++, locator++) {
            qeo_log_d("locator %d", i);
            if (locator != NULL) {
                qeo_log_i("valid locator: %s:%d", locator->address, locator->port);
                if (factory->fwd.u.client.state == FWD_CLIENT_STATE_WAIT) {
                    qeo_log_i("Going to use this forwarder");
                    flags_t flags = { .forwarding_enabled = true };
                    client_state_machine_eval(factory, CLIENT_EVENT_LOC_SRV_DATA_RECEIVED, locator, forwarder->deviceID, flags);
                }
                else {
                    /* TODO: at the moment only one forwarder is taken into account. */
                    qeo_log_i("Going to ignore this forwarder as not the first in the list");
                }
                break;
            }
Пример #12
0
/** This callback will be called for each forwarder in the list received from the management client. */
qeo_mgmt_client_retcode_t forwarder_cb(qeo_mgmt_client_forwarder_t* forwarder, void *cookie)
{
    qeo_factory_t             *factory = (qeo_factory_t *) cookie;
    qeo_mgmt_client_locator_t *locator = NULL;
    int                       i = 0;

    /* Get the IP address and port from the qeo_mgmt_client_forwarder_t info. */
    if ((forwarder != NULL) && (forwarder->nrOfLocators > 0)) {
        qeo_log_i("received %d locators", forwarder->nrOfLocators);
        for (i = 0, locator = forwarder->locators; i < forwarder->nrOfLocators; i++, locator++) {
            qeo_log_i("locator %d", i);
            if (locator != NULL) {
                qeo_log_i("valid locator");
                /* TODO: at the moment only one forwarder is taken into account. */
                if (factory->fwd.locator == NULL) {
                    client_state_machine_eval(factory, CLIENT_EVENT_LOC_SRV_DATA_RECEIVED, locator, forwarder->deviceID);
                }
            }
        }
        qeo_mgmt_client_free_forwarder(forwarder);
    }

    return QMGMTCLIENT_OK;
}
Пример #13
0
static void list_forwarders_and_expect_error(qeo_mgmt_client_retcode_t expected, char* message, int line){
    _forwarder_cb_helper helper = {0};
    int i = 0;

    qeo_log_i("Testing message <%s> at line <%d>", message, line);
    curl_easy_mock_clean();
    curl_easy_mock_return_data(message, true);
    curl_easy_mock_ignore_and_return(CURLE_OK, true, CURLE_OK, CURLE_OK, CURLE_OK);
    ck_assert_int_eq(qeo_mgmt_client_get_forwarders_sync(s_ctx, TEST_URL, my_fwd_cb, (void*)&helper, my_ssl_cb, (void*)COOKIE_MAGIC_NUMBER), expected);

    for (i = 0; i < helper.nrForwarders; ++i) {
        qeo_mgmt_client_free_forwarder(helper.forwarders[i]);
    }
    free(helper.forwarders);
}
Пример #14
0
static void list_forwarders_and_expect_async(int nrForwarders, char* message, int line){
    _forwarder_cb_helper helper = {0};
    int i = 0;

    qeo_log_i("Testing message <%s> at line <%d> using async api", message, line);
    curl_easy_mock_clean();
    curl_easy_mock_return_data(message, true);
    curl_easy_mock_ignore_and_return(CURLE_OK, true, CURLE_OK, CURLE_OK, CURLE_OK);
    ck_assert_int_eq(qeo_mgmt_client_get_forwarders(s_ctx, TEST_URL, my_fwd_cb, my_result_cb, (void*)&helper, my_ssl_cb, (void*)COOKIE_MAGIC_NUMBER), QMGMTCLIENT_OK);
    pthread_cond_wait(&s_cond, &s_mutex);

    ck_assert_int_eq(helper.nrForwarders, nrForwarders);

    for (i = 0; i < helper.nrForwarders; ++i) {
        qeo_mgmt_client_free_forwarder(helper.forwarders[i]);
    }
    free(helper.forwarders);
}
Пример #15
0
qeo_retcode_t fwd_init_post_auth(qeo_factory_t *factory)
{
    qeo_retcode_t rc = QEO_EFAIL;
    qeocore_type_t *type = NULL;

    /* this will eventually also take the factory lock, so postponing our lock */
    type = qeocore_type_register_tsm(factory, org_qeo_system_Forwarder_type, org_qeo_system_Forwarder_type->name);
    if (NULL != type) {
        lock(&factory->mutex);
        if (factory->flags.is_forwarder) {
            factory->fwd.listener.on_data = fwd_server_on_data;
            factory->fwd.reader = qeocore_reader_open(factory, type, org_qeo_system_Forwarder_type->name,
                                                      QEOCORE_EFLAG_STATE_UPDATE, &factory->fwd.listener, NULL);
            if (NULL != factory->fwd.reader) {
                factory->fwd.u.server.writer = qeocore_writer_open(factory, type, org_qeo_system_Forwarder_type->name,
                                                                   QEOCORE_EFLAG_STATE_DATA | QEOCORE_EFLAG_ENABLE,
                                                                   NULL, NULL);
                if (NULL != factory->fwd.u.server.writer) {
                    factory->fwd.u.server.state = FWD_STATE_INIT;
                    rc = fwd_server_state_machine_eval_ul(factory, -1, false, false);
                }
            }
        } else {
            factory->fwd.listener.on_data = fwd_client_on_data;
            factory->fwd.listener.userdata = (uintptr_t)factory;
            factory->fwd.reader = qeocore_reader_open(factory, type, org_qeo_system_Forwarder_type->name,
                                                      QEOCORE_EFLAG_STATE_DATA, &factory->fwd.listener, NULL);
            /* note: reader construction failure is not fatal */
            if (qeocore_parameter_get_number("FWD_DISABLE_FORWARDING")) {
                qeo_log_i("Disable forwarding");
                factory->fwd.u.client.state = FWD_CLIENT_STATE_READY;
            }
            else {
                factory->fwd.u.client.state = FWD_CLIENT_STATE_INIT;
                client_state_machine_eval_ul(factory, CLIENT_EVENT_START, NULL, -1);
            }
            rc = QEO_OK;
        }
        unlock(&factory->mutex);
        qeocore_type_free(type);
    }
    return rc;
}
Пример #16
0
static qeo_retcode_t fwd_get_list(qeo_factory_t *factory)
{
    qeo_retcode_t             rc = QEO_OK;

    if (!qeocore_parameter_get_number("FWD_DISABLE_LOCATION_SERVICE")) {
        qeo_security_hndl         qeo_sec = factory->qeo_sec;
        qeo_mgmt_client_retcode_t mgmt_rc = QMGMTCLIENT_EFAIL;
        qeo_mgmt_client_ctx_t     *mgmt_client_ctx = NULL;

        do {
            if ((rc = qeo_security_get_mgmt_client_ctx(qeo_sec, &mgmt_client_ctx)) != QEO_OK) {
                qeo_log_e("get_forwarders get security mgmt client failed (rc=%d)", rc);
                break;
            }
            /* Factory is already locked when calling this function. */
            if (true == factory->fwd.rqst_pending) {
                /* Just break, we will retry later. */
                qeo_log_i("no need to send request (previous fwd request still ongoing)");
                break;
            }

            /* Now get the list of forwarders. */
            factory->fwd.rqst_pending = true;
            mgmt_rc = qeo_mgmt_client_get_forwarders(mgmt_client_ctx, factory->qeo_id.url, forwarder_cb, result_cb,
                                                     factory, ssl_ctx_cb, qeo_sec);
            if (mgmt_rc == QMGMTCLIENT_OK) {
                qeo_log_d("get_forwarders succeeded");
            } else {
                factory->fwd.rqst_pending = false; /* result callback will not be called. */
                if ((mgmt_rc == QMGMTCLIENT_ESSL) || (mgmt_rc == QMGMTCLIENT_ENOTALLOWED)) {
                    qeo_log_e("get_forwarders failed (rc=%d), aborting", mgmt_rc);
                    rc = QEO_EFAIL;
                    break;
                }
                else {
                    qeo_log_e("get_forwarders failed (rc=%d), ignoring", mgmt_rc);
                }
            }

        } while (0);
    }
    return rc;
}
Пример #17
0
static int fwd_server_count_instances(const qeocore_reader_t *reader)
{
    qeo_retcode_t rc = QEO_OK;
    qeocore_filter_t filter = { 0 };
    qeocore_data_t *data;
    int cnt = 0;

    data = qeocore_reader_data_new(reader);
    if (NULL != data) {
        filter.instance_handle = DDS_HANDLE_NIL;
        while (1) {
            rc = qeocore_reader_read(reader, &filter, data);
            if (QEO_OK == rc) {
                filter.instance_handle = qeocore_data_get_instance_handle(data);
                cnt++;
#ifdef DEBUG
                {
                    const org_qeo_system_Forwarder_t *fwd = qeocore_data_get_data(data);

                    qeo_log_d("forwarder %d : id=%" PRIx64 " -> %s", cnt, fwd->deviceId,
                              (fwd->deviceId == reader->entity.factory->qeo_id.device_id ? "self" : "other"));
                }
#endif
                qeocore_data_reset(data);
                continue;
            }
            else if (QEO_ENODATA == rc) {
                rc = QEO_OK;
            }
            /* QEO_ENODATA or error */
            break;
        }
        qeocore_data_free(data);
    }
    if (QEO_OK == rc) {
        qeo_log_i("found %d local forwarders", cnt);
    }
    else {
        qeo_log_e("failed to read all local forwarders");
    }
    return cnt;
}
Пример #18
0
END_TEST

START_TEST(test_error_json)
{
    int id = 0;
    qeo_mgmt_url_ctx_t ctx = NULL;
    qeo_mgmt_client_ctx_t mg_ctx;
    char* message = NULL;
    const char *url = NULL;
    fail_if(s_ctx == NULL);
    while ((message = get_error_messages(id))){
        id++;
        qeo_log_i("Testing message <%s>", message);
        curl_easy_mock_return_data(message, false);
        ctx = qeo_mgmt_url_init(s_ctx);
        mg_ctx.url_ctx = ctx;
        mg_ctx.curl_ctx = s_ctx;
        fail_if(ctx == NULL);
        fail_if(qeo_mgmt_url_get(&mg_ctx, NULL, NULL, "blabla", QMGMT_URL_ENROLL_DEVICE, &url) == QMGMTCLIENT_OK);
        qeo_mgmt_url_cleanup(ctx);
    }
}
Пример #19
0
static void fwd_client_reconfig(qeo_factory_t *factory,
                                qeo_mgmt_client_locator_t *locator,
                                int64_t device_id)
{
    qeo_retcode_t rc = QEO_OK;

    /* Configure the locator in the factory */
    if (QEO_OK == fwd_locator_create(factory)) {
        if (QEO_OK == fwd_locator_update(factory, locator)) {
            char *tcp_server = calloc(1, strlen(locator->address) + 12);

            if (NULL != tcp_server) {
                snprintf(tcp_server, strlen(locator->address) + 12, "%s:%d", locator->address, locator->port);
                qeo_log_i("use forwarder %s", tcp_server);
                if ((rc = core_factory_set_tcp_server_no_lock(factory, tcp_server)) != QEO_OK) {
                    qeo_log_e("set tcp server failed (rc=%d)", rc);
                }
                free(tcp_server);
            }
        }
    }
    /* Configure the device ID in the factory */
    factory->fwd.device_id = device_id;
}
Пример #20
0
END_TEST

START_TEST(test_curl_upload_memory)
{
    qmgmt_curl_data_helper helper={0};
    size_t len = 0;
    helper.length = 0x8000;
    helper.data = calloc(helper.length, sizeof(char));
    char *data = calloc(helper.length, sizeof(char));
    memset(helper.data, 'a', helper.length-1);

    for (len = 0x1; len <= 0x4000; len*=2) {
        qeo_log_i("read buffer of size %d", len);
        ck_assert_int_eq(_read_from_memory_cb(data, sizeof(char), len, &helper), (sizeof(char) * len));
        ck_assert_int_eq(strlen(data), len);
    }
    ck_assert_int_eq(helper.offset, 0x7FFF);

    ck_assert_int_eq(_read_from_memory_cb(data, sizeof(char), 1, &helper), (sizeof(char) * 1));
    ck_assert_int_eq(helper.offset, 0x8000);

    ck_assert_int_eq(_read_from_memory_cb(data, sizeof(char), 1, &helper), 0);
    ck_assert_int_eq(helper.offset, 0x8000);
}
Пример #21
0
qeo_mgmt_client_retcode_t ssl_ctx_cb(SSL_CTX *ctx, void *cookie)
{
    qeo_mgmt_client_retcode_t client_ret  = QMGMTCLIENT_EFAIL;
    qeo_retcode_t             qeo_ret     = QEO_OK;
    qeo_security_hndl         qeo_sec   = (qeo_security_hndl)cookie;
    EVP_PKEY                  *key        = NULL;

    STACK_OF(X509) * certs = NULL;
    X509  *user_cert  = NULL;
    X509  *cert       = NULL;
    int   i           = 0;

    do {
        if (qeo_sec == NULL) {
            qeo_log_e("qeoSecPol == NULL");
            break;
        }

        qeo_ret = qeo_security_get_credentials(qeo_sec, &key, &certs);
        if (qeo_ret != QEO_OK) {
            qeo_log_e("failed to get credentials");
            break;
        }

        if (sk_X509_num(certs) <= 1) {
            qeo_log_e("not enough certificates in chain");
            break;
        }

        user_cert = sk_X509_value(certs, 0);
        if (user_cert == NULL) {
            qeo_log_e("user_cert == NULL");
            break;
        }

        if (!SSL_CTX_use_certificate(ctx, user_cert)) {
            qeo_log_e("SSL_CTX_use_certificate failed");
            break;
        }
        if (!SSL_CTX_use_PrivateKey(ctx, key)) {
            qeo_log_e("SSL_CTX_use_PrivateKey failed");
            break;
        }

        if (!SSL_CTX_check_private_key(ctx)) {
            qeo_log_e("SSL_CTX_check_private_key failed");
            break;
        }

        security_util_configure_ssl_ctx(ctx);
        for (i = 1; i < sk_X509_num(certs); i++) {
            qeo_log_i("add cert: %d", i);
            cert = sk_X509_value(certs, i);
            if (cert == NULL) {
                qeo_log_e("cert == NULL");
                break;
            }

            if (!X509_STORE_add_cert(SSL_CTX_get_cert_store(ctx), cert)) {
                dump_openssl_error_stack("X509_STORE_add_cert failed");
                break;
            }
        }

        client_ret = QMGMTCLIENT_OK;
    } while (0);

    return client_ret;
}
Пример #22
0
/**
 * \pre This should be called with the factory lock taken.
 *
 * param[in] num_local Number of local forwarders discovered, -1 if not counted
 * param[in] timeout   True if a timeout occurred
 */
static qeo_retcode_t fwd_server_state_machine_eval_ul(qeo_factory_t *factory,
                                                      int num_local,
                                                      bool timeout,
                                                      bool public_ip_available)
{
    qeo_retcode_t rc = QEO_OK;

    qeo_log_i("old state %s : local fwd count = %d, timeout = %s, public ip available = %s",
              server_state_to_str(factory->fwd.u.server.state), num_local, bool2str(timeout), bool2str(public_ip_available));
    switch (factory->fwd.u.server.state) {
        case FWD_STATE_INIT: {
            /* done with initialization */
            int timeout = qeocore_parameter_get_number("FWD_WAIT_LOCAL_FWD");

            rc = ddsrc_to_qeorc(DDS_Timer_start(factory->fwd.timer, timeout, (uintptr_t)factory,
                                                fwd_server_timeout));
            if (QEO_OK != rc) {
                qeo_log_e("failed to start forwarder timer");
                break;
            }
            rc = qeocore_reader_enable(factory->fwd.reader);
            if (QEO_OK != rc) {
                qeo_log_e("failed to enable forwarder reader");
                break;
            }
            factory->fwd.u.server.state = FWD_STATE_WAIT_LOCAL;
            break;
        }
        case FWD_STATE_WAIT_LOCAL:
            /* done waiting for local forwarder */
            if (timeout) {
                /* no local forwarders found, try start forwarding ourselves */
                factory->fwd.u.server.state = FWD_STATE_STARTING;
                unlock(&factory->mutex);
                factory->listener.on_fwdfactory_get_public_locator(factory);
                lock(&factory->mutex);
            }
            else if (num_local > 0) {
                /* local forwarder(s) available stop timer */
                DDS_Timer_stop(factory->fwd.timer);
                factory->fwd.u.server.state = FWD_STATE_DISABLED;
            }
            break;
        case FWD_STATE_STARTING:
            /* done waiting for publicly available locator */
            if (num_local > 0) {
                factory->fwd.u.server.state = FWD_STATE_DISABLED;
            }
            else if (public_ip_available) {
                if (QEO_OK == fwd_server_start_forwarding(factory)) {
                    factory->fwd.u.server.state = FWD_STATE_ENABLED;
                }
                else {
                    /* failed to start */
                    factory->fwd.u.server.state = FWD_STATE_DISABLED;
                }
            }
            break;
        case FWD_STATE_ENABLED:
            if (public_ip_available) {
                if (QEO_OK == fwd_server_start_forwarding(factory)) {
                    factory->fwd.u.server.state = FWD_STATE_ENABLED;
                }
                else {
                    /* failed to start */
                    factory->fwd.u.server.state = FWD_STATE_DISABLED;
                }
            }
            break;
        case FWD_STATE_DISABLED:
            if (0 == num_local) {
                /* no local forwarders anymore, try start forwarding ourselves */
                factory->fwd.u.server.state = FWD_STATE_STARTING;
                unlock(&factory->mutex);
                factory->listener.on_fwdfactory_get_public_locator(factory);
                lock(&factory->mutex);
            }
            break;
    }
    qeo_log_i("new state %s", server_state_to_str(factory->fwd.u.server.state));
    return rc;
}
Пример #23
0
/*
 * Wrap data in PKCS#7 envelopes and base64-encode the result.
 * Data is PKCS#10 request in PKCSReq, or pkcs7_issuer_and_subject
 * structure in GetCertInitial and PKCS7_ISSUER_AND_SERIAL in
 * GetCert and GETCrl.
 */
int pkcs7_wrap(struct scep *s, struct sscep_ctx *ctx, struct sscep_operation_info *op_info)
{
    BIO *databio = NULL;
    BIO *encbio = NULL;
    BIO *pkcs7bio = NULL;
    BIO *memorybio = NULL;
    BIO *outbio = NULL;
    unsigned char *buffer = NULL;
    int len = 0;
    STACK_OF(X509) *recipients = NULL;
    PKCS7 *p7enc = NULL;
    PKCS7_SIGNER_INFO *si;
    STACK_OF(X509_ATTRIBUTE) *attributes;
    X509 *signercert = NULL;
    EVP_PKEY *signerkey = NULL;
    int ret = SCEP_PKISTATUS_P7;
    char *payload = NULL;
    int payload_len;

    /* Create a new sender nonce for all messages
     * XXXXXXXXXXXXXX should it be per transaction? */
    s->sender_nonce_len = 16;
    free(s->sender_nonce);/* Clean up from previous runs */
    s->sender_nonce = (char *)malloc(s->sender_nonce_len * sizeof(char));
    RAND_bytes((unsigned char *) s->sender_nonce, s->sender_nonce_len);

    /* Prepare data payload */
    switch (s->request_type) {
        case SCEP_REQUEST_PKCSREQ:
            /*
             * Set printable message type
             * We set this later as an autheticated attribute
             * "messageType".
             */
            s->request_type_str = SCEP_REQUEST_PKCSREQ_STR;

            /* Signer cert */
            signercert = s->signercert;
            signerkey = s->signerkey;

            /* Create inner PKCS#7  */
            if (ctx->verbose){
                qeo_log_i("creating inner PKCS#7");
            }

            /* Read request in memory bio */
            databio = BIO_new(BIO_s_mem());
            if (i2d_X509_REQ_bio(databio, op_info->request) <= 0) {
                qeo_log_e("error writing certificate request in bio");
                goto error;
            }
            (void)BIO_flush(databio);
            break;

        case SCEP_REQUEST_GETCERTINIT:

            /* Set printable message type */
            s->request_type_str = SCEP_REQUEST_GETCERTINIT_STR;

            /* Signer cert */
            signercert = s->signercert;
            signerkey = s->signerkey;

            /* Create inner PKCS#7  */
            if (ctx->verbose){
                qeo_log_i("creating inner PKCS#7");
            }

            /* Read data in memory bio */
            databio = BIO_new(BIO_s_mem());
            if (i2d_pkcs7_issuer_and_subject_bio(databio, s->ias_getcertinit)) {
                qeo_log_e("error writing GetCertInitial data in bio");
                goto error;
            }
            (void)BIO_flush(databio);
            break;
    }
    /* Below this is the common code for all request_type */

    /* Read in the payload */
    payload_len = BIO_get_mem_data(databio, &payload);
    if (ctx->verbose){
        qeo_log_i("data payload size: %d bytes", payload_len);
    }

    /* Create encryption certificate stack */
    if ((recipients = sk_X509_new(NULL) ) == NULL) {
        qeo_log_e("error creating certificate stack");
        goto error;
    }
    if (sk_X509_push(recipients, op_info->racert) <= 0) {
        qeo_log_e("error adding recipient encryption certificate");
        goto error;
    }

    /* Create BIO for encryption  */
    if ((encbio = BIO_new_mem_buf(payload, payload_len)) == NULL ) {
        qeo_log_e("error creating data bio");
        goto error;
    }

    /* Encrypt */
    if (!(p7enc = PKCS7_encrypt(recipients, encbio, ctx->enc_alg, PKCS7_BINARY))) {
        qeo_log_e("request payload encrypt failed");
        goto error;
    }
    if (ctx->verbose){
        qeo_log_i("successfully encrypted payload");
    }

    /* Write encrypted data */
    memorybio = BIO_new(BIO_s_mem());
    if (i2d_PKCS7_bio(memorybio, p7enc) <= 0) {
        qeo_log_e("error writing encrypted data");
        goto error;
    }
    (void)BIO_flush(memorybio);
    BIO_set_flags(memorybio, BIO_FLAGS_MEM_RDONLY);
    len = BIO_get_mem_data(memorybio, &buffer);
    BIO_free(memorybio);
    memorybio=NULL;
    if (ctx->verbose){
        qeo_log_i("envelope size: %d bytes", len);
    }
    if (ctx->debug) {
        qeo_log_i("printing PEM fomatted PKCS#7");
        PEM_write_PKCS7(stdout, p7enc);
    }

    /* Create outer PKCS#7  */
    if (ctx->verbose){
        qeo_log_i("creating outer PKCS#7");
    }
    s->request_p7 = PKCS7_new();
    if (s->request_p7 == NULL ) {
        qeo_log_e("failed creating PKCS#7 for signing");
        goto error;
    }
    if (!PKCS7_set_type(s->request_p7, NID_pkcs7_signed)) {
        qeo_log_e("failed setting PKCS#7 type");
        goto error;
    }

    /* Add signer certificate  and signature */
    PKCS7_add_certificate(s->request_p7, signercert);
    if ((si = PKCS7_add_signature(s->request_p7, signercert, signerkey, ctx->sig_alg)) == NULL ) {
        qeo_log_e("error adding PKCS#7 signature");
        goto error;
    }
    if (ctx->verbose){
        qeo_log_i("signature added successfully");
    }

    /* Set signed attributes */
    if (ctx->verbose){
        qeo_log_i("adding signed attributes");
    }
    attributes = sk_X509_ATTRIBUTE_new_null();
    add_attribute_string(attributes, ctx->nid_transId, s->transaction_id, ctx);
    add_attribute_string(attributes, ctx->nid_messageType, s->request_type_str, ctx);
    add_attribute_octet(attributes, ctx->nid_senderNonce, s->sender_nonce, s->sender_nonce_len, ctx);
    PKCS7_set_signed_attributes(si, attributes);
    sk_X509_ATTRIBUTE_pop_free(attributes, X509_ATTRIBUTE_free);

    /* Add contentType */
    if (!PKCS7_add_signed_attribute(si, NID_pkcs9_contentType, V_ASN1_OBJECT, OBJ_nid2obj(NID_pkcs7_data))) {
        qeo_log_e("error adding NID_pkcs9_contentType");
        goto error;
    }

    /* Create new content */
    if (!PKCS7_content_new(s->request_p7, NID_pkcs7_data)) {
        qeo_log_e("failed setting PKCS#7 content type");
        goto error;
    }

    /* Write data  */
    pkcs7bio = PKCS7_dataInit(s->request_p7, NULL );
    if (pkcs7bio == NULL ) {
        qeo_log_e("error opening bio for writing PKCS#7 data");
        goto error;
    }
    if (len != BIO_write(pkcs7bio, buffer, len)) {
        qeo_log_e("error writing PKCS#7 data");
        goto error;
    }
    if (ctx->verbose){
        qeo_log_i("PKCS#7 data written successfully");
    }

    /* Finalize PKCS#7  */
    if (!PKCS7_dataFinal(s->request_p7, pkcs7bio)) {
        qeo_log_e("error finalizing outer PKCS#7");
        goto error;
    }
    if (ctx->debug) {
        qeo_log_i("printing PEM fomatted PKCS#7");
        PEM_write_PKCS7(stdout, s->request_p7);
    }

    /* base64-encode the data */
    if (ctx->verbose){
        qeo_log_i("applying base64 encoding");
    }

    /* Create base64 filtering bio */
    memorybio = BIO_new(BIO_s_mem());
    outbio = BIO_push(BIO_new(BIO_f_base64()), memorybio);

    /* Copy PKCS#7 */
    i2d_PKCS7_bio(outbio, s->request_p7);
    (void)BIO_flush(outbio);
    payload_len = BIO_get_mem_data(memorybio, &payload);
    s->request_payload = (char*) malloc(sizeof(char)*payload_len);
    if (!s->request_payload){
        goto error;
    }
    s->request_len = payload_len;
    memcpy(s->request_payload, payload, s->request_len);
    if (ctx->verbose){
        qeo_log_i("base64 encoded payload size: %d bytes", payload_len);
    }

    ret = 0;
error:
    BIO_free(databio);
    BIO_free(encbio);
    BIO_free_all(pkcs7bio);
    BIO_free(memorybio);
    BIO_free(outbio);
    if (recipients != NULL){
        sk_X509_free(recipients);/* Only free the stack, not the certificates */
    }
    PKCS7_free(p7enc);
    OPENSSL_free(buffer);
    return ret;
}
Пример #24
0
/*
 * Unwrap PKCS#7 data and decrypt if necessary
 */
int pkcs7_unwrap(struct scep *s, struct sscep_ctx *ctx, struct sscep_operation_info *op_info, char* data, int datalen)
{
    BIO *memorybio = NULL;
    BIO *outbio = NULL;
    BIO *pkcs7bio = NULL;
    int i, bytes, used;
    STACK_OF(PKCS7_SIGNER_INFO) *sk;
    PKCS7 *p7enc = NULL;
    PKCS7_SIGNER_INFO *si;
    STACK_OF(X509_ATTRIBUTE) *attribs;
    char *p = NULL;
    unsigned char buffer[1024];
    X509 *recipientcert;
    EVP_PKEY *recipientkey;
    int ret = SCEP_PKISTATUS_P7;

    /* Create new memory BIO for outer PKCS#7 */
    memorybio = BIO_new(BIO_s_mem());

    /* Read in data */
    if (ctx->verbose){
        qeo_log_i("reading outer PKCS#7");
    }
    if (BIO_write(memorybio, data, datalen) <= 0) {
        qeo_log_e("error reading PKCS#7 data");
        goto error;
    }
    if (ctx->verbose){
        qeo_log_i("PKCS#7 payload size: %d bytes", datalen);
    }
    s->reply_p7 = d2i_PKCS7_bio(memorybio, NULL );
    if (s->reply_p7 == NULL ) {
        qeo_log_e("error retrieving PKCS#7 data");
        goto error;
    }
    if (ctx->debug) {
        qeo_log_i("printing PEM fomatted PKCS#7");
        PEM_write_PKCS7(stdout, s->reply_p7);
    }

    /* Make sure this is a signed PKCS#7 */
    if (!PKCS7_type_is_signed(s->reply_p7)) {
        qeo_log_e("PKCS#7 is not signed!");
        goto error;
    }

    /* Create BIO for content data */
    pkcs7bio = PKCS7_dataInit(s->reply_p7, NULL );
    if (pkcs7bio == NULL ) {
        qeo_log_e("cannot get PKCS#7 data");
        goto error;
    }

    /* Copy enveloped data from PKCS#7 */
    outbio = BIO_new(BIO_s_mem());
    used = 0;
    for (;;) {
        bytes = BIO_read(pkcs7bio, buffer, sizeof(buffer));
        used += bytes;
        if (bytes <= 0)
            break;
        BIO_write(outbio, buffer, bytes);
    }
    (void)BIO_flush(outbio);
    if (ctx->verbose){
        qeo_log_i("PKCS#7 contains %d bytes of enveloped data", used);
    }

    /* Get signer */
    sk = PKCS7_get_signer_info(s->reply_p7);
    if (sk == NULL ) {
        qeo_log_e("cannot get signer info!");
        goto error;
    }

    /* Verify signature */
    if (ctx->verbose){
        qeo_log_i("verifying signature");
    }
    si = sk_PKCS7_SIGNER_INFO_value(sk, 0);
    if (PKCS7_signatureVerify(pkcs7bio, s->reply_p7, si, op_info->racert) <= 0) {
        qeo_log_e("error verifying signature");
        goto error;
    }
    if (ctx->verbose){
        qeo_log_i("signature ok");
    }

    /* Get signed attributes */
    if (ctx->verbose){
        qeo_log_i("finding signed attributes");
    }
    attribs = PKCS7_get_signed_attributes(si);
    if (attribs == NULL ) {
        qeo_log_e("no attributes found");
        goto error;
    }

    /* Transaction id */
    if ((get_signed_attribute(attribs, ctx->nid_transId, V_ASN1_PRINTABLESTRING, &p, ctx)) == 1) {
        qeo_log_e("cannot find transId");
        goto error;
    }
    if (ctx->verbose){
        qeo_log_i("reply transaction id: %s", p);
    }
    if (strncmp(s->transaction_id, p, strlen(p))) {
        qeo_log_e("transaction id mismatch");
        goto error;
    }
    free(p);
    p=NULL;
    /* Message type, should be of type CertRep */
    if (get_signed_attribute(attribs, ctx->nid_messageType, V_ASN1_PRINTABLESTRING, &p, ctx) == 1) {
        qeo_log_e("cannot find messageType");
        goto error;
    }
    if (atoi(p) != 3) {
        qeo_log_e("wrong message type in reply");
        goto error;
    }
    if (ctx->verbose){
        qeo_log_i("reply message type is good");
    }

    free(p);
    p=NULL;
    /* Recipient nonces: */
    if (get_signed_attribute(attribs, ctx->nid_recipientNonce, V_ASN1_OCTET_STRING, &p, ctx) == 1) {
        qeo_log_e("cannot find recipientNonce");
        goto error;
    }
    s->reply_recipient_nonce = p;
    p = NULL;
    if (ctx->verbose) {
        qeo_log_i("recipientNonce in reply");
    }
    /*
     * Compare recipient nonce to original sender nonce
     * The draft says nothing about this, but it makes sense to me..
     * XXXXXXXXXXXXXX check
     */
    for (i = 0; i < 16; i++) {
        if (s->sender_nonce[i] != s->reply_recipient_nonce[i]) {
            if (ctx->verbose)
                qeo_log_e("corrupted nonce received");
            /* Instead of exit, break out */
            break;
        }
    }
    /* Get pkiStatus */
    if (get_signed_attribute(attribs, ctx->nid_pkiStatus, V_ASN1_PRINTABLESTRING, &p, ctx) == 1) {
        qeo_log_e("cannot find pkiStatus");
        /* This is a mandatory attribute.. */
        goto error;
    }
    switch (atoi(p)) {
        case SCEP_PKISTATUS_SUCCESS:
            qeo_log_i("pkistatus: SUCCESS");
            s->pki_status = SCEP_PKISTATUS_SUCCESS;
            break;
        case SCEP_PKISTATUS_FAILURE:
            qeo_log_i("pkistatus: FAILURE");
            s->pki_status = SCEP_PKISTATUS_FAILURE;
            break;
        case SCEP_PKISTATUS_PENDING:
            qeo_log_i("pkistatus: PENDING");
            s->pki_status = SCEP_PKISTATUS_PENDING;
            break;
        default:
            qeo_log_e("wrong pkistatus in reply");
            goto error;
    }
    free(p);
    p=NULL;

    /* Get failInfo */
    if (s->pki_status == SCEP_PKISTATUS_FAILURE) {
        if (get_signed_attribute(attribs, ctx->nid_failInfo, V_ASN1_PRINTABLESTRING, &p, ctx) == 1) {
            qeo_log_e("cannot find failInfo");
            goto error;
        }
        switch (atoi(p)) {
            case SCEP_FAILINFO_BADALG:
                s->fail_info = SCEP_FAILINFO_BADALG;
                qeo_log_i("reason: %s", SCEP_FAILINFO_BADALG_STR);
                break;
            case SCEP_FAILINFO_BADMSGCHK:
                s->fail_info = SCEP_FAILINFO_BADMSGCHK;
                qeo_log_i("reason: %s", SCEP_FAILINFO_BADMSGCHK_STR);
                break;
            case SCEP_FAILINFO_BADREQ:
                s->fail_info = SCEP_FAILINFO_BADREQ;
                qeo_log_i("reason: %s", SCEP_FAILINFO_BADREQ_STR);
                break;
            case SCEP_FAILINFO_BADTIME:
                s->fail_info = SCEP_FAILINFO_BADTIME;
                qeo_log_i("reason: %s", SCEP_FAILINFO_BADTIME_STR);
                break;
            case SCEP_FAILINFO_BADCERTID:
                s->fail_info = SCEP_FAILINFO_BADCERTID;
                qeo_log_i("reason: %s", SCEP_FAILINFO_BADCERTID_STR);
                break;
            default:
                qeo_log_e("wrong failInfo in " "reply");
                goto error;
        }
        free(p);
        p=NULL;
    }
    /* If FAILURE or PENDING, we can return */
    if (s->pki_status != SCEP_PKISTATUS_SUCCESS) {
        /* There shouldn't be any more data... */
        if (ctx->verbose && (used != 0)) {
            qeo_log_e("illegal size of payload");
        }
        return (0);
    }
    /* We got success and expect data */
    if (used == 0) {
        qeo_log_e("illegal size of payload");
        goto error;
    }

    /* Decrypt the inner PKCS#7 */
    recipientcert = s->signercert;
    recipientkey = s->signerkey;

    if (ctx->verbose){
        qeo_log_i("reading inner PKCS#7");
    }
    p7enc = d2i_PKCS7_bio(outbio, NULL );
    if (p7enc == NULL ) {
        qeo_log_e("cannot read inner PKCS#7");
        goto error;
    }
    BIO_free(outbio);/* No longer need it */
    outbio = NULL;
    if (ctx->debug) {
        qeo_log_i("printing PEM fomatted PKCS#7");
        PEM_write_PKCS7(stdout, p7enc);
    }

    /* Decrypt the data  */

    outbio = BIO_new(BIO_s_mem());
    if (ctx->verbose){
        qeo_log_i("decrypting inner PKCS#7");
    }
    if (PKCS7_decrypt(p7enc, recipientkey, recipientcert, outbio, 0) == 0) {
        qeo_log_e("error decrypting inner PKCS#7");
        goto error;
    }
    (void)BIO_flush(outbio);

    /* Write decrypted data */
    PKCS7_free(s->reply_p7);
    s->reply_p7 = d2i_PKCS7_bio(outbio, NULL );
    ret = 0;
error:
    free(p);
    BIO_free(outbio);
    BIO_free_all(pkcs7bio);
    BIO_free(memorybio);
    PKCS7_free(p7enc);
    return ret;
}
Пример #25
0
qeo_mgmt_client_retcode_t qeo_mgmt_json_util_parseGetFWDMessage(const char* data, ssize_t length, qeo_mgmt_client_forwarder_cb callback, void* cookie)
{
    json_error_t json_error = {0};
    qeo_mgmt_client_retcode_t result = QMGMTCLIENT_EBADREPLY;
    json_t* message = json_loadb(data, length, JSON_REJECT_DUPLICATES, &json_error);
    qeo_mgmt_client_forwarder_t* fwd = NULL;
    do {
       json_t* fwdArray;
       ssize_t fwdSize;
       ssize_t i;
       if (message == NULL) {
           qeo_log_w("Failed to parse json message %s (%s:%d:%d)", json_error.text, json_error.source, json_error.line, json_error.column);
           qeo_log_w("Data = (%s)", data);
           //JSON parsing error
           break;
       }
       if (!json_is_object(message)) {
           qeo_log_w("invalid message received - top level is not a JSON object");
           break;
       }
       fwdArray = json_object_get(message, "forwarders");
       if (fwdArray == NULL || !json_is_array(fwdArray)) {
           qeo_log_w("root object did not contain a field 'forwarders' of type array (%p)", fwdArray);
       }
       fwdSize = json_array_size(fwdArray);
       qeo_log_i("Found an array of %d forwarder(s) in message\n", fwdSize);

       for (i = 0; i < fwdSize; i++) {
           qeo_mgmt_client_retcode_t cb_result;
           json_t* fwdObject = json_array_get(fwdArray, i);
           json_t* idString;
           json_t* locatorArray;
           ssize_t nrOfLocators;
           ssize_t j;

           if (!json_is_object(fwdObject)) {
               qeo_log_w("unexpected content in fwdArray - object expected");
               break;
           }
           idString = json_object_get(fwdObject, "id");
           if (idString == NULL || !json_is_string(idString)) {
               qeo_log_w("forwarder object did not contain a string field called 'id' (%p)",  idString);
               break;
           }
           locatorArray = json_object_get(fwdObject, "locators");
           if (locatorArray == NULL || !json_is_array(locatorArray)) {
               qeo_log_w("forwarder object did not contain an array field called 'nrOfLocators' (%p)",  locatorArray);
               break;

           }
           nrOfLocators = json_array_size(locatorArray);
           qeo_log_i("found forwarder with id='%s' and %d locator(s)", json_string_value(idString), nrOfLocators);
           fwd = malloc(sizeof(qeo_mgmt_client_forwarder_t));
           if (fwd == NULL) {
               qeo_log_w("fwd == NULL");
               result = QMGMTCLIENT_EMEM;
               break;
           }
           fwd->nrOfLocators = nrOfLocators;
           fwd->locators = calloc(nrOfLocators, sizeof(qeo_mgmt_client_locator_t));
           fwd->deviceID = qeo_mgmt_util_hex_to_int(json_string_value(idString));
           if (fwd->deviceID == -1){
               qeo_log_w("Invalid device id inside json message");
               break;
           }

           if (fwd->locators == NULL) {
               qeo_log_w("fwd->locators == NULL");
               result = QMGMTCLIENT_EMEM;
               break;
           }

           for (j = 0; j < nrOfLocators; j++) {
               json_t* endpointObj = json_array_get(locatorArray, j);
               json_t* typeString = json_object_get(endpointObj,"type");
               json_t* addrString = json_object_get(endpointObj,"address");
               json_t* portInt = json_object_get(endpointObj,"port");

               if (portInt == NULL || !json_is_integer(portInt)) {
                   qeo_log_w("locator object did not contain a integer field called 'port' (%p)",  portInt);
                   break;
               }
               if (addrString == NULL || !json_is_string(addrString)) {
                   qeo_log_w("locator object did not contain a string field called 'address' (%p)",  addrString);
                   break;
               }
               if (typeString == NULL || !json_is_string(typeString)) {
                   qeo_log_w("locator object did not contain a string field called 'type' (%p)",  typeString);
                   break;
               }
               qeo_log_i("locator object %d = {type = '%s', address = '%s', port = %d}",  j, json_string_value(typeString),
                         json_string_value(addrString), (int) json_integer_value(portInt));
               //valid locator

               fwd->locators[j].port = (int) json_integer_value(portInt);
               if (fwd->locators[j].port < -1 || fwd->locators[j].port > 0xffff){
                   qeo_log_w("Invalid port inside locator");
                   break;
               }
               fwd->locators[j].type = _get_locator_type(json_string_value(typeString));
               fwd->locators[j].address = strdup(json_string_value(addrString)); //check value; don't forget to free!
               if (fwd->locators[j].address == NULL) {
                   qeo_log_w("locator->address == NULL");
                   break;
               }
           }
           if (j != nrOfLocators){
               break;
           }
           cb_result = callback(fwd, cookie);
           fwd = NULL; //pointer is handed over; set it to NULL so we wont free it.
           if (cb_result != QMGMTCLIENT_OK) {//the callback reports an error abort.
               result = cb_result;
               break;

           }
       }
       if (i != fwdSize){
           break;
       }
       qeo_log_i("Successfully walked JSON object tree...");
       result = QMGMTCLIENT_OK;
    }
    while(0);
    if (message) {
        json_decref(message);
    }
    if (fwd) { //if an error occurred, then the 'fwd' is not freed.
        qeo_mgmt_client_free_forwarder(fwd);
    }

    return result;
}
Пример #26
0
void notify_cb(DDS_DomainId_t domain_id,
               DDS_BuiltinTopicKey_t *client_key,
               DDS_ActivitiesClientState state)
{
    qeo_log_i("Domain: %d, topic: %x-%x-%x, state: %d", domain_id, client_key->value[0], client_key->value[1], client_key->value[2], state);
}
Пример #27
0
qeo_mgmt_client_retcode_t qeo_mgmt_curl_util_http_get_with_cb(qeo_mgmt_client_ctx_t* mg_ctx,
                                                     const char* url,
                                                     char *header,
                                                     curl_write_callback data_cb,
                                                     void *write_cookie){
    qeo_mgmt_client_retcode_t ret = QMGMTCLIENT_EFAIL;
    struct curl_slist *chunk = (header != NULL)?curl_slist_append(NULL, header):NULL;
    long http_status = 0;
    char correlation_id[CURL_UTIL_CORRELATION_ID_MAX_SIZE];
    curl_opt_helper opts[] = {
        { CURLOPT_WRITEFUNCTION, (void*) data_cb },
        { CURLOPT_WRITEDATA, (void*)write_cookie},
        { CURLOPT_FAILONERROR, (void*)1 },
        { CURLOPT_HTTPHEADER, (void*) chunk}};
    bool reset = false;

    do {
        CURL* ctx;
        if ((mg_ctx == NULL) || (mg_ctx->curl_ctx == NULL) || (url == NULL) || (data_cb == NULL)){
            ret = QMGMTCLIENT_EINVAL;
            break;
        }
        ctx = mg_ctx->curl_ctx;
        if ((header != NULL) && (chunk == NULL)) {
            ret = QMGMTCLIENT_EMEM;
            break;
        }
        reset = true;
        if (CURLE_OK != qeo_mgmt_curl_util_set_opts(opts, sizeof(opts) / sizeof(curl_opt_helper), mg_ctx)) {
            ret = QMGMTCLIENT_EINVAL;
            break;
        }

        qeo_log_i("Start fetching data from <%s>", url);
        ret = qeo_mgmt_curl_util_perform(ctx, url, NULL);
        if (ret != QMGMTCLIENT_OK) {
            break;
        }
        if (curl_easy_getinfo(ctx, CURLINFO_RESPONSE_CODE, &http_status) == CURLE_OK) {
            if (http_status >= 400){
                ret = qeo_mgmt_curl_util_translate_rc(CURLE_HTTP_RETURNED_ERROR);
                curl_util_log_http_error_description(ctx, correlation_id);
                break;
            }
        }
        qeo_log_i("Successfully downloaded data");
    } while (0);

    if (reset == true){
        /* Make sure we reset all configuration for next calls */
        curl_easy_reset(mg_ctx->curl_ctx);
    }
    if (chunk != NULL){
        curl_slist_free_all(chunk);
    }

    if (ret != QMGMTCLIENT_OK) {
        qeo_log_w("Failure getting %s",url);
    }

    return ret;
}
Пример #28
0
static void client_state_machine_eval_ul(qeo_factory_t *factory,
                                         client_state_events_t event,
                                         qeo_mgmt_client_locator_t *locator,
                                         int64_t device_id)
{
    qeo_log_i("received event %s in state %s", client_event_to_str(event),
              client_state_to_str(factory->fwd.u.client.state));
    switch (factory->fwd.u.client.state) {
        case FWD_CLIENT_STATE_INIT:
            switch (event) {
                case CLIENT_EVENT_START:
                    factory->fwd.device_id = -1;
                    if (QEO_OK == client_start_timer(factory, 1)) {
                        factory->fwd.u.client.state = FWD_CLIENT_STATE_WAIT;
                    }
                    if (QEO_OK != qeocore_reader_enable(factory->fwd.reader)) {
                        qeo_log_e("error enabling forwarder topic reader");
                    }
                    if (QEO_OK != fwd_get_list(factory)) {
                        qeo_log_e("error requesting list of forwarders");
                    }
                    break;
                default:
                    qeo_log_e("unexpected event %s in state %s", client_event_to_str(event),
                              client_state_to_str(factory->fwd.u.client.state));
                    break;
            }
            break;
        case FWD_CLIENT_STATE_WAIT:
            switch (event) {
                case CLIENT_EVENT_TIMEOUT:
                    if (QEO_OK == client_start_timer(factory, 0)) {
                        factory->fwd.u.client.state = FWD_CLIENT_STATE_WAIT;
                    }
                    if (QEO_OK != fwd_get_list(factory)) {
                        qeo_log_e("error requesting list of forwarders");
                    }
                    break;
                case CLIENT_EVENT_LOC_SRV_DATA_RECEIVED:
                    fwd_client_reconfig(factory, locator, device_id);
                    factory->fwd.u.client.state = FWD_CLIENT_STATE_WAIT_READER;
                    break;
                case CLIENT_EVENT_FWD_DATA_RECEIVED:
                    fwd_client_reconfig(factory, locator, device_id);
                    DDS_Timer_stop(factory->fwd.timer);
                    factory->fwd.u.client.state = FWD_CLIENT_STATE_READY;
                    break;
                default:
                    qeo_log_e("unexpected event %s in state %s", client_event_to_str(event),
                              client_state_to_str(factory->fwd.u.client.state));
                    break;
            }
            break;
        case FWD_CLIENT_STATE_WAIT_READER:
            switch (event) {
                case CLIENT_EVENT_TIMEOUT:
                    if (QEO_OK == client_start_timer(factory, 0)) {
                        factory->fwd.u.client.state = FWD_CLIENT_STATE_WAIT;
                    }
                    fwd_locator_destroy(factory);
                    factory->fwd.device_id = -1;
                    if (QEO_OK != fwd_get_list(factory)) {
                        qeo_log_e("error requesting list of forwarders");
                    }
                    break;
                case CLIENT_EVENT_FWD_DATA_RECEIVED:
                    DDS_Timer_stop(factory->fwd.timer);
                    factory->fwd.u.client.state = FWD_CLIENT_STATE_READY;
                    if (factory->fwd.device_id != device_id) {
                        fwd_client_reconfig(factory, locator, device_id);
                    }
                    break;
                default:
                    qeo_log_e("unexpected event %s in state %s", client_event_to_str(event),
                              client_state_to_str(factory->fwd.u.client.state));
                    break;
            }
            break;
        case FWD_CLIENT_STATE_READY:
            switch (event) {
                case CLIENT_EVENT_FWD_DATA_REMOVED:
                    if (QEO_OK == client_start_timer(factory, 1)) {
                        factory->fwd.u.client.state = FWD_CLIENT_STATE_WAIT;
                    }
                    fwd_locator_destroy(factory);
                    factory->fwd.device_id = -1;
                    if (QEO_OK != fwd_get_list(factory)) {
                        qeo_log_e("error requesting list of forwarders");
                    }
                    break;
                default:
                    qeo_log_e("unexpected event %s in state %s", client_event_to_str(event),
                              client_state_to_str(factory->fwd.u.client.state));
                    break;
            }
            break;
    }
    qeo_log_i("new state %s", client_state_to_str(factory->fwd.u.client.state));
}