Esempio n. 1
0
static int
cib_remote_msg(gpointer data)
{
    xmlNode *command = NULL;
    crm_client_t *client = data;
    int disconnected = 0;
    int timeout = client->remote->authenticated ? -1 : 1000;

    crm_trace("%s callback", client->kind != CRM_CLIENT_TCP ? "secure" : "clear-text");

#ifdef HAVE_GNUTLS_GNUTLS_H
    if (client->kind == CRM_CLIENT_TLS && (client->remote->tls_handshake_complete == FALSE)) {
        int rc = pcmk__read_handshake_data(client);

        if (rc == 0) {
            /* No more data is available at the moment. Just return for now;
             * we'll get invoked again once the client sends more.
             */
            return 0;
        } else if (rc < 0) {
            crm_err("TLS handshake with remote CIB client failed: %s "
                    CRM_XS " rc=%d", gnutls_strerror(rc), rc);
            return -1;
        }

        crm_debug("TLS handshake with remote CIB client completed");
        client->remote->tls_handshake_complete = TRUE;
        if (client->remote->auth_timeout) {
            g_source_remove(client->remote->auth_timeout);
        }

        // Require the client to authenticate within this time
        client->remote->auth_timeout = g_timeout_add(REMOTE_AUTH_TIMEOUT,
                                                     remote_auth_timeout_cb,
                                                     client);
        return 0;
    }
#endif

    crm_remote_recv(client->remote, timeout, &disconnected);

    /* must pass auth before we will process anything else */
    if (client->remote->authenticated == FALSE) {
        xmlNode *reg;

#if ENABLE_ACL
        const char *user = NULL;
#endif
        command = crm_remote_parse_buffer(client->remote);
        if (cib_remote_auth(command) == FALSE) {
            free_xml(command);
            return -1;
        }

        crm_notice("Remote CIB client connection accepted");
        client->remote->authenticated = TRUE;
        g_source_remove(client->remote->auth_timeout);
        client->remote->auth_timeout = 0;
        client->name = crm_element_value_copy(command, "name");

#if ENABLE_ACL
        user = crm_element_value(command, "user");
        if (user) {
            client->user = strdup(user);
        }
#endif

        /* send ACK */
        reg = create_xml_node(NULL, "cib_result");
        crm_xml_add(reg, F_CIB_OPERATION, CRM_OP_REGISTER);
        crm_xml_add(reg, F_CIB_CLIENTID, client->id);
        crm_remote_send(client->remote, reg);
        free_xml(reg);
        free_xml(command);
    }

    command = crm_remote_parse_buffer(client->remote);
    while (command) {
        crm_trace("Remote client message received");
        cib_handle_remote_msg(client, command);
        free_xml(command);
        command = crm_remote_parse_buffer(client->remote);
    }

    if (disconnected) {
        crm_trace("Remote CIB client disconnected while reading from it");
        return -1;
    }

    return 0;
}
Esempio n. 2
0
static void
do_local_notify(xmlNode * notify_src, const char *client_id,
                gboolean sync_reply, gboolean from_peer)
{
    /* send callback to originating child */
    crm_client_t *client_obj = NULL;
    int local_rc = pcmk_ok;
    int call_id = 0;

    crm_element_value_int(notify_src, F_CIB_CALLID, &call_id);

    if (client_id != NULL) {
        client_obj = crm_client_get_by_id(client_id);
    }

    if (client_obj == NULL) {
        local_rc = -ECONNRESET;
        crm_trace("No client to sent response %d to, F_CIB_CLIENTID not set.", call_id);

    } else {
        int rid = 0;

        if (sync_reply) {
            if (client_obj->ipcs) {
                CRM_LOG_ASSERT(client_obj->request_id);

                rid = client_obj->request_id;
                client_obj->request_id = 0;

                crm_trace("Sending response %d to %s %s",
                          rid, client_obj->name,
                          from_peer ? "(originator of delegated request)" : "");
            } else {
                crm_trace("Sending response [call %d] to %s %s",
                          call_id, client_obj->name, from_peer ? "(originator of delegated request)" : "");
            }

        } else {
            crm_trace("Sending event %d to %s %s",
                      call_id, client_obj->name, from_peer ? "(originator of delegated request)" : "");
        }

        switch (client_obj->kind) {
            case CRM_CLIENT_IPC:
                if (crm_ipcs_send(client_obj, rid, notify_src, sync_reply?crm_ipc_flags_none:crm_ipc_server_event) < 0) {
                    local_rc = -ENOMSG;
                }
                break;
#ifdef HAVE_GNUTLS_GNUTLS_H
            case CRM_CLIENT_TLS:
#endif
            case CRM_CLIENT_TCP:
                crm_remote_send(client_obj->remote, notify_src);
                break;
            default:
                crm_err("Unknown transport %d for %s", client_obj->kind, client_obj->name);
        }
    }

    if (local_rc != pcmk_ok && client_obj != NULL) {
        crm_warn("%sSync reply to %s failed: %s",
                 sync_reply ? "" : "A-",
                 client_obj ? client_obj->name : "<unknown>", pcmk_strerror(local_rc));
    }
}