Beispiel #1
0
static int _handle_bind(xmpp_conn_t * const conn,
			xmpp_stanza_t * const stanza,
			void * const userdata)
{
    const char *type;
    xmpp_stanza_t *iq, *session;

    /* delete missing bind handler */
    xmpp_timed_handler_delete(conn, _handle_missing_bind);

    /* server has replied to bind request */
    type = xmpp_stanza_get_type(stanza);
    if (type && strcmp(type, "error") == 0) {
	xmpp_error(conn->ctx, "xmpp", "Binding failed.");
	xmpp_disconnect(conn);
    } else if (type && strcmp(type, "result") == 0) {
        xmpp_stanza_t *binding = xmpp_stanza_get_child_by_name(stanza, "bind");
	xmpp_debug(conn->ctx, "xmpp", "Bind successful.");

        if (binding) {
            xmpp_stanza_t *jid_stanza = xmpp_stanza_get_child_by_name(binding,
                                                                      "jid");
            if (jid_stanza) {
                conn->bound_jid = xmpp_stanza_get_text(jid_stanza);
            }
        }

	/* establish a session if required */
	if (conn->session_required) {
	    /* setup response handlers */
	    handler_add_id(conn, _handle_session, "_xmpp_session1", NULL);
	    handler_add_timed(conn, _handle_missing_session,
			      SESSION_TIMEOUT, NULL);

	    /* send session request */
	    iq = xmpp_stanza_new(conn->ctx);
	    if (!iq) {
		disconnect_mem_error(conn);
		return 0;
	    }

	    xmpp_stanza_set_name(iq, "iq");
	    xmpp_stanza_set_type(iq, "set");
	    xmpp_stanza_set_id(iq, "_xmpp_session1");

	    session = xmpp_stanza_new(conn->ctx);
	    if (!session) {
		xmpp_stanza_release(iq);
		disconnect_mem_error(conn);
	    }

	    xmpp_stanza_set_name(session, "session");
	    xmpp_stanza_set_ns(session, XMPP_NS_SESSION);

	    xmpp_stanza_add_child(iq, session);
	    xmpp_stanza_release(session);

	    /* send session establishment request */
	    xmpp_send(conn, iq);
	    xmpp_stanza_release(iq);
	} else {
	    conn->authenticated = 1;

	    /* call connection handler */
	    conn->conn_handler(conn, XMPP_CONN_CONNECT, 0, NULL,
			       conn->userdata);
	}
    } else {
	xmpp_error(conn->ctx, "xmpp", "Server sent malformed bind reply.");
	xmpp_disconnect(conn);
    }

    return 0;
}
Beispiel #2
0
/* authenticate the connection
 * this may get called multiple times.  if any auth method fails,
 * this will get called again until one auth method succeeds or every
 * method fails
 */
static void _auth(xmpp_conn_t * const conn)
{
    xmpp_stanza_t *auth, *authdata, *query, *child, *iq;
    char *str, *authid;
    char *scram_init;
    int anonjid;

    /* if there is no node in conn->jid, we assume anonymous connect */
    str = xmpp_jid_node(conn->ctx, conn->jid);
    if (str == NULL) {
	anonjid = 1;
    } else {
	xmpp_free(conn->ctx, str);
	anonjid = 0;
    }

    if (conn->tls_support) {
	tls_t *tls = tls_new(conn->ctx, conn->sock, conn->certfail_handler, conn->tls_cert_path);

	/* If we couldn't init tls, it isn't there, so go on */
	if (!tls) {
	    conn->tls_support = 0;
	    _auth(conn);
	    return;
	} else {
	    tls_free(tls);
	}

	auth = _make_starttls(conn);

	if (!auth) {
	    disconnect_mem_error(conn);
	    return;
	}

	handler_add(conn, _handle_proceedtls_default,
		    XMPP_NS_TLS, NULL, NULL, NULL);

	xmpp_send(conn, auth);
	xmpp_stanza_release(auth);

	/* TLS was tried, unset flag */
	conn->tls_support = 0;
	/* _auth() will be called later */
	return;
    }

    if (conn->tls_mandatory && !xmpp_conn_is_secured(conn)) {
        xmpp_error(conn->ctx, "xmpp", "TLS is not supported, but set as "
                                      "mandatory for this connection");
        conn_disconnect(conn);
        return;
    }

    if (anonjid && conn->sasl_support & SASL_MASK_ANONYMOUS) {
	/* some crap here */
	auth = _make_sasl_auth(conn, "ANONYMOUS");
	if (!auth) {
	    disconnect_mem_error(conn);
	    return;
	}

	handler_add(conn, _handle_sasl_result, XMPP_NS_SASL,
	            NULL, NULL, "ANONYMOUS");

	xmpp_send(conn, auth);
	xmpp_stanza_release(auth);

	/* SASL ANONYMOUS was tried, unset flag */
	conn->sasl_support &= ~SASL_MASK_ANONYMOUS;
    } else if (anonjid) {
	xmpp_error(conn->ctx, "auth",
		   "No node in JID, and SASL ANONYMOUS unsupported.");
	xmpp_disconnect(conn);
    } else if (conn->sasl_support & SASL_MASK_SCRAMSHA1) {
        auth = _make_sasl_auth(conn, "SCRAM-SHA-1");
        if (!auth) {
            disconnect_mem_error(conn);
            return;
        }

        /* don't free scram_init on success */
        scram_init = _make_scram_sha1_init_msg(conn);
        if (!scram_init) {
            xmpp_stanza_release(auth);
            disconnect_mem_error(conn);
            return;
        }

        str = xmpp_base64_encode(conn->ctx, (unsigned char *)scram_init,
                                 strlen(scram_init));
        if (!str) {
            xmpp_free(conn->ctx, scram_init);
            xmpp_stanza_release(auth);
            disconnect_mem_error(conn);
            return;
        }

        authdata = xmpp_stanza_new(conn->ctx);
        if (!authdata) {
            xmpp_free(conn->ctx, str);
            xmpp_free(conn->ctx, scram_init);
            xmpp_stanza_release(auth);
            disconnect_mem_error(conn);
            return;
        }
        xmpp_stanza_set_text(authdata, str);
        xmpp_free(conn->ctx, str);
        xmpp_stanza_add_child(auth, authdata);
        xmpp_stanza_release(authdata);

        handler_add(conn, _handle_scram_sha1_challenge,
                    XMPP_NS_SASL, NULL, NULL, (void *)scram_init);

        xmpp_send(conn, auth);
        xmpp_stanza_release(auth);

        /* SASL SCRAM-SHA-1 was tried, unset flag */
        conn->sasl_support &= ~SASL_MASK_SCRAMSHA1;
    } else if (conn->sasl_support & SASL_MASK_DIGESTMD5) {
	auth = _make_sasl_auth(conn, "DIGEST-MD5");
	if (!auth) {
	    disconnect_mem_error(conn);
	    return;

	}

	handler_add(conn, _handle_digestmd5_challenge,
		    XMPP_NS_SASL, NULL, NULL, NULL);

	xmpp_send(conn, auth);
	xmpp_stanza_release(auth);

	/* SASL DIGEST-MD5 was tried, unset flag */
	conn->sasl_support &= ~SASL_MASK_DIGESTMD5;
    } else if (conn->sasl_support & SASL_MASK_PLAIN) {
	auth = _make_sasl_auth(conn, "PLAIN");
	if (!auth) {
	    disconnect_mem_error(conn);
	    return;
	}
	authdata = xmpp_stanza_new(conn->ctx);
	if (!authdata) {
	    disconnect_mem_error(conn);
	    return;
	}
	authid = _get_authid(conn);
	if (!authid) {
	    disconnect_mem_error(conn);
	    return;
	}
	str = sasl_plain(conn->ctx, authid, conn->pass);
	if (!str) {
	    disconnect_mem_error(conn);
	    return;
	}
	xmpp_stanza_set_text(authdata, str);
	xmpp_free(conn->ctx, str);
	xmpp_free(conn->ctx, authid);

	xmpp_stanza_add_child(auth, authdata);
	xmpp_stanza_release(authdata);

	handler_add(conn, _handle_sasl_result,
		    XMPP_NS_SASL, NULL, NULL, "PLAIN");

	xmpp_send(conn, auth);
	xmpp_stanza_release(auth);

	/* SASL PLAIN was tried */
	conn->sasl_support &= ~SASL_MASK_PLAIN;
    } else if (conn->type == XMPP_CLIENT) {
	/* legacy client authentication */

	iq = xmpp_stanza_new(conn->ctx);
	if (!iq) {
	    disconnect_mem_error(conn);
	    return;
	}
	xmpp_stanza_set_name(iq, "iq");
	xmpp_stanza_set_type(iq, "set");
	xmpp_stanza_set_id(iq, "_xmpp_auth1");

	query = xmpp_stanza_new(conn->ctx);
	if (!query) {
	    xmpp_stanza_release(iq);
	    disconnect_mem_error(conn);
	    return;
	}
	xmpp_stanza_set_name(query, "query");
	xmpp_stanza_set_ns(query, XMPP_NS_AUTH);
	xmpp_stanza_add_child(iq, query);
	xmpp_stanza_release(query);

	child = xmpp_stanza_new(conn->ctx);
	if (!child) {
	    xmpp_stanza_release(iq);
	    disconnect_mem_error(conn);
	    return;
	}
	xmpp_stanza_set_name(child, "username");
	xmpp_stanza_add_child(query, child);
	xmpp_stanza_release(child);

	authdata = xmpp_stanza_new(conn->ctx);
	if (!authdata) {
	    xmpp_stanza_release(iq);
	    disconnect_mem_error(conn);
	    return;
	}
	str = xmpp_jid_node(conn->ctx, conn->jid);
	xmpp_stanza_set_text(authdata, str);
	xmpp_free(conn->ctx, str);
	xmpp_stanza_add_child(child, authdata);
	xmpp_stanza_release(authdata);

	child = xmpp_stanza_new(conn->ctx);
	if (!child) {
	    xmpp_stanza_release(iq);
	    disconnect_mem_error(conn);
	    return;
	}
	xmpp_stanza_set_name(child, "password");
	xmpp_stanza_add_child(query, child);
	xmpp_stanza_release(child);

	authdata = xmpp_stanza_new(conn->ctx);
	if (!authdata) {
	    xmpp_stanza_release(iq);
	    disconnect_mem_error(conn);
	    return;
	}
	xmpp_stanza_set_text(authdata, conn->pass);
	xmpp_stanza_add_child(child, authdata);
	xmpp_stanza_release(authdata);

	child = xmpp_stanza_new(conn->ctx);
	if (!child) {
	    xmpp_stanza_release(iq);
	    disconnect_mem_error(conn);
	    return;
	}
	xmpp_stanza_set_name(child, "resource");
	xmpp_stanza_add_child(query, child);
	xmpp_stanza_release(child);

	authdata = xmpp_stanza_new(conn->ctx);
	if (!authdata) {
	    xmpp_stanza_release(iq);
	    disconnect_mem_error(conn);
	    return;
	}
	str = xmpp_jid_resource(conn->ctx, conn->jid);
	if (str) {
	    xmpp_stanza_set_text(authdata, str);
	    xmpp_free(conn->ctx, str);
	} else {
	    xmpp_stanza_release(authdata);
	    xmpp_stanza_release(iq);
	    xmpp_error(conn->ctx, "auth",
		       "Cannot authenticate without resource");
	    xmpp_disconnect(conn);
	    return;
	}
	xmpp_stanza_add_child(child, authdata);
	xmpp_stanza_release(authdata);

	handler_add_id(conn, _handle_legacy, "_xmpp_auth1", NULL);
	handler_add_timed(conn, _handle_missing_legacy,
			  LEGACY_TIMEOUT, NULL);

	xmpp_send(conn, iq);
	xmpp_stanza_release(iq);
    }
}
Beispiel #3
0
static int _handle_features_sasl(xmpp_conn_t * const conn,
				 xmpp_stanza_t * const stanza,
				 void * const userdata)
{
    xmpp_stanza_t *bind, *session, *iq, *res, *text;
    char *resource;

    /* remove missing features handler */
    xmpp_timed_handler_delete(conn, _handle_missing_features_sasl);

    /* we are expecting <bind/> and <session/> since this is a
       XMPP style connection */

    bind = xmpp_stanza_get_child_by_name(stanza, "bind");
    if (bind && strcmp(xmpp_stanza_get_ns(bind), XMPP_NS_BIND) == 0) {
	/* resource binding is required */
	conn->bind_required = 1;
    }

    session = xmpp_stanza_get_child_by_name(stanza, "session");
    if (session && strcmp(xmpp_stanza_get_ns(session), XMPP_NS_SESSION) == 0) {
	/* session establishment required */
	conn->session_required = 1;
    }

    /* if bind is required, go ahead and start it */
    if (conn->bind_required) {
	/* bind resource */

	/* setup response handlers */
	handler_add_id(conn, _handle_bind, "_xmpp_bind1", NULL);
	handler_add_timed(conn, _handle_missing_bind,
			  BIND_TIMEOUT, NULL);

	/* send bind request */
	iq = xmpp_stanza_new(conn->ctx);
	if (!iq) {
	    disconnect_mem_error(conn);
	    return 0;
	}

	xmpp_stanza_set_name(iq, "iq");
	xmpp_stanza_set_type(iq, "set");
	xmpp_stanza_set_id(iq, "_xmpp_bind1");

	bind = xmpp_stanza_copy(bind);
	if (!bind) {
	    xmpp_stanza_release(iq);
	    disconnect_mem_error(conn);
	    return 0;
	}

	/* request a specific resource if we have one */
        resource = xmpp_jid_resource(conn->ctx, conn->jid);
	if ((resource != NULL) && (strlen(resource) == 0)) {
	    /* jabberd2 doesn't handle an empty resource */
	    xmpp_free(conn->ctx, resource);
	    resource = NULL;
	}

	/* if we have a resource to request, do it. otherwise the
	   server will assign us one */
	if (resource) {
	    res = xmpp_stanza_new(conn->ctx);
	    if (!res) {
		xmpp_stanza_release(bind);
		xmpp_stanza_release(iq);
		disconnect_mem_error(conn);
		return 0;
	    }
	    xmpp_stanza_set_name(res, "resource");
	    text = xmpp_stanza_new(conn->ctx);
	    if (!text) {
		xmpp_stanza_release(res);
		xmpp_stanza_release(bind);
		xmpp_stanza_release(iq);
		disconnect_mem_error(conn);
		return 0;
	    }
	    xmpp_stanza_set_text(text, resource);
	    xmpp_stanza_add_child(res, text);
            xmpp_stanza_release(text);
	    xmpp_stanza_add_child(bind, res);
            xmpp_stanza_release(res);
	    xmpp_free(conn->ctx, resource);
	}

	xmpp_stanza_add_child(iq, bind);
	xmpp_stanza_release(bind);

	/* send bind request */
	xmpp_send(conn, iq);
	xmpp_stanza_release(iq);
    } else {
	/* can't bind, disconnect */
	xmpp_error(conn->ctx, "xmpp", "Stream features does not allow "\
		   "resource bind.");
	xmpp_disconnect(conn);
    }

    return 0;
}
Beispiel #4
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;
    const 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 {
	    const 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 #5
0
/* handle the challenge phase of SCRAM-SHA-1 auth */
static int _handle_scram_sha1_challenge(xmpp_conn_t * const conn,
					xmpp_stanza_t * const stanza,
					void * const userdata)
{
    char *text;
    char *response;
    xmpp_stanza_t *auth, *authdata;
    const char *name;
    char *challenge;
    char *scram_init = (char *)userdata;

    name = xmpp_stanza_get_name(stanza);
    xmpp_debug(conn->ctx, "xmpp",
               "handle SCRAM-SHA-1 (challenge) called for %s", name);

    if (strcmp(name, "challenge") == 0) {
        text = xmpp_stanza_get_text(stanza);
        if (!text)
            goto err;

        challenge = xmpp_base64_decode_str(conn->ctx, text, strlen(text));
        xmpp_free(conn->ctx, text);
        if (!challenge)
            goto err;

        response = sasl_scram_sha1(conn->ctx, challenge, scram_init,
                                   conn->jid, conn->pass);
        xmpp_free(conn->ctx, challenge);
        if (!response)
            goto err;

        auth = xmpp_stanza_new(conn->ctx);
        if (!auth)
            goto err_free_response;
        xmpp_stanza_set_name(auth, "response");
        xmpp_stanza_set_ns(auth, XMPP_NS_SASL);

        authdata = xmpp_stanza_new(conn->ctx);
        if (!authdata)
            goto err_release_auth;
        xmpp_stanza_set_text(authdata, response);
        xmpp_free(conn->ctx, response);

        xmpp_stanza_add_child(auth, authdata);
        xmpp_stanza_release(authdata);

        xmpp_send(conn, auth);
        xmpp_stanza_release(auth);

    } else {
        xmpp_free(conn->ctx, scram_init);
        return _handle_sasl_result(conn, stanza, "SCRAM-SHA-1");
    }

    return 1;

err_release_auth:
    xmpp_stanza_release(auth);
err_free_response:
    xmpp_free(conn->ctx, response);
err:
    xmpp_free(conn->ctx, scram_init);
    disconnect_mem_error(conn);
    return 0;
}
Beispiel #6
0
/** Release a Strophe connection object.
 *  Decrement the reference count by one for a connection, freeing the 
 *  connection object if the count reaches 0.
 *
 *  @param conn a Strophe connection object
 *
 *  @return TRUE if the connection object was freed and FALSE otherwise
 *
 *  @ingroup Connections
 */
int xmpp_conn_release(xmpp_conn_t * const conn)
{
    xmpp_ctx_t *ctx;
    xmpp_connlist_t *item, *prev;
    xmpp_handlist_t *hlitem, *thli;
    hash_iterator_t *iter;
    const char *key;
    int released = 0;

    if (conn->ref > 1) 
	conn->ref--;
    else {
	ctx = conn->ctx;

	/* remove connection from context's connlist */
	if (ctx->connlist->conn == conn) {
	    item = ctx->connlist;
	    ctx->connlist = item->next;
	    xmpp_free(ctx, item);
	} else {
	    prev = NULL;
	    item = ctx->connlist;
	    while (item && item->conn != conn) {
		prev = item;
		item = item->next;
	    }

	    if (!item) {
		xmpp_error(ctx, "xmpp", "Connection not in context's list\n");
	    } else {
		prev->next = item->next;
		xmpp_free(ctx, item);
	    }
	}

	/* free handler stuff
	 * note that userdata is the responsibility of the client
	 * and the handler pointers don't need to be freed since they
	 * are pointers to functions */

	hlitem = conn->timed_handlers;
	while (hlitem) {
	    thli = hlitem;
	    hlitem = hlitem->next;

	    xmpp_free(ctx, thli);
	}

	/* id handlers
	 * we have to traverse the hash table freeing list elements 
	 * then release the hash table */
	iter = hash_iter_new(conn->id_handlers);
	while ((key = hash_iter_next(iter))) {
	    hlitem = (xmpp_handlist_t *)hash_get(conn->id_handlers, key);
	    while (hlitem) {
		thli = hlitem;
		hlitem = hlitem->next;
		xmpp_free(conn->ctx, thli->id);
		xmpp_free(conn->ctx, thli);
	    }
	}
	hash_iter_release(iter);
	hash_release(conn->id_handlers);

	hlitem = conn->handlers;
	while (hlitem) {
	    thli = hlitem;
	    hlitem = hlitem->next;

	    if (thli->ns) xmpp_free(ctx, thli->ns);
	    if (thli->name) xmpp_free(ctx, thli->name);
	    if (thli->type) xmpp_free(ctx, thli->type);
	    xmpp_free(ctx, thli);
	}

	if (conn->stream_error) {
	    xmpp_stanza_release(conn->stream_error->stanza);
	    if (conn->stream_error->text)
		xmpp_free(ctx, conn->stream_error->text);
	    xmpp_free(ctx, conn->stream_error);
	}

        parser_free(conn->parser);
	
	if (conn->domain) xmpp_free(ctx, conn->domain);
	if (conn->jid) xmpp_free(ctx, conn->jid);
    if (conn->bound_jid) xmpp_free(ctx, conn->bound_jid);
	if (conn->pass) xmpp_free(ctx, conn->pass);
	if (conn->stream_id) xmpp_free(ctx, conn->stream_id);
	if (conn->lang) xmpp_free(ctx, conn->lang);
	xmpp_free(ctx, conn);
	released = 1;
    }

    return released;
}
Beispiel #7
0
static void
_send_bookmarks(void)
{
    xmpp_conn_t *conn = connection_get_conn();
    xmpp_ctx_t *ctx = connection_get_ctx();

    xmpp_stanza_t *iq = xmpp_stanza_new(ctx);
    xmpp_stanza_set_name(iq, STANZA_NAME_IQ);
    char *id = create_unique_id("bookmarks_update");
    xmpp_stanza_set_id(iq, id);
    free(id);
    xmpp_stanza_set_type(iq, STANZA_TYPE_SET);

    xmpp_stanza_t *query = xmpp_stanza_new(ctx);
    xmpp_stanza_set_name(query, STANZA_NAME_QUERY);
    xmpp_stanza_set_ns(query, "jabber:iq:private");

    xmpp_stanza_t *storage = xmpp_stanza_new(ctx);
    xmpp_stanza_set_name(storage, STANZA_NAME_STORAGE);
    xmpp_stanza_set_ns(storage, "storage:bookmarks");

    GList *curr = bookmark_list;
    while (curr != NULL) {
        Bookmark *bookmark = curr->data;
        xmpp_stanza_t *conference = xmpp_stanza_new(ctx);
        xmpp_stanza_set_name(conference, STANZA_NAME_CONFERENCE);
        xmpp_stanza_set_attribute(conference, STANZA_ATTR_JID, bookmark->jid);

        Jid *jidp = jid_create(bookmark->jid);
        if (jidp->localpart != NULL) {
            xmpp_stanza_set_attribute(conference, STANZA_ATTR_NAME, jidp->localpart);
        }
        jid_destroy(jidp);

        if (bookmark->autojoin) {
            xmpp_stanza_set_attribute(conference, STANZA_ATTR_AUTOJOIN, "true");
        } else {
            xmpp_stanza_set_attribute(conference, STANZA_ATTR_AUTOJOIN, "false");
        }

        if (bookmark->nick != NULL) {
            xmpp_stanza_t *nick_st = xmpp_stanza_new(ctx);
            xmpp_stanza_set_name(nick_st, STANZA_NAME_NICK);
            xmpp_stanza_t *nick_text = xmpp_stanza_new(ctx);
            xmpp_stanza_set_text(nick_text, bookmark->nick);
            xmpp_stanza_add_child(nick_st, nick_text);
            xmpp_stanza_add_child(conference, nick_st);

            xmpp_stanza_release(nick_text);
            xmpp_stanza_release(nick_st);
        }

        if (bookmark->password != NULL) {
            xmpp_stanza_t *password_st = xmpp_stanza_new(ctx);
            xmpp_stanza_set_name(password_st, STANZA_NAME_PASSWORD);
            xmpp_stanza_t *password_text = xmpp_stanza_new(ctx);
            xmpp_stanza_set_text(password_text, bookmark->password);
            xmpp_stanza_add_child(password_st, password_text);
            xmpp_stanza_add_child(conference, password_st);

            xmpp_stanza_release(password_text);
            xmpp_stanza_release(password_st);
        }

        xmpp_stanza_add_child(storage, conference);
        xmpp_stanza_release(conference);

        curr = curr->next;
    }

    xmpp_stanza_add_child(query, storage);
    xmpp_stanza_add_child(iq, query);
    xmpp_stanza_release(storage);
    xmpp_stanza_release(query);

    xmpp_send(conn, iq);
    xmpp_stanza_release(iq);
}
Beispiel #8
0
xmpp_stanza_t*
form_create_submission(DataForm *form)
{
    xmpp_ctx_t *ctx = connection_get_ctx();

    xmpp_stanza_t *x = xmpp_stanza_new(ctx);
    xmpp_stanza_set_name(x, STANZA_NAME_X);
    xmpp_stanza_set_ns(x, STANZA_NS_DATA);
    xmpp_stanza_set_type(x, "submit");

    GSList *curr_field = form->fields;
    while (curr_field) {
        FormField *field = curr_field->data;

        if (field->type_t != FIELD_FIXED) {
            xmpp_stanza_t *field_stanza = xmpp_stanza_new(ctx);
            xmpp_stanza_set_name(field_stanza, "field");
            xmpp_stanza_set_attribute(field_stanza, "var", field->var);

            xmpp_stanza_t *value_stanza = NULL;
            GSList *curr_value = NULL;

            switch (field->type_t) {
                case FIELD_HIDDEN:
                case FIELD_TEXT_SINGLE:
                case FIELD_TEXT_PRIVATE:
                case FIELD_BOOLEAN:
                case FIELD_LIST_SINGLE:
                case FIELD_JID_SINGLE:
                    value_stanza = xmpp_stanza_new(ctx);
                    xmpp_stanza_set_name(value_stanza, "value");
                    if (field->values) {
                        if (field->values->data) {
                            xmpp_stanza_t *text_stanza = xmpp_stanza_new(ctx);
                            xmpp_stanza_set_text(text_stanza, field->values->data);
                            xmpp_stanza_add_child(value_stanza, text_stanza);
                            xmpp_stanza_release(text_stanza);
                        }
                    }
                    xmpp_stanza_add_child(field_stanza, value_stanza);
                    xmpp_stanza_release(value_stanza);

                    break;

                case FIELD_TEXT_MULTI:
                case FIELD_LIST_MULTI:
                case FIELD_JID_MULTI:
                    curr_value = field->values;
                    while (curr_value) {
                        char *value = curr_value->data;

                        value_stanza = xmpp_stanza_new(ctx);
                        xmpp_stanza_set_name(value_stanza, "value");
                        if (value) {
                            xmpp_stanza_t *text_stanza = xmpp_stanza_new(ctx);
                            xmpp_stanza_set_text(text_stanza, value);
                            xmpp_stanza_add_child(value_stanza, text_stanza);
                            xmpp_stanza_release(text_stanza);
                        }

                        xmpp_stanza_add_child(field_stanza, value_stanza);
                        xmpp_stanza_release(value_stanza);

                        curr_value = g_slist_next(curr_value);
                    }
                    break;
                case FIELD_FIXED:
                default:
                    break;
            }

            xmpp_stanza_add_child(x, field_stanza);
            xmpp_stanza_release(field_stanza);
        }

        curr_field = g_slist_next(curr_field);
    }

    return x;
}
Beispiel #9
0
/** registration at connections
 *
 *  @param conn a Strophe connection object
 */
static void _register(xmpp_conn_t * const conn)
{
    char *str;

    xmpp_stanza_t *iq, *q, *child, *regdata;

    iq = xmpp_stanza_new(conn->ctx);
    if (!iq) {
	disconnect_mem_error(conn);
	return;
    }

    xmpp_stanza_set_name(iq, "iq");
    xmpp_stanza_set_type(iq, "set");
    xmpp_stanza_set_id(iq, "_xmpp_reg1");

    q = xmpp_stanza_new(conn->ctx);
    if (!q) {
	xmpp_stanza_release(iq);
	disconnect_mem_error(conn);
	return;
    }
    xmpp_stanza_set_name(q, "query");
    xmpp_stanza_set_ns(q, XMPP_NS_REGISTER);
    xmpp_stanza_add_child(iq, q);
    xmpp_stanza_release(q);

    child = xmpp_stanza_new(conn->ctx);
    if (!child) {
	xmpp_stanza_release(iq);
	disconnect_mem_error(conn);
	return;
    }
    xmpp_stanza_set_name(child, "registered");
    xmpp_stanza_add_child(q, child);
    xmpp_stanza_release(child);

    child = xmpp_stanza_new(conn->ctx);
    if (!child) {
	xmpp_stanza_release(iq);
	disconnect_mem_error(conn);
	return;
    }
    xmpp_stanza_set_name(child, "username");
    xmpp_stanza_add_child(q, child);
    xmpp_stanza_release(child);

    regdata = xmpp_stanza_new(conn->ctx);
    if (!regdata) {
	xmpp_stanza_release(iq);
	disconnect_mem_error(conn);
	return;
    }
    str = xmpp_jid_node(conn->ctx, conn->jid);
    xmpp_stanza_set_text(regdata, str);
    xmpp_free(conn->ctx, str);
    xmpp_stanza_add_child(child, regdata);
    xmpp_stanza_release(regdata);

    child = xmpp_stanza_new(conn->ctx);
    if (!child) {
	xmpp_stanza_release(iq);
	disconnect_mem_error(conn);
	return;
    }
    xmpp_stanza_set_name(child, "password");
    xmpp_stanza_add_child(q, child);
    xmpp_stanza_release(child);

    regdata = xmpp_stanza_new(conn->ctx);
    if (!regdata) {
	xmpp_stanza_release(iq);
	disconnect_mem_error(conn);
	return;
    }
    xmpp_stanza_set_text(regdata, conn->pass);
    xmpp_stanza_add_child(child, regdata);
    xmpp_stanza_release(regdata);

    child = xmpp_stanza_new(conn->ctx);
    if (!child) {
	xmpp_stanza_release(iq);
	disconnect_mem_error(conn);
	return;
    }
    xmpp_stanza_set_name(child, "email");
    xmpp_stanza_add_child(q, child);
    xmpp_stanza_release(child);

    regdata = xmpp_stanza_new(conn->ctx);
    if (!regdata) {
	xmpp_stanza_release(iq);
	disconnect_mem_error(conn);
	return;
    }
    str = xmpp_jid_node(conn->ctx, conn->jid);
    xmpp_stanza_set_text(regdata, str);
    xmpp_free(conn->ctx, str);
    xmpp_stanza_add_child(child, regdata);
    xmpp_stanza_release(regdata);

    handler_add_id(conn, _handle_register, "_xmpp_reg1", NULL);
    handler_add_timed(conn, _handle_missing_register, 
		      LAZY_REGISTRATION_TIMEOUT, NULL);

    xmpp_send(conn, iq);
    xmpp_stanza_release(iq);
}
Beispiel #10
0
static int version_handler(xmpp_conn_t * const conn,
                           xmpp_stanza_t * const stanza,
                           void * const userdata)
{
    xmpp_stanza_t *reply, *query, *name, *version, *text;
    conflate_handle_t *handle = (conflate_handle_t*) userdata;
    xmpp_ctx_t *ctx = handle->ctx;
    char *ns;
    struct utsname un = {};

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

    reply = xmpp_stanza_new(ctx);
    assert(reply);
    xmpp_stanza_set_name(reply, "iq");
    xmpp_stanza_set_type(reply, "result");
    xmpp_stanza_set_id(reply, xmpp_stanza_get_id(stanza));
    xmpp_stanza_set_attribute(reply, "to", xmpp_stanza_get_attribute(stanza, "from"));

    query = xmpp_stanza_new(ctx);
    assert(query);
    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);
    assert(name);
    xmpp_stanza_set_name(name, "name");
    add_and_release(query, name);

    text = xmpp_stanza_new(ctx);
    assert(text);
    xmpp_stanza_set_text(text, handle->conf->software);
    add_and_release(name, text);

    version = xmpp_stanza_new(ctx);
    assert(version);
    xmpp_stanza_set_name(version, "version");
    add_and_release(query, version);

    text = xmpp_stanza_new(ctx);
    assert(text);
    xmpp_stanza_set_text(text, handle->conf->version);
    add_and_release(version, text);

    if (uname(&un) == 0) {
        char os_buf[128];
        snprintf(os_buf, sizeof(os_buf), "%s/%s/%s",
                 un.machine, un.sysname, un.release);

        xmpp_stanza_t *os = xmpp_stanza_new(ctx);
        assert(os);
        xmpp_stanza_set_name(os, "os");
        add_and_release(query, os);

        text = xmpp_stanza_new(ctx);
        assert(text);
        xmpp_stanza_set_text(text, os_buf);
        add_and_release(os, text);
    }

    add_and_release(reply, query);

    xmpp_send(conn, reply);
    xmpp_stanza_release(reply);
    return 1;
}
Beispiel #11
0
static int
_iq_handle_version_get(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza,
    void * const userdata)
{
    xmpp_ctx_t *ctx = (xmpp_ctx_t *)userdata;
    const char *id = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_ID);
    const char *from = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_FROM);

    if (from != NULL) {
        xmpp_stanza_t *response = xmpp_stanza_new(ctx);
        xmpp_stanza_set_name(response, STANZA_NAME_IQ);
        if (id != NULL) {
            xmpp_stanza_set_id(response, id);
        }
        xmpp_stanza_set_attribute(response, STANZA_ATTR_TO, from);
        xmpp_stanza_set_type(response, STANZA_TYPE_RESULT);

        xmpp_stanza_t *query = xmpp_stanza_new(ctx);
        xmpp_stanza_set_name(query, STANZA_NAME_QUERY);
        xmpp_stanza_set_ns(query, STANZA_NS_VERSION);

        xmpp_stanza_t *name = xmpp_stanza_new(ctx);
        xmpp_stanza_set_name(name, "name");
        xmpp_stanza_t *name_txt = xmpp_stanza_new(ctx);
        xmpp_stanza_set_text(name_txt, "Profanity");
        xmpp_stanza_add_child(name, name_txt);

        xmpp_stanza_t *version = xmpp_stanza_new(ctx);
        xmpp_stanza_set_name(version, "version");
        xmpp_stanza_t *version_txt = xmpp_stanza_new(ctx);
        GString *version_str = g_string_new(PACKAGE_VERSION);
        if (strcmp(PACKAGE_STATUS, "development") == 0) {
#ifdef HAVE_GIT_VERSION
            g_string_append(version_str, "dev.");
            g_string_append(version_str, PROF_GIT_BRANCH);
            g_string_append(version_str, ".");
            g_string_append(version_str, PROF_GIT_REVISION);
#else
            g_string_append(version_str, "dev");
#endif
        }
        xmpp_stanza_set_text(version_txt, version_str->str);
        xmpp_stanza_add_child(version, version_txt);

        xmpp_stanza_add_child(query, name);
        xmpp_stanza_add_child(query, version);
        xmpp_stanza_add_child(response, query);

        xmpp_send(conn, response);

        g_string_free(version_str, TRUE);
        xmpp_stanza_release(name_txt);
        xmpp_stanza_release(version_txt);
        xmpp_stanza_release(name);
        xmpp_stanza_release(version);
        xmpp_stanza_release(query);
        xmpp_stanza_release(response);
    }

    return 1;
}
Beispiel #12
0
static void add_and_release(xmpp_stanza_t* parent, xmpp_stanza_t* child)
{
    xmpp_stanza_add_child(parent, child);
    xmpp_stanza_release(child);
}
xmpp_stanza_t *
caps_create_query_response_stanza(xmpp_ctx_t * const ctx)
{
    xmpp_stanza_t *query = xmpp_stanza_new(ctx);
    xmpp_stanza_set_name(query, STANZA_NAME_QUERY);
    xmpp_stanza_set_ns(query, XMPP_NS_DISCO_INFO);

    xmpp_stanza_t *identity = xmpp_stanza_new(ctx);
    xmpp_stanza_set_name(identity, "identity");
    xmpp_stanza_set_attribute(identity, "category", "client");
    xmpp_stanza_set_attribute(identity, "type", "console");

    GString *name_str = g_string_new("Profanity ");
    g_string_append(name_str, PACKAGE_VERSION);
    if (strcmp(PACKAGE_STATUS, "development") == 0) {
#ifdef HAVE_GIT_VERSION
        g_string_append(name_str, "dev.");
        g_string_append(name_str, PROF_GIT_BRANCH);
        g_string_append(name_str, ".");
        g_string_append(name_str, PROF_GIT_REVISION);
#else
        g_string_append(name_str, "dev");
#endif
    }
    xmpp_stanza_set_attribute(identity, "name", name_str->str);

    xmpp_stanza_t *feature_caps = xmpp_stanza_new(ctx);
    xmpp_stanza_set_name(feature_caps, STANZA_NAME_FEATURE);
    xmpp_stanza_set_attribute(feature_caps, STANZA_ATTR_VAR, STANZA_NS_CAPS);

    xmpp_stanza_t *feature_discoinfo = xmpp_stanza_new(ctx);
    xmpp_stanza_set_name(feature_discoinfo, STANZA_NAME_FEATURE);
    xmpp_stanza_set_attribute(feature_discoinfo, STANZA_ATTR_VAR, XMPP_NS_DISCO_INFO);

    xmpp_stanza_t *feature_discoitems = xmpp_stanza_new(ctx);
    xmpp_stanza_set_name(feature_discoitems, STANZA_NAME_FEATURE);
    xmpp_stanza_set_attribute(feature_discoitems, STANZA_ATTR_VAR, XMPP_NS_DISCO_ITEMS);

    xmpp_stanza_t *feature_muc = xmpp_stanza_new(ctx);
    xmpp_stanza_set_name(feature_muc, STANZA_NAME_FEATURE);
    xmpp_stanza_set_attribute(feature_muc, STANZA_ATTR_VAR, STANZA_NS_MUC);

    xmpp_stanza_t *feature_version = xmpp_stanza_new(ctx);
    xmpp_stanza_set_name(feature_version, STANZA_NAME_FEATURE);
    xmpp_stanza_set_attribute(feature_version, STANZA_ATTR_VAR, STANZA_NS_VERSION);

    xmpp_stanza_t *feature_chatstates = xmpp_stanza_new(ctx);
    xmpp_stanza_set_name(feature_chatstates, STANZA_NAME_FEATURE);
    xmpp_stanza_set_attribute(feature_chatstates, STANZA_ATTR_VAR, STANZA_NS_CHATSTATES);

    xmpp_stanza_t *feature_ping = xmpp_stanza_new(ctx);
    xmpp_stanza_set_name(feature_ping, STANZA_NAME_FEATURE);
    xmpp_stanza_set_attribute(feature_ping, STANZA_ATTR_VAR, STANZA_NS_PING);

    xmpp_stanza_add_child(query, identity);

    xmpp_stanza_add_child(query, feature_caps);
    xmpp_stanza_add_child(query, feature_chatstates);
    xmpp_stanza_add_child(query, feature_discoinfo);
    xmpp_stanza_add_child(query, feature_discoitems);
    xmpp_stanza_add_child(query, feature_muc);
    xmpp_stanza_add_child(query, feature_version);
    xmpp_stanza_add_child(query, feature_ping);

    xmpp_stanza_release(feature_ping);
    xmpp_stanza_release(feature_version);
    xmpp_stanza_release(feature_muc);
    xmpp_stanza_release(feature_discoitems);
    xmpp_stanza_release(feature_discoinfo);
    xmpp_stanza_release(feature_chatstates);
    xmpp_stanza_release(feature_caps);
    xmpp_stanza_release(identity);

    return query;
}
Beispiel #14
0
void
presence_send(const resource_presence_t presence_type, const int idle, char *signed_status)
{
    if (connection_get_status() != JABBER_CONNECTED) {
        log_warning("Error setting presence, not connected.");
        return;
    }

    char *msg = connection_get_presence_msg();
    if (msg) {
        log_debug("Updating presence: %s, \"%s\"", string_from_resource_presence(presence_type), msg);
    } else {
        log_debug("Updating presence: %s", string_from_resource_presence(presence_type));
    }

    const int pri = accounts_get_priority_for_presence_type(session_get_account_name(), presence_type);
    connection_set_priority(pri);

    xmpp_ctx_t * const ctx = connection_get_ctx();
    xmpp_stanza_t *presence = xmpp_presence_new(ctx);

    char *id = create_unique_id("presence");
    xmpp_stanza_set_id(presence, id);
    free(id);

    const char *show = stanza_get_presence_string_from_type(presence_type);
    stanza_attach_show(ctx, presence, show);

    stanza_attach_status(ctx, presence, msg);

    if (signed_status) {
        xmpp_stanza_t *x = xmpp_stanza_new(ctx);
        xmpp_stanza_set_name(x, STANZA_NAME_X);
        xmpp_stanza_set_ns(x, STANZA_NS_SIGNED);

        xmpp_stanza_t *signed_text = xmpp_stanza_new(ctx);
        xmpp_stanza_set_text(signed_text, signed_status);

        xmpp_stanza_add_child(x, signed_text);
        xmpp_stanza_release(signed_text);

        xmpp_stanza_add_child(presence, x);
        xmpp_stanza_release(x);
    }

    stanza_attach_priority(ctx, presence, pri);

    if (idle > 0) {
        stanza_attach_last_activity(ctx, presence, idle);
    }

    stanza_attach_caps(ctx, presence);

    _send_presence_stanza(presence);
    _send_room_presence(presence);

    xmpp_stanza_release(presence);

    // set last presence for account
    const char *last = show;
    if (last == NULL) {
        last = STANZA_TEXT_ONLINE;
    }

    char *account = session_get_account_name();
    accounts_set_last_presence(account, last);
    accounts_set_last_status(account, msg);
}
Beispiel #15
0
static int wfuse_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
                         off_t offset, struct fuse_file_info *fi)
{
  wlog("wfuse_readdir path = %s\n", path);

  if (!is_owner_online) {
    return -ENOENT;
  }

  int rc; /* Return code */

  rc = pthread_mutex_lock(&mutex);
  wsyserr(rc != 0, "pthread_mutex_lock");

  xmpp_stanza_t *message = xmpp_stanza_new(ctx); /* message with done */
  xmpp_stanza_set_name(message, "message");
  xmpp_stanza_set_attribute(message, "to", owner_str);

  xmpp_stanza_t *files = xmpp_stanza_new(ctx); /* message with done */
  xmpp_stanza_set_name(files, "files");
  xmpp_stanza_set_ns(files, WNS);
  xmpp_stanza_set_attribute(files, "action", "list");
  xmpp_stanza_set_attribute(files, "path", path);

  xmpp_stanza_add_child(message, files);
  xmpp_send(conn, message);
  xmpp_stanza_release(files);
  xmpp_stanza_release(message);

  while (signal_list == false) {
    pthread_cond_wait(&cond, &mutex);
  }

  int res = 0;

  /* Do your job */
  if (signal_fail == true) {
    res = -ENOENT;
    signal_attr = false;
    signal_list = false;
    signal_read = false;
    signal_fail = false;
  } else {
    // wfatal(root == NULL, "root is NULL");

    (void) offset;
    (void) fi;

    filler(buf, ".", NULL, 0);
    filler(buf, "..", NULL, 0);

    elem_t *aux = root;
    while (aux != NULL) {
      filler(buf, aux->filename, NULL, 0);
      aux = aux->next;
    }

    /* Free list */
    aux = root;
    elem_t *aux2;
    while (aux != NULL) {
      free(aux->filename);
      aux2 = aux;
      aux = aux->next;
      free(aux2);
    }

    root = NULL;
  }
  /* Job done */

  signal_list = false;
  rc = pthread_mutex_unlock(&mutex);
  wsyserr(rc != 0, "pthread_mutex_unlock");

  return res;
}
Beispiel #16
0
/**
 * Handles the service
 */
xmpp_stanza_t * _HandleServiceRequest(xmpp_conn_t * const conn,
		xmpp_stanza_t * const stanza, void * const userdata) {
	xmpp_stanza_t *reply;
	xmpp_stanza_t *wd, *nodetext;
	xmpp_ctx_t *ctx = (xmpp_ctx_t*) userdata;
	sdvp_method_t methodType = SDVP_METHOD_UNDEFINED;
	sdvp_from_t* from;
	char *method;
	sdvp_reply_params_t* sdvpReplyParams = NULL;
    void* replyParams;
	void* paramStructure = NULL;
	char strbuf[20];
	static unsigned int watchdog = 1;

	//HJP: Hvorfor oprette reply her, når den næsten altid bliver overskrevet?
	reply = xmpp_stanza_new(ctx);
	xmpp_stanza_set_name(reply, "iq");

	from = _CreateFrom(xmpp_stanza_get_attribute(stanza, "from"), "TODO",
			"TODO");
	syslog(LOG_DEBUG, "Received a RPC Method call from %s\n", from->name);

	method = _GetRpcMethode(stanza);
	methodType = _GetDefinedMetodeFromMethod(method);

	syslog(LOG_DEBUG, "XML-RPC method name %s\n", method);

	free(method);

	if (methodType == SDVP_METHOD_UNDEFINED) {
		syslog(LOG_DEBUG, "Undefined method type\n");

		sdvp_InitiateReplyParameters(&sdvpReplyParams, 1);
		sdvpReplyParams->params[0].strValue =
				strdup("ERROR: Method is undefined. Methods are CasE SentItive.\n");
		sdvpReplyParams->params[0].type = IEC_VISIBLE_STRING;
		//HJP: Jeg releaser reply her, det ville være smartere kun at oprette den når nødvendigt...
		xmpp_stanza_release(reply);
        reply = _CreateReply(ctx, methodType, sdvpReplyParams);
		xmpp_stanza_set_type(reply, "error");
        sdvp_FreeReplyParameters(sdvpReplyParams);
	} else if (methodType == LIAB_WATCHDOG) {
		xmpp_stanza_release(reply);
		reply = xmpp_stanza_new(ctx);
		xmpp_stanza_set_name(reply, "query");
		xmpp_stanza_set_ns(reply, "jabber:iq:rpc");

		wd = xmpp_stanza_new(ctx);
		xmpp_stanza_set_name(wd, "watchdog");
		xmpp_stanza_add_child(reply, wd);
		xmpp_stanza_release(wd);

		nodetext = xmpp_stanza_new(ctx);
		sprintf(strbuf, "%u", watchdog++);
		xmpp_stanza_set_text(nodetext, strbuf);
		xmpp_stanza_add_child(wd, nodetext);
		xmpp_stanza_release(nodetext);

	} else{
		if (_CallbackIsRegistered(methodType)) {
			paramStructure = _CreateParamStructureFromParameters(methodType, stanza);
			replyParams = _CallTheRightCallback(methodType, paramStructure);
			_FreeParamStructure(methodType,paramStructure);
			xmpp_stanza_release(reply);
            reply = _CreateReply(ctx, methodType, replyParams);

			sdvp_FreeCallbackReply(methodType, replyParams);
        	sdvp_FreeReplyParameters(sdvpReplyParams);
		} else {
			// TODO: Send a error with method not implemented or alike
		}
	}

	_FreeFrom(from);


	return reply;
}
Beispiel #17
0
static int wfuse_read(const char *path, char *buf, size_t size, off_t offset,
                      struct fuse_file_info *fi)
{
  wlog("wfuse_read path = %s\n", path);

  if (!is_owner_online) {
    return -ENOENT;
  }

  int rc; /* Return code */

  rc = pthread_mutex_lock(&mutex);
  wsyserr(rc != 0, "pthread_mutex_lock");

  xmpp_stanza_t *message = xmpp_stanza_new(ctx); /* message with done */
  xmpp_stanza_set_name(message, "message");
  xmpp_stanza_set_attribute(message, "to", owner_str);

  xmpp_stanza_t *files = xmpp_stanza_new(ctx); /* message with done */
  xmpp_stanza_set_name(files, "files");
  xmpp_stanza_set_ns(files, WNS);
  xmpp_stanza_set_attribute(files, "action", "read");
  xmpp_stanza_set_attribute(files, "path", path);

  xmpp_stanza_add_child(message, files);
  xmpp_send(conn, message);
  xmpp_stanza_release(files);
  xmpp_stanza_release(message);

  /* Wait until attributes is set */
  while (signal_read == false) {
    pthread_cond_wait(&cond, &mutex);
  }

  int res = size;

  /* Do your job */
  if (signal_fail == true) {
    res = -ENOENT;
    signal_attr = false;
    signal_list = false;
    signal_read = false;
    signal_fail = false;
  } else {
    size_t len;
    (void) fi;
    len = strlen(read_data);

    if (offset < len) {
      if (offset + size > len) {
        size = len - offset;
      }
      memcpy(buf, read_data + offset, size);
    } else {
      size = 0;
    }
  }
  /* Job done */

  signal_read = false;

  rc = pthread_mutex_unlock(&mutex);
  wsyserr(rc != 0, "pthread_mutex_unlock");

  return res;
}
Beispiel #18
0
/** Release a Strophe connection object.
 *  Decrement the reference count by one for a connection, freeing the
 *  connection object if the count reaches 0.
 *
 *  @param conn a Strophe connection object
 *
 *  @return TRUE if the connection object was freed and FALSE otherwise
 *
 *  @ingroup Connections
 */
int xmpp_conn_release(xmpp_conn_t * const conn)
{
	xmpp_ctx_t *ctx;
	list_t *item;
	xmpp_handler_t *temp;
	xmpp_handlist_t *hlitem, *thli;
	hash_iterator_t *iter;
	const char *key;

	if (conn->ref > 1) {
		conn->ref--;
		return 0;
	}

	ctx = conn->ctx;

	/* remove connection from context's connlist */
	item = list_pop_by_data(ctx->connlist, (void *)conn);
	if (item)
		xmpp_free(ctx, item);
	else
		xmpp_error(ctx, "xmpp", "Connection not in context's list\n");

	/* free handler stuff
	 * note that userdata is the responsibility of the client
	 * and the handler pointers don't need to be freed since they
	 * are pointers to functions */

	while ((item = list_shift(conn->timed_handlers))) {
		xmpp_free(ctx, item->data);
		xmpp_free(ctx, item);
	}
	list_destroy(conn->timed_handlers);

	/* id handlers
	 * we have to traverse the hash table freeing list elements
	 * then release the hash table */
	iter = hash_iter_new(conn->id_handlers);
	while ((key = hash_iter_next(iter))) {
		hlitem = (xmpp_handlist_t *)hash_get(conn->id_handlers, key);
		while (hlitem) {
			thli = hlitem;
			hlitem = hlitem->next;
			xmpp_free(ctx, thli->id);
			xmpp_free(ctx, thli);
		}
	}
	hash_iter_release(iter);
	hash_release(conn->id_handlers);

	while ((item = list_shift(conn->handlers))) {
		temp = (xmpp_handler_t *)item->data;

		if (temp->ns)
			xmpp_free(ctx, temp->ns);
		if (temp->name)
			xmpp_free(ctx, temp->name);
		if (temp->type)
			xmpp_free(ctx, temp->type);
		xmpp_free(ctx, temp);
		xmpp_free(ctx, item);
	}
	list_destroy(conn->handlers);

	if (conn->stream_error) {
		xmpp_stanza_release(conn->stream_error->stanza);
		if (conn->stream_error->text)
			xmpp_free(ctx, conn->stream_error->text);
		xmpp_free(ctx, conn->stream_error);
	}

	parser_free(conn->parser);

	/* free send_queue */
	list_destroy(conn->send_queue);

	if (conn->domain)
		xmpp_free(ctx, conn->domain);
	if (conn->jid)
		xmpp_free(ctx, conn->jid);
	if (conn->bound_jid)
		xmpp_free(ctx, conn->bound_jid);
	if (conn->pass)
		xmpp_free(ctx, conn->pass);
	if (conn->stream_id)
		xmpp_free(ctx, conn->stream_id);
	if (conn->lang)
		xmpp_free(ctx, conn->lang);
	if (conn->tls)
		tls_free(conn->tls);
	xmpp_free(ctx, conn);

	return 1;
}