/** * Create the initiate stream string, we'll get: * * <stream:stream xmlns="jabber:client" * xmlns:stream="http://etherx.jabber.org/streams" * version="1.0" to="gmail.com"> */ static gchar* create_initiate_stream(XmppStream *stream) { xmlnode *node; gchar *version; gchar *res; node = xmlnode_create("stream:stream"); xmlnode_new_prop(node, "to", stream->account->to); xmlnode_new_namespace(node, NULL, "jabber:client"); xmlnode_new_namespace(node, "stream", "http://etherx.jabber.org/streams"); version = g_strdup_printf("%d.%d", stream->major_version, stream->miner_version); xmlnode_new_prop(node, "version", version); g_free(version); res = xmlnode_to_string(node); xmpp_strip_end_label(res); xmlnode_free(node); return res; }
gint xmpp_message_send(XmppStream *stream, const gchar *text, const gchar *to) { xmlnode *root; xmlnode *node; gchar *xml_string; g_return_val_if_fail(stream != NULL, HYBRID_ERROR); g_return_val_if_fail(text != NULL, HYBRID_ERROR); g_return_val_if_fail(to != NULL, HYBRID_ERROR); root = xmlnode_create("message"); xmlnode_new_prop(root, "from", stream->jid); xmlnode_new_prop(root, "to", to); xmlnode_new_prop(root, "type", "chat"); node = xmlnode_new_child(root, "body"); xmlnode_set_content(node, text); xml_string = xmlnode_to_string(root); xmlnode_free(root); hybrid_debug_info("xmpp", "send message to %s:\n%s", to, xml_string); if (hybrid_ssl_write(stream->ssl, xml_string, strlen(xml_string)) == -1) { hybrid_debug_error("xmpp", "send message to %s failed\n", to); g_free(xml_string); return HYBRID_ERROR; } g_free(xml_string); return HYBRID_OK; }
static gchar* generate_handle_request_body(const gchar *sipuri, const gchar *userid, const gchar *alias, const gchar *groupid, gboolean accept) { xmlnode *root; xmlnode *node; gchar *res; root = xmlnode_create("args"); node = xmlnode_new_child(root, "contacts"); node = xmlnode_new_child(node, "buddies"); node = xmlnode_new_child(node, "buddy"); xmlnode_new_prop(node, "user-id", userid); xmlnode_new_prop(node, "uri", sipuri); xmlnode_new_prop(node, "result", accept ? "1": "0"); xmlnode_new_prop(node, "buddy-lists", groupid); xmlnode_new_prop(node, "expose-mobile-no", "1"); xmlnode_new_prop(node, "expose-name", "1"); xmlnode_new_prop(node, "local-name", alias); res = xmlnode_to_string(root); xmlnode_free(root); return res; }
gint xmpp_message_send_typing(XmppStream *stream, const gchar *to, HybridInputState state) { xmlnode *root; xmlnode *node; gchar *xml_string; g_return_val_if_fail(stream != NULL, HYBRID_ERROR); g_return_val_if_fail(to != NULL, HYBRID_ERROR); root = xmlnode_create("message"); xmlnode_new_prop(root, "from", stream->jid); xmlnode_new_prop(root, "to", to); xmlnode_new_prop(root, "type", "chat"); switch (state) { case INPUT_STATE_TYPING: node = xmlnode_new_child(root, "composing"); break; case INPUT_STATE_ACTIVE: node = xmlnode_new_child(root, "active"); break; case INPUT_STATE_PAUSED: node = xmlnode_new_child(root, "paused"); break; default: node = NULL; break; } if (node) { xmlnode_new_namespace(node, NULL, NS_CHANGESTATES); } xml_string = xmlnode_to_string(root); xmlnode_free(root); hybrid_debug_info("xmpp", "send message to %s:\n%s", to, xml_string); if (hybrid_ssl_write(stream->ssl, xml_string, strlen(xml_string)) == -1) { hybrid_debug_error("xmpp", "send message to %s failed\n", to); g_free(xml_string); return HYBRID_ERROR; } g_free(xml_string); return HYBRID_OK; }
static gchar* generate_starttls_body(XmppStream *stream) { xmlnode *node; gchar *body; node = xmlnode_create("starttls"); xmlnode_new_namespace(node, NULL, NS_XMPP_TLS); body = xmlnode_to_string(node); xmlnode_free(node); return body; }
/** * Start sasl authentication. */ static void xmpp_stream_startsasl(XmppStream *stream) { guchar *auth; gchar *auth_encoded; gchar *xml_string; gint username_len; gint password_len; xmlnode *node; g_return_if_fail(stream != NULL); hybrid_debug_info("xmpp", "start sasl authentication."); hybrid_account_set_connection_string(stream->account->account, "Start sasl authentication."); xmpp_stream_set_state(stream, XMPP_STATE_SASL_AUTHENTICATING); /* * construct the authentication string to be base64 encoded, * which is in form of '\0 + username + \0 + password ' */ username_len = strlen(stream->account->username); password_len = strlen(stream->account->password); auth = g_malloc0(username_len + password_len + 2); auth[0] = '\0'; memcpy(auth + 1, stream->account->username, username_len); auth[username_len + 1] = '\0'; memcpy(auth + 2 + username_len, stream->account->password, password_len); auth_encoded = hybrid_base64_encode(auth, username_len + password_len + 2); g_free(auth); /* construct the xml string, which is in form of: * * <auth xmlns="urn:ietf:params:xml:ns:xmpp-sasl" * mechanism="PLAIN">encoded sasl string</auth> */ node = xmlnode_create("auth"); xmlnode_new_namespace(node, NULL, NS_XMPP_SASL); xmlnode_new_namespace(node, "ga", "http://www.google.com/talk/protocol/auth"); xmlnode_new_prop(node, "ga:client-uses-full-bind-result", "true"); xmlnode_new_prop(node, "mechanism", "PLAIN"); xmlnode_set_content(node, auth_encoded); g_free(auth_encoded); xml_string = xmlnode_to_string(node); xmlnode_free(node); hybrid_debug_info("xmpp", "sasl send:\n%s", xml_string); if (hybrid_ssl_write(stream->ssl, xml_string, strlen(xml_string)) == -1) { hybrid_account_error_reason(stream->account->account, "SASL authentication error."); return; } g_free(xml_string); }