/**
 * 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;
}
Beispiel #2
0
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;
}
Beispiel #3
0
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;
}
Beispiel #4
0
int handle_reply(xmpp_conn_t * const conn,
		 xmpp_stanza_t * const stanza,
		 void * const userdata)
{
    xmpp_stanza_t *query, *item;
    char *type, *name;

    type = xmpp_stanza_get_type(stanza);
    if (strcmp(type, "error") == 0)
	fprintf(stderr, "ERROR: query failed\n");
    else {
	query = xmpp_stanza_get_child_by_name(stanza, "query");
	printf("Roster:\n");
	for (item = xmpp_stanza_get_children(query); item; 
	     item = xmpp_stanza_get_next(item))
	    if ((name = xmpp_stanza_get_attribute(item, "name")))
		printf("\t %s (%s) sub=%s\n", 
		       name,
		       xmpp_stanza_get_attribute(item, "jid"),
		       xmpp_stanza_get_attribute(item, "subscription"));
	    else
		printf("\t %s sub=%s\n",
		       xmpp_stanza_get_attribute(item, "jid"),
		       xmpp_stanza_get_attribute(item, "subscription"));
	printf("END OF LIST\n");
    }

    /* disconnect */
    xmpp_disconnect(conn);

    return 0;
}
Beispiel #5
0
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;
}
Beispiel #6
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");
}
Beispiel #7
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;
}
Beispiel #8
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;
}
Beispiel #9
0
int config_parse_text_stanza(char **const dest,
    xmpp_stanza_t *stanza)
{
    xmpp_stanza_t *const text_child = xmpp_stanza_get_children(stanza);
    if (!xmpp_stanza_is_text(text_child)) {
        return 1;
    }
    const char *text = xmpp_stanza_get_text_ptr(text_child);
    *dest = strdup(text);
    return 0;
}
Beispiel #10
0
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;
}
Beispiel #11
0
    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;
}
Beispiel #12
0
static int
_roster_result_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);

    if (g_strcmp0(id, "roster") != 0) {
        return 1;
    }

    // handle initial roster response
    xmpp_stanza_t *query = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_QUERY);
    xmpp_stanza_t *item = xmpp_stanza_get_children(query);

    while (item) {
        const char *barejid = xmpp_stanza_get_attribute(item, STANZA_ATTR_JID);
        gchar *barejid_lower = g_utf8_strdown(barejid, -1);
        const char *name = xmpp_stanza_get_attribute(item, STANZA_ATTR_NAME);
        const char *sub = xmpp_stanza_get_attribute(item, STANZA_ATTR_SUBSCRIPTION);

        // do not set nickname to empty string, set to NULL instead
        if (name && (strlen(name) == 0)) name = NULL;

        gboolean pending_out = FALSE;
        const char *ask = xmpp_stanza_get_attribute(item, STANZA_ATTR_ASK);
        if (g_strcmp0(ask, "subscribe") == 0) {
            pending_out = TRUE;
        }

        GSList *groups = _get_groups_from_item(item);

        gboolean added = roster_add(barejid_lower, name, groups, sub, pending_out);
        if (!added) {
            log_warning("Attempt to add contact twice: %s", barejid_lower);
        }

        g_free(barejid_lower);
        item = xmpp_stanza_get_next(item);
    }

    sv_ev_roster_received();

    resource_presence_t conn_presence = accounts_get_login_presence(jabber_get_account_name());
    cl_ev_presence_send(conn_presence, NULL, 0);

    return 1;
}
Beispiel #13
0
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;
}
Beispiel #14
0
int version_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata)
{
    xmpp_stanza_t *reply, *query, *name, *version, *text;
    const char *ns;
    xmpp_ctx_t *ctx = (xmpp_ctx_t*)userdata;

    printf("Received version request from %s\n", xmpp_stanza_get_from(stanza));

    reply = xmpp_stanza_reply(stanza);
    xmpp_stanza_set_type(reply, "result");

    query = xmpp_stanza_new(ctx);
    xmpp_stanza_set_name(query, "query");
    ns = xmpp_stanza_get_ns(xmpp_stanza_get_children(stanza));
    if (ns) {
        xmpp_stanza_set_ns(query, ns);
    }

    name = xmpp_stanza_new(ctx);
    xmpp_stanza_set_name(name, "name");
    xmpp_stanza_add_child(query, name);
    xmpp_stanza_release(name);

    text = xmpp_stanza_new(ctx);
    xmpp_stanza_set_text(text, "libstrophe example bot");
    xmpp_stanza_add_child(name, text);
    xmpp_stanza_release(text);

    version = xmpp_stanza_new(ctx);
    xmpp_stanza_set_name(version, "version");
    xmpp_stanza_add_child(query, version);
    xmpp_stanza_release(version);

    text = xmpp_stanza_new(ctx);
    xmpp_stanza_set_text(text, "1.0");
    xmpp_stanza_add_child(version, text);
    xmpp_stanza_release(text);

    xmpp_stanza_add_child(reply, query);
    xmpp_stanza_release(query);

    xmpp_send(conn, reply);
    xmpp_stanza_release(reply);
    return 1;
}
Beispiel #15
0
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;
}
Beispiel #16
0
static int
_roster_result_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);

    // handle initial roster response
    if (g_strcmp0(id, "roster") == 0) {
        xmpp_stanza_t *query = xmpp_stanza_get_child_by_name(stanza,
            STANZA_NAME_QUERY);
        xmpp_stanza_t *item = xmpp_stanza_get_children(query);

        while (item != NULL) {
            const char *barejid =
                xmpp_stanza_get_attribute(item, STANZA_ATTR_JID);
            const char *name =
                xmpp_stanza_get_attribute(item, STANZA_ATTR_NAME);
            const char *sub =
                xmpp_stanza_get_attribute(item, STANZA_ATTR_SUBSCRIPTION);

            gboolean pending_out = FALSE;
            const char *ask = xmpp_stanza_get_attribute(item, STANZA_ATTR_ASK);
            if (g_strcmp0(ask, "subscribe") == 0) {
                pending_out = TRUE;
            }

            GSList *groups = _get_groups_from_item(item);

            gboolean added = roster_add(barejid, name, groups, sub, pending_out);

            if (!added) {
                log_warning("Attempt to add contact twice: %s", barejid);
            }

            item = xmpp_stanza_get_next(item);
        }

        resource_presence_t conn_presence =
            accounts_get_login_presence(jabber_get_account_name());
        presence_update(conn_presence, NULL, 0);
    }

    return 1;
}
Beispiel #17
0
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;
}
Beispiel #18
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;

}
Beispiel #19
0
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;
    }
}
Beispiel #20
0
/**
 * Creates the parameter structure for the GetNameList 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_GetNameListParam_t* _CreateGetNameListParam (xmpp_stanza_t * params) {
    const int expectedParams = 4;
    sdvp_GetNameListParam_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 = _InitiateGetNameListParameters();
    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"))) {
                _FreeGetNameListParameters(rv);
                // TODO: Signal error back
                return NULL ;
            }
            name = xmpp_stanza_get_children(name);

			textname = xmpp_stanza_get_text(name);
            if (strcmp(textname, "ObjectClass") == 0) {
                if (!(value = xmpp_stanza_get_child_by_name(member, "value"))) {
                    _FreeGetNameListParameters(rv);
                    // TODO: Signal error back
                    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->params.objectClass = text;
                    } else {
                        rv->params.objectClass = NULL;
                    }
                } else {
                    elementNotFund = true;
                }

            } else if (strcmp(textname, "ObjectScope") == 0) {
                if ((type = xmpp_stanza_get_child_by_name(value, "string"))) {
                    if (xmpp_stanza_get_children(type)) {
                        text = xmpp_stanza_get_text(type);
                        rv->params.objectScope = text;
                    } else {
                        rv->params.objectScope = NULL;
                    }
                } else {
                    elementNotFund = true;
                }
            } else if (strcmp(textname, "DomainName") == 0) {
                if ((type = xmpp_stanza_get_child_by_name(value, "string"))) {
                    if (xmpp_stanza_get_children(type)) {
                        text = xmpp_stanza_get_text(type);
                        rv->params.domainName = text;
                    } else {
                        rv->params.domainName = NULL;
                    }
                } else {
                    elementNotFund = true;
                }
            } else if (strcmp(textname, "ContinueAfter") == 0) {
                if ((type = xmpp_stanza_get_child_by_name(value, "string"))) {
                    if (xmpp_stanza_get_children(type)) {
                        text = xmpp_stanza_get_text(type);
                        rv->params.continueAfter = text;
                    } else {
                        rv->params.continueAfter = NULL;
                    }
                } else {
                    elementNotFund = true;
                }
            } else {
//                if (!type) {
//                    _FreeGetNameListParameters(rv);
//                    return NULL ;
//                }
            }
			free(textname);
        }
    }
    return rv;
}
Beispiel #21
0
char *
caps_create_sha1_str(xmpp_stanza_t * const query)
{
    char *category = NULL;
    char *type = NULL;
    char *lang = NULL;
    char *name = NULL;
    char *feature_str = NULL;
    GSList *identities = NULL;
    GSList *features = NULL;
    GSList *form_names = NULL;
    DataForm *form = NULL;
    FormField *field = NULL;
    GHashTable *forms = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, (GDestroyNotify)form_destroy);

    xmpp_stanza_t *child = xmpp_stanza_get_children(query);
    while (child) {
        if (g_strcmp0(xmpp_stanza_get_name(child), STANZA_NAME_IDENTITY) == 0) {
            category = xmpp_stanza_get_attribute(child, "category");
            type = xmpp_stanza_get_attribute(child, "type");
            lang = xmpp_stanza_get_attribute(child, "xml:lang");
            name = xmpp_stanza_get_attribute(child, "name");

            GString *identity_str = g_string_new(category);
            g_string_append(identity_str, "/");
            if (type) {
                g_string_append(identity_str, type);
            }
            g_string_append(identity_str, "/");
            if (lang) {
                g_string_append(identity_str, lang);
            }
            g_string_append(identity_str, "/");
            if (name) {
                g_string_append(identity_str, name);
            }
            g_string_append(identity_str, "<");
            identities = g_slist_insert_sorted(identities, g_strdup(identity_str->str), (GCompareFunc)strcmp);
            g_string_free(identity_str, TRUE);
        } else if (g_strcmp0(xmpp_stanza_get_name(child), STANZA_NAME_FEATURE) == 0) {
            feature_str = xmpp_stanza_get_attribute(child, "var");
            features = g_slist_insert_sorted(features, g_strdup(feature_str), (GCompareFunc)strcmp);
        } else if (g_strcmp0(xmpp_stanza_get_name(child), STANZA_NAME_X) == 0) {
            if (g_strcmp0(xmpp_stanza_get_ns(child), STANZA_NS_DATA) == 0) {
                form = form_create(child);
                char *form_type = form_get_form_type_field(form);
                form_names = g_slist_insert_sorted(form_names, g_strdup(form_type), (GCompareFunc)strcmp);
                g_hash_table_insert(forms, g_strdup(form_type), form);
            }
        }
        child = xmpp_stanza_get_next(child);
    }

    GString *s = g_string_new("");

    GSList *curr = identities;
    while (curr) {
        g_string_append(s, curr->data);
        curr = g_slist_next(curr);
    }

    curr = features;
    while (curr) {
        g_string_append(s, curr->data);
        g_string_append(s, "<");
        curr = g_slist_next(curr);
    }

    curr = form_names;
    while (curr) {
        form = g_hash_table_lookup(forms, curr->data);
        char *form_type = form_get_form_type_field(form);
        g_string_append(s, form_type);
        g_string_append(s, "<");

        GSList *sorted_fields = form_get_non_form_type_fields_sorted(form);
        GSList *curr_field = sorted_fields;
        while (curr_field) {
            field = curr_field->data;
            g_string_append(s, field->var);
            g_string_append(s, "<");

            GSList *sorted_values = form_get_field_values_sorted(field);
            GSList *curr_value = sorted_values;
            while (curr_value) {
                g_string_append(s, curr_value->data);
                g_string_append(s, "<");
                curr_value = g_slist_next(curr_value);
            }
            g_slist_free(sorted_values);
            curr_field = g_slist_next(curr_field);
        }
        g_slist_free(sorted_fields);

        curr = g_slist_next(curr);
    }

    char *result = p_sha1_hash(s->str);

    g_string_free(s, TRUE);
    g_slist_free_full(identities, g_free);
    g_slist_free_full(features, g_free);
    g_slist_free_full(form_names, g_free);
    g_hash_table_destroy(forms);

    return result;
}
Beispiel #22
0
static int
_bookmark_handle_result(xmpp_conn_t * const conn,
    xmpp_stanza_t * const stanza, void * const userdata)
{
    xmpp_ctx_t *ctx = connection_get_ctx();
    char *id = (char *)userdata;
    xmpp_stanza_t *ptr;
    xmpp_stanza_t *nick;
    char *name;
    char *jid;
    char *autojoin;
    gboolean autojoin_val;
    Jid *my_jid;
    Bookmark *item;

    xmpp_timed_handler_delete(conn, _bookmark_handle_delete);
    g_free(id);

    name = xmpp_stanza_get_name(stanza);
    if (!name || strcmp(name, STANZA_NAME_IQ) != 0) {
        return 0;
    }

    ptr = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_QUERY);
    if (!ptr) {
        return 0;
    }
    ptr = xmpp_stanza_get_child_by_name(ptr, STANZA_NAME_STORAGE);
    if (!ptr) {
        return 0;
    }

    if (bookmark_ac == NULL) {
        bookmark_ac = autocomplete_new();
    }
    my_jid = jid_create(jabber_get_fulljid());

    ptr = xmpp_stanza_get_children(ptr);
    while (ptr) {
        name = xmpp_stanza_get_name(ptr);
        if (!name || strcmp(name, STANZA_NAME_CONFERENCE) != 0) {
            ptr = xmpp_stanza_get_next(ptr);
            continue;
        }
        jid = xmpp_stanza_get_attribute(ptr, STANZA_ATTR_JID);
        if (!jid) {
            ptr = xmpp_stanza_get_next(ptr);
            continue;
        }

        log_debug("Handle bookmark for %s", jid);

        name = NULL;
        nick = xmpp_stanza_get_child_by_name(ptr, "nick");
        if (nick) {
            char *tmp;
            tmp = xmpp_stanza_get_text(nick);
            if (tmp) {
                name = strdup(tmp);
                xmpp_free(ctx, tmp);
            }
        }

        autojoin = xmpp_stanza_get_attribute(ptr, "autojoin");
        if (autojoin && (strcmp(autojoin, "1") == 0 || strcmp(autojoin, "true") == 0)) {
            autojoin_val = TRUE;
        } else {
            autojoin_val = FALSE;
        }

        autocomplete_add(bookmark_ac, jid);
        item = malloc(sizeof(*item));
        item->jid = strdup(jid);
        item->nick = name;
        item->autojoin = autojoin_val;
        bookmark_list = g_list_append(bookmark_list, item);


        /* TODO: preference whether autojoin */
        if (autojoin_val) {
            if (autojoin_count < BOOKMARK_AUTOJOIN_MAX) {
                Jid *room_jid;

                ++autojoin_count;

                if (name == NULL) {
                    name = my_jid->localpart;
                }

                log_debug("Autojoin %s with nick=%s", jid, name);
                room_jid = jid_create_from_bare_and_resource(jid, name);
                if (!muc_room_is_active(room_jid)) {
                    presence_join_room(room_jid);
                    /* TODO: this should be removed after fixing #195 */
                    ui_room_join(room_jid);
                }
                jid_destroy(room_jid);
            } else {
                log_debug("Rejected autojoin %s (maximum has been reached)", jid);
            }
        }

        ptr = xmpp_stanza_get_next(ptr);
    }

    jid_destroy(my_jid);

    return 0;
}
Beispiel #23
0
Capabilities *
caps_create(xmpp_stanza_t *query)
{
    char *category = NULL;
    char *type = NULL;
    char *name = NULL;
    char *software = NULL;
    char *software_version = NULL;
    char *os = NULL;
    char *os_version = NULL;
    GSList *features = NULL;

    xmpp_stanza_t *softwareinfo = xmpp_stanza_get_child_by_ns(query, STANZA_NS_DATA);
    if (softwareinfo != NULL) {
        DataForm *form = form_create(softwareinfo);
        FormField *formField = NULL;

        char *form_type = form_get_form_type_field(form);
        if (g_strcmp0(form_type, STANZA_DATAFORM_SOFTWARE) == 0) {
            GSList *field = form->fields;
            while (field != NULL) {
                formField = field->data;
                if (formField->values != NULL) {
                    if (strcmp(formField->var, "software") == 0) {
                        software = strdup(formField->values->data);
                    } else if (strcmp(formField->var, "software_version") == 0) {
                        software_version = strdup(formField->values->data);
                    } else if (strcmp(formField->var, "os") == 0) {
                        os = strdup(formField->values->data);
                    } else if (strcmp(formField->var, "os_version") == 0) {
                        os_version = strdup(formField->values->data);
                    }
                }
                field = g_slist_next(field);
            }
        }

        form_destroy(form);
    }

    xmpp_stanza_t *child = xmpp_stanza_get_children(query);
    GSList *identity_stanzas = NULL;
    while (child != NULL) {
        if (g_strcmp0(xmpp_stanza_get_name(child), "feature") == 0) {
            features = g_slist_append(features, strdup(xmpp_stanza_get_attribute(child, "var")));
        }
        if (g_strcmp0(xmpp_stanza_get_name(child), "identity") == 0) {
            identity_stanzas = g_slist_append(identity_stanzas, child);
        }

        child = xmpp_stanza_get_next(child);
    }

    // find identity by locale
    const gchar* const *langs = g_get_language_names();
    int num_langs = g_strv_length((gchar**)langs);
    xmpp_stanza_t *found = NULL;
    GSList *curr_identity = identity_stanzas;
    while (curr_identity) {
        xmpp_stanza_t *id_stanza = curr_identity->data;
        char *stanza_lang = xmpp_stanza_get_attribute(id_stanza, "xml:lang");
        if (stanza_lang) {
            int i = 0;
            for (i = 0; i < num_langs; i++) {
                if (g_strcmp0(langs[i], stanza_lang) == 0) {
                    found = id_stanza;
                    break;
                }
            }
        }
        if (found) {
            break;
        }
        curr_identity = g_slist_next(curr_identity);
    }

    // not lang match, use default with no lang
    if (!found) {
        curr_identity = identity_stanzas;
        while (curr_identity) {
            xmpp_stanza_t *id_stanza = curr_identity->data;
            char *stanza_lang = xmpp_stanza_get_attribute(id_stanza, "xml:lang");
            if (!stanza_lang) {
                found = id_stanza;
                break;
            }

            curr_identity = g_slist_next(curr_identity);
        }
    }

    // no matching lang, no identity without lang, use first
    if (!found) {
        if (identity_stanzas) {
            found = identity_stanzas->data;
        }
    }

    g_slist_free(identity_stanzas);

    if (found) {
        category = xmpp_stanza_get_attribute(found, "category");
        type = xmpp_stanza_get_attribute(found, "type");
        name = xmpp_stanza_get_attribute(found, "name");
    }

    Capabilities *new_caps = malloc(sizeof(struct capabilities_t));

    if (category != NULL) {
        new_caps->category = strdup(category);
    } else {
        new_caps->category = NULL;
    }
    if (type != NULL) {
        new_caps->type = strdup(type);
    } else {
        new_caps->type = NULL;
    }
    if (name != NULL) {
        new_caps->name = strdup(name);
    } else {
        new_caps->name = NULL;
    }
    if (software != NULL) {
        new_caps->software = software;
    } else {
        new_caps->software = NULL;
    }
    if (software_version != NULL) {
        new_caps->software_version = software_version;
    } else {
        new_caps->software_version = NULL;
    }
    if (os != NULL) {
        new_caps->os = os;
    } else {
        new_caps->os = NULL;
    }
    if (os_version != NULL) {
        new_caps->os_version = os_version;
    } else {
        new_caps->os_version = NULL;
    }
    if (features != NULL) {
        new_caps->features = features;
    } else {
        new_caps->features = NULL;
    }

    return new_caps;
}
Beispiel #24
0
static int
_iq_handle_discoinfo_result(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza,
    void * const userdata)
{
    log_debug("Recieved diso#info response");
    const char *id = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_ID);
    const char *from = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_FROM);

    if (g_strcmp0(id, "discoinforeq") == 0) {
        GSList *identities = NULL;
        GSList *features = NULL;

        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) {
                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);
        }
    } else if ((id != NULL) && (g_str_has_prefix(id, "capsreq"))) {
        log_debug("Response to query: %s", id);
        xmpp_stanza_t *query = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_QUERY);
        char *node = xmpp_stanza_get_attribute(query, STANZA_ATTR_NODE);
        if (node == NULL) {
            return 1;
        }

        char *caps_key = NULL;

        // xep-0115
        if (g_strcmp0(id, "capsreq") == 0) {
            log_debug("xep-0115 supported capabilities");
            caps_key = strdup(node);

            // 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_info("Generated sha-1 does not match given:");
                log_info("Generated : %s", generated_sha1);
                log_info("Given     : %s", given_sha1);
                g_free(generated_sha1);
                g_strfreev(split);
                free(caps_key);

                return 1;
            }
            g_free(generated_sha1);
            g_strfreev(split);

        // non supported hash, or legacy caps
        } else {
            log_debug("Unsupported hash, or legacy capabilities");
            caps_key = strdup(id + 8);
            log_debug("Caps key: %s", caps_key);
        }

        // already cached
        if (caps_contains(caps_key)) {
            log_info("Client info already cached.");
            free(caps_key);
            return 1;
        }

        log_debug("Client info not cached");

        const char *category = NULL;
        const char *type = NULL;
        const char *name = NULL;
        const char *software = NULL;
        const char *software_version = NULL;
        const char *os = NULL;
        const char *os_version = NULL;
        GSList *features = NULL;

        xmpp_stanza_t *identity = xmpp_stanza_get_child_by_name(query, "identity");
        if (identity != NULL) {
            category = xmpp_stanza_get_attribute(identity, "category");
            type = xmpp_stanza_get_attribute(identity, "type");
            name = xmpp_stanza_get_attribute(identity, "name");
        }

        xmpp_stanza_t *softwareinfo = xmpp_stanza_get_child_by_ns(query, STANZA_NS_DATA);
        if (softwareinfo != NULL) {
            DataForm *form = stanza_create_form(softwareinfo);
            FormField *formField = NULL;

            if (g_strcmp0(form->form_type, STANZA_DATAFORM_SOFTWARE) == 0) {
                GSList *field = form->fields;
                while (field != NULL) {
                    formField = field->data;
                    if (formField->values != NULL) {
                        if (strcmp(formField->var, "software") == 0) {
                            software = formField->values->data;
                        } else if (strcmp(formField->var, "software_version") == 0) {
                            software_version = formField->values->data;
                        } else if (strcmp(formField->var, "os") == 0) {
                            os = formField->values->data;
                        } else if (strcmp(formField->var, "os_version") == 0) {
                            os_version = formField->values->data;
                        }
                    }
                    field = g_slist_next(field);
                }
            }

            stanza_destroy_form(form);
        }

        xmpp_stanza_t *child = xmpp_stanza_get_children(query);
        while (child != NULL) {
            if (g_strcmp0(xmpp_stanza_get_name(child), "feature") == 0) {
                features = g_slist_append(features, strdup(xmpp_stanza_get_attribute(child, "var")));
            }

            child = xmpp_stanza_get_next(child);
        }

        caps_add(caps_key, category, type, name, software, software_version,
            os, os_version, features);

        free(caps_key);
    }

    return 1;
}
Beispiel #25
0
static sdvp_WriteParam_t* _CreateWriteParam (xmpp_stanza_t * params) {
    int expectedParams, nVarParams = 0;
    sdvp_WriteParam_t* rv = NULL;
    int i = 0, j = 0, expectedDataElementsInArray;
    bool elementNotFund = false;
    xmpp_stanza_t *structure = NULL, *member = NULL, *value = NULL,
            *type = NULL;
    xmpp_stanza_t *name = NULL, *array, *arrayEntry;
    char *text, *textname;

    structure = _GetRpcStructureElementFromParams(params);
    if (structure == NULL ) {
        return NULL ;
    }

    // Get the number of elements
    //
    expectedParams = _FindNumberOfParams(params);
    if (expectedParams > 1) {
        nVarParams = expectedParams - 1;
    } else {
        // TODO: This should result in a ServiceError as minimum two is expected
    }

    rv = _InitiateWriteParameters(nVarParams);
    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"))) {
                _FreeWriteParameters(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"))) {
                    _FreeWriteParameters(rv);
                    // TODO: Signal error back
                    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->params->reference = text;
                    } else {
                        rv->params->reference = NULL;
                    }
                } else {
                    elementNotFund = true;
                }
            } else if (strcmp(textname, "ListOfData") == 0) {
                if (!(value = xmpp_stanza_get_child_by_name(member, "value"))) {
                    _FreeWriteParameters(rv);
                    // TODO: Signal error back
                    return NULL ;
                }
                if (!(array = xmpp_stanza_get_child_by_name(value, "array"))) {
                    _FreeWriteParameters(rv);
                    // TODO: Signal error back
                    return NULL ;
                }

                expectedDataElementsInArray = _countDataElementsInArray(array);
                _InitiateWriteDataParameters(rv, expectedDataElementsInArray);

//                array = xmpp_stanza_get_children(array);
                arrayEntry = xmpp_stanza_get_children(array);
//HJP Why skip the first element?!
//                arrayEntry = xmpp_stanza_get_next(arrayEntry);

                for (j = 0; arrayEntry;
                     arrayEntry = xmpp_stanza_get_next(arrayEntry)) {

                    if (xmpp_stanza_is_tag(arrayEntry)) {
                        if (!(value = xmpp_stanza_get_child_by_name(arrayEntry,
                                "value"))) {
                            _FreeWriteParameters(rv);
                            // TODO: Signal error back
                            return NULL ;
                        }

                        // MISSING: base64
                        if ((type = xmpp_stanza_get_child_by_name(value,
                                "string"))) {
                            rv->params->dataAttributeValues[j]->dataType =
                                    IEC_VISIBLE_STRING;
                            rv->params->dataAttributeValues[j]->strValue =
                                    xmpp_stanza_get_text(type);
                        } else if ((type = xmpp_stanza_get_child_by_name(value,
                                "i4"))
                                ||
                                (type = xmpp_stanza_get_child_by_name(value,
                                        "int"))) {
                            rv->params->dataAttributeValues[j]->dataType =
                                    IEC_INT32;
							text = xmpp_stanza_get_text(type);
                            rv->params->dataAttributeValues[j]->intValue =
                                    strtol(text, NULL,
                                            10);
							free(text);
                        } else if ((type = xmpp_stanza_get_child_by_name(value,
                                "double"))) {
                            rv->params->dataAttributeValues[j]->dataType =
                                    IEC_FLOAT32;
							text = xmpp_stanza_get_text(type);
                            rv->params->dataAttributeValues[j]->f32Value =
                                    strtof(text, NULL );
							free(text);
                        } else if ((type = xmpp_stanza_get_child_by_name(value,
                                "boolean"))) {
                            rv->params->dataAttributeValues[j]->dataType =
                                    IEC_BOOLEAN;
							text = xmpp_stanza_get_text(type);
                            if (strcmp(text, "1") == 0) {
                                rv->params->dataAttributeValues[j]->boolValue =
                                        true;
                            } else {
                                rv->params->dataAttributeValues[j]->boolValue =
                                        false;
                            }
							free(text);
                        } else if ((type = xmpp_stanza_get_child_by_name(value,
                                "dateTime.iso8601"))) {
                            rv->params->dataAttributeValues[j]->dataType =
                                    IEC_TIME;
							text = xmpp_stanza_get_text(type);
                            rv->params->dataAttributeValues[j]->time =
                                    ne_iso8601_parse(text);
							free(text);
                        }
                        j++;
                    }
                }

            } else {
//                if (!type) {
//                    _FreeWriteParameters(rv);
//                    return NULL ;
//                }
            }
			free(textname);
        }
    }
    return rv;
}
Beispiel #26
0
static int
_bookmark_result_id_handler(xmpp_stanza_t *const stanza, void *const userdata)
{
    const char *name = xmpp_stanza_get_name(stanza);
    if (!name || strcmp(name, STANZA_NAME_IQ) != 0) {
        return 0;
    }

    xmpp_stanza_t *query = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_QUERY);
    if (!query) {
        return 0;
    }
    xmpp_stanza_t *storage = xmpp_stanza_get_child_by_name(query, STANZA_NAME_STORAGE);
    if (!storage) {
        return 0;
    }

    if (bookmark_ac == NULL) {
        bookmark_ac = autocomplete_new();
    }

    xmpp_stanza_t *child = xmpp_stanza_get_children(storage);
    while (child) {
        name = xmpp_stanza_get_name(child);
        if (!name || strcmp(name, STANZA_NAME_CONFERENCE) != 0) {
            child = xmpp_stanza_get_next(child);
            continue;
        }
        const char *barejid = xmpp_stanza_get_attribute(child, STANZA_ATTR_JID);
        if (!barejid) {
            child = xmpp_stanza_get_next(child);
            continue;
        }

        log_debug("Handle bookmark for %s", barejid);

        char *nick = NULL;
        xmpp_stanza_t *nick_st = xmpp_stanza_get_child_by_name(child, "nick");
        if (nick_st) {
            nick = stanza_text_strdup(nick_st);
        }

        char *password = NULL;
        xmpp_stanza_t *password_st = xmpp_stanza_get_child_by_name(child, "password");
        if (password_st) {
            password = stanza_text_strdup(password_st);
        }

        const char *autojoin = xmpp_stanza_get_attribute(child, "autojoin");
        gboolean autojoin_val = FALSE;;
        if (autojoin && (strcmp(autojoin, "1") == 0 || strcmp(autojoin, "true") == 0)) {
            autojoin_val = TRUE;
        }

        autocomplete_add(bookmark_ac, barejid);
        Bookmark *bookmark = malloc(sizeof(Bookmark));
        bookmark->barejid = strdup(barejid);
        bookmark->nick = nick;
        bookmark->password = password;
        bookmark->autojoin = autojoin_val;
        g_hash_table_insert(bookmarks, strdup(barejid), bookmark);

        if (autojoin_val) {
            sv_ev_bookmark_autojoin(bookmark);
        }

        Jid *jidp = jid_create(barejid);
        if (jidp->domainpart) {
            muc_confserver_add(jidp->domainpart);
        }
        jid_destroy(jidp);

        child = xmpp_stanza_get_next(child);
    }

    return 0;
}
Beispiel #27
0
static int
_bookmark_handle_result(xmpp_conn_t *const conn,
    xmpp_stanza_t *const stanza, void *const userdata)
{
    xmpp_ctx_t *ctx = connection_get_ctx();
    char *id = (char *)userdata;
    xmpp_stanza_t *ptr;
    xmpp_stanza_t *nick;
    xmpp_stanza_t *password_st;
    char *name;
    char *jid;
    char *autojoin;
    char *password;
    gboolean autojoin_val;
    Jid *my_jid;
    Bookmark *item;

    xmpp_timed_handler_delete(conn, _bookmark_handle_delete);
    g_free(id);

    name = xmpp_stanza_get_name(stanza);
    if (!name || strcmp(name, STANZA_NAME_IQ) != 0) {
        return 0;
    }

    ptr = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_QUERY);
    if (!ptr) {
        return 0;
    }
    ptr = xmpp_stanza_get_child_by_name(ptr, STANZA_NAME_STORAGE);
    if (!ptr) {
        return 0;
    }

    if (bookmark_ac == NULL) {
        bookmark_ac = autocomplete_new();
    }
    my_jid = jid_create(jabber_get_fulljid());

    ptr = xmpp_stanza_get_children(ptr);
    while (ptr) {
        name = xmpp_stanza_get_name(ptr);
        if (!name || strcmp(name, STANZA_NAME_CONFERENCE) != 0) {
            ptr = xmpp_stanza_get_next(ptr);
            continue;
        }
        jid = xmpp_stanza_get_attribute(ptr, STANZA_ATTR_JID);
        if (!jid) {
            ptr = xmpp_stanza_get_next(ptr);
            continue;
        }

        log_debug("Handle bookmark for %s", jid);

        name = NULL;
        nick = xmpp_stanza_get_child_by_name(ptr, "nick");
        if (nick) {
            char *tmp;
            tmp = xmpp_stanza_get_text(nick);
            if (tmp) {
                name = strdup(tmp);
                xmpp_free(ctx, tmp);
            }
        }

        password = NULL;
        password_st = xmpp_stanza_get_child_by_name(ptr, "password");
        if (password_st) {
            char *tmp;
            tmp = xmpp_stanza_get_text(password_st);
            if (tmp) {
                password = strdup(tmp);
                xmpp_free(ctx, tmp);
            }
        }

        autojoin = xmpp_stanza_get_attribute(ptr, "autojoin");
        if (autojoin && (strcmp(autojoin, "1") == 0 || strcmp(autojoin, "true") == 0)) {
            autojoin_val = TRUE;
        } else {
            autojoin_val = FALSE;
        }

        autocomplete_add(bookmark_ac, jid);
        item = malloc(sizeof(*item));
        item->jid = strdup(jid);
        item->nick = name;
        item->password = password;
        item->autojoin = autojoin_val;
        bookmark_list = g_list_append(bookmark_list, item);

        if (autojoin_val) {
            Jid *room_jid;

            char *account_name = jabber_get_account_name();
            ProfAccount *account = accounts_get_account(account_name);
            if (name == NULL) {
                name = account->muc_nick;
            }

            log_debug("Autojoin %s with nick=%s", jid, name);
            room_jid = jid_create_from_bare_and_resource(jid, name);
            if (!muc_active(room_jid->barejid)) {
                presence_join_room(jid, name, password);
                muc_join(jid, name, password, TRUE);
            }
            jid_destroy(room_jid);
            account_free(account);
        }

        ptr = xmpp_stanza_get_next(ptr);
    }

    jid_destroy(my_jid);

    return 0;
}
Beispiel #28
0
DataForm*
form_create(xmpp_stanza_t *const form_stanza)
{
    xmpp_ctx_t *ctx = connection_get_ctx();

    if (!_is_valid_form_element(form_stanza)) {
        return NULL;
    }

    DataForm *form = _form_new();
    form->type = _get_attr(form_stanza, "type");
    form->title = _get_property(form_stanza, "title");
    form->instructions = _get_property(form_stanza, "instructions");
    form->var_to_tag = g_hash_table_new_full(g_str_hash, g_str_equal, free, free);
    form->tag_to_var = g_hash_table_new_full(g_str_hash, g_str_equal, free, free);
    form->tag_ac = autocomplete_new();
    form->modified = FALSE;

    int tag_num = 1;

    // get fields
    xmpp_stanza_t *form_child = xmpp_stanza_get_children(form_stanza);
    while (form_child) {
        const char *child_name = xmpp_stanza_get_name(form_child);
        if (g_strcmp0(child_name, "field") == 0) {
            xmpp_stanza_t *field_stanza = form_child;

            FormField *field = _field_new();
            field->label = _get_attr(field_stanza, "label");
            field->type = _get_attr(field_stanza, "type");
            field->type_t = _get_field_type(field->type);
            field->value_ac = autocomplete_new();

            field->var = _get_attr(field_stanza, "var");

            if (field->type_t != FIELD_HIDDEN && field->var) {
                GString *tag = g_string_new("");
                g_string_printf(tag, "field%d", tag_num++);
                g_hash_table_insert(form->var_to_tag, strdup(field->var), strdup(tag->str));
                g_hash_table_insert(form->tag_to_var, strdup(tag->str), strdup(field->var));
                autocomplete_add(form->tag_ac, tag->str);
                g_string_free(tag, TRUE);
            }

            field->description = _get_property(field_stanza, "desc");
            field->required = _is_required(field_stanza);

            // handle repeated field children
            xmpp_stanza_t *field_child = xmpp_stanza_get_children(field_stanza);
            int value_index = 1;
            while (field_child) {
                child_name = xmpp_stanza_get_name(field_child);

                // handle values
                if (g_strcmp0(child_name, "value") == 0) {
                    char *value = xmpp_stanza_get_text(field_child);
                    if (value) {
                        field->values = g_slist_append(field->values, strdup(value));

                        if (field->type_t == FIELD_TEXT_MULTI) {
                            GString *ac_val = g_string_new("");
                            g_string_printf(ac_val, "val%d", value_index++);
                            autocomplete_add(field->value_ac, ac_val->str);
                            g_string_free(ac_val, TRUE);
                        }
                        if (field->type_t == FIELD_JID_MULTI) {
                            autocomplete_add(field->value_ac, value);
                        }

                        xmpp_free(ctx, value);
                    }

                // handle options
                } else if (g_strcmp0(child_name, "option") == 0) {
                    FormOption *option = malloc(sizeof(FormOption));
                    option->label = _get_attr(field_child, "label");
                    option->value = _get_property(field_child, "value");

                    if ((field->type_t == FIELD_LIST_SINGLE) || (field->type_t == FIELD_LIST_MULTI)) {
                        autocomplete_add(field->value_ac, option->value);
                    }

                    field->options = g_slist_append(field->options, option);
                }

                field_child = xmpp_stanza_get_next(field_child);
            }

            form->fields = g_slist_append(form->fields, field);
        }

        form_child = xmpp_stanza_get_next(form_child);
    }

    return form;
}
Beispiel #29
0
/* stream:error handler */
static int _handle_error(xmpp_conn_t * const conn,
			 xmpp_stanza_t * const stanza,
			 void * const userdata)
{
    xmpp_stanza_t *child;
    char *name;

    /* free old stream error if it's still there */
    if (conn->stream_error) {
	xmpp_stanza_release(conn->stream_error->stanza);
	if (conn->stream_error->text)
	    xmpp_free(conn->ctx, conn->stream_error->text);
	xmpp_free(conn->ctx, conn->stream_error);
    }

    /* create stream error structure */
    conn->stream_error = (xmpp_stream_error_t *)xmpp_alloc(conn->ctx, sizeof(xmpp_stream_error_t));

	conn->stream_error->text = NULL;
	conn->stream_error->type = XMPP_SE_UNDEFINED_CONDITION;

    if (conn->stream_error) {
	child = xmpp_stanza_get_children(stanza);
	do {
	    char *ns = NULL;

	    if (child) {
		ns = xmpp_stanza_get_ns(child);
	    }

	    if (ns && strcmp(ns, XMPP_NS_STREAMS_IETF) == 0) {
		name = xmpp_stanza_get_name(child);
		if (strcmp(name, "text") == 0) {
		    if (conn->stream_error->text)
			xmpp_free(conn->ctx, conn->stream_error->text);
		    conn->stream_error->text = xmpp_stanza_get_text(child);
		} else if (strcmp(name, "bad-format") == 0)
		    conn->stream_error->type = XMPP_SE_BAD_FORMAT;
		else if (strcmp(name, "bad-namespace-prefix") == 0)
		    conn->stream_error->type = XMPP_SE_BAD_NS_PREFIX;
		else if (strcmp(name, "conflict") == 0)
		    conn->stream_error->type = XMPP_SE_CONFLICT;
		else if (strcmp(name, "connection-timeout") == 0)
		    conn->stream_error->type = XMPP_SE_CONN_TIMEOUT;
		else if (strcmp(name, "host-gone") == 0)
		    conn->stream_error->type = XMPP_SE_HOST_GONE;
		else if (strcmp(name, "host-unknown") == 0)
		    conn->stream_error->type = XMPP_SE_HOST_UNKNOWN;
		else if (strcmp(name, "improper-addressing") == 0)
		    conn->stream_error->type = XMPP_SE_IMPROPER_ADDR;
		else if (strcmp(name, "internal-server-error") == 0)
		    conn->stream_error->type = XMPP_SE_INTERNAL_SERVER_ERROR;
		else if (strcmp(name, "invalid-from") == 0)
		    conn->stream_error->type = XMPP_SE_INVALID_FROM;
		else if (strcmp(name, "invalid-id") == 0)
		    conn->stream_error->type = XMPP_SE_INVALID_ID;
		else if (strcmp(name, "invalid-namespace") == 0)
		    conn->stream_error->type = XMPP_SE_INVALID_NS;
		else if (strcmp(name, "invalid-xml") == 0)
		    conn->stream_error->type = XMPP_SE_INVALID_XML;
		else if (strcmp(name, "not-authorized") == 0)
		    conn->stream_error->type = XMPP_SE_NOT_AUTHORIZED;
		else if (strcmp(name, "policy-violation") == 0)
		    conn->stream_error->type = XMPP_SE_POLICY_VIOLATION;
		else if (strcmp(name, "remote-connection-failed") == 0)
		    conn->stream_error->type = XMPP_SE_REMOTE_CONN_FAILED;
		else if (strcmp(name, "resource-constraint") == 0)
		    conn->stream_error->type = XMPP_SE_RESOURCE_CONSTRAINT;
		else if (strcmp(name, "restricted-xml") == 0)
		    conn->stream_error->type = XMPP_SE_RESTRICTED_XML;
		else if (strcmp(name, "see-other-host") == 0)
		    conn->stream_error->type = XMPP_SE_SEE_OTHER_HOST;
		else if (strcmp(name, "system-shutdown") == 0)
		    conn->stream_error->type = XMPP_SE_SYSTEM_SHUTDOWN;
		else if (strcmp(name, "undefined-condition") == 0)
		    conn->stream_error->type = XMPP_SE_UNDEFINED_CONDITION;
		else if (strcmp(name, "unsupported-encoding") == 0)
		    conn->stream_error->type = XMPP_SE_UNSUPPORTED_ENCODING;
		else if (strcmp(name, "unsupported-stanza-type") == 0)
		    conn->stream_error->type = XMPP_SE_UNSUPPORTED_STANZA_TYPE;
		else if (strcmp(name, "unsupported-version") == 0)
		    conn->stream_error->type = XMPP_SE_UNSUPPORTED_VERSION;
		else if (strcmp(name, "xml-not-well-formed") == 0)
		    conn->stream_error->type = XMPP_SE_XML_NOT_WELL_FORMED;
	    }
	} while ((child = xmpp_stanza_get_next(child)));

	conn->stream_error->stanza = xmpp_stanza_clone(stanza);
    }

    return 1;
}
Beispiel #30
0
static int
_roster_result_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);

    if (g_strcmp0(id, "roster") != 0) {
        return 1;
    }

    // handle initial roster response
    xmpp_stanza_t *query = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_QUERY);
    xmpp_stanza_t *item = xmpp_stanza_get_children(query);

    while (item) {
        const char *barejid = xmpp_stanza_get_attribute(item, STANZA_ATTR_JID);
        gchar *barejid_lower = g_utf8_strdown(barejid, -1);
        const char *name = xmpp_stanza_get_attribute(item, STANZA_ATTR_NAME);
        const char *sub = xmpp_stanza_get_attribute(item, STANZA_ATTR_SUBSCRIPTION);

        // do not set nickname to empty string, set to NULL instead
        if (name && (strlen(name) == 0)) name = NULL;

        gboolean pending_out = FALSE;
        const char *ask = xmpp_stanza_get_attribute(item, STANZA_ATTR_ASK);
        if (g_strcmp0(ask, "subscribe") == 0) {
            pending_out = TRUE;
        }

        GSList *groups = _get_groups_from_item(item);

        gboolean added = roster_add(barejid_lower, name, groups, sub, pending_out);
        if (!added) {
            log_warning("Attempt to add contact twice: %s", barejid_lower);
        }

        g_free(barejid_lower);
        item = xmpp_stanza_get_next(item);
    }

    sv_ev_roster_received();

    char *account = jabber_get_account_name();
    resource_presence_t conn_presence = accounts_get_login_presence(account);

    char *last_activity_str = accounts_get_last_activity(account);
    if (last_activity_str) {
        GDateTime *nowdt = g_date_time_new_now_utc();

        GTimeVal lasttv;
        gboolean res = g_time_val_from_iso8601(last_activity_str, &lasttv);
        if (res) {
            GDateTime *lastdt = g_date_time_new_from_timeval_utc(&lasttv);
            GTimeSpan diff_micros = g_date_time_difference(nowdt, lastdt);
            int diff_secs = (diff_micros / 1000) / 1000;
            cl_ev_presence_send(conn_presence, NULL, diff_secs);
            g_date_time_unref(lastdt);
        } else {
            cl_ev_presence_send(conn_presence, NULL, 0);
        }

        free(last_activity_str);
        g_date_time_unref(nowdt);
    } else {
        cl_ev_presence_send(conn_presence, NULL, 0);
    }

    return 1;
}