/** * Creates the parameter structure for the Read callback * @param[in] params This stanza is the params element in the XML-RPC format * @return The structure or null if an error were found. */ static sdvp_ReadParam_t* _CreateReadParam (xmpp_stanza_t * params) { const int expectedParams = 1; sdvp_ReadParam_t* rv = NULL; int i = 0; bool elementNotFund = false; xmpp_stanza_t *structure = NULL, *member = NULL, *value = NULL, *type = NULL, *name = NULL; char *text, *textname; structure = _GetRpcStructureElementFromParams(params); if (structure == NULL ) { return NULL ; } rv = _InitiateReadParameters(); for (member = xmpp_stanza_get_children(structure); member && !elementNotFund && (i < expectedParams); member = xmpp_stanza_get_next(member)) { if (xmpp_stanza_get_name(member) && strcmp(xmpp_stanza_get_name(member), "member") == 0) { if (!(name = xmpp_stanza_get_child_by_name(member, "name"))) { _FreeReadParameters(rv); // TODO: Signal error back return NULL ; } name = xmpp_stanza_get_children(name); textname = xmpp_stanza_get_text(name); if (strcmp(textname, "VariableAccessSpecification") == 0) { if (!(value = xmpp_stanza_get_child_by_name(member, "value"))) { _FreeReadParameters(rv); // TODO: Signal error back free(textname); return NULL ; } if ((type = xmpp_stanza_get_child_by_name(value, "string"))) { if (xmpp_stanza_get_children(type)) { text = xmpp_stanza_get_text(type); rv->reference = text; } else { rv->reference = NULL; } } else { elementNotFund = true; } } else { // if (!type) { // _FreeReadParameters(rv); // return NULL ; // } } free(textname); } } return rv; }
gboolean stanza_is_muc_self_presence(xmpp_stanza_t * const stanza, const char * const self_jid) { if (stanza == NULL) { return FALSE; } if (strcmp(xmpp_stanza_get_name(stanza), STANZA_NAME_PRESENCE) != 0) { return FALSE; } xmpp_stanza_t *x = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_X); if (x == NULL) { return FALSE; } char *ns = xmpp_stanza_get_ns(x); if (ns == NULL) { return FALSE; } if (strcmp(ns, STANZA_NS_MUC_USER) != 0) { return FALSE; } xmpp_stanza_t *x_children = xmpp_stanza_get_children(x); if (x_children == NULL) { return FALSE; } while (x_children != NULL) { if (strcmp(xmpp_stanza_get_name(x_children), STANZA_NAME_STATUS) == 0) { char *code = xmpp_stanza_get_attribute(x_children, STANZA_ATTR_CODE); if (strcmp(code, "110") == 0) { return TRUE; } } x_children = xmpp_stanza_get_next(x_children); } // for older server that don't send status 110 x_children = xmpp_stanza_get_children(x); while (x_children != NULL) { if (strcmp(xmpp_stanza_get_name(x_children), STANZA_NAME_ITEM) == 0) { char *jid = xmpp_stanza_get_attribute(x_children, STANZA_ATTR_JID); if (jid != NULL) { if (g_str_has_prefix(jid, self_jid)) { return TRUE; } } } x_children = xmpp_stanza_get_next(x_children); } return FALSE; }
int blocked_set_handler(xmpp_stanza_t *stanza) { xmpp_stanza_t *block = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_BLOCK); if (block) { xmpp_stanza_t *child = xmpp_stanza_get_children(block); while (child) { if (g_strcmp0(xmpp_stanza_get_name(child), STANZA_NAME_ITEM) == 0) { const char *jid = xmpp_stanza_get_attribute(child, STANZA_ATTR_JID); if (jid) { blocked = g_list_append(blocked, strdup(jid)); autocomplete_add(blocked_ac, jid); } } child = xmpp_stanza_get_next(child); } } xmpp_stanza_t *unblock = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_UNBLOCK); if (unblock) { xmpp_stanza_t *child = xmpp_stanza_get_children(unblock); if (!child) { g_list_free_full(blocked, free); blocked = NULL; autocomplete_clear(blocked_ac); } else { while (child) { if (g_strcmp0(xmpp_stanza_get_name(child), STANZA_NAME_ITEM) == 0) { const char *jid = xmpp_stanza_get_attribute(child, STANZA_ATTR_JID); if (jid) { GList *found = g_list_find_custom(blocked, jid, (GCompareFunc)g_strcmp0); if (found) { blocked = g_list_remove_link(blocked, found); g_list_free_full(found, free); autocomplete_remove(blocked_ac, jid); } } } child = xmpp_stanza_get_next(child); } } } return 1; }
static int _handle_legacy(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata) { char *type, *name; /* delete missing handler */ xmpp_timed_handler_delete(conn, _handle_missing_legacy); /* server responded to legacy auth request */ type = xmpp_stanza_get_type(stanza); name = xmpp_stanza_get_name(stanza); if (!type || strcmp(name, "iq") != 0) { xmpp_error(conn->ctx, "xmpp", "Server sent us an unexpected response "\ "to legacy authentication request."); xmpp_disconnect(conn); } else if (strcmp(type, "error") == 0) { /* legacy client auth failed, no more fallbacks */ xmpp_error(conn->ctx, "xmpp", "Legacy client authentication failed."); xmpp_disconnect(conn); } else if (strcmp(type, "result") == 0) { /* auth succeeded */ xmpp_debug(conn->ctx, "xmpp", "Legacy auth succeeded."); conn->authenticated = 1; conn->conn_handler(conn, XMPP_CONN_CONNECT, 0, NULL, conn->userdata); } else { xmpp_error(conn->ctx, "xmpp", "Server sent us a legacy authentication "\ "response with a bad type."); xmpp_disconnect(conn); } return 0; }
void _receipt_request_handler(xmpp_stanza_t *const stanza) { if (!prefs_get_boolean(PREF_RECEIPTS_SEND)) { return; } char *id = xmpp_stanza_get_id(stanza); if (!id) { return; } xmpp_stanza_t *receipts = xmpp_stanza_get_child_by_ns(stanza, STANZA_NS_RECEIPTS); if (!receipts) { return; } char *receipts_name = xmpp_stanza_get_name(receipts); if (g_strcmp0(receipts_name, "request") != 0) { return; } gchar *from = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_FROM); Jid *jid = jid_create(from); _message_send_receipt(jid->fulljid, id); jid_destroy(jid); }
static int _receipt_received_handler(xmpp_conn_t *const conn, xmpp_stanza_t *const stanza, void *const userdata) { xmpp_stanza_t *receipt = xmpp_stanza_get_child_by_ns(stanza, STANZA_NS_RECEIPTS); char *name = xmpp_stanza_get_name(receipt); if (g_strcmp0(name, "received") != 0) { return 1; } char *id = xmpp_stanza_get_attribute(receipt, STANZA_ATTR_ID); if (!id) { return 1; } char *fulljid = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_FROM); if (!fulljid) { return 1; } Jid *jidp = jid_create(fulljid); sv_ev_message_receipt(jidp->barejid, id); jid_destroy(jidp); return 1; }
static int _handle_sasl_result(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata) { char *name; name = xmpp_stanza_get_name(stanza); /* the server should send a <success> or <failure> stanza */ if (strcmp(name, "failure") == 0) { xmpp_debug(conn->ctx, "xmpp", "SASL %s auth failed", (char *)userdata); /* fall back to next auth method */ _auth(conn); } else if (strcmp(name, "success") == 0) { /* SASL PLAIN auth successful, we need to restart the stream */ xmpp_debug(conn->ctx, "xmpp", "SASL %s auth successful", (char *)userdata); /* reset parser */ conn_prepare_reset(conn, _handle_open_sasl); /* send stream tag */ conn_open_stream(conn); } else { /* got unexpected reply */ xmpp_error(conn->ctx, "xmpp", "Got unexpected reply to SASL %s"\ "authentication.", (char *)userdata); xmpp_disconnect(conn); } return 0; }
/* handle the rspauth phase of digest auth */ static int _handle_digestmd5_rspauth(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata) { xmpp_stanza_t *auth; char *name; name = xmpp_stanza_get_name(stanza); xmpp_debug(conn->ctx, "xmpp", "handle digest-md5 (rspauth) called for %s", name); if (strcmp(name, "challenge") == 0) { /* assume it's an rspauth response */ auth = xmpp_stanza_new(conn->ctx); if (!auth) { disconnect_mem_error(conn); return 0; } xmpp_stanza_set_name(auth, "response"); xmpp_stanza_set_ns(auth, XMPP_NS_SASL); xmpp_send(conn, auth); xmpp_stanza_release(auth); } else { return _handle_sasl_result(conn, stanza, "DIGEST-MD5"); } return 1; }
static gboolean _is_valid_form_element(xmpp_stanza_t *stanza) { const char *name = xmpp_stanza_get_name(stanza); if (g_strcmp0(name, STANZA_NAME_X) != 0) { log_error("Error parsing form, root element not <x/>."); return FALSE; } const char *ns = xmpp_stanza_get_ns(stanza); if (g_strcmp0(ns, STANZA_NS_DATA) != 0) { log_error("Error parsing form, namespace not %s.", STANZA_NS_DATA); return FALSE; } const char *type = xmpp_stanza_get_type(stanza); if ((g_strcmp0(type, "form") != 0) && (g_strcmp0(type, "submit") != 0) && (g_strcmp0(type, "cancel") != 0) && (g_strcmp0(type, "result") != 0)) { log_error("Error parsing form, unknown type."); return FALSE; } return TRUE; }
static int command_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata) { xmpp_stanza_t *reply = NULL, *req = NULL; char *cmd = NULL; /* Figure out what the command is */ req = xmpp_stanza_get_child_by_name(stanza, "command"); assert(req); assert(strcmp(xmpp_stanza_get_name(req), "command") == 0); cmd = xmpp_stanza_get_attribute(req, "node"); assert(cmd); CONFLATE_LOG(((conflate_handle_t *)userdata), LOG_LVL_INFO, "Command: %s", cmd); reply = command_dispatch(conn, stanza, userdata, cmd, req, true); if (reply) { xmpp_send(conn, reply); xmpp_stanza_release(reply); } return 1; }
/** Add <body/> child element to a <message/> stanza with the given text. * * @param msg a <message> stanza object without <body/> child element. * * @return 0 on success (XMPP_EOK), and a number less than 0 on failure * (XMPP_EMEM, XMPP_EINVOP) * * @ingroup Stanza */ int xmpp_message_set_body(xmpp_stanza_t *msg, const char * const text) { xmpp_ctx_t *ctx = msg->ctx; xmpp_stanza_t *body; xmpp_stanza_t *text_stanza; const char *name; int ret; /* check that msg is a <message/> stanza and doesn't contain <body/> */ name = xmpp_stanza_get_name(msg); body = xmpp_stanza_get_child_by_name(msg, "body"); if (!name || strcmp(name, "message") != 0 || body) return XMPP_EINVOP; body = xmpp_stanza_new(ctx); text_stanza = xmpp_stanza_new(ctx); ret = body && text_stanza ? XMPP_EOK : XMPP_EMEM; if (ret == XMPP_EOK) ret = xmpp_stanza_set_name(body, "body"); if (ret == XMPP_EOK) ret = xmpp_stanza_set_text(text_stanza, text); if (ret == XMPP_EOK) ret = xmpp_stanza_add_child(body, text_stanza); if (ret == XMPP_EOK) ret = xmpp_stanza_add_child(msg, body); if (text_stanza) xmpp_stanza_release(text_stanza); if (body) xmpp_stanza_release(body); return ret; }
static int _zkmuc_on_source_query(xmpp_ua_t *ua, xmpp_stanza_t *stanza, void *userdata) { query_source_data *data = (query_source_data *)userdata; char *from = xmpp_stanza_get_attribute(stanza, "from"); xmpp_stanza_t *x = xmpp_stanza_get_child_by_name(stanza, "x"); xmpp_stanza_t *item = xmpp_stanza_get_children(x); zkmuc_source_t *head = NULL; zkmuc_source_t **current = &head; while (item) { if (!strcmp("item", xmpp_stanza_get_name(item))) { *current = (zkmuc_source_t *)malloc(sizeof(zkmuc_source_t)); (*current)->cid = atoi(xmpp_stanza_get_attribute(item, "cid")); (*current)->sid = atoi(xmpp_stanza_get_attribute(item, "sid")); (*current)->description = strdup(xmpp_stanza_get_attribute(item, "desc")); (*current)->mcu = strdup(xmpp_stanza_get_attribute(item, "mcu")); current = &(*current)->next; } item = xmpp_stanza_get_next(item); } *current = NULL; data->cb(data->ctx, from, data->userdata, head); _zkmuc_free_all_remote_source(head); free(data); return 1; }
static int _handle_proceedtls_default(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata) { char *name; name = xmpp_stanza_get_name(stanza); xmpp_debug(conn->ctx, "xmpp", "handle proceedtls called for %s", name); if (strcmp(name, "proceed") == 0) { xmpp_debug(conn->ctx, "xmpp", "proceeding with TLS"); conn->tls = tls_new(conn->ctx, conn->sock); if (!tls_start(conn->tls)) { xmpp_debug(conn->ctx, "xmpp", "Couldn't start TLS! error %d", tls_error(conn->tls)); tls_free(conn->tls); conn->tls = NULL; conn->tls_failed = 1; /* failed tls spoils the connection, so disconnect */ xmpp_disconnect(conn); } else { conn->secured = 1; conn_prepare_reset(conn, auth_handle_open); conn_open_stream(conn); } } return 0; }
/* Check if the received stanza is <handshake/> and set auth to true * and fire connection handler. */ int _handle_component_hs_response(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata) { char *name; xmpp_timed_handler_delete(conn, _handle_missing_handshake); name = xmpp_stanza_get_name(stanza); if (strcmp(name, "handshake") != 0) { char *msg; size_t msg_size; xmpp_stanza_to_text(stanza, &msg, &msg_size); if (msg) { xmpp_debug(conn->ctx, "auth", "Handshake failed: %s", msg); xmpp_free(conn->ctx, msg); } xmpp_disconnect(conn); return XMPP_EINT; } else { conn->authenticated = 1; conn->conn_handler(conn, XMPP_CONN_CONNECT, 0, NULL, conn->userdata); } /* We don't need this handler anymore, return 0 so it can be deleted * from the list of handlers. */ return 0; }
static void files_list(xmpp_stanza_t *stanza) { int rc; /* Return code */ rc = pthread_mutex_lock(&mutex); wsyserr(rc != 0, "pthread_mutex_lock"); char *error_attr = xmpp_stanza_get_attribute(stanza, "error"); /* error attribute */ wfatal(error_attr == NULL, "no error attribute in files stanza"); if (strcmp(error_attr, "0") != 0) { wlog("Error in attributes: %s", error_attr); } else { char *path_attr = xmpp_stanza_get_attribute(stanza, "path"); /* path attribute */ wfatal(path_attr == NULL, "xmpp_stanza_get_attribute [attribute = path]"); xmpp_stanza_t *child = xmpp_stanza_get_children(stanza); while (child != NULL) { elem_t *elem = (elem_t *)malloc(sizeof(elem_t)); wsyserr(elem == NULL, "malloc"); elem->next = NULL; char *name = xmpp_stanza_get_name(child); wfatal(name == NULL, "xmpp_stanza_get_name"); if (strcmp(name, "directory") == 0) { elem->type = DIR; } else if (strcmp(name, "file") == 0) { elem->type = REG; } else { werr("Unknown name: %s", name); } char *filename_attr = xmpp_stanza_get_attribute(child, "filename"); wfatal(filename_attr == NULL, "xmpp_stanza_get_attribute [attribute = filename]"); elem->filename = strdup(filename_attr); wsyserr(elem->filename == NULL, "strdup"); /* Add elem in list */ if (root == NULL) { root = elem; } else { last->next = elem; } last = elem; child = xmpp_stanza_get_next(child); } } /* Data set */ signal_list = true; rc = pthread_cond_signal(&cond); wsyserr(rc != 0, "pthread_cond_signal"); rc = pthread_mutex_unlock(&mutex); wsyserr(rc != 0, "pthread_mutex_unlock"); }
static gboolean _handle_carbons(xmpp_stanza_t *const stanza) { xmpp_stanza_t *carbons = xmpp_stanza_get_child_by_ns(stanza, STANZA_NS_CARBONS); if (!carbons) { return FALSE; } char *name = xmpp_stanza_get_name(carbons); if ((g_strcmp0(name, "received") == 0) || (g_strcmp0(name, "sent")) == 0) { xmpp_stanza_t *forwarded = xmpp_stanza_get_child_by_ns(carbons, STANZA_NS_FORWARD); xmpp_stanza_t *message = xmpp_stanza_get_child_by_name(forwarded, STANZA_NAME_MESSAGE); xmpp_ctx_t *ctx = connection_get_ctx(); gchar *to = xmpp_stanza_get_attribute(message, STANZA_ATTR_TO); gchar *from = xmpp_stanza_get_attribute(message, STANZA_ATTR_FROM); // happens when receive a carbon of a self sent message if (!to) to = from; Jid *jid_from = jid_create(from); Jid *jid_to = jid_create(to); Jid *my_jid = jid_create(jabber_get_fulljid()); // check for and deal with message xmpp_stanza_t *body = xmpp_stanza_get_child_by_name(message, STANZA_NAME_BODY); if (body) { char *message_txt = xmpp_stanza_get_text(body); if (message_txt) { // check for pgp encrypted message char *enc_message = NULL; xmpp_stanza_t *x = xmpp_stanza_get_child_by_ns(message, STANZA_NS_ENCRYPTED); if (x) { enc_message = xmpp_stanza_get_text(x); } // if we are the recipient, treat as standard incoming message if(g_strcmp0(my_jid->barejid, jid_to->barejid) == 0){ sv_ev_incoming_carbon(jid_from->barejid, jid_from->resourcepart, message_txt, enc_message); // else treat as a sent message } else { sv_ev_outgoing_carbon(jid_to->barejid, message_txt, enc_message); } xmpp_free(ctx, message_txt); xmpp_free(ctx, enc_message); } } jid_destroy(jid_from); jid_destroy(jid_to); jid_destroy(my_jid); return TRUE; } return FALSE; }
static int _handle_features(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata) { xmpp_stanza_t *child, *mech; char *text; /* remove the handler that detects missing stream:features */ xmpp_timed_handler_delete(conn, _handle_missing_features); /* check for TLS */ if (!conn->secured) { if (!conn->tls_disabled) { child = xmpp_stanza_get_child_by_name(stanza, "starttls"); if (child && (strcmp(xmpp_stanza_get_ns(child), XMPP_NS_TLS) == 0)) conn->tls_support = 1; } else { conn->tls_support = 0; } } /* check for SASL */ child = xmpp_stanza_get_child_by_name(stanza, "mechanisms"); if (child && (strcmp(xmpp_stanza_get_ns(child), XMPP_NS_SASL) == 0)) { for (mech = xmpp_stanza_get_children(child); mech; mech = xmpp_stanza_get_next(mech)) { if (xmpp_stanza_get_name(mech) && strcmp(xmpp_stanza_get_name(mech), "mechanism") == 0) { text = xmpp_stanza_get_text(mech); if (strcasecmp(text, "PLAIN") == 0) conn->sasl_support |= SASL_MASK_PLAIN; else if (strcasecmp(text, "DIGEST-MD5") == 0) conn->sasl_support |= SASL_MASK_DIGESTMD5; else if (strcasecmp(text, "SCRAM-SHA-1") == 0) conn->sasl_support |= SASL_MASK_SCRAMSHA1; else if (strcasecmp(text, "ANONYMOUS") == 0) conn->sasl_support |= SASL_MASK_ANONYMOUS; xmpp_free(conn->ctx, text); } } } _auth(conn); return 0; }
int handle_disco_items(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata) { xmpp_stanza_t *query, *item; xmppipe_state_t *state = userdata; xmpp_ctx_t *ctx = state->ctx; query = xmpp_stanza_get_child_by_name(stanza, "query"); if (query == NULL) return 1; for (item = xmpp_stanza_get_children(query); item != NULL; item = xmpp_stanza_get_next(item)) { xmpp_stanza_t *iq, *reply; const char *jid = NULL; const char *name = NULL; char *id = NULL; name = xmpp_stanza_get_name(item); if (name == NULL) continue; if (XMPPIPE_STRNEQ(name, "item")) continue; jid = xmpp_stanza_get_attribute(item, "jid"); if (jid == NULL) continue; iq = xmppipe_stanza_new(ctx); xmppipe_stanza_set_name(iq, "iq"); xmppipe_stanza_set_type(iq, "get"); xmppipe_stanza_set_attribute(iq, "to", jid); id = xmpp_uuid_gen(state->ctx); if (id == NULL) { errx(EXIT_FAILURE, "unable to allocate message id"); } xmppipe_stanza_set_id(iq, id); reply = xmppipe_stanza_new(ctx); xmppipe_stanza_set_name(reply, "query"); xmppipe_stanza_set_ns(reply, "http://jabber.org/protocol/disco#info"); xmppipe_stanza_add_child(iq, reply); xmppipe_send(state, iq); (void)xmpp_stanza_release(iq); xmpp_free(state->ctx, id); } return 0; }
/* handle the challenge phase of digest auth */ static int _handle_digestmd5_challenge(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata) { char *text; char *response; xmpp_stanza_t *auth, *authdata; char *name; name = xmpp_stanza_get_name(stanza); xmpp_debug(conn->ctx, "xmpp",\ "handle digest-md5 (challenge) called for %s", name); if (strcmp(name, "challenge") == 0) { text = xmpp_stanza_get_text(stanza); response = sasl_digest_md5(conn->ctx, text, conn->jid, conn->pass); if (!response) { disconnect_mem_error(conn); return 0; } xmpp_free(conn->ctx, text); auth = xmpp_stanza_new(conn->ctx); if (!auth) { disconnect_mem_error(conn); return 0; } xmpp_stanza_set_name(auth, "response"); xmpp_stanza_set_ns(auth, XMPP_NS_SASL); authdata = xmpp_stanza_new(conn->ctx); if (!authdata) { disconnect_mem_error(conn); return 0; } xmpp_stanza_set_text(authdata, response); xmpp_free(conn->ctx, response); xmpp_stanza_add_child(auth, authdata); xmpp_stanza_release(authdata); handler_add(conn, _handle_digestmd5_rspauth, XMPP_NS_SASL, NULL, NULL, NULL); xmpp_send(conn, auth); xmpp_stanza_release(auth); } else { return _handle_sasl_result(conn, stanza, "DIGEST-MD5"); } /* remove ourselves */ return 0; }
gboolean stanza_is_room_nick_change(xmpp_stanza_t * const stanza) { if (stanza == NULL) { return FALSE; } if (strcmp(xmpp_stanza_get_name(stanza), STANZA_NAME_PRESENCE) != 0) { return FALSE; } xmpp_stanza_t *x = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_X); if (x == NULL) { return FALSE; } char *ns = xmpp_stanza_get_ns(x); if (ns == NULL) { return FALSE; } if (strcmp(ns, STANZA_NS_MUC_USER) != 0) { return FALSE; } xmpp_stanza_t *x_children = xmpp_stanza_get_children(x); if (x_children == NULL) { return FALSE; } while (x_children != NULL) { if (strcmp(xmpp_stanza_get_name(x_children), STANZA_NAME_STATUS) == 0) { char *code = xmpp_stanza_get_attribute(x_children, STANZA_ATTR_CODE); if (strcmp(code, "303") == 0) { return TRUE; } } x_children = xmpp_stanza_get_next(x_children); } return FALSE; }
/** Get the first child of stanza with name. * This function searches all the immediate children of stanza for a child * stanza that matches the name. The first matching child is returned. * * @param stanza a Strophe stanza object * @param name a string with the name to match * * @return the matching child stanza object or NULL if no match was found * * @ingroup Stanza */ xmpp_stanza_t *xmpp_stanza_get_child_by_name(xmpp_stanza_t * const stanza, const char * const name) { xmpp_stanza_t *child; for (child = stanza->children; child; child = child->next) { if (child->type == XMPP_STANZA_TAG && (strcmp(name, xmpp_stanza_get_name(child)) == 0)) break; } return child; }
/** Get text from <body/> child element. * This function returns new allocated string. The caller is responsible * for freeing this string with xmpp_free(). * * @param msg well formed <message/> stanza * * @return allocated string or NULL on failure (no <body/> element or * memory allocation error) * * @ingroup Stanza */ char *xmpp_message_get_body(xmpp_stanza_t *msg) { xmpp_stanza_t *body; const char *name; char *text = NULL; name = xmpp_stanza_get_name(msg); body = xmpp_stanza_get_child_by_name(msg, "body"); if (name && strcmp(name, "message") == 0 && body) { text = xmpp_stanza_get_text(body); } return text; }
int handle_disco_info(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata) { xmpp_stanza_t *query, *child; const char *from = NULL; xmppipe_state_t *state = userdata; from = xmpp_stanza_get_attribute(stanza, "from"); if (from == NULL) return 1; query = xmpp_stanza_get_child_by_name(stanza, "query"); if (query == NULL) return 1; for (child = xmpp_stanza_get_children(query); child != NULL; child = xmpp_stanza_get_next(child)) { const char *feature = NULL; const char *var = NULL; feature = xmpp_stanza_get_name(child); if (feature == NULL) continue; if (XMPPIPE_STRNEQ(feature, "feature")) continue; var = xmpp_stanza_get_attribute(child, "var"); if (var == NULL) continue; if (XMPPIPE_STRNEQ(var, "http://jabber.org/protocol/muc")) continue; state->mucservice = xmppipe_strdup(from); state->out = xmppipe_conference(state->room, state->mucservice); state->mucjid = xmppipe_mucjid(state->out, state->resource); if (state->opt & XMPPIPE_OPT_GROUPCHAT) { xmppipe_muc_join(state); xmppipe_muc_unlock(state); } return 0; } return 1; }
static int _iq_handle_discoitems_result(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata) { log_debug("Recieved diso#items response"); const char *id = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_ID); const char *from = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_FROM); const char *stanza_name = NULL; const char *item_jid = NULL; const char *item_name = NULL; GSList *items = NULL; if ((g_strcmp0(id, "confreq") == 0) || (g_strcmp0(id, "discoitemsreq") == 0)) { log_debug("Response to query: %s", id); 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); while (child != NULL) { stanza_name = xmpp_stanza_get_name(child); if ((stanza_name != NULL) && (g_strcmp0(stanza_name, STANZA_NAME_ITEM) == 0)) { item_jid = xmpp_stanza_get_attribute(child, STANZA_ATTR_JID); if (item_jid != NULL) { DiscoItem *item = malloc(sizeof(struct disco_item_t)); item->jid = strdup(item_jid); item_name = xmpp_stanza_get_attribute(child, STANZA_ATTR_NAME); if (item_name != NULL) { item->name = strdup(item_name); } else { item->name = NULL; } items = g_slist_append(items, item); } } child = xmpp_stanza_get_next(child); } } } if (g_strcmp0(id, "confreq") == 0) { handle_room_list(items, from); } else if (g_strcmp0(id, "discoitemsreq") == 0) { handle_disco_items(items, from); } g_slist_free_full(items, (GDestroyNotify)_item_destroy); return 1; }
GSList * _get_groups_from_item(xmpp_stanza_t *item) { GSList *groups = NULL; xmpp_stanza_t *group_element = xmpp_stanza_get_children(item); while (group_element) { if (strcmp(xmpp_stanza_get_name(group_element), STANZA_NAME_GROUP) == 0) { char *groupname = xmpp_stanza_get_text(group_element); if (groupname) { groups = g_slist_append(groups, groupname); } } group_element = xmpp_stanza_get_next(group_element); } return groups; }
static int _blocklist_result_handler(xmpp_stanza_t *const stanza, void *const userdata) { log_info("Blocked list result handler fired."); const char *type = xmpp_stanza_get_type(stanza); if (g_strcmp0(type, "result") != 0) { log_info("Received blocklist without result type"); return 0; } xmpp_stanza_t *blocklist = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_BLOCKLIST); if (!blocklist) { log_info("Received blocklist without blocklist element"); return 0; } if (blocked) { g_list_free_full(blocked, free); blocked = NULL; } xmpp_stanza_t *items = xmpp_stanza_get_children(blocklist); if (!items) { log_info("No blocked users."); return 0; } xmpp_stanza_t *curr = items; while (curr) { const char *name = xmpp_stanza_get_name(curr); if (g_strcmp0(name, "item") == 0) { const char *jid = xmpp_stanza_get_attribute(curr, STANZA_ATTR_JID); if (jid) { blocked = g_list_append(blocked, strdup(jid)); autocomplete_add(blocked_ac, jid); } } curr = xmpp_stanza_get_next(curr); } return 0; }
//TODO: Create structure for holding the roster static int _HandleRosterReply(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata) { xmpp_stanza_t *query, *item, *group; char *type, *name, *jid, *sub, groups[200], *groupName; char *g; int r_count = 0; sdvpIdleCounter = 0; sdvpPingsSent = 0; type = xmpp_stanza_get_type(stanza); if (strcmp(type, "error") == 0) { syslog(LOG_WARNING, "ERROR: query failed\n"); } else { query = xmpp_stanza_get_child_by_name(stanza, "query"); syslog(LOG_INFO, "Roster (Only the first group is shown!):\n----------\n"); for (item = xmpp_stanza_get_children(query); item; item = xmpp_stanza_get_next(item)) { name = xmpp_stanza_get_attribute(item, "name"); jid = xmpp_stanza_get_attribute(item, "jid"); sub = xmpp_stanza_get_attribute(item, "subscription"); // Get groups // strcpy(groups, "-"); for (group = xmpp_stanza_get_children(item); group; group = xmpp_stanza_get_next(group)) { groupName = xmpp_stanza_get_name(group); if (strcmp(groupName, "group") == 0) { g = xmpp_stanza_get_text(group); strcpy(groups, g); free(g); } } syslog(LOG_INFO, "#%d\tName=%s\n\tJID=%s\n\tsubscription=%s\n\tGroups=%s\n\n", r_count, name, jid, sub, groups); r_count++; } syslog(LOG_INFO, "----------\n"); } return 1; }
int presence_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata) { xmpp_ctx_t *ctx = (xmpp_ctx_t*)userdata; if (!strcmp(xmpp_stanza_get_name(stanza), "presence")) { xmpp_stanza_t *message, *text, *body; char username[1024]; char sendtext[1024]; printf("Enter the username you would like to send this message to: "); scanf("%[^\n]", username); char c = getchar(); printf("Type the message that you would like to send: "); scanf("%[^\n]", sendtext); message = xmpp_stanza_new(ctx); xmpp_stanza_set_name(message, "message"); xmpp_stanza_set_type(message, "chat"); xmpp_stanza_set_attribute(message, "to", username); body = xmpp_stanza_new(ctx); xmpp_stanza_set_name(body, "body"); text = xmpp_stanza_new(ctx); xmpp_stanza_set_text(text, sendtext); xmpp_stanza_add_child(body, text); xmpp_stanza_add_child(message, body); xmpp_send(conn, message); xmpp_stanza_release(message); } }
char * stanza_get_new_nick(xmpp_stanza_t * const stanza) { if (!stanza_is_room_nick_change(stanza)) { return NULL; } else { xmpp_stanza_t *x = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_X); xmpp_stanza_t *x_children = xmpp_stanza_get_children(x); while (x_children != NULL) { if (strcmp(xmpp_stanza_get_name(x_children), STANZA_NAME_ITEM) == 0) { char *nick = xmpp_stanza_get_attribute(x_children, STANZA_ATTR_NICK); if (nick != NULL) { return strdup(nick); } } x_children = xmpp_stanza_get_next(x_children); } return NULL; } }
static int _handle_proceedtls_default(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata) { const char *name; name = xmpp_stanza_get_name(stanza); xmpp_debug(conn->ctx, "xmpp", "handle proceedtls called for %s", name); if (strcmp(name, "proceed") == 0) { xmpp_debug(conn->ctx, "xmpp", "proceeding with TLS"); if (conn_tls_start(conn) == 0) { conn_prepare_reset(conn, auth_handle_open); conn_open_stream(conn); } else { /* failed tls spoils the connection, so disconnect */ xmpp_disconnect(conn); } } return 0; }