/** Send the opening <stream:stream> tag to the server. * This function is used by Strophe to begin an XMPP stream. It should * not be used outside of the library. * * @param conn a Strophe connection object */ void conn_open_stream(xmpp_conn_t * const conn) { if (conn->type == XMPP_CLIENT) { xmpp_send_raw_string(conn, "<?xml version=\"1.0\"?>" \ "<stream:stream to=\"%s\" " \ "xml:lang=\"%s\" " \ "version=\"1.0\" " \ "xmlns=\"%s\" " \ "xmlns:stream=\"%s\">", conn->domain, conn->lang, conn->type == XMPP_CLIENT ? XMPP_NS_CLIENT : XMPP_NS_COMPONENT, XMPP_NS_STREAMS); } else { xmpp_send_raw_string(conn, "<?xml version=\"1.0\"?>" \ "<stream:stream to=\"%s\" " \ "from=\"%s\" " \ "xml:lang=\"%s\" " \ "version=\"1.0\" " \ "xmlns=\"%s\" " \ "xmlns:stream=\"%s\">", conn->domain, conn->jid, conn->lang, conn->type == XMPP_CLIENT ? XMPP_NS_CLIENT : XMPP_NS_COMPONENT, XMPP_NS_STREAMS); } }
static void _send_presence_stanza(xmpp_stanza_t *const stanza) { char *text; size_t text_size; xmpp_stanza_to_text(stanza, &text, &text_size); xmpp_conn_t *conn = connection_get_conn(); char *plugin_text = plugins_on_presence_stanza_send(text); if (plugin_text) { xmpp_send_raw_string(conn, "%s", plugin_text); free(plugin_text); } else { xmpp_send_raw_string(conn, "%s", text); } xmpp_free(connection_get_ctx(), text); }
gboolean connection_send_stanza(const char *const stanza) { if (conn.conn_status != JABBER_CONNECTED) { return FALSE; } else { xmpp_send_raw_string(conn.xmpp_conn, "%s", stanza); return TRUE; } }
/** Initiate termination of the connection to the XMPP server. * This function starts the disconnection sequence by sending * </stream:stream> to the XMPP server. This function will do nothing * if the connection state is CONNECTING or CONNECTED. * * @param conn a Strophe connection object * * @ingroup Connections */ void xmpp_disconnect(xmpp_conn_t * const conn) { if (conn->state != XMPP_STATE_CONNECTING && conn->state != XMPP_STATE_CONNECTED) return; /* close the stream */ xmpp_send_raw_string(conn, "</stream:stream>"); /* setup timed handler in case disconnect takes too long */ handler_add_timed(conn, _disconnect_cleanup, DISCONNECT_TIMEOUT, NULL); }
/** Send an opening stream tag. * User's connection handler is called with event XMPP_CONN_CONNECT when * server replies with its opening tag. * * @param conn a Strophe connection object * @param attributes Array of strings in format: even index points to * an attribute name and odd index points to its value * @param attributes_len Number of elements in the attributes array, it * should be number of attributes multiplied by 2 * * @return XMPP_EOK (0) on success a number less than 0 on failure * * @note The connection must be connected with xmpp_connect_raw(). * * @ingroup Connections */ int xmpp_conn_open_stream(xmpp_conn_t * const conn, char **attributes, size_t attributes_len) { char *tag; if (!conn->is_raw) return XMPP_EINVOP; tag = _conn_build_stream_tag(conn, attributes, attributes_len); if (!tag) return XMPP_EMEM; conn_prepare_reset(conn, auth_handle_open_raw); xmpp_send_raw_string(conn, "<?xml version=\"1.0\"?>%s", tag); xmpp_free(conn->ctx, tag); return XMPP_EOK; }
/* Will compute SHA1 and authenticate the component to the server */ int _handle_component_auth(xmpp_conn_t * const conn) { uint8_t md_value[SHA1_DIGEST_SIZE]; SHA1_CTX mdctx; char *digest; size_t i; if (conn->stream_id == NULL) { xmpp_error(conn->ctx, "auth", "Received no stream id from the server."); return XMPP_EINT; } /* Feed the session id and passphrase to the algorithm. * We need to compute SHA1(session_id + passphrase) */ crypto_SHA1_Init(&mdctx); crypto_SHA1_Update(&mdctx, (uint8_t*)conn->stream_id, strlen(conn->stream_id)); crypto_SHA1_Update(&mdctx, (uint8_t*)conn->pass, strlen(conn->pass)); crypto_SHA1_Final(&mdctx, md_value); digest = xmpp_alloc(conn->ctx, 2*sizeof(md_value)+1); if (digest) { /* convert the digest into string representation */ for (i = 0; i < sizeof(md_value); i++) xmpp_snprintf(digest+i*2, 3, "%02x", md_value[i]); digest[2*sizeof(md_value)] = '\0'; xmpp_debug(conn->ctx, "auth", "Digest: %s, len: %d", digest, strlen(digest)); /* Send the digest to the server */ xmpp_send_raw_string(conn, "<handshake xmlns='%s'>%s</handshake>", XMPP_NS_COMPONENT, digest); xmpp_debug(conn->ctx, "auth", "Sent component handshake to the server."); xmpp_free(conn->ctx, digest); } else { xmpp_debug(conn->ctx, "auth", "Couldn't allocate memory for component "\ "handshake digest."); return XMPP_EMEM; } return 0; }