Exemple #1
0
static int
_manual_pong_handler(xmpp_conn_t *const conn, xmpp_stanza_t * const stanza,
    void * const userdata)
{
    char *from = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_FROM);
    char *type = xmpp_stanza_get_type(stanza);

    // handle error responses
    if (g_strcmp0(type, STANZA_TYPE_ERROR) == 0) {
        char *error_message = stanza_get_error_message(stanza);
        handle_ping_error_result(from, error_message);
        free(error_message);
        return 0;
    }

    GDateTime *sent = (GDateTime *)userdata;
    GDateTime *now = g_date_time_new_now_local();

    GTimeSpan elapsed = g_date_time_difference(now, sent);
    int elapsed_millis = elapsed / 1000;

    g_date_time_unref(sent);
    g_date_time_unref(now);

    handle_ping_result(from, elapsed_millis);

    return 0;
}
Exemple #2
0
static int
_room_config_submit_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza,
    void * const userdata)
{
    const char *id = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_ID);
    const char *type = xmpp_stanza_get_type(stanza);
    const char *from = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_FROM);

    if (id != NULL) {
        log_debug("IQ room config submit handler fired, id: %s.", id);
    } else {
        log_debug("IQ room config submit handler fired.");
    }

    // handle error responses
    if (g_strcmp0(type, STANZA_TYPE_ERROR) == 0) {
        char *error_message = stanza_get_error_message(stanza);
        handle_room_config_submit_result_error(from, error_message);
        free(error_message);
        return 0;
    }

    handle_room_config_submit_result(from);

    return 0;
}
Exemple #3
0
static int
_room_config_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza,
    void * const userdata)
{
    const char *id = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_ID);
    const char *type = xmpp_stanza_get_type(stanza);
    const char *from = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_FROM);

    if (id != NULL) {
        log_debug("IQ room config handler fired, id: %s.", id);
    } else {
        log_debug("IQ room config handler fired.");
    }

    // handle error responses
    if (g_strcmp0(type, STANZA_TYPE_ERROR) == 0) {
        char *error_message = stanza_get_error_message(stanza);
        handle_room_configuration_form_error(from, error_message);
        free(error_message);
        return 0;
    }

    if (from == NULL) {
        log_warning("No from attribute for IQ config request result");
        handle_room_configuration_form_error(from, "No from attribute for room cofig response.");
        return 0;
    }

    xmpp_stanza_t *query = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_QUERY);
    if (query == NULL) {
        log_warning("No query element found parsing room config response");
        handle_room_configuration_form_error(from, "No query element found parsing room config response");
        return 0;
    }

    xmpp_stanza_t *x = xmpp_stanza_get_child_by_ns(query, STANZA_NS_DATA);
    if (x == NULL) {
        log_warning("No x element found with %s namespace parsing room config response", STANZA_NS_DATA);
        handle_room_configuration_form_error(from, "No form configuration options available");
        return 0;
    }

    char *form_type = xmpp_stanza_get_attribute(x, STANZA_ATTR_TYPE);
    if (g_strcmp0(form_type, "form") != 0) {
        log_warning("x element not of type 'form' parsing room config response");
        handle_room_configuration_form_error(from, "Form not of type 'form' parsing room config response.");
        return 0;
    }

    DataForm *form = form_create(x);
    handle_room_configure(from, form);

    return 0;
}
Exemple #4
0
static int
_message_error_handler(xmpp_conn_t *const conn, xmpp_stanza_t *const stanza, void *const userdata)
{
    char *id = xmpp_stanza_get_id(stanza);
    char *jid = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_FROM);
    xmpp_stanza_t *error_stanza = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_ERROR);
    char *type = NULL;
    if (error_stanza) {
        type = xmpp_stanza_get_attribute(error_stanza, STANZA_ATTR_TYPE);
    }

    // stanza_get_error never returns NULL
    char *err_msg = stanza_get_error_message(stanza);

    GString *log_msg = g_string_new("message stanza error received");
    if (id) {
        g_string_append(log_msg, " id=");
        g_string_append(log_msg, id);
    }
    if (jid) {
        g_string_append(log_msg, " from=");
        g_string_append(log_msg, jid);
    }
    if (type) {
        g_string_append(log_msg, " type=");
        g_string_append(log_msg, type);
    }
    g_string_append(log_msg, " error=");
    g_string_append(log_msg, err_msg);

    log_info(log_msg->str);

    g_string_free(log_msg, TRUE);

    if (!jid) {
        ui_handle_error(err_msg);
    } else if (type && (strcmp(type, "cancel") == 0)) {
        log_info("Recipient %s not found: %s", jid, err_msg);
        Jid *jidp = jid_create(jid);
        chat_session_remove(jidp->barejid);
        jid_destroy(jidp);
    } else {
        ui_handle_recipient_error(jid, err_msg);
    }

    free(err_msg);

    return 1;
}
Exemple #5
0
static int
_error_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza,
    void * const userdata)
{
    const char *id = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_ID);
    char *error_msg = stanza_get_error_message(stanza);

    if (id != NULL) {
        log_debug("IQ error handler fired, id: %s, error: %s", id, error_msg);
        log_error("IQ error received, id: %s, error: %s", id, error_msg);
    } else {
        log_debug("IQ error handler fired, error: %s", error_msg);
        log_error("IQ error received, error: %s", error_msg);
    }

    free(error_msg);

    return 1;
}
Exemple #6
0
static int
_message_error_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza,
    void * const userdata)
{
    char *id = xmpp_stanza_get_id(stanza);
    char *from = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_FROM);
    xmpp_stanza_t *error_stanza = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_ERROR);
    char *type = NULL;
    if (error_stanza != NULL) {
        type = xmpp_stanza_get_attribute(error_stanza, STANZA_ATTR_TYPE);
    }

    // stanza_get_error never returns NULL
    char *err_msg = stanza_get_error_message(stanza);

    GString *log_msg = g_string_new("message stanza error received");
    if (id != NULL) {
        g_string_append(log_msg, " id=");
        g_string_append(log_msg, id);
    }
    if (from != NULL) {
        g_string_append(log_msg, " from=");
        g_string_append(log_msg, from);
    }
    if (type != NULL) {
        g_string_append(log_msg, " type=");
        g_string_append(log_msg, type);
    }
    g_string_append(log_msg, " error=");
    g_string_append(log_msg, err_msg);

    log_info(log_msg->str);

    g_string_free(log_msg, TRUE);

    handle_message_error(from, type, err_msg);

    free(err_msg);

    return 1;
}
Exemple #7
0
static int
_pong_handler(xmpp_conn_t *const conn, xmpp_stanza_t * const stanza,
    void * const userdata)
{
    char *id = xmpp_stanza_get_id(stanza);
    char *type = xmpp_stanza_get_type(stanza);

    if (id != NULL) {
        log_debug("IQ pong handler fired, id: %s.", id);
    } else {
        log_debug("IQ pong handler fired.");
    }

    if (id != NULL && type != NULL) {
        // show warning if error
        if (strcmp(type, STANZA_TYPE_ERROR) == 0) {
            char *error_msg = stanza_get_error_message(stanza);
            log_warning("Server ping (id=%s) responded with error: %s", id, error_msg);
            free(error_msg);

            // turn off autoping if error type is 'cancel'
            xmpp_stanza_t *error = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_ERROR);
            if (error != NULL) {
                char *errtype = xmpp_stanza_get_type(error);
                if (errtype != NULL) {
                    if (strcmp(errtype, "cancel") == 0) {
                        log_warning("Server ping (id=%s) error type 'cancel', disabling autoping.", id);
                        handle_autoping_cancel();
                        xmpp_timed_handler_delete(conn, _ping_timed_handler);
                    }
                }
            }
        }
    }

    // remove this handler
    return 0;
}
Exemple #8
0
static int
_presence_error_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza,
    void * const userdata)
{
    char *id = xmpp_stanza_get_id(stanza);
    char *from = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_FROM);
    xmpp_stanza_t *error_stanza = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_ERROR);
    xmpp_stanza_t *x = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_X);
    char *xmlns = NULL;
    if (x != NULL) {
        xmlns = xmpp_stanza_get_ns(x);
    }
    char *type = NULL;
    if (error_stanza != NULL) {
        type = xmpp_stanza_get_attribute(error_stanza, STANZA_ATTR_TYPE);
    }

    // handle MUC join errors
    if (g_strcmp0(xmlns, STANZA_NS_MUC) == 0) {
        Jid *fulljid = jid_create(from);

        char *error_cond = NULL;
        xmpp_stanza_t *reason_st = xmpp_stanza_get_child_by_ns(error_stanza, STANZA_NS_STANZAS);
        if (reason_st != NULL) {
            error_cond = xmpp_stanza_get_name(reason_st);
        }
        if (error_cond == NULL) {
            error_cond = "unknown";
        }

        log_info("Error joining room: %s, reason: %s", fulljid->barejid, error_cond);
        handle_room_join_error(fulljid->barejid, error_cond);
        return 1;
    }

    // stanza_get_error never returns NULL
    char *err_msg = stanza_get_error_message(stanza);

    GString *log_msg = g_string_new("presence stanza error received");
    if (id != NULL) {
        g_string_append(log_msg, " id=");
        g_string_append(log_msg, id);
    }
    if (from != NULL) {
        g_string_append(log_msg, " from=");
        g_string_append(log_msg, from);
    }
    if (type != NULL) {
        g_string_append(log_msg, " type=");
        g_string_append(log_msg, type);
    }
    g_string_append(log_msg, " error=");
    g_string_append(log_msg, err_msg);

    log_info(log_msg->str);

    g_string_free(log_msg, TRUE);

    handle_presence_error(from, type, err_msg);

    free(err_msg);

    return 1;
}
Exemple #9
0
static int
_disco_info_response_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza,
    void * const userdata)
{
    log_info("Received diso#info response");

    const char *from = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_FROM);
    const char *type = xmpp_stanza_get_type(stanza);

    // handle error responses
    if (g_strcmp0(type, STANZA_TYPE_ERROR) == 0) {
        char *error_message = stanza_get_error_message(stanza);
        handle_disco_info_error(from, error_message);
        free(error_message);
        return 0;
    }

    xmpp_stanza_t *query = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_QUERY);

    if (query != NULL) {
        xmpp_stanza_t *child = xmpp_stanza_get_children(query);
        GSList *identities = NULL;
        GSList *features = NULL;
        while (child != NULL) {
            const char *stanza_name = xmpp_stanza_get_name(child);
            if (g_strcmp0(stanza_name, STANZA_NAME_FEATURE) == 0) {
                const char *var = xmpp_stanza_get_attribute(child, STANZA_ATTR_VAR);
                if (var != NULL) {
                    features = g_slist_append(features, strdup(var));
                }
            } else if (g_strcmp0(stanza_name, STANZA_NAME_IDENTITY) == 0) {
                const char *name = xmpp_stanza_get_attribute(child, STANZA_ATTR_NAME);
                const char *type = xmpp_stanza_get_attribute(child, STANZA_ATTR_TYPE);
                const char *category = xmpp_stanza_get_attribute(child, STANZA_ATTR_CATEGORY);

                if ((name != NULL) || (category != NULL) || (type != NULL)) {
                    DiscoIdentity *identity = malloc(sizeof(struct disco_identity_t));

                    if (name != NULL) {
                        identity->name = strdup(name);
                    } else {
                        identity->name = NULL;
                    }
                    if (category != NULL) {
                        identity->category = strdup(category);
                    } else {
                        identity->category = NULL;
                    }
                    if (type != NULL) {
                        identity->type = strdup(type);
                    } else {
                        identity->type = NULL;
                    }

                    identities = g_slist_append(identities, identity);
                }
            }

            child = xmpp_stanza_get_next(child);
        }

        handle_disco_info(from, identities, features);
        g_slist_free_full(features, free);
        g_slist_free_full(identities, (GDestroyNotify)_identity_destroy);
    }
    return 1;
}
Exemple #10
0
static int
_caps_response_handler(xmpp_conn_t *const conn, xmpp_stanza_t * const stanza,
    void * const userdata)
{
    const char *id = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_ID);
    xmpp_stanza_t *query = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_QUERY);

    if (id) {
        log_info("Capabilities response handler fired for id %s", id);
    } else {
        log_info("Capabilities response handler fired");
    }

    const char *from = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_FROM);
    if (!from) {
        log_info("No from attribute");
        return 0;
    }

    char *type = xmpp_stanza_get_type(stanza);
    // handle error responses
    if (g_strcmp0(type, STANZA_TYPE_ERROR) == 0) {
        char *error_message = stanza_get_error_message(stanza);
        log_warning("Error received for capabilities response from %s: ", from, error_message);
        free(error_message);
        return 0;
    }

    if (query == NULL) {
        log_warning("No query element found.");
        return 0;
    }

    char *node = xmpp_stanza_get_attribute(query, STANZA_ATTR_NODE);
    if (node == NULL) {
        log_warning("No node attribute found");
        return 0;
    }

    // validate sha1
    gchar **split = g_strsplit(node, "#", -1);
    char *given_sha1 = split[1];
    char *generated_sha1 = caps_create_sha1_str(query);

    if (g_strcmp0(given_sha1, generated_sha1) != 0) {
        log_warning("Generated sha-1 does not match given:");
        log_warning("Generated : %s", generated_sha1);
        log_warning("Given     : %s", given_sha1);
    } else {
        log_info("Valid SHA-1 hash found: %s", given_sha1);

        if (caps_contains(given_sha1)) {
            log_info("Capabilties cached: %s", given_sha1);
        } else {
            log_info("Capabilities not cached: %s, storing", given_sha1);
            Capabilities *capabilities = caps_create(query);
            caps_add(given_sha1, capabilities);
            caps_destroy(capabilities);
        }

        caps_map(from, given_sha1);
    }

    g_free(generated_sha1);
    g_strfreev(split);
    return 0;
}
Exemple #11
0
static void
_presence_error_handler(xmpp_stanza_t *const stanza)
{
    const char *xmlns = NULL;
    xmpp_stanza_t *x = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_X);
    if (x) {
        xmlns = xmpp_stanza_get_ns(x);
    }

    const char *from = xmpp_stanza_get_from(stanza);
    xmpp_stanza_t *error_stanza = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_ERROR);

    // handle MUC join errors
    if (g_strcmp0(xmlns, STANZA_NS_MUC) == 0) {
        const char *error_cond = NULL;
        xmpp_stanza_t *reason_st = xmpp_stanza_get_child_by_ns(error_stanza, STANZA_NS_STANZAS);
        if (reason_st) {
            error_cond = xmpp_stanza_get_name(reason_st);
        }
        if (error_cond == NULL) {
            error_cond = "unknown";
        }

        Jid *fulljid = jid_create(from);
        log_info("Error joining room: %s, reason: %s", fulljid->barejid, error_cond);
        if (muc_active(fulljid->barejid)) {
            muc_leave(fulljid->barejid);
        }
        cons_show_error("Error joining room %s, reason: %s", fulljid->barejid, error_cond);
        jid_destroy(fulljid);

        return;
    }

    GString *log_msg = g_string_new("presence stanza error received");
    const char *id = xmpp_stanza_get_id(stanza);
    if (id) {
        g_string_append(log_msg, " id=");
        g_string_append(log_msg, id);
    }
    if (from) {
        g_string_append(log_msg, " from=");
        g_string_append(log_msg, from);
    }

    const char *type = NULL;
    if (error_stanza) {
        type = xmpp_stanza_get_type(error_stanza);
    }
    if (type) {
        g_string_append(log_msg, " type=");
        g_string_append(log_msg, type);
    }

    // stanza_get_error never returns NULL
    char *err_msg = stanza_get_error_message(stanza);
    g_string_append(log_msg, " error=");
    g_string_append(log_msg, err_msg);

    log_info(log_msg->str);

    g_string_free(log_msg, TRUE);

    if (from) {
        ui_handle_recipient_error(from, err_msg);
    } else {
        ui_handle_error(err_msg);
    }

    free(err_msg);
}