Unify coding style
@sjaeckel integrated clang-format with formal coding style. Run his script and commit changes. There are pros and cons of this commit. Mixed coding style is a "broken window". A good single style simplifies reading and writing code. On the other hand, this is a big change which will lead to conflicts.
This commit is contained in:
@@ -19,23 +19,23 @@
|
|||||||
|
|
||||||
#include <strophe.h>
|
#include <strophe.h>
|
||||||
|
|
||||||
int handle_reply(xmpp_conn_t * const conn,
|
int handle_reply(xmpp_conn_t *const conn,
|
||||||
xmpp_stanza_t * const stanza,
|
xmpp_stanza_t *const stanza,
|
||||||
void * const userdata)
|
void *const userdata)
|
||||||
{
|
{
|
||||||
xmpp_stanza_t *query, *item;
|
xmpp_stanza_t *query, *item;
|
||||||
const char *type;
|
const char *type;
|
||||||
|
|
||||||
type = xmpp_stanza_get_type(stanza);
|
type = xmpp_stanza_get_type(stanza);
|
||||||
if (strcmp(type, "error") == 0)
|
if (strcmp(type, "error") == 0)
|
||||||
fprintf(stderr, "ERROR: query failed\n");
|
fprintf(stderr, "ERROR: query failed\n");
|
||||||
else {
|
else {
|
||||||
query = xmpp_stanza_get_child_by_name(stanza, "query");
|
query = xmpp_stanza_get_child_by_name(stanza, "query");
|
||||||
printf("Active Sessions:\n");
|
printf("Active Sessions:\n");
|
||||||
for (item = xmpp_stanza_get_children(query); item;
|
for (item = xmpp_stanza_get_children(query); item;
|
||||||
item = xmpp_stanza_get_next(item))
|
item = xmpp_stanza_get_next(item))
|
||||||
printf("\t %s\n", xmpp_stanza_get_attribute(item, "jid"));
|
printf("\t %s\n", xmpp_stanza_get_attribute(item, "jid"));
|
||||||
printf("END OF LIST\n");
|
printf("END OF LIST\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* disconnect */
|
/* disconnect */
|
||||||
@@ -44,41 +44,43 @@ int handle_reply(xmpp_conn_t * const conn,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void conn_handler(xmpp_conn_t * const conn, const xmpp_conn_event_t status,
|
void conn_handler(xmpp_conn_t *const conn,
|
||||||
const int error, xmpp_stream_error_t * const stream_error,
|
const xmpp_conn_event_t status,
|
||||||
void * const userdata)
|
const int error,
|
||||||
|
xmpp_stream_error_t *const stream_error,
|
||||||
|
void *const userdata)
|
||||||
{
|
{
|
||||||
xmpp_ctx_t *ctx = (xmpp_ctx_t *)userdata;
|
xmpp_ctx_t *ctx = (xmpp_ctx_t *)userdata;
|
||||||
xmpp_stanza_t *iq, *query;
|
xmpp_stanza_t *iq, *query;
|
||||||
|
|
||||||
if (status == XMPP_CONN_CONNECT) {
|
if (status == XMPP_CONN_CONNECT) {
|
||||||
fprintf(stderr, "DEBUG: connected\n");
|
fprintf(stderr, "DEBUG: connected\n");
|
||||||
|
|
||||||
/* create iq stanza for request */
|
/* create iq stanza for request */
|
||||||
iq = xmpp_iq_new(ctx, "get", "active1");
|
iq = xmpp_iq_new(ctx, "get", "active1");
|
||||||
xmpp_stanza_set_to(iq, "xxxxxxxxx.com");
|
xmpp_stanza_set_to(iq, "xxxxxxxxx.com");
|
||||||
|
|
||||||
query = xmpp_stanza_new(ctx);
|
query = xmpp_stanza_new(ctx);
|
||||||
xmpp_stanza_set_name(query, "query");
|
xmpp_stanza_set_name(query, "query");
|
||||||
xmpp_stanza_set_ns(query, XMPP_NS_DISCO_ITEMS);
|
xmpp_stanza_set_ns(query, XMPP_NS_DISCO_ITEMS);
|
||||||
xmpp_stanza_set_attribute(query, "node", "sessions");
|
xmpp_stanza_set_attribute(query, "node", "sessions");
|
||||||
|
|
||||||
xmpp_stanza_add_child(iq, query);
|
xmpp_stanza_add_child(iq, query);
|
||||||
|
|
||||||
/* we can release the stanza since it belongs to iq now */
|
/* we can release the stanza since it belongs to iq now */
|
||||||
xmpp_stanza_release(query);
|
xmpp_stanza_release(query);
|
||||||
|
|
||||||
/* set up reply handler */
|
/* set up reply handler */
|
||||||
xmpp_id_handler_add(conn, handle_reply, "active1", ctx);
|
xmpp_id_handler_add(conn, handle_reply, "active1", ctx);
|
||||||
|
|
||||||
/* send out the stanza */
|
/* send out the stanza */
|
||||||
xmpp_send(conn, iq);
|
xmpp_send(conn, iq);
|
||||||
|
|
||||||
/* release the stanza */
|
/* release the stanza */
|
||||||
xmpp_stanza_release(iq);
|
xmpp_stanza_release(iq);
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "DEBUG: disconnected\n");
|
fprintf(stderr, "DEBUG: disconnected\n");
|
||||||
xmpp_stop(ctx);
|
xmpp_stop(ctx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -88,8 +90,8 @@ int main(int argc, char **argv)
|
|||||||
xmpp_conn_t *conn;
|
xmpp_conn_t *conn;
|
||||||
|
|
||||||
if (argc != 3) {
|
if (argc != 3) {
|
||||||
fprintf(stderr, "Usage: active <jid> <pass>\n\n");
|
fprintf(stderr, "Usage: active <jid> <pass>\n\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* initialize lib */
|
/* initialize lib */
|
||||||
|
|||||||
@@ -19,9 +19,11 @@
|
|||||||
#define KA_INTERVAL 1
|
#define KA_INTERVAL 1
|
||||||
|
|
||||||
/* define a handler for connection events */
|
/* define a handler for connection events */
|
||||||
void conn_handler(xmpp_conn_t * const conn, const xmpp_conn_event_t status,
|
void conn_handler(xmpp_conn_t *const conn,
|
||||||
const int error, xmpp_stream_error_t * const stream_error,
|
const xmpp_conn_event_t status,
|
||||||
void * const userdata)
|
const int error,
|
||||||
|
xmpp_stream_error_t *const stream_error,
|
||||||
|
void *const userdata)
|
||||||
{
|
{
|
||||||
xmpp_ctx_t *ctx = (xmpp_ctx_t *)userdata;
|
xmpp_ctx_t *ctx = (xmpp_ctx_t *)userdata;
|
||||||
int secured;
|
int secured;
|
||||||
@@ -32,8 +34,7 @@ void conn_handler(xmpp_conn_t * const conn, const xmpp_conn_event_t status,
|
|||||||
fprintf(stderr, "DEBUG: connection is %s.\n",
|
fprintf(stderr, "DEBUG: connection is %s.\n",
|
||||||
secured ? "secured" : "NOT secured");
|
secured ? "secured" : "NOT secured");
|
||||||
xmpp_disconnect(conn);
|
xmpp_disconnect(conn);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
fprintf(stderr, "DEBUG: disconnected\n");
|
fprintf(stderr, "DEBUG: disconnected\n");
|
||||||
xmpp_stop(ctx);
|
xmpp_stop(ctx);
|
||||||
}
|
}
|
||||||
@@ -70,7 +71,7 @@ int main(int argc, char **argv)
|
|||||||
" --legacy-ssl Use old style SSL.\n"
|
" --legacy-ssl Use old style SSL.\n"
|
||||||
" --tcp-keepalive Configure TCP keepalive.\n\n"
|
" --tcp-keepalive Configure TCP keepalive.\n\n"
|
||||||
"Note: --disable-tls conflicts with --mandatory-tls or "
|
"Note: --disable-tls conflicts with --mandatory-tls or "
|
||||||
"--legacy-ssl\n");
|
"--legacy-ssl\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -87,8 +88,9 @@ int main(int argc, char **argv)
|
|||||||
/* init library */
|
/* init library */
|
||||||
xmpp_initialize();
|
xmpp_initialize();
|
||||||
|
|
||||||
|
/* pass NULL instead to silence output */
|
||||||
|
log = xmpp_get_default_logger(XMPP_LEVEL_DEBUG);
|
||||||
/* create a context */
|
/* create a context */
|
||||||
log = xmpp_get_default_logger(XMPP_LEVEL_DEBUG); /* pass NULL instead to silence output */
|
|
||||||
ctx = xmpp_ctx_new(NULL, log);
|
ctx = xmpp_ctx_new(NULL, log);
|
||||||
|
|
||||||
/* create a connection */
|
/* create a connection */
|
||||||
@@ -97,7 +99,8 @@ int main(int argc, char **argv)
|
|||||||
/* configure connection properties (optional) */
|
/* configure connection properties (optional) */
|
||||||
xmpp_conn_set_flags(conn, flags);
|
xmpp_conn_set_flags(conn, flags);
|
||||||
/* configure TCP keepalive (optional) */
|
/* configure TCP keepalive (optional) */
|
||||||
if (tcp_keepalive) xmpp_conn_set_keepalive(conn, KA_TIMEOUT, KA_INTERVAL);
|
if (tcp_keepalive)
|
||||||
|
xmpp_conn_set_keepalive(conn, KA_TIMEOUT, KA_INTERVAL);
|
||||||
|
|
||||||
/* setup authentication information */
|
/* setup authentication information */
|
||||||
xmpp_conn_set_jid(conn, jid);
|
xmpp_conn_set_jid(conn, jid);
|
||||||
|
|||||||
@@ -22,12 +22,13 @@
|
|||||||
|
|
||||||
#include <strophe.h>
|
#include <strophe.h>
|
||||||
|
|
||||||
|
int version_handler(xmpp_conn_t *const conn,
|
||||||
int version_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata)
|
xmpp_stanza_t *const stanza,
|
||||||
|
void *const userdata)
|
||||||
{
|
{
|
||||||
xmpp_stanza_t *reply, *query, *name, *version, *text;
|
xmpp_stanza_t *reply, *query, *name, *version, *text;
|
||||||
const char *ns;
|
const char *ns;
|
||||||
xmpp_ctx_t *ctx = (xmpp_ctx_t*)userdata;
|
xmpp_ctx_t *ctx = (xmpp_ctx_t *)userdata;
|
||||||
|
|
||||||
printf("Received version request from %s\n", xmpp_stanza_get_from(stanza));
|
printf("Received version request from %s\n", xmpp_stanza_get_from(stanza));
|
||||||
|
|
||||||
@@ -69,10 +70,11 @@ int version_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int message_handler(xmpp_conn_t *const conn,
|
||||||
int message_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata)
|
xmpp_stanza_t *const stanza,
|
||||||
|
void *const userdata)
|
||||||
{
|
{
|
||||||
xmpp_ctx_t *ctx = (xmpp_ctx_t*)userdata;
|
xmpp_ctx_t *ctx = (xmpp_ctx_t *)userdata;
|
||||||
xmpp_stanza_t *body, *reply;
|
xmpp_stanza_t *body, *reply;
|
||||||
const char *type;
|
const char *type;
|
||||||
char *intext, *replytext;
|
char *intext, *replytext;
|
||||||
@@ -87,7 +89,8 @@ int message_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void
|
|||||||
|
|
||||||
intext = xmpp_stanza_get_text(body);
|
intext = xmpp_stanza_get_text(body);
|
||||||
|
|
||||||
printf("Incoming message from %s: %s\n", xmpp_stanza_get_from(stanza), intext);
|
printf("Incoming message from %s: %s\n", xmpp_stanza_get_from(stanza),
|
||||||
|
intext);
|
||||||
|
|
||||||
reply = xmpp_stanza_reply(stanza);
|
reply = xmpp_stanza_reply(stanza);
|
||||||
if (xmpp_stanza_get_type(reply) == NULL)
|
if (xmpp_stanza_get_type(reply) == NULL)
|
||||||
@@ -97,7 +100,7 @@ int message_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void
|
|||||||
replytext = strdup("bye!");
|
replytext = strdup("bye!");
|
||||||
quit = 1;
|
quit = 1;
|
||||||
} else {
|
} else {
|
||||||
replytext = (char *) malloc(strlen(" to you too!") + strlen(intext) + 1);
|
replytext = (char *)malloc(strlen(" to you too!") + strlen(intext) + 1);
|
||||||
strcpy(replytext, intext);
|
strcpy(replytext, intext);
|
||||||
strcat(replytext, " to you too!");
|
strcat(replytext, " to you too!");
|
||||||
}
|
}
|
||||||
@@ -115,24 +118,26 @@ int message_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* define a handler for connection events */
|
/* define a handler for connection events */
|
||||||
void conn_handler(xmpp_conn_t * const conn, const xmpp_conn_event_t status,
|
void conn_handler(xmpp_conn_t *const conn,
|
||||||
const int error, xmpp_stream_error_t * const stream_error,
|
const xmpp_conn_event_t status,
|
||||||
void * const userdata)
|
const int error,
|
||||||
|
xmpp_stream_error_t *const stream_error,
|
||||||
|
void *const userdata)
|
||||||
{
|
{
|
||||||
xmpp_ctx_t *ctx = (xmpp_ctx_t *)userdata;
|
xmpp_ctx_t *ctx = (xmpp_ctx_t *)userdata;
|
||||||
|
|
||||||
if (status == XMPP_CONN_CONNECT) {
|
if (status == XMPP_CONN_CONNECT) {
|
||||||
xmpp_stanza_t* pres;
|
xmpp_stanza_t *pres;
|
||||||
fprintf(stderr, "DEBUG: connected\n");
|
fprintf(stderr, "DEBUG: connected\n");
|
||||||
xmpp_handler_add(conn, version_handler, "jabber:iq:version", "iq", NULL, ctx);
|
xmpp_handler_add(conn, version_handler, "jabber:iq:version", "iq", NULL,
|
||||||
|
ctx);
|
||||||
xmpp_handler_add(conn, message_handler, NULL, "message", NULL, ctx);
|
xmpp_handler_add(conn, message_handler, NULL, "message", NULL, ctx);
|
||||||
|
|
||||||
/* Send initial <presence/> so that we appear online to contacts */
|
/* Send initial <presence/> so that we appear online to contacts */
|
||||||
pres = xmpp_presence_new(ctx);
|
pres = xmpp_presence_new(ctx);
|
||||||
xmpp_send(conn, pres);
|
xmpp_send(conn, pres);
|
||||||
xmpp_stanza_release(pres);
|
xmpp_stanza_release(pres);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
fprintf(stderr, "DEBUG: disconnected\n");
|
fprintf(stderr, "DEBUG: disconnected\n");
|
||||||
xmpp_stop(ctx);
|
xmpp_stop(ctx);
|
||||||
}
|
}
|
||||||
@@ -157,8 +162,9 @@ int main(int argc, char **argv)
|
|||||||
/* init library */
|
/* init library */
|
||||||
xmpp_initialize();
|
xmpp_initialize();
|
||||||
|
|
||||||
|
/* pass NULL instead to silence output */
|
||||||
|
log = xmpp_get_default_logger(XMPP_LEVEL_DEBUG);
|
||||||
/* create a context */
|
/* create a context */
|
||||||
log = xmpp_get_default_logger(XMPP_LEVEL_DEBUG); /* pass NULL instead to silence output */
|
|
||||||
ctx = xmpp_ctx_new(NULL, log);
|
ctx = xmpp_ctx_new(NULL, log);
|
||||||
|
|
||||||
/* create a connection */
|
/* create a connection */
|
||||||
|
|||||||
@@ -19,19 +19,19 @@
|
|||||||
|
|
||||||
#include <strophe.h>
|
#include <strophe.h>
|
||||||
|
|
||||||
|
|
||||||
/* define a handler for connection events */
|
/* define a handler for connection events */
|
||||||
void conn_handler(xmpp_conn_t * const conn, const xmpp_conn_event_t status,
|
void conn_handler(xmpp_conn_t *const conn,
|
||||||
const int error, xmpp_stream_error_t * const stream_error,
|
const xmpp_conn_event_t status,
|
||||||
void * const userdata)
|
const int error,
|
||||||
|
xmpp_stream_error_t *const stream_error,
|
||||||
|
void *const userdata)
|
||||||
{
|
{
|
||||||
xmpp_ctx_t *ctx = (xmpp_ctx_t *)userdata;
|
xmpp_ctx_t *ctx = (xmpp_ctx_t *)userdata;
|
||||||
|
|
||||||
if (status == XMPP_CONN_CONNECT) {
|
if (status == XMPP_CONN_CONNECT) {
|
||||||
fprintf(stderr, "DEBUG: connected\n");
|
fprintf(stderr, "DEBUG: connected\n");
|
||||||
xmpp_disconnect(conn);
|
xmpp_disconnect(conn);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
fprintf(stderr, "DEBUG: disconnected\n");
|
fprintf(stderr, "DEBUG: disconnected\n");
|
||||||
xmpp_stop(ctx);
|
xmpp_stop(ctx);
|
||||||
}
|
}
|
||||||
@@ -56,19 +56,20 @@ int main(int argc, char **argv)
|
|||||||
host = argv[3];
|
host = argv[3];
|
||||||
|
|
||||||
if (argc == 5) {
|
if (argc == 5) {
|
||||||
short tmp_port = (short) strtol(argv[4], &port_err, 10);
|
short tmp_port = (short)strtol(argv[4], &port_err, 10);
|
||||||
if (tmp_port < 0 || *port_err != '\0') {
|
if (tmp_port < 0 || *port_err != '\0') {
|
||||||
fprintf(stderr, "Invalid value of <port> [%s].\n", argv[4]);
|
fprintf(stderr, "Invalid value of <port> [%s].\n", argv[4]);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
port = (unsigned short) tmp_port;
|
port = (unsigned short)tmp_port;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* init library */
|
/* init library */
|
||||||
xmpp_initialize();
|
xmpp_initialize();
|
||||||
|
|
||||||
|
/* pass NULL instead to silence output */
|
||||||
|
log = xmpp_get_default_logger(XMPP_LEVEL_DEBUG);
|
||||||
/* create a context */
|
/* create a context */
|
||||||
log = xmpp_get_default_logger(XMPP_LEVEL_DEBUG); /* pass NULL instead to silence output */
|
|
||||||
ctx = xmpp_ctx_new(NULL, log);
|
ctx = xmpp_ctx_new(NULL, log);
|
||||||
|
|
||||||
/* create a connection */
|
/* create a connection */
|
||||||
@@ -94,4 +95,3 @@ int main(int argc, char **argv)
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -36,9 +36,8 @@ typedef struct {
|
|||||||
|
|
||||||
#define FEATURES_TIMEOUT 5000 /* 5 seconds */
|
#define FEATURES_TIMEOUT 5000 /* 5 seconds */
|
||||||
|
|
||||||
static void iq_reg_send_form(xmpp_reg_t *reg,
|
static void
|
||||||
xmpp_conn_t *conn,
|
iq_reg_send_form(xmpp_reg_t *reg, xmpp_conn_t *conn, xmpp_stanza_t *stanza)
|
||||||
xmpp_stanza_t *stanza)
|
|
||||||
{
|
{
|
||||||
xmpp_ctx_t *ctx = reg->ctx;
|
xmpp_ctx_t *ctx = reg->ctx;
|
||||||
xmpp_stanza_t *query;
|
xmpp_stanza_t *query;
|
||||||
@@ -101,9 +100,9 @@ static void iq_reg_send_form(xmpp_reg_t *reg,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int iq_reg2_cb(xmpp_conn_t * const conn,
|
static int iq_reg2_cb(xmpp_conn_t *const conn,
|
||||||
xmpp_stanza_t * const stanza,
|
xmpp_stanza_t *const stanza,
|
||||||
void * const userdata)
|
void *const userdata)
|
||||||
{
|
{
|
||||||
const char *type;
|
const char *type;
|
||||||
|
|
||||||
@@ -126,9 +125,9 @@ quit:
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int iq_reg_cb(xmpp_conn_t * const conn,
|
static int iq_reg_cb(xmpp_conn_t *const conn,
|
||||||
xmpp_stanza_t * const stanza,
|
xmpp_stanza_t *const stanza,
|
||||||
void * const userdata)
|
void *const userdata)
|
||||||
{
|
{
|
||||||
xmpp_reg_t *reg = (xmpp_reg_t *)userdata;
|
xmpp_reg_t *reg = (xmpp_reg_t *)userdata;
|
||||||
xmpp_stanza_t *registered = NULL;
|
xmpp_stanza_t *registered = NULL;
|
||||||
@@ -163,9 +162,9 @@ quit:
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _handle_error(xmpp_conn_t * const conn,
|
static int _handle_error(xmpp_conn_t *const conn,
|
||||||
xmpp_stanza_t * const stanza,
|
xmpp_stanza_t *const stanza,
|
||||||
void * const userdata)
|
void *const userdata)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "DEBUG: received stream error\n");
|
fprintf(stderr, "DEBUG: received stream error\n");
|
||||||
xmpp_disconnect(conn);
|
xmpp_disconnect(conn);
|
||||||
@@ -173,9 +172,9 @@ static int _handle_error(xmpp_conn_t * const conn,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _handle_proceedtls_default(xmpp_conn_t * const conn,
|
static int _handle_proceedtls_default(xmpp_conn_t *const conn,
|
||||||
xmpp_stanza_t * const stanza,
|
xmpp_stanza_t *const stanza,
|
||||||
void * const userdata)
|
void *const userdata)
|
||||||
{
|
{
|
||||||
const char *name = xmpp_stanza_get_name(stanza);
|
const char *name = xmpp_stanza_get_name(stanza);
|
||||||
|
|
||||||
@@ -193,8 +192,8 @@ static int _handle_proceedtls_default(xmpp_conn_t * const conn,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _handle_missing_features(xmpp_conn_t * const conn,
|
static int _handle_missing_features(xmpp_conn_t *const conn,
|
||||||
void * const userdata)
|
void *const userdata)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "DEBUG: timeout\n");
|
fprintf(stderr, "DEBUG: timeout\n");
|
||||||
xmpp_disconnect(conn);
|
xmpp_disconnect(conn);
|
||||||
@@ -202,9 +201,9 @@ static int _handle_missing_features(xmpp_conn_t * const conn,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _handle_features(xmpp_conn_t * const conn,
|
static int _handle_features(xmpp_conn_t *const conn,
|
||||||
xmpp_stanza_t * const stanza,
|
xmpp_stanza_t *const stanza,
|
||||||
void * const userdata)
|
void *const userdata)
|
||||||
{
|
{
|
||||||
xmpp_reg_t *reg = (xmpp_reg_t *)userdata;
|
xmpp_reg_t *reg = (xmpp_reg_t *)userdata;
|
||||||
xmpp_ctx_t *ctx = reg->ctx;
|
xmpp_ctx_t *ctx = reg->ctx;
|
||||||
@@ -221,8 +220,8 @@ static int _handle_features(xmpp_conn_t * const conn,
|
|||||||
child = xmpp_stanza_new(ctx);
|
child = xmpp_stanza_new(ctx);
|
||||||
xmpp_stanza_set_name(child, "starttls");
|
xmpp_stanza_set_name(child, "starttls");
|
||||||
xmpp_stanza_set_ns(child, XMPP_NS_TLS);
|
xmpp_stanza_set_ns(child, XMPP_NS_TLS);
|
||||||
xmpp_handler_add(conn, _handle_proceedtls_default,
|
xmpp_handler_add(conn, _handle_proceedtls_default, XMPP_NS_TLS, NULL,
|
||||||
XMPP_NS_TLS, NULL, NULL, NULL);
|
NULL, NULL);
|
||||||
xmpp_send(conn, child);
|
xmpp_send(conn, child);
|
||||||
xmpp_stanza_release(child);
|
xmpp_stanza_release(child);
|
||||||
return 0;
|
return 0;
|
||||||
@@ -255,11 +254,11 @@ static int _handle_features(xmpp_conn_t * const conn,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void conn_handler(xmpp_conn_t * const conn,
|
static void conn_handler(xmpp_conn_t *const conn,
|
||||||
const xmpp_conn_event_t status,
|
const xmpp_conn_event_t status,
|
||||||
const int error,
|
const int error,
|
||||||
xmpp_stream_error_t * const stream_error,
|
xmpp_stream_error_t *const stream_error,
|
||||||
void * const userdata)
|
void *const userdata)
|
||||||
{
|
{
|
||||||
xmpp_reg_t *reg = (xmpp_reg_t *)userdata;
|
xmpp_reg_t *reg = (xmpp_reg_t *)userdata;
|
||||||
int secured;
|
int secured;
|
||||||
@@ -274,14 +273,14 @@ static void conn_handler(xmpp_conn_t * const conn,
|
|||||||
secured ? "secured" : "NOT secured");
|
secured ? "secured" : "NOT secured");
|
||||||
|
|
||||||
/* setup handler for stream:error */
|
/* setup handler for stream:error */
|
||||||
xmpp_handler_add(conn, _handle_error, XMPP_NS_STREAMS,
|
xmpp_handler_add(conn, _handle_error, XMPP_NS_STREAMS, "error", NULL,
|
||||||
"error", NULL, NULL);
|
NULL);
|
||||||
|
|
||||||
/* setup handlers for incoming <stream:features> */
|
/* setup handlers for incoming <stream:features> */
|
||||||
xmpp_handler_add(conn, _handle_features, XMPP_NS_STREAMS,
|
xmpp_handler_add(conn, _handle_features, XMPP_NS_STREAMS, "features",
|
||||||
"features", NULL, reg);
|
NULL, reg);
|
||||||
xmpp_timed_handler_add(conn, _handle_missing_features,
|
xmpp_timed_handler_add(conn, _handle_missing_features, FEATURES_TIMEOUT,
|
||||||
FEATURES_TIMEOUT, NULL);
|
NULL);
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "DEBUG: disconnected\n");
|
fprintf(stderr, "DEBUG: disconnected\n");
|
||||||
xmpp_stop(reg->ctx);
|
xmpp_stop(reg->ctx);
|
||||||
|
|||||||
@@ -18,31 +18,29 @@
|
|||||||
|
|
||||||
#include <strophe.h>
|
#include <strophe.h>
|
||||||
|
|
||||||
int handle_reply(xmpp_conn_t * const conn,
|
int handle_reply(xmpp_conn_t *const conn,
|
||||||
xmpp_stanza_t * const stanza,
|
xmpp_stanza_t *const stanza,
|
||||||
void * const userdata)
|
void *const userdata)
|
||||||
{
|
{
|
||||||
xmpp_stanza_t *query, *item;
|
xmpp_stanza_t *query, *item;
|
||||||
const char *type, *name;
|
const char *type, *name;
|
||||||
|
|
||||||
type = xmpp_stanza_get_type(stanza);
|
type = xmpp_stanza_get_type(stanza);
|
||||||
if (strcmp(type, "error") == 0)
|
if (strcmp(type, "error") == 0)
|
||||||
fprintf(stderr, "ERROR: query failed\n");
|
fprintf(stderr, "ERROR: query failed\n");
|
||||||
else {
|
else {
|
||||||
query = xmpp_stanza_get_child_by_name(stanza, "query");
|
query = xmpp_stanza_get_child_by_name(stanza, "query");
|
||||||
printf("Roster:\n");
|
printf("Roster:\n");
|
||||||
for (item = xmpp_stanza_get_children(query); item;
|
for (item = xmpp_stanza_get_children(query); item;
|
||||||
item = xmpp_stanza_get_next(item))
|
item = xmpp_stanza_get_next(item))
|
||||||
if ((name = xmpp_stanza_get_attribute(item, "name")))
|
if ((name = xmpp_stanza_get_attribute(item, "name")))
|
||||||
printf("\t %s (%s) sub=%s\n",
|
printf("\t %s (%s) sub=%s\n", name,
|
||||||
name,
|
xmpp_stanza_get_attribute(item, "jid"),
|
||||||
xmpp_stanza_get_attribute(item, "jid"),
|
xmpp_stanza_get_attribute(item, "subscription"));
|
||||||
xmpp_stanza_get_attribute(item, "subscription"));
|
else
|
||||||
else
|
printf("\t %s sub=%s\n", xmpp_stanza_get_attribute(item, "jid"),
|
||||||
printf("\t %s sub=%s\n",
|
xmpp_stanza_get_attribute(item, "subscription"));
|
||||||
xmpp_stanza_get_attribute(item, "jid"),
|
printf("END OF LIST\n");
|
||||||
xmpp_stanza_get_attribute(item, "subscription"));
|
|
||||||
printf("END OF LIST\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* disconnect */
|
/* disconnect */
|
||||||
@@ -51,39 +49,41 @@ int handle_reply(xmpp_conn_t * const conn,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void conn_handler(xmpp_conn_t * const conn, const xmpp_conn_event_t status,
|
void conn_handler(xmpp_conn_t *const conn,
|
||||||
const int error, xmpp_stream_error_t * const stream_error,
|
const xmpp_conn_event_t status,
|
||||||
void * const userdata)
|
const int error,
|
||||||
|
xmpp_stream_error_t *const stream_error,
|
||||||
|
void *const userdata)
|
||||||
{
|
{
|
||||||
xmpp_ctx_t *ctx = (xmpp_ctx_t *)userdata;
|
xmpp_ctx_t *ctx = (xmpp_ctx_t *)userdata;
|
||||||
xmpp_stanza_t *iq, *query;
|
xmpp_stanza_t *iq, *query;
|
||||||
|
|
||||||
if (status == XMPP_CONN_CONNECT) {
|
if (status == XMPP_CONN_CONNECT) {
|
||||||
fprintf(stderr, "DEBUG: connected\n");
|
fprintf(stderr, "DEBUG: connected\n");
|
||||||
|
|
||||||
/* create iq stanza for request */
|
/* create iq stanza for request */
|
||||||
iq = xmpp_iq_new(ctx, "get", "roster1");
|
iq = xmpp_iq_new(ctx, "get", "roster1");
|
||||||
|
|
||||||
query = xmpp_stanza_new(ctx);
|
query = xmpp_stanza_new(ctx);
|
||||||
xmpp_stanza_set_name(query, "query");
|
xmpp_stanza_set_name(query, "query");
|
||||||
xmpp_stanza_set_ns(query, XMPP_NS_ROSTER);
|
xmpp_stanza_set_ns(query, XMPP_NS_ROSTER);
|
||||||
|
|
||||||
xmpp_stanza_add_child(iq, query);
|
xmpp_stanza_add_child(iq, query);
|
||||||
|
|
||||||
/* we can release the stanza since it belongs to iq now */
|
/* we can release the stanza since it belongs to iq now */
|
||||||
xmpp_stanza_release(query);
|
xmpp_stanza_release(query);
|
||||||
|
|
||||||
/* set up reply handler */
|
/* set up reply handler */
|
||||||
xmpp_id_handler_add(conn, handle_reply, "roster1", ctx);
|
xmpp_id_handler_add(conn, handle_reply, "roster1", ctx);
|
||||||
|
|
||||||
/* send out the stanza */
|
/* send out the stanza */
|
||||||
xmpp_send(conn, iq);
|
xmpp_send(conn, iq);
|
||||||
|
|
||||||
/* release the stanza */
|
/* release the stanza */
|
||||||
xmpp_stanza_release(iq);
|
xmpp_stanza_release(iq);
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "DEBUG: disconnected\n");
|
fprintf(stderr, "DEBUG: disconnected\n");
|
||||||
xmpp_stop(ctx);
|
xmpp_stop(ctx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -93,8 +93,8 @@ int main(int argc, char **argv)
|
|||||||
xmpp_conn_t *conn;
|
xmpp_conn_t *conn;
|
||||||
|
|
||||||
if (argc != 3) {
|
if (argc != 3) {
|
||||||
fprintf(stderr, "Usage: roster <jid> <pass>\n\n");
|
fprintf(stderr, "Usage: roster <jid> <pass>\n\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* initialize lib */
|
/* initialize lib */
|
||||||
|
|||||||
@@ -76,8 +76,8 @@ static void vcard_photo(vcard_t *vc, xmpp_stanza_t *stanza)
|
|||||||
xmpp_free(vc->ctx, img);
|
xmpp_free(vc->ctx, img);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void vcard_print_string(vcard_t *vc, xmpp_stanza_t *stanza,
|
static void
|
||||||
const char *info)
|
vcard_print_string(vcard_t *vc, xmpp_stanza_t *stanza, const char *info)
|
||||||
{
|
{
|
||||||
char *s = xmpp_stanza_get_text(stanza);
|
char *s = xmpp_stanza_get_text(stanza);
|
||||||
|
|
||||||
@@ -140,14 +140,9 @@ static vcard_cb_t vcard_cb_get(xmpp_stanza_t *stanza)
|
|||||||
const char *tag;
|
const char *tag;
|
||||||
vcard_cb_t cb;
|
vcard_cb_t cb;
|
||||||
} vcard_tbl[] = {
|
} vcard_tbl[] = {
|
||||||
{ "PHOTO", vcard_photo },
|
{"PHOTO", vcard_photo}, {"BDAY", vcard_bday}, {"DESC", vcard_desc},
|
||||||
{ "BDAY", vcard_bday },
|
{"EMAIL", vcard_email}, {"FN", vcard_fn}, {"N", vcard_name},
|
||||||
{ "DESC", vcard_desc },
|
{"NICKNAME", vcard_nick}, {"URL", vcard_url},
|
||||||
{ "EMAIL", vcard_email },
|
|
||||||
{ "FN", vcard_fn },
|
|
||||||
{ "N", vcard_name },
|
|
||||||
{ "NICKNAME", vcard_nick },
|
|
||||||
{ "URL", vcard_url },
|
|
||||||
};
|
};
|
||||||
|
|
||||||
tag = xmpp_stanza_get_name(stanza);
|
tag = xmpp_stanza_get_name(stanza);
|
||||||
@@ -165,7 +160,7 @@ exit:
|
|||||||
return cb;
|
return cb;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int timedout(xmpp_conn_t * const conn, void * const userdata)
|
static int timedout(xmpp_conn_t *const conn, void *const userdata)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Timeout reached.\n");
|
fprintf(stderr, "Timeout reached.\n");
|
||||||
xmpp_disconnect(conn);
|
xmpp_disconnect(conn);
|
||||||
@@ -173,8 +168,9 @@ static int timedout(xmpp_conn_t * const conn, void * const userdata)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int recv_vcard(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza,
|
static int recv_vcard(xmpp_conn_t *const conn,
|
||||||
void * const userdata)
|
xmpp_stanza_t *const stanza,
|
||||||
|
void *const userdata)
|
||||||
{
|
{
|
||||||
vcard_t *vc = userdata;
|
vcard_t *vc = userdata;
|
||||||
vcard_cb_t cb;
|
vcard_cb_t cb;
|
||||||
@@ -213,16 +209,17 @@ exit:
|
|||||||
static void send_vcard_req(xmpp_conn_t *conn, const char *to, const char *id)
|
static void send_vcard_req(xmpp_conn_t *conn, const char *to, const char *id)
|
||||||
{
|
{
|
||||||
printf("Requesting vCard from %s.\n", to);
|
printf("Requesting vCard from %s.\n", to);
|
||||||
xmpp_send_raw_string(conn, "<iq from='%s' to='%s' type='get' id='%s'>"
|
xmpp_send_raw_string(conn,
|
||||||
"<vCard xmlns='vcard-temp'/></iq>",
|
"<iq from='%s' to='%s' type='get' id='%s'>"
|
||||||
xmpp_conn_get_bound_jid(conn), to, id);
|
"<vCard xmlns='vcard-temp'/></iq>",
|
||||||
|
xmpp_conn_get_bound_jid(conn), to, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void conn_handler(xmpp_conn_t * const conn,
|
static void conn_handler(xmpp_conn_t *const conn,
|
||||||
const xmpp_conn_event_t status,
|
const xmpp_conn_event_t status,
|
||||||
const int error,
|
const int error,
|
||||||
xmpp_stream_error_t * const stream_error,
|
xmpp_stream_error_t *const stream_error,
|
||||||
void * const userdata)
|
void *const userdata)
|
||||||
{
|
{
|
||||||
vcard_t *vc = userdata;
|
vcard_t *vc = userdata;
|
||||||
|
|
||||||
@@ -235,25 +232,26 @@ static void conn_handler(xmpp_conn_t * const conn,
|
|||||||
fprintf(stderr, "Disconnected with error=%d.\n", error);
|
fprintf(stderr, "Disconnected with error=%d.\n", error);
|
||||||
if (stream_error != NULL)
|
if (stream_error != NULL)
|
||||||
fprintf(stderr, "Stream error type=%d text=%s.\n",
|
fprintf(stderr, "Stream error type=%d text=%s.\n",
|
||||||
stream_error->type, stream_error->text);
|
stream_error->type, stream_error->text);
|
||||||
xmpp_stop(vc->ctx);
|
xmpp_stop(vc->ctx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
xmpp_log_t *log;
|
xmpp_log_t *log;
|
||||||
xmpp_ctx_t *ctx;
|
xmpp_ctx_t *ctx;
|
||||||
xmpp_conn_t *conn;
|
xmpp_conn_t *conn;
|
||||||
const char *jid;
|
const char *jid;
|
||||||
const char *pass;
|
const char *pass;
|
||||||
char *prog;
|
char *prog;
|
||||||
vcard_t vcard;
|
vcard_t vcard;
|
||||||
|
|
||||||
if (argc < 4 || argc > 5) {
|
if (argc < 4 || argc > 5) {
|
||||||
prog = argc > 0 ? strdup(argv[0]) : NULL;
|
prog = argc > 0 ? strdup(argv[0]) : NULL;
|
||||||
printf("Usage: %s <login-jid> <password> <recipient-jid> "
|
printf("Usage: %s <login-jid> <password> <recipient-jid> "
|
||||||
"[image-file]\n\n", prog == NULL ? "vcard" : basename(prog));
|
"[image-file]\n\n",
|
||||||
|
prog == NULL ? "vcard" : basename(prog));
|
||||||
printf("If vCard contains a photo it will be stored to "
|
printf("If vCard contains a photo it will be stored to "
|
||||||
"image-file. If you don't provide the image-file "
|
"image-file. If you don't provide the image-file "
|
||||||
"default filename will be generated.\n");
|
"default filename will be generated.\n");
|
||||||
@@ -281,4 +279,3 @@ int main(int argc, char **argv)
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
965
src/auth.c
965
src/auth.c
File diff suppressed because it is too large
Load Diff
101
src/common.h
101
src/common.h
@@ -19,7 +19,6 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
|
||||||
#include "strophe.h"
|
#include "strophe.h"
|
||||||
#include "ostypes.h"
|
#include "ostypes.h"
|
||||||
#include "sock.h"
|
#include "sock.h"
|
||||||
@@ -54,35 +53,33 @@ struct _xmpp_ctx_t {
|
|||||||
unsigned long timeout;
|
unsigned long timeout;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/* convenience functions for accessing the context */
|
/* convenience functions for accessing the context */
|
||||||
void *xmpp_alloc(const xmpp_ctx_t * const ctx, const size_t size);
|
void *xmpp_alloc(const xmpp_ctx_t *const ctx, const size_t size);
|
||||||
void *xmpp_realloc(const xmpp_ctx_t * const ctx, void *p,
|
void *xmpp_realloc(const xmpp_ctx_t *const ctx, void *p, const size_t size);
|
||||||
const size_t size);
|
char *xmpp_strdup(const xmpp_ctx_t *const ctx, const char *const s);
|
||||||
char *xmpp_strdup(const xmpp_ctx_t * const ctx, const char * const s);
|
|
||||||
|
|
||||||
void xmpp_log(const xmpp_ctx_t * const ctx,
|
void xmpp_log(const xmpp_ctx_t *const ctx,
|
||||||
const xmpp_log_level_t level,
|
const xmpp_log_level_t level,
|
||||||
const char * const area,
|
const char *const area,
|
||||||
const char * const fmt,
|
const char *const fmt,
|
||||||
va_list ap);
|
va_list ap);
|
||||||
|
|
||||||
/* wrappers for xmpp_log at specific levels */
|
/* wrappers for xmpp_log at specific levels */
|
||||||
void xmpp_error(const xmpp_ctx_t * const ctx,
|
void xmpp_error(const xmpp_ctx_t *const ctx,
|
||||||
const char * const area,
|
const char *const area,
|
||||||
const char * const fmt,
|
const char *const fmt,
|
||||||
...);
|
...);
|
||||||
void xmpp_warn(const xmpp_ctx_t * const ctx,
|
void xmpp_warn(const xmpp_ctx_t *const ctx,
|
||||||
const char * const area,
|
const char *const area,
|
||||||
const char * const fmt,
|
const char *const fmt,
|
||||||
...);
|
...);
|
||||||
void xmpp_info(const xmpp_ctx_t * const ctx,
|
void xmpp_info(const xmpp_ctx_t *const ctx,
|
||||||
const char * const area,
|
const char *const area,
|
||||||
const char * const fmt,
|
const char *const fmt,
|
||||||
...);
|
...);
|
||||||
void xmpp_debug(const xmpp_ctx_t * const ctx,
|
void xmpp_debug(const xmpp_ctx_t *const ctx,
|
||||||
const char * const area,
|
const char *const area,
|
||||||
const char * const fmt,
|
const char *const fmt,
|
||||||
...);
|
...);
|
||||||
|
|
||||||
/** connection **/
|
/** connection **/
|
||||||
@@ -135,7 +132,7 @@ struct _xmpp_handlist_t {
|
|||||||
|
|
||||||
#define MAX_DOMAIN_LEN 256
|
#define MAX_DOMAIN_LEN 256
|
||||||
|
|
||||||
#define SASL_MASK_PLAIN (1 << 0)
|
#define SASL_MASK_PLAIN (1 << 0)
|
||||||
#define SASL_MASK_DIGESTMD5 (1 << 1)
|
#define SASL_MASK_DIGESTMD5 (1 << 1)
|
||||||
#define SASL_MASK_ANONYMOUS (1 << 2)
|
#define SASL_MASK_ANONYMOUS (1 << 2)
|
||||||
#define SASL_MASK_SCRAMSHA1 (1 << 3)
|
#define SASL_MASK_SCRAMSHA1 (1 << 3)
|
||||||
@@ -146,7 +143,7 @@ enum {
|
|||||||
XMPP_PORT_COMPONENT = 5347,
|
XMPP_PORT_COMPONENT = 5347,
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef void (*xmpp_open_handler)(xmpp_conn_t * const conn);
|
typedef void (*xmpp_open_handler)(xmpp_conn_t *const conn);
|
||||||
|
|
||||||
struct _xmpp_conn_t {
|
struct _xmpp_conn_t {
|
||||||
unsigned int ref;
|
unsigned int ref;
|
||||||
@@ -160,7 +157,7 @@ struct _xmpp_conn_t {
|
|||||||
xmpp_stream_error_t *stream_error;
|
xmpp_stream_error_t *stream_error;
|
||||||
|
|
||||||
sock_t sock;
|
sock_t sock;
|
||||||
int ka_timeout; /* TCP keepalive timeout */
|
int ka_timeout; /* TCP keepalive timeout */
|
||||||
int ka_interval; /* TCP keepalive interval */
|
int ka_interval; /* TCP keepalive interval */
|
||||||
|
|
||||||
tls_t *tls;
|
tls_t *tls;
|
||||||
@@ -169,7 +166,7 @@ struct _xmpp_conn_t {
|
|||||||
int tls_mandatory;
|
int tls_mandatory;
|
||||||
int tls_legacy_ssl;
|
int tls_legacy_ssl;
|
||||||
int tls_trust;
|
int tls_trust;
|
||||||
int tls_failed; /* set when tls fails, so we don't try again */
|
int tls_failed; /* set when tls fails, so we don't try again */
|
||||||
int sasl_support; /* if true, field is a bitfield of supported
|
int sasl_support; /* if true, field is a bitfield of supported
|
||||||
mechanisms */
|
mechanisms */
|
||||||
int auth_legacy_enabled;
|
int auth_legacy_enabled;
|
||||||
@@ -218,14 +215,13 @@ struct _xmpp_conn_t {
|
|||||||
xmpp_handlist_t *handlers;
|
xmpp_handlist_t *handlers;
|
||||||
};
|
};
|
||||||
|
|
||||||
void conn_disconnect(xmpp_conn_t * const conn);
|
void conn_disconnect(xmpp_conn_t *const conn);
|
||||||
void conn_disconnect_clean(xmpp_conn_t * const conn);
|
void conn_disconnect_clean(xmpp_conn_t *const conn);
|
||||||
void conn_established(xmpp_conn_t * const conn);
|
void conn_established(xmpp_conn_t *const conn);
|
||||||
void conn_open_stream(xmpp_conn_t * const conn);
|
void conn_open_stream(xmpp_conn_t *const conn);
|
||||||
int conn_tls_start(xmpp_conn_t * const conn);
|
int conn_tls_start(xmpp_conn_t *const conn);
|
||||||
void conn_prepare_reset(xmpp_conn_t * const conn, xmpp_open_handler handler);
|
void conn_prepare_reset(xmpp_conn_t *const conn, xmpp_open_handler handler);
|
||||||
void conn_parser_reset(xmpp_conn_t * const conn);
|
void conn_parser_reset(xmpp_conn_t *const conn);
|
||||||
|
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
XMPP_STANZA_UNKNOWN,
|
XMPP_STANZA_UNKNOWN,
|
||||||
@@ -250,33 +246,32 @@ struct _xmpp_stanza_t {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/* handler management */
|
/* handler management */
|
||||||
void handler_fire_stanza(xmpp_conn_t * const conn,
|
void handler_fire_stanza(xmpp_conn_t *const conn, xmpp_stanza_t *const stanza);
|
||||||
xmpp_stanza_t * const stanza);
|
uint64_t handler_fire_timed(xmpp_ctx_t *const ctx);
|
||||||
uint64_t handler_fire_timed(xmpp_ctx_t * const ctx);
|
|
||||||
void handler_reset_timed(xmpp_conn_t *conn, int user_only);
|
void handler_reset_timed(xmpp_conn_t *conn, int user_only);
|
||||||
void handler_add_timed(xmpp_conn_t * const conn,
|
void handler_add_timed(xmpp_conn_t *const conn,
|
||||||
xmpp_timed_handler handler,
|
xmpp_timed_handler handler,
|
||||||
const unsigned long period,
|
const unsigned long period,
|
||||||
void * const userdata);
|
void *const userdata);
|
||||||
void handler_add_id(xmpp_conn_t * const conn,
|
void handler_add_id(xmpp_conn_t *const conn,
|
||||||
xmpp_handler handler,
|
xmpp_handler handler,
|
||||||
const char * const id,
|
const char *const id,
|
||||||
void * const userdata);
|
void *const userdata);
|
||||||
void handler_add(xmpp_conn_t * const conn,
|
void handler_add(xmpp_conn_t *const conn,
|
||||||
xmpp_handler handler,
|
xmpp_handler handler,
|
||||||
const char * const ns,
|
const char *const ns,
|
||||||
const char * const name,
|
const char *const name,
|
||||||
const char * const type,
|
const char *const type,
|
||||||
void * const userdata);
|
void *const userdata);
|
||||||
void handler_system_delete_all(xmpp_conn_t *conn);
|
void handler_system_delete_all(xmpp_conn_t *conn);
|
||||||
|
|
||||||
/* utility functions */
|
/* utility functions */
|
||||||
void disconnect_mem_error(xmpp_conn_t * const conn);
|
void disconnect_mem_error(xmpp_conn_t *const conn);
|
||||||
|
|
||||||
/* auth functions */
|
/* auth functions */
|
||||||
void auth_handle_open(xmpp_conn_t * const conn);
|
void auth_handle_open(xmpp_conn_t *const conn);
|
||||||
void auth_handle_component_open(xmpp_conn_t * const conn);
|
void auth_handle_component_open(xmpp_conn_t *const conn);
|
||||||
void auth_handle_open_raw(xmpp_conn_t * const conn);
|
void auth_handle_open_raw(xmpp_conn_t *const conn);
|
||||||
void auth_handle_open_stub(xmpp_conn_t * const conn);
|
void auth_handle_open_stub(xmpp_conn_t *const conn);
|
||||||
|
|
||||||
#endif /* __LIBSTROPHE_COMMON_H__ */
|
#endif /* __LIBSTROPHE_COMMON_H__ */
|
||||||
|
|||||||
371
src/conn.c
371
src/conn.c
@@ -48,32 +48,35 @@
|
|||||||
#define CONNECT_TIMEOUT 5000 /* 5 seconds */
|
#define CONNECT_TIMEOUT 5000 /* 5 seconds */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int _disconnect_cleanup(xmpp_conn_t * const conn,
|
static int _disconnect_cleanup(xmpp_conn_t *const conn, void *const userdata);
|
||||||
void * const userdata);
|
static char *_conn_build_stream_tag(xmpp_conn_t *const conn,
|
||||||
static char *_conn_build_stream_tag(xmpp_conn_t * const conn,
|
char **attributes,
|
||||||
char **attributes, size_t attributes_len);
|
size_t attributes_len);
|
||||||
static void _conn_attributes_new(xmpp_conn_t *conn, char **attrs,
|
static void _conn_attributes_new(xmpp_conn_t *conn,
|
||||||
char ***attributes, size_t *attributes_len);
|
char **attrs,
|
||||||
static void _conn_attributes_destroy(xmpp_conn_t *conn, char **attributes,
|
char ***attributes,
|
||||||
|
size_t *attributes_len);
|
||||||
|
static void _conn_attributes_destroy(xmpp_conn_t *conn,
|
||||||
|
char **attributes,
|
||||||
size_t attributes_len);
|
size_t attributes_len);
|
||||||
static void _handle_stream_start(char *name, char **attrs,
|
static void
|
||||||
void * const userdata);
|
_handle_stream_start(char *name, char **attrs, void *const userdata);
|
||||||
static void _handle_stream_end(char *name,
|
static void _handle_stream_end(char *name, void *const userdata);
|
||||||
void * const userdata);
|
static void _handle_stream_stanza(xmpp_stanza_t *stanza, void *const userdata);
|
||||||
static void _handle_stream_stanza(xmpp_stanza_t *stanza,
|
static unsigned short _conn_default_port(xmpp_conn_t *const conn,
|
||||||
void * const userdata);
|
|
||||||
static unsigned short _conn_default_port(xmpp_conn_t * const conn,
|
|
||||||
xmpp_conn_type_t type);
|
xmpp_conn_type_t type);
|
||||||
static void _conn_reset(xmpp_conn_t * const conn);
|
static void _conn_reset(xmpp_conn_t *const conn);
|
||||||
static int _conn_connect(xmpp_conn_t * const conn,
|
static int _conn_connect(xmpp_conn_t *const conn,
|
||||||
const char * const domain,
|
const char *const domain,
|
||||||
const char * const host,
|
const char *const host,
|
||||||
unsigned short port,
|
unsigned short port,
|
||||||
xmpp_conn_type_t type,
|
xmpp_conn_type_t type,
|
||||||
xmpp_conn_handler callback,
|
xmpp_conn_handler callback,
|
||||||
void * const userdata);
|
void *const userdata);
|
||||||
|
|
||||||
void xmpp_send_error(xmpp_conn_t * const conn, xmpp_error_type_t const type, char * const text)
|
void xmpp_send_error(xmpp_conn_t *const conn,
|
||||||
|
xmpp_error_type_t const type,
|
||||||
|
char *const text)
|
||||||
{
|
{
|
||||||
xmpp_stanza_t *error = xmpp_error_new(conn->ctx, type, text);
|
xmpp_stanza_t *error = xmpp_error_new(conn->ctx, type, text);
|
||||||
|
|
||||||
@@ -90,12 +93,13 @@ void xmpp_send_error(xmpp_conn_t * const conn, xmpp_error_type_t const type, cha
|
|||||||
*
|
*
|
||||||
* @ingroup Connections
|
* @ingroup Connections
|
||||||
*/
|
*/
|
||||||
xmpp_conn_t *xmpp_conn_new(xmpp_ctx_t * const ctx)
|
xmpp_conn_t *xmpp_conn_new(xmpp_ctx_t *const ctx)
|
||||||
{
|
{
|
||||||
xmpp_conn_t *conn = NULL;
|
xmpp_conn_t *conn = NULL;
|
||||||
xmpp_connlist_t *tail, *item;
|
xmpp_connlist_t *tail, *item;
|
||||||
|
|
||||||
if (ctx == NULL) return NULL;
|
if (ctx == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
conn = xmpp_alloc(ctx, sizeof(xmpp_conn_t));
|
conn = xmpp_alloc(ctx, sizeof(xmpp_conn_t));
|
||||||
if (conn != NULL) {
|
if (conn != NULL) {
|
||||||
@@ -146,11 +150,9 @@ xmpp_conn_t *xmpp_conn_new(xmpp_ctx_t * const ctx)
|
|||||||
conn->bind_required = 0;
|
conn->bind_required = 0;
|
||||||
conn->session_required = 0;
|
conn->session_required = 0;
|
||||||
|
|
||||||
conn->parser = parser_new(conn->ctx,
|
conn->parser =
|
||||||
_handle_stream_start,
|
parser_new(conn->ctx, _handle_stream_start, _handle_stream_end,
|
||||||
_handle_stream_end,
|
_handle_stream_stanza, conn);
|
||||||
_handle_stream_stanza,
|
|
||||||
conn);
|
|
||||||
conn->reset_parser = 0;
|
conn->reset_parser = 0;
|
||||||
|
|
||||||
conn->authenticated = 0;
|
conn->authenticated = 0;
|
||||||
@@ -166,7 +168,8 @@ xmpp_conn_t *xmpp_conn_new(xmpp_ctx_t * const ctx)
|
|||||||
|
|
||||||
/* add connection to ctx->connlist */
|
/* add connection to ctx->connlist */
|
||||||
tail = conn->ctx->connlist;
|
tail = conn->ctx->connlist;
|
||||||
while (tail && tail->next) tail = tail->next;
|
while (tail && tail->next)
|
||||||
|
tail = tail->next;
|
||||||
|
|
||||||
item = xmpp_alloc(conn->ctx, sizeof(xmpp_connlist_t));
|
item = xmpp_alloc(conn->ctx, sizeof(xmpp_connlist_t));
|
||||||
if (!item) {
|
if (!item) {
|
||||||
@@ -179,8 +182,10 @@ xmpp_conn_t *xmpp_conn_new(xmpp_ctx_t * const ctx)
|
|||||||
item->conn = conn;
|
item->conn = conn;
|
||||||
item->next = NULL;
|
item->next = NULL;
|
||||||
|
|
||||||
if (tail) tail->next = item;
|
if (tail)
|
||||||
else conn->ctx->connlist = item;
|
tail->next = item;
|
||||||
|
else
|
||||||
|
conn->ctx->connlist = item;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -196,7 +201,7 @@ xmpp_conn_t *xmpp_conn_new(xmpp_ctx_t * const ctx)
|
|||||||
*
|
*
|
||||||
* @ingroup Connections
|
* @ingroup Connections
|
||||||
*/
|
*/
|
||||||
xmpp_conn_t *xmpp_conn_clone(xmpp_conn_t * const conn)
|
xmpp_conn_t *xmpp_conn_clone(xmpp_conn_t *const conn)
|
||||||
{
|
{
|
||||||
conn->ref++;
|
conn->ref++;
|
||||||
return conn;
|
return conn;
|
||||||
@@ -214,7 +219,7 @@ xmpp_conn_t *xmpp_conn_clone(xmpp_conn_t * const conn)
|
|||||||
*
|
*
|
||||||
* @ingroup Connections
|
* @ingroup Connections
|
||||||
*/
|
*/
|
||||||
void xmpp_conn_set_keepalive(xmpp_conn_t * const conn, int timeout, int interval)
|
void xmpp_conn_set_keepalive(xmpp_conn_t *const conn, int timeout, int interval)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
@@ -240,7 +245,7 @@ void xmpp_conn_set_keepalive(xmpp_conn_t * const conn, int timeout, int interval
|
|||||||
*
|
*
|
||||||
* @ingroup Connections
|
* @ingroup Connections
|
||||||
*/
|
*/
|
||||||
int xmpp_conn_release(xmpp_conn_t * const conn)
|
int xmpp_conn_release(xmpp_conn_t *const conn)
|
||||||
{
|
{
|
||||||
xmpp_ctx_t *ctx;
|
xmpp_ctx_t *ctx;
|
||||||
xmpp_connlist_t *item, *prev;
|
xmpp_connlist_t *item, *prev;
|
||||||
@@ -255,8 +260,7 @@ int xmpp_conn_release(xmpp_conn_t * const conn)
|
|||||||
ctx = conn->ctx;
|
ctx = conn->ctx;
|
||||||
|
|
||||||
if (conn->state == XMPP_STATE_CONNECTING ||
|
if (conn->state == XMPP_STATE_CONNECTING ||
|
||||||
conn->state == XMPP_STATE_CONNECTED)
|
conn->state == XMPP_STATE_CONNECTED) {
|
||||||
{
|
|
||||||
conn_disconnect(conn);
|
conn_disconnect(conn);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -317,17 +321,23 @@ int xmpp_conn_release(xmpp_conn_t * const conn)
|
|||||||
thli = hlitem;
|
thli = hlitem;
|
||||||
hlitem = hlitem->next;
|
hlitem = hlitem->next;
|
||||||
|
|
||||||
if (thli->u.ns) xmpp_free(ctx, thli->u.ns);
|
if (thli->u.ns)
|
||||||
if (thli->u.name) xmpp_free(ctx, thli->u.name);
|
xmpp_free(ctx, thli->u.ns);
|
||||||
if (thli->u.type) xmpp_free(ctx, thli->u.type);
|
if (thli->u.name)
|
||||||
|
xmpp_free(ctx, thli->u.name);
|
||||||
|
if (thli->u.type)
|
||||||
|
xmpp_free(ctx, thli->u.type);
|
||||||
xmpp_free(ctx, thli);
|
xmpp_free(ctx, thli);
|
||||||
}
|
}
|
||||||
|
|
||||||
parser_free(conn->parser);
|
parser_free(conn->parser);
|
||||||
|
|
||||||
if (conn->jid) xmpp_free(ctx, conn->jid);
|
if (conn->jid)
|
||||||
if (conn->pass) xmpp_free(ctx, conn->pass);
|
xmpp_free(ctx, conn->jid);
|
||||||
if (conn->lang) xmpp_free(ctx, conn->lang);
|
if (conn->pass)
|
||||||
|
xmpp_free(ctx, conn->pass);
|
||||||
|
if (conn->lang)
|
||||||
|
xmpp_free(ctx, conn->lang);
|
||||||
xmpp_free(ctx, conn);
|
xmpp_free(ctx, conn);
|
||||||
released = 1;
|
released = 1;
|
||||||
}
|
}
|
||||||
@@ -343,7 +353,7 @@ int xmpp_conn_release(xmpp_conn_t * const conn)
|
|||||||
*
|
*
|
||||||
* @ingroup Connections
|
* @ingroup Connections
|
||||||
*/
|
*/
|
||||||
const char *xmpp_conn_get_jid(const xmpp_conn_t * const conn)
|
const char *xmpp_conn_get_jid(const xmpp_conn_t *const conn)
|
||||||
{
|
{
|
||||||
return conn->jid;
|
return conn->jid;
|
||||||
}
|
}
|
||||||
@@ -361,7 +371,7 @@ const char *xmpp_conn_get_jid(const xmpp_conn_t * const conn)
|
|||||||
*
|
*
|
||||||
* @ingroup Connections
|
* @ingroup Connections
|
||||||
*/
|
*/
|
||||||
const char *xmpp_conn_get_bound_jid(const xmpp_conn_t * const conn)
|
const char *xmpp_conn_get_bound_jid(const xmpp_conn_t *const conn)
|
||||||
{
|
{
|
||||||
return conn->bound_jid;
|
return conn->bound_jid;
|
||||||
}
|
}
|
||||||
@@ -377,9 +387,10 @@ const char *xmpp_conn_get_bound_jid(const xmpp_conn_t * const conn)
|
|||||||
*
|
*
|
||||||
* @ingroup Connections
|
* @ingroup Connections
|
||||||
*/
|
*/
|
||||||
void xmpp_conn_set_jid(xmpp_conn_t * const conn, const char * const jid)
|
void xmpp_conn_set_jid(xmpp_conn_t *const conn, const char *const jid)
|
||||||
{
|
{
|
||||||
if (conn->jid) xmpp_free(conn->ctx, conn->jid);
|
if (conn->jid)
|
||||||
|
xmpp_free(conn->ctx, conn->jid);
|
||||||
conn->jid = xmpp_strdup(conn->ctx, jid);
|
conn->jid = xmpp_strdup(conn->ctx, jid);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -391,7 +402,7 @@ void xmpp_conn_set_jid(xmpp_conn_t * const conn, const char * const jid)
|
|||||||
*
|
*
|
||||||
* @ingroup Connections
|
* @ingroup Connections
|
||||||
*/
|
*/
|
||||||
const char *xmpp_conn_get_pass(const xmpp_conn_t * const conn)
|
const char *xmpp_conn_get_pass(const xmpp_conn_t *const conn)
|
||||||
{
|
{
|
||||||
return conn->pass;
|
return conn->pass;
|
||||||
}
|
}
|
||||||
@@ -405,22 +416,23 @@ const char *xmpp_conn_get_pass(const xmpp_conn_t * const conn)
|
|||||||
*
|
*
|
||||||
* @ingroup Connections
|
* @ingroup Connections
|
||||||
*/
|
*/
|
||||||
void xmpp_conn_set_pass(xmpp_conn_t * const conn, const char * const pass)
|
void xmpp_conn_set_pass(xmpp_conn_t *const conn, const char *const pass)
|
||||||
{
|
{
|
||||||
if (conn->pass) xmpp_free(conn->ctx, conn->pass);
|
if (conn->pass)
|
||||||
|
xmpp_free(conn->ctx, conn->pass);
|
||||||
conn->pass = xmpp_strdup(conn->ctx, pass);
|
conn->pass = xmpp_strdup(conn->ctx, pass);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Get the strophe context that the connection is associated with.
|
/** Get the strophe context that the connection is associated with.
|
||||||
* @param conn a Strophe connection object
|
* @param conn a Strophe connection object
|
||||||
*
|
*
|
||||||
* @return a Strophe context
|
* @return a Strophe context
|
||||||
*
|
*
|
||||||
* @ingroup Connections
|
* @ingroup Connections
|
||||||
*/
|
*/
|
||||||
xmpp_ctx_t* xmpp_conn_get_context(xmpp_conn_t * const conn)
|
xmpp_ctx_t *xmpp_conn_get_context(xmpp_conn_t *const conn)
|
||||||
{
|
{
|
||||||
return conn->ctx;
|
return conn->ctx;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Initiate a connection to the XMPP server.
|
/** Initiate a connection to the XMPP server.
|
||||||
@@ -444,11 +456,11 @@ xmpp_ctx_t* xmpp_conn_get_context(xmpp_conn_t * const conn)
|
|||||||
*
|
*
|
||||||
* @ingroup Connections
|
* @ingroup Connections
|
||||||
*/
|
*/
|
||||||
int xmpp_connect_client(xmpp_conn_t * const conn,
|
int xmpp_connect_client(xmpp_conn_t *const conn,
|
||||||
const char * const altdomain,
|
const char *const altdomain,
|
||||||
unsigned short altport,
|
unsigned short altport,
|
||||||
xmpp_conn_handler callback,
|
xmpp_conn_handler callback,
|
||||||
void * const userdata)
|
void *const userdata)
|
||||||
{
|
{
|
||||||
resolver_srv_rr_t *srv_rr_list = NULL;
|
resolver_srv_rr_t *srv_rr_list = NULL;
|
||||||
resolver_srv_rr_t *rr;
|
resolver_srv_rr_t *rr;
|
||||||
@@ -459,7 +471,8 @@ int xmpp_connect_client(xmpp_conn_t * const conn,
|
|||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
domain = xmpp_jid_domain(conn->ctx, conn->jid);
|
domain = xmpp_jid_domain(conn->ctx, conn->jid);
|
||||||
if (!domain) return XMPP_EMEM;
|
if (!domain)
|
||||||
|
return XMPP_EMEM;
|
||||||
|
|
||||||
if (altdomain != NULL) {
|
if (altdomain != NULL) {
|
||||||
xmpp_debug(conn->ctx, "xmpp", "Connecting via altdomain.");
|
xmpp_debug(conn->ctx, "xmpp", "Connecting via altdomain.");
|
||||||
@@ -467,16 +480,17 @@ int xmpp_connect_client(xmpp_conn_t * const conn,
|
|||||||
port = altport ? altport : _conn_default_port(conn, XMPP_CLIENT);
|
port = altport ? altport : _conn_default_port(conn, XMPP_CLIENT);
|
||||||
found = XMPP_DOMAIN_ALTDOMAIN;
|
found = XMPP_DOMAIN_ALTDOMAIN;
|
||||||
|
|
||||||
/* SSL tunneled connection on 5223 port is legacy and doesn't
|
/* SSL tunneled connection on 5223 port is legacy and doesn't
|
||||||
* have an SRV record. */
|
* have an SRV record. */
|
||||||
} else if (!conn->tls_legacy_ssl) {
|
} else if (!conn->tls_legacy_ssl) {
|
||||||
found = resolver_srv_lookup(conn->ctx, "xmpp-client", "tcp", domain,
|
found = resolver_srv_lookup(conn->ctx, "xmpp-client", "tcp", domain,
|
||||||
&srv_rr_list);
|
&srv_rr_list);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (XMPP_DOMAIN_NOT_FOUND == found) {
|
if (XMPP_DOMAIN_NOT_FOUND == found) {
|
||||||
xmpp_debug(conn->ctx, "xmpp", "SRV lookup failed, "
|
xmpp_debug(conn->ctx, "xmpp",
|
||||||
"connecting via domain.");
|
"SRV lookup failed, "
|
||||||
|
"connecting via domain.");
|
||||||
host = domain;
|
host = domain;
|
||||||
port = altport ? altport : _conn_default_port(conn, XMPP_CLIENT);
|
port = altport ? altport : _conn_default_port(conn, XMPP_CLIENT);
|
||||||
found = XMPP_DOMAIN_ALTDOMAIN;
|
found = XMPP_DOMAIN_ALTDOMAIN;
|
||||||
@@ -489,8 +503,8 @@ int xmpp_connect_client(xmpp_conn_t * const conn,
|
|||||||
port = rr->port;
|
port = rr->port;
|
||||||
rr = rr->next;
|
rr = rr->next;
|
||||||
}
|
}
|
||||||
rc = _conn_connect(conn, domain, host, port, XMPP_CLIENT,
|
rc = _conn_connect(conn, domain, host, port, XMPP_CLIENT, callback,
|
||||||
callback, userdata);
|
userdata);
|
||||||
} while (rc != 0 && rr != NULL);
|
} while (rc != 0 && rr != NULL);
|
||||||
|
|
||||||
xmpp_free(conn->ctx, domain);
|
xmpp_free(conn->ctx, domain);
|
||||||
@@ -522,18 +536,22 @@ int xmpp_connect_client(xmpp_conn_t * const conn,
|
|||||||
*
|
*
|
||||||
* @ingroup Connections
|
* @ingroup Connections
|
||||||
*/
|
*/
|
||||||
int xmpp_connect_component(xmpp_conn_t * const conn, const char * const server,
|
int xmpp_connect_component(xmpp_conn_t *const conn,
|
||||||
unsigned short port, xmpp_conn_handler callback,
|
const char *const server,
|
||||||
void * const userdata)
|
unsigned short port,
|
||||||
|
xmpp_conn_handler callback,
|
||||||
|
void *const userdata)
|
||||||
{
|
{
|
||||||
/* The server domain, jid and password MUST be specified. */
|
/* The server domain, jid and password MUST be specified. */
|
||||||
if (!(server && conn->jid && conn->pass)) return XMPP_EINVOP;
|
if (!(server && conn->jid && conn->pass))
|
||||||
|
return XMPP_EINVOP;
|
||||||
|
|
||||||
/* XEP-0114 does not support TLS */
|
/* XEP-0114 does not support TLS */
|
||||||
xmpp_conn_disable_tls(conn);
|
xmpp_conn_disable_tls(conn);
|
||||||
if (!conn->tls_disabled) {
|
if (!conn->tls_disabled) {
|
||||||
xmpp_error(conn->ctx, "conn", "Failed to disable TLS. "
|
xmpp_error(conn->ctx, "conn",
|
||||||
"XEP-0114 does not support TLS");
|
"Failed to disable TLS. "
|
||||||
|
"XEP-0114 does not support TLS");
|
||||||
return XMPP_EINT;
|
return XMPP_EINT;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -565,18 +583,18 @@ int xmpp_connect_component(xmpp_conn_t * const conn, const char * const server,
|
|||||||
*
|
*
|
||||||
* @ingroup Connections
|
* @ingroup Connections
|
||||||
*/
|
*/
|
||||||
int xmpp_connect_raw(xmpp_conn_t * const conn,
|
int xmpp_connect_raw(xmpp_conn_t *const conn,
|
||||||
const char * const altdomain,
|
const char *const altdomain,
|
||||||
unsigned short altport,
|
unsigned short altport,
|
||||||
xmpp_conn_handler callback,
|
xmpp_conn_handler callback,
|
||||||
void * const userdata)
|
void *const userdata)
|
||||||
{
|
{
|
||||||
conn->is_raw = 1;
|
conn->is_raw = 1;
|
||||||
return xmpp_connect_client(conn, altdomain, altport, callback, userdata);
|
return xmpp_connect_client(conn, altdomain, altport, callback, userdata);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Called when tcp connection is established. */
|
/* Called when tcp connection is established. */
|
||||||
void conn_established(xmpp_conn_t * const conn)
|
void conn_established(xmpp_conn_t *const conn)
|
||||||
{
|
{
|
||||||
if (conn->tls_legacy_ssl && !conn->is_raw) {
|
if (conn->tls_legacy_ssl && !conn->is_raw) {
|
||||||
xmpp_debug(conn->ctx, "xmpp", "using legacy SSL connection");
|
xmpp_debug(conn->ctx, "xmpp", "using legacy SSL connection");
|
||||||
@@ -591,7 +609,8 @@ void conn_established(xmpp_conn_t * const conn)
|
|||||||
/* we skip authentication for a "raw" connection, but the event loop
|
/* we skip authentication for a "raw" connection, but the event loop
|
||||||
ignores user's handlers when conn->authenticated is not set. */
|
ignores user's handlers when conn->authenticated is not set. */
|
||||||
conn->authenticated = 1;
|
conn->authenticated = 1;
|
||||||
conn->conn_handler(conn, XMPP_CONN_RAW_CONNECT, 0, NULL, conn->userdata);
|
conn->conn_handler(conn, XMPP_CONN_RAW_CONNECT, 0, NULL,
|
||||||
|
conn->userdata);
|
||||||
} else {
|
} else {
|
||||||
/* send stream init */
|
/* send stream init */
|
||||||
conn_open_stream(conn);
|
conn_open_stream(conn);
|
||||||
@@ -609,7 +628,7 @@ void conn_established(xmpp_conn_t * const conn)
|
|||||||
*
|
*
|
||||||
* @ingroup Connections
|
* @ingroup Connections
|
||||||
*/
|
*/
|
||||||
int xmpp_conn_open_stream_default(xmpp_conn_t * const conn)
|
int xmpp_conn_open_stream_default(xmpp_conn_t *const conn)
|
||||||
{
|
{
|
||||||
if (!conn->is_raw)
|
if (!conn->is_raw)
|
||||||
return XMPP_EINVOP;
|
return XMPP_EINVOP;
|
||||||
@@ -636,7 +655,8 @@ int xmpp_conn_open_stream_default(xmpp_conn_t * const conn)
|
|||||||
*
|
*
|
||||||
* @ingroup Connections
|
* @ingroup Connections
|
||||||
*/
|
*/
|
||||||
int xmpp_conn_open_stream(xmpp_conn_t * const conn, char **attributes,
|
int xmpp_conn_open_stream(xmpp_conn_t *const conn,
|
||||||
|
char **attributes,
|
||||||
size_t attributes_len)
|
size_t attributes_len)
|
||||||
{
|
{
|
||||||
char *tag;
|
char *tag;
|
||||||
@@ -661,7 +681,7 @@ int xmpp_conn_open_stream(xmpp_conn_t * const conn, char **attributes,
|
|||||||
*
|
*
|
||||||
* @ingroup Connections
|
* @ingroup Connections
|
||||||
*/
|
*/
|
||||||
int xmpp_conn_tls_start(xmpp_conn_t * const conn)
|
int xmpp_conn_tls_start(xmpp_conn_t *const conn)
|
||||||
{
|
{
|
||||||
return conn_tls_start(conn);
|
return conn_tls_start(conn);
|
||||||
}
|
}
|
||||||
@@ -672,7 +692,7 @@ int xmpp_conn_tls_start(xmpp_conn_t * const conn)
|
|||||||
*
|
*
|
||||||
* @param conn a Strophe connection object
|
* @param conn a Strophe connection object
|
||||||
*/
|
*/
|
||||||
void conn_disconnect_clean(xmpp_conn_t * const conn)
|
void conn_disconnect_clean(xmpp_conn_t *const conn)
|
||||||
{
|
{
|
||||||
/* remove the timed handler */
|
/* remove the timed handler */
|
||||||
xmpp_timed_handler_delete(conn, _disconnect_cleanup);
|
xmpp_timed_handler_delete(conn, _disconnect_cleanup);
|
||||||
@@ -686,7 +706,7 @@ void conn_disconnect_clean(xmpp_conn_t * const conn)
|
|||||||
*
|
*
|
||||||
* @param conn a Strophe connection object
|
* @param conn a Strophe connection object
|
||||||
*/
|
*/
|
||||||
void conn_disconnect(xmpp_conn_t * const conn)
|
void conn_disconnect(xmpp_conn_t *const conn)
|
||||||
{
|
{
|
||||||
xmpp_debug(conn->ctx, "xmpp", "Closing socket.");
|
xmpp_debug(conn->ctx, "xmpp", "Closing socket.");
|
||||||
conn->state = XMPP_STATE_DISCONNECTED;
|
conn->state = XMPP_STATE_DISCONNECTED;
|
||||||
@@ -704,14 +724,14 @@ void conn_disconnect(xmpp_conn_t * const conn)
|
|||||||
|
|
||||||
/* prepares a parser reset. this is called from handlers. we can't
|
/* prepares a parser reset. this is called from handlers. we can't
|
||||||
* reset the parser immediately as it is not re-entrant. */
|
* reset the parser immediately as it is not re-entrant. */
|
||||||
void conn_prepare_reset(xmpp_conn_t * const conn, xmpp_open_handler handler)
|
void conn_prepare_reset(xmpp_conn_t *const conn, xmpp_open_handler handler)
|
||||||
{
|
{
|
||||||
conn->reset_parser = 1;
|
conn->reset_parser = 1;
|
||||||
conn->open_handler = handler;
|
conn->open_handler = handler;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* reset the parser */
|
/* reset the parser */
|
||||||
void conn_parser_reset(xmpp_conn_t * const conn)
|
void conn_parser_reset(xmpp_conn_t *const conn)
|
||||||
{
|
{
|
||||||
conn->reset_parser = 0;
|
conn->reset_parser = 0;
|
||||||
parser_reset(conn->parser);
|
parser_reset(conn->parser);
|
||||||
@@ -726,7 +746,7 @@ void conn_parser_reset(xmpp_conn_t * const conn)
|
|||||||
*
|
*
|
||||||
* @ingroup Connections
|
* @ingroup Connections
|
||||||
*/
|
*/
|
||||||
void xmpp_disconnect(xmpp_conn_t * const conn)
|
void xmpp_disconnect(xmpp_conn_t *const conn)
|
||||||
{
|
{
|
||||||
if (conn->state != XMPP_STATE_CONNECTING &&
|
if (conn->state != XMPP_STATE_CONNECTING &&
|
||||||
conn->state != XMPP_STATE_CONNECTED)
|
conn->state != XMPP_STATE_CONNECTED)
|
||||||
@@ -736,8 +756,7 @@ void xmpp_disconnect(xmpp_conn_t * const conn)
|
|||||||
xmpp_send_raw_string(conn, "</stream:stream>");
|
xmpp_send_raw_string(conn, "</stream:stream>");
|
||||||
|
|
||||||
/* setup timed handler in case disconnect takes too long */
|
/* setup timed handler in case disconnect takes too long */
|
||||||
handler_add_timed(conn, _disconnect_cleanup,
|
handler_add_timed(conn, _disconnect_cleanup, DISCONNECT_TIMEOUT, NULL);
|
||||||
DISCONNECT_TIMEOUT, NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Send a raw string to the XMPP server.
|
/** Send a raw string to the XMPP server.
|
||||||
@@ -753,8 +772,7 @@ void xmpp_disconnect(xmpp_conn_t * const conn)
|
|||||||
*
|
*
|
||||||
* @ingroup Connections
|
* @ingroup Connections
|
||||||
*/
|
*/
|
||||||
void xmpp_send_raw_string(xmpp_conn_t * const conn,
|
void xmpp_send_raw_string(xmpp_conn_t *const conn, const char *const fmt, ...)
|
||||||
const char * const fmt, ...)
|
|
||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
size_t len;
|
size_t len;
|
||||||
@@ -771,7 +789,8 @@ void xmpp_send_raw_string(xmpp_conn_t * const conn,
|
|||||||
len++; /* account for trailing \0 */
|
len++; /* account for trailing \0 */
|
||||||
bigbuf = xmpp_alloc(conn->ctx, len);
|
bigbuf = xmpp_alloc(conn->ctx, len);
|
||||||
if (!bigbuf) {
|
if (!bigbuf) {
|
||||||
xmpp_debug(conn->ctx, "xmpp", "Could not allocate memory for send_raw_string");
|
xmpp_debug(conn->ctx, "xmpp",
|
||||||
|
"Could not allocate memory for send_raw_string");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
va_start(ap, fmt);
|
va_start(ap, fmt);
|
||||||
@@ -802,16 +821,19 @@ void xmpp_send_raw_string(xmpp_conn_t * const conn,
|
|||||||
*
|
*
|
||||||
* @ingroup Connections
|
* @ingroup Connections
|
||||||
*/
|
*/
|
||||||
void xmpp_send_raw(xmpp_conn_t * const conn,
|
void xmpp_send_raw(xmpp_conn_t *const conn,
|
||||||
const char * const data, const size_t len)
|
const char *const data,
|
||||||
|
const size_t len)
|
||||||
{
|
{
|
||||||
xmpp_send_queue_t *item;
|
xmpp_send_queue_t *item;
|
||||||
|
|
||||||
if (conn->state != XMPP_STATE_CONNECTED) return;
|
if (conn->state != XMPP_STATE_CONNECTED)
|
||||||
|
return;
|
||||||
|
|
||||||
/* create send queue item for queue */
|
/* create send queue item for queue */
|
||||||
item = xmpp_alloc(conn->ctx, sizeof(xmpp_send_queue_t));
|
item = xmpp_alloc(conn->ctx, sizeof(xmpp_send_queue_t));
|
||||||
if (!item) return;
|
if (!item)
|
||||||
|
return;
|
||||||
|
|
||||||
item->data = xmpp_alloc(conn->ctx, len);
|
item->data = xmpp_alloc(conn->ctx, len);
|
||||||
if (!item->data) {
|
if (!item->data) {
|
||||||
@@ -845,8 +867,7 @@ void xmpp_send_raw(xmpp_conn_t * const conn,
|
|||||||
*
|
*
|
||||||
* @ingroup Connections
|
* @ingroup Connections
|
||||||
*/
|
*/
|
||||||
void xmpp_send(xmpp_conn_t * const conn,
|
void xmpp_send(xmpp_conn_t *const conn, xmpp_stanza_t *const stanza)
|
||||||
xmpp_stanza_t * const stanza)
|
|
||||||
{
|
{
|
||||||
char *buf;
|
char *buf;
|
||||||
size_t len;
|
size_t len;
|
||||||
@@ -866,23 +887,22 @@ void xmpp_send(xmpp_conn_t * const conn,
|
|||||||
*
|
*
|
||||||
* @param conn a Strophe connection object
|
* @param conn a Strophe connection object
|
||||||
*/
|
*/
|
||||||
void conn_open_stream(xmpp_conn_t * const conn)
|
void conn_open_stream(xmpp_conn_t *const conn)
|
||||||
{
|
{
|
||||||
xmpp_send_raw_string(conn,
|
xmpp_send_raw_string(conn,
|
||||||
"<?xml version=\"1.0\"?>" \
|
"<?xml version=\"1.0\"?>"
|
||||||
"<stream:stream to=\"%s\" " \
|
"<stream:stream to=\"%s\" "
|
||||||
"xml:lang=\"%s\" " \
|
"xml:lang=\"%s\" "
|
||||||
"version=\"1.0\" " \
|
"version=\"1.0\" "
|
||||||
"xmlns=\"%s\" " \
|
"xmlns=\"%s\" "
|
||||||
"xmlns:stream=\"%s\">",
|
"xmlns:stream=\"%s\">",
|
||||||
conn->domain,
|
conn->domain, conn->lang,
|
||||||
conn->lang,
|
conn->type == XMPP_CLIENT ? XMPP_NS_CLIENT
|
||||||
conn->type == XMPP_CLIENT ? XMPP_NS_CLIENT :
|
: XMPP_NS_COMPONENT,
|
||||||
XMPP_NS_COMPONENT,
|
|
||||||
XMPP_NS_STREAMS);
|
XMPP_NS_STREAMS);
|
||||||
}
|
}
|
||||||
|
|
||||||
int conn_tls_start(xmpp_conn_t * const conn)
|
int conn_tls_start(xmpp_conn_t *const conn)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
@@ -906,8 +926,10 @@ int conn_tls_start(xmpp_conn_t * const conn)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (rc != 0) {
|
if (rc != 0) {
|
||||||
xmpp_debug(conn->ctx, "conn", "Couldn't start TLS! "
|
xmpp_debug(conn->ctx, "conn",
|
||||||
"error %d tls_error %d", rc, conn->error);
|
"Couldn't start TLS! "
|
||||||
|
"error %d tls_error %d",
|
||||||
|
rc, conn->error);
|
||||||
}
|
}
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
@@ -920,7 +942,7 @@ int conn_tls_start(xmpp_conn_t * const conn)
|
|||||||
*
|
*
|
||||||
* @ingroup Connections
|
* @ingroup Connections
|
||||||
*/
|
*/
|
||||||
long xmpp_conn_get_flags(const xmpp_conn_t * const conn)
|
long xmpp_conn_get_flags(const xmpp_conn_t *const conn)
|
||||||
{
|
{
|
||||||
long flags;
|
long flags;
|
||||||
|
|
||||||
@@ -928,7 +950,8 @@ long xmpp_conn_get_flags(const xmpp_conn_t * const conn)
|
|||||||
XMPP_CONN_FLAG_MANDATORY_TLS * conn->tls_mandatory |
|
XMPP_CONN_FLAG_MANDATORY_TLS * conn->tls_mandatory |
|
||||||
XMPP_CONN_FLAG_LEGACY_SSL * conn->tls_legacy_ssl |
|
XMPP_CONN_FLAG_LEGACY_SSL * conn->tls_legacy_ssl |
|
||||||
XMPP_CONN_FLAG_TRUST_TLS * conn->tls_trust |
|
XMPP_CONN_FLAG_TRUST_TLS * conn->tls_trust |
|
||||||
XMPP_CONN_FLAG_LEGACY_AUTH * conn->auth_legacy_enabled;;
|
XMPP_CONN_FLAG_LEGACY_AUTH * conn->auth_legacy_enabled;
|
||||||
|
;
|
||||||
|
|
||||||
return flags;
|
return flags;
|
||||||
}
|
}
|
||||||
@@ -955,11 +978,12 @@ long xmpp_conn_get_flags(const xmpp_conn_t * const conn)
|
|||||||
*
|
*
|
||||||
* @ingroup Connections
|
* @ingroup Connections
|
||||||
*/
|
*/
|
||||||
int xmpp_conn_set_flags(xmpp_conn_t * const conn, long flags)
|
int xmpp_conn_set_flags(xmpp_conn_t *const conn, long flags)
|
||||||
{
|
{
|
||||||
if (conn->state != XMPP_STATE_DISCONNECTED) {
|
if (conn->state != XMPP_STATE_DISCONNECTED) {
|
||||||
xmpp_error(conn->ctx, "conn", "Flags can be set only "
|
xmpp_error(conn->ctx, "conn",
|
||||||
"for disconnected connection");
|
"Flags can be set only "
|
||||||
|
"for disconnected connection");
|
||||||
return XMPP_EINVOP;
|
return XMPP_EINVOP;
|
||||||
}
|
}
|
||||||
if (flags & XMPP_CONN_FLAG_DISABLE_TLS &&
|
if (flags & XMPP_CONN_FLAG_DISABLE_TLS &&
|
||||||
@@ -989,7 +1013,7 @@ int xmpp_conn_set_flags(xmpp_conn_t * const conn, long flags)
|
|||||||
*
|
*
|
||||||
* @ingroup Connections
|
* @ingroup Connections
|
||||||
*/
|
*/
|
||||||
void xmpp_conn_disable_tls(xmpp_conn_t * const conn)
|
void xmpp_conn_disable_tls(xmpp_conn_t *const conn)
|
||||||
{
|
{
|
||||||
long flags = xmpp_conn_get_flags(conn);
|
long flags = xmpp_conn_get_flags(conn);
|
||||||
|
|
||||||
@@ -1003,7 +1027,7 @@ void xmpp_conn_disable_tls(xmpp_conn_t * const conn)
|
|||||||
*
|
*
|
||||||
* @ingroup Connections
|
* @ingroup Connections
|
||||||
*/
|
*/
|
||||||
int xmpp_conn_is_secured(xmpp_conn_t * const conn)
|
int xmpp_conn_is_secured(xmpp_conn_t *const conn)
|
||||||
{
|
{
|
||||||
return conn->secured && !conn->tls_failed && conn->tls != NULL ? 1 : 0;
|
return conn->secured && !conn->tls_failed && conn->tls != NULL ? 1 : 0;
|
||||||
}
|
}
|
||||||
@@ -1013,7 +1037,7 @@ int xmpp_conn_is_secured(xmpp_conn_t * const conn)
|
|||||||
*
|
*
|
||||||
* @ingroup Connections
|
* @ingroup Connections
|
||||||
*/
|
*/
|
||||||
int xmpp_conn_is_connecting(xmpp_conn_t * const conn)
|
int xmpp_conn_is_connecting(xmpp_conn_t *const conn)
|
||||||
{
|
{
|
||||||
return conn->state == XMPP_STATE_CONNECTING ? 1 : 0;
|
return conn->state == XMPP_STATE_CONNECTING ? 1 : 0;
|
||||||
}
|
}
|
||||||
@@ -1023,7 +1047,7 @@ int xmpp_conn_is_connecting(xmpp_conn_t * const conn)
|
|||||||
*
|
*
|
||||||
* @ingroup Connections
|
* @ingroup Connections
|
||||||
*/
|
*/
|
||||||
int xmpp_conn_is_connected(xmpp_conn_t * const conn)
|
int xmpp_conn_is_connected(xmpp_conn_t *const conn)
|
||||||
{
|
{
|
||||||
return conn->state == XMPP_STATE_CONNECTED ? 1 : 0;
|
return conn->state == XMPP_STATE_CONNECTED ? 1 : 0;
|
||||||
}
|
}
|
||||||
@@ -1033,26 +1057,24 @@ int xmpp_conn_is_connected(xmpp_conn_t * const conn)
|
|||||||
*
|
*
|
||||||
* @ingroup Connections
|
* @ingroup Connections
|
||||||
*/
|
*/
|
||||||
int xmpp_conn_is_disconnected(xmpp_conn_t * const conn)
|
int xmpp_conn_is_disconnected(xmpp_conn_t *const conn)
|
||||||
{
|
{
|
||||||
return conn->state == XMPP_STATE_DISCONNECTED ? 1 : 0;
|
return conn->state == XMPP_STATE_DISCONNECTED ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* timed handler for cleanup if normal disconnect procedure takes too long */
|
/* timed handler for cleanup if normal disconnect procedure takes too long */
|
||||||
static int _disconnect_cleanup(xmpp_conn_t * const conn,
|
static int _disconnect_cleanup(xmpp_conn_t *const conn, void *const userdata)
|
||||||
void * const userdata)
|
|
||||||
{
|
{
|
||||||
xmpp_debug(conn->ctx, "xmpp",
|
xmpp_debug(conn->ctx, "xmpp", "disconnection forced by cleanup timeout");
|
||||||
"disconnection forced by cleanup timeout");
|
|
||||||
|
|
||||||
conn_disconnect(conn);
|
conn_disconnect(conn);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *_conn_build_stream_tag(xmpp_conn_t * const conn,
|
static char *_conn_build_stream_tag(xmpp_conn_t *const conn,
|
||||||
char **attributes, size_t attributes_len)
|
char **attributes,
|
||||||
|
size_t attributes_len)
|
||||||
{
|
{
|
||||||
char *tag;
|
char *tag;
|
||||||
size_t len;
|
size_t len;
|
||||||
@@ -1068,7 +1090,8 @@ static char *_conn_build_stream_tag(xmpp_conn_t * const conn,
|
|||||||
for (i = 0; i < attributes_len; ++i)
|
for (i = 0; i < attributes_len; ++i)
|
||||||
len += strlen(attributes[i]) + 2;
|
len += strlen(attributes[i]) + 2;
|
||||||
tag = xmpp_alloc(conn->ctx, len + 1);
|
tag = xmpp_alloc(conn->ctx, len + 1);
|
||||||
if (!tag) return NULL;
|
if (!tag)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
strcpy(tag, tag_head);
|
strcpy(tag, tag_head);
|
||||||
for (i = 0; i < attributes_len; ++i) {
|
for (i = 0; i < attributes_len; ++i) {
|
||||||
@@ -1084,8 +1107,9 @@ static char *_conn_build_stream_tag(xmpp_conn_t * const conn,
|
|||||||
strcat(tag, tag_tail);
|
strcat(tag, tag_tail);
|
||||||
|
|
||||||
if (strlen(tag) != len) {
|
if (strlen(tag) != len) {
|
||||||
xmpp_error(conn->ctx, "xmpp", "Internal error in "
|
xmpp_error(conn->ctx, "xmpp",
|
||||||
"_conn_build_stream_tag().");
|
"Internal error in "
|
||||||
|
"_conn_build_stream_tag().");
|
||||||
xmpp_free(conn->ctx, tag);
|
xmpp_free(conn->ctx, tag);
|
||||||
tag = NULL;
|
tag = NULL;
|
||||||
}
|
}
|
||||||
@@ -1093,20 +1117,24 @@ static char *_conn_build_stream_tag(xmpp_conn_t * const conn,
|
|||||||
return tag;
|
return tag;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _conn_attributes_new(xmpp_conn_t *conn, char **attrs,
|
static void _conn_attributes_new(xmpp_conn_t *conn,
|
||||||
char ***attributes, size_t *attributes_len)
|
char **attrs,
|
||||||
|
char ***attributes,
|
||||||
|
size_t *attributes_len)
|
||||||
{
|
{
|
||||||
char **array = NULL;
|
char **array = NULL;
|
||||||
size_t nr = 0;
|
size_t nr = 0;
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
if (attrs) {
|
if (attrs) {
|
||||||
for (; attrs[nr]; ++nr);
|
for (; attrs[nr]; ++nr)
|
||||||
|
;
|
||||||
array = xmpp_alloc(conn->ctx, sizeof(*array) * nr);
|
array = xmpp_alloc(conn->ctx, sizeof(*array) * nr);
|
||||||
for (i = 0; array && i < nr; ++i) {
|
for (i = 0; array && i < nr; ++i) {
|
||||||
array[i] = (i & 1) == 0 ? parser_attr_name(conn->ctx, attrs[i])
|
array[i] = (i & 1) == 0 ? parser_attr_name(conn->ctx, attrs[i])
|
||||||
: xmpp_strdup(conn->ctx, attrs[i]);
|
: xmpp_strdup(conn->ctx, attrs[i]);
|
||||||
if (array[i] == NULL) break;
|
if (array[i] == NULL)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
if (!array || i < nr) {
|
if (!array || i < nr) {
|
||||||
xmpp_error(conn->ctx, "xmpp", "Memory allocation error.");
|
xmpp_error(conn->ctx, "xmpp", "Memory allocation error.");
|
||||||
@@ -1119,7 +1147,8 @@ static void _conn_attributes_new(xmpp_conn_t *conn, char **attrs,
|
|||||||
*attributes_len = nr;
|
*attributes_len = nr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _conn_attributes_destroy(xmpp_conn_t *conn, char **attributes,
|
static void _conn_attributes_destroy(xmpp_conn_t *conn,
|
||||||
|
char **attributes,
|
||||||
size_t attributes_len)
|
size_t attributes_len)
|
||||||
{
|
{
|
||||||
size_t i;
|
size_t i;
|
||||||
@@ -1150,23 +1179,24 @@ static char *_get_stream_attribute(char **attrs, char *name)
|
|||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (!attrs) return NULL;
|
if (!attrs)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
for (i = 0; attrs[i]; i += 2)
|
for (i = 0; attrs[i]; i += 2)
|
||||||
if (strcmp(name, attrs[i]) == 0)
|
if (strcmp(name, attrs[i]) == 0)
|
||||||
return attrs[i+1];
|
return attrs[i + 1];
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _handle_stream_start(char *name, char **attrs,
|
static void _handle_stream_start(char *name, char **attrs, void *const userdata)
|
||||||
void * const userdata)
|
|
||||||
{
|
{
|
||||||
xmpp_conn_t *conn = (xmpp_conn_t *)userdata;
|
xmpp_conn_t *conn = (xmpp_conn_t *)userdata;
|
||||||
char *id;
|
char *id;
|
||||||
int failed = 0;
|
int failed = 0;
|
||||||
|
|
||||||
if (conn->stream_id) xmpp_free(conn->ctx, conn->stream_id);
|
if (conn->stream_id)
|
||||||
|
xmpp_free(conn->ctx, conn->stream_id);
|
||||||
conn->stream_id = NULL;
|
conn->stream_id = NULL;
|
||||||
|
|
||||||
if (strcmp(name, "stream") == 0) {
|
if (strcmp(name, "stream") == 0) {
|
||||||
@@ -1180,8 +1210,10 @@ static void _handle_stream_start(char *name, char **attrs,
|
|||||||
failed = 1;
|
failed = 1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
xmpp_error(conn->ctx, "conn", "Server did not open valid stream."
|
xmpp_error(conn->ctx, "conn",
|
||||||
" name = %s.", name);
|
"Server did not open valid stream."
|
||||||
|
" name = %s.",
|
||||||
|
name);
|
||||||
failed = 1;
|
failed = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1193,8 +1225,7 @@ static void _handle_stream_start(char *name, char **attrs,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _handle_stream_end(char *name,
|
static void _handle_stream_end(char *name, void *const userdata)
|
||||||
void * const userdata)
|
|
||||||
{
|
{
|
||||||
xmpp_conn_t *conn = (xmpp_conn_t *)userdata;
|
xmpp_conn_t *conn = (xmpp_conn_t *)userdata;
|
||||||
|
|
||||||
@@ -1203,8 +1234,7 @@ static void _handle_stream_end(char *name,
|
|||||||
conn_disconnect_clean(conn);
|
conn_disconnect_clean(conn);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _handle_stream_stanza(xmpp_stanza_t *stanza,
|
static void _handle_stream_stanza(xmpp_stanza_t *stanza, void *const userdata)
|
||||||
void * const userdata)
|
|
||||||
{
|
{
|
||||||
xmpp_conn_t *conn = (xmpp_conn_t *)userdata;
|
xmpp_conn_t *conn = (xmpp_conn_t *)userdata;
|
||||||
char *buf;
|
char *buf;
|
||||||
@@ -1218,13 +1248,13 @@ static void _handle_stream_stanza(xmpp_stanza_t *stanza,
|
|||||||
handler_fire_stanza(conn, stanza);
|
handler_fire_stanza(conn, stanza);
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned short _conn_default_port(xmpp_conn_t * const conn,
|
static unsigned short _conn_default_port(xmpp_conn_t *const conn,
|
||||||
xmpp_conn_type_t type)
|
xmpp_conn_type_t type)
|
||||||
{
|
{
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case XMPP_CLIENT:
|
case XMPP_CLIENT:
|
||||||
return conn->tls_legacy_ssl ? XMPP_PORT_CLIENT_LEGACY_SSL :
|
return conn->tls_legacy_ssl ? XMPP_PORT_CLIENT_LEGACY_SSL
|
||||||
XMPP_PORT_CLIENT;
|
: XMPP_PORT_CLIENT;
|
||||||
case XMPP_COMPONENT:
|
case XMPP_COMPONENT:
|
||||||
return XMPP_PORT_COMPONENT;
|
return XMPP_PORT_COMPONENT;
|
||||||
default:
|
default:
|
||||||
@@ -1232,7 +1262,7 @@ static unsigned short _conn_default_port(xmpp_conn_t * const conn,
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _conn_reset(xmpp_conn_t * const conn)
|
static void _conn_reset(xmpp_conn_t *const conn)
|
||||||
{
|
{
|
||||||
xmpp_ctx_t *ctx = conn->ctx;
|
xmpp_ctx_t *ctx = conn->ctx;
|
||||||
xmpp_send_queue_t *sq, *tsq;
|
xmpp_send_queue_t *sq, *tsq;
|
||||||
@@ -1262,9 +1292,12 @@ static void _conn_reset(xmpp_conn_t * const conn)
|
|||||||
conn->stream_error = NULL;
|
conn->stream_error = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (conn->domain) xmpp_free(ctx, conn->domain);
|
if (conn->domain)
|
||||||
if (conn->bound_jid) xmpp_free(ctx, conn->bound_jid);
|
xmpp_free(ctx, conn->domain);
|
||||||
if (conn->stream_id) xmpp_free(ctx, conn->stream_id);
|
if (conn->bound_jid)
|
||||||
|
xmpp_free(ctx, conn->bound_jid);
|
||||||
|
if (conn->stream_id)
|
||||||
|
xmpp_free(ctx, conn->stream_id);
|
||||||
conn->domain = NULL;
|
conn->domain = NULL;
|
||||||
conn->bound_jid = NULL;
|
conn->bound_jid = NULL;
|
||||||
conn->stream_id = NULL;
|
conn->stream_id = NULL;
|
||||||
@@ -1280,30 +1313,35 @@ static void _conn_reset(xmpp_conn_t * const conn)
|
|||||||
handler_system_delete_all(conn);
|
handler_system_delete_all(conn);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _conn_connect(xmpp_conn_t * const conn,
|
static int _conn_connect(xmpp_conn_t *const conn,
|
||||||
const char * const domain,
|
const char *const domain,
|
||||||
const char * const host,
|
const char *const host,
|
||||||
unsigned short port,
|
unsigned short port,
|
||||||
xmpp_conn_type_t type,
|
xmpp_conn_type_t type,
|
||||||
xmpp_conn_handler callback,
|
xmpp_conn_handler callback,
|
||||||
void * const userdata)
|
void *const userdata)
|
||||||
{
|
{
|
||||||
xmpp_open_handler open_handler;
|
xmpp_open_handler open_handler;
|
||||||
|
|
||||||
if (conn->state != XMPP_STATE_DISCONNECTED) return XMPP_EINVOP;
|
if (conn->state != XMPP_STATE_DISCONNECTED)
|
||||||
if (type != XMPP_CLIENT && type != XMPP_COMPONENT) return XMPP_EINVOP;
|
return XMPP_EINVOP;
|
||||||
if (host == NULL || port == 0) return XMPP_EINT;
|
if (type != XMPP_CLIENT && type != XMPP_COMPONENT)
|
||||||
|
return XMPP_EINVOP;
|
||||||
|
if (host == NULL || port == 0)
|
||||||
|
return XMPP_EINT;
|
||||||
|
|
||||||
_conn_reset(conn);
|
_conn_reset(conn);
|
||||||
|
|
||||||
conn->type = type;
|
conn->type = type;
|
||||||
conn->domain = xmpp_strdup(conn->ctx, domain);
|
conn->domain = xmpp_strdup(conn->ctx, domain);
|
||||||
if (!conn->domain) return XMPP_EMEM;
|
if (!conn->domain)
|
||||||
|
return XMPP_EMEM;
|
||||||
|
|
||||||
conn->sock = sock_connect(host, port);
|
conn->sock = sock_connect(host, port);
|
||||||
xmpp_debug(conn->ctx, "xmpp", "sock_connect() to %s:%u returned %d",
|
xmpp_debug(conn->ctx, "xmpp", "sock_connect() to %s:%u returned %d", host,
|
||||||
host, port, conn->sock);
|
port, conn->sock);
|
||||||
if (conn->sock == -1) return XMPP_EINT;
|
if (conn->sock == -1)
|
||||||
|
return XMPP_EINT;
|
||||||
if (conn->ka_timeout || conn->ka_interval)
|
if (conn->ka_timeout || conn->ka_interval)
|
||||||
sock_set_keepalive(conn->sock, conn->ka_timeout, conn->ka_interval);
|
sock_set_keepalive(conn->sock, conn->ka_timeout, conn->ka_interval);
|
||||||
|
|
||||||
@@ -1311,9 +1349,10 @@ static int _conn_connect(xmpp_conn_t * const conn,
|
|||||||
conn->conn_handler = callback;
|
conn->conn_handler = callback;
|
||||||
conn->userdata = userdata;
|
conn->userdata = userdata;
|
||||||
|
|
||||||
open_handler = conn->is_raw ? auth_handle_open_stub :
|
open_handler = conn->is_raw
|
||||||
type == XMPP_CLIENT ? auth_handle_open :
|
? auth_handle_open_stub
|
||||||
auth_handle_component_open;
|
: type == XMPP_CLIENT ? auth_handle_open
|
||||||
|
: auth_handle_component_open;
|
||||||
conn_prepare_reset(conn, open_handler);
|
conn_prepare_reset(conn, open_handler);
|
||||||
|
|
||||||
/* FIXME: it could happen that the connect returns immediately as
|
/* FIXME: it could happen that the connect returns immediately as
|
||||||
|
|||||||
240
src/crypto.c
240
src/crypto.c
@@ -20,13 +20,13 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <string.h> /* memset, memcpy */
|
#include <string.h> /* memset, memcpy */
|
||||||
|
|
||||||
#include "common.h" /* xmpp_alloc */
|
#include "common.h" /* xmpp_alloc */
|
||||||
#include "ostypes.h" /* uint8_t, size_t */
|
#include "ostypes.h" /* uint8_t, size_t */
|
||||||
#include "sha1.h"
|
#include "sha1.h"
|
||||||
#include "snprintf.h" /* xmpp_snprintf */
|
#include "snprintf.h" /* xmpp_snprintf */
|
||||||
#include "strophe.h" /* xmpp_ctx_t, xmpp_free */
|
#include "strophe.h" /* xmpp_ctx_t, xmpp_free */
|
||||||
|
|
||||||
struct _xmpp_sha1_t {
|
struct _xmpp_sha1_t {
|
||||||
xmpp_ctx_t *xmpp_ctx;
|
xmpp_ctx_t *xmpp_ctx;
|
||||||
@@ -91,7 +91,8 @@ char *xmpp_sha1(xmpp_ctx_t *ctx, const unsigned char *data, size_t len)
|
|||||||
*
|
*
|
||||||
* @ingroup Digests
|
* @ingroup Digests
|
||||||
*/
|
*/
|
||||||
void xmpp_sha1_digest(const unsigned char *data, size_t len,
|
void xmpp_sha1_digest(const unsigned char *data,
|
||||||
|
size_t len,
|
||||||
unsigned char *digest)
|
unsigned char *digest)
|
||||||
{
|
{
|
||||||
crypto_SHA1((const uint8_t *)data, len, digest);
|
crypto_SHA1((const uint8_t *)data, len, digest);
|
||||||
@@ -214,52 +215,44 @@ void xmpp_sha1_to_digest(xmpp_sha1_t *sha1, unsigned char *digest)
|
|||||||
memcpy(digest, sha1->digest, SHA1_DIGEST_SIZE);
|
memcpy(digest, sha1->digest, SHA1_DIGEST_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Base64 encoding routines. Implemented according to RFC 3548. */
|
/* Base64 encoding routines. Implemented according to RFC 3548. */
|
||||||
|
|
||||||
/* map of all byte values to the base64 values, or to
|
/* map of all byte values to the base64 values, or to
|
||||||
'65' which indicates an invalid character. '=' is '64' */
|
'65' which indicates an invalid character. '=' is '64' */
|
||||||
static const unsigned char _base64_invcharmap[256] = {
|
static const unsigned char _base64_invcharmap[256] = {
|
||||||
65,65,65,65, 65,65,65,65, 65,65,65,65, 65,65,65,65,
|
65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
|
||||||
65,65,65,65, 65,65,65,65, 65,65,65,65, 65,65,65,65,
|
65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
|
||||||
65,65,65,65, 65,65,65,65, 65,65,65,62, 65,65,65,63,
|
65, 65, 65, 65, 65, 62, 65, 65, 65, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60,
|
||||||
52,53,54,55, 56,57,58,59, 60,61,65,65, 65,64,65,65,
|
61, 65, 65, 65, 64, 65, 65, 65, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
|
||||||
65, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 11,12,13,14,
|
11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 65, 65, 65, 65,
|
||||||
15,16,17,18, 19,20,21,22, 23,24,25,65, 65,65,65,65,
|
65, 65, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42,
|
||||||
65,26,27,28, 29,30,31,32, 33,34,35,36, 37,38,39,40,
|
43, 44, 45, 46, 47, 48, 49, 50, 51, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
|
||||||
41,42,43,44, 45,46,47,48, 49,50,51,65, 65,65,65,65,
|
65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
|
||||||
65,65,65,65, 65,65,65,65, 65,65,65,65, 65,65,65,65,
|
65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
|
||||||
65,65,65,65, 65,65,65,65, 65,65,65,65, 65,65,65,65,
|
65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
|
||||||
65,65,65,65, 65,65,65,65, 65,65,65,65, 65,65,65,65,
|
65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
|
||||||
65,65,65,65, 65,65,65,65, 65,65,65,65, 65,65,65,65,
|
65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
|
||||||
65,65,65,65, 65,65,65,65, 65,65,65,65, 65,65,65,65,
|
65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
|
||||||
65,65,65,65, 65,65,65,65, 65,65,65,65, 65,65,65,65,
|
65, 65, 65, 65, 65, 65, 65, 65, 65};
|
||||||
65,65,65,65, 65,65,65,65, 65,65,65,65, 65,65,65,65,
|
|
||||||
65,65,65,65, 65,65,65,65, 65,65,65,65, 65,65,65,65
|
|
||||||
};
|
|
||||||
|
|
||||||
/* map of all 6-bit values to their corresponding byte
|
/* map of all 6-bit values to their corresponding byte
|
||||||
in the base64 alphabet. Padding char is the value '64' */
|
in the base64 alphabet. Padding char is the value '64' */
|
||||||
static const char _base64_charmap[65] = {
|
static const char _base64_charmap[65] = {
|
||||||
'A','B','C','D', 'E','F','G','H',
|
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
|
||||||
'I','J','K','L', 'M','N','O','P',
|
'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
|
||||||
'Q','R','S','T', 'U','V','W','X',
|
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
|
||||||
'Y','Z','a','b', 'c','d','e','f',
|
'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
|
||||||
'g','h','i','j', 'k','l','m','n',
|
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/', '='};
|
||||||
'o','p','q','r', 's','t','u','v',
|
|
||||||
'w','x','y','z', '0','1','2','3',
|
|
||||||
'4','5','6','7', '8','9','+','/',
|
|
||||||
'='
|
|
||||||
};
|
|
||||||
|
|
||||||
static size_t base64_encoded_len(const size_t len)
|
static size_t base64_encoded_len(const size_t len)
|
||||||
{
|
{
|
||||||
/* encoded steam is 4 bytes for every three, rounded up */
|
/* encoded steam is 4 bytes for every three, rounded up */
|
||||||
return ((len + 2)/3) << 2;
|
return ((len + 2) / 3) << 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *base64_encode(xmpp_ctx_t *ctx,
|
static char *base64_encode(xmpp_ctx_t *ctx,
|
||||||
const unsigned char * const buffer, const size_t len)
|
const unsigned char *const buffer,
|
||||||
|
const size_t len)
|
||||||
{
|
{
|
||||||
size_t clen;
|
size_t clen;
|
||||||
char *cbuf, *c;
|
char *cbuf, *c;
|
||||||
@@ -272,7 +265,7 @@ static char *base64_encode(xmpp_ctx_t *ctx,
|
|||||||
c = cbuf;
|
c = cbuf;
|
||||||
/* loop over data, turning every 3 bytes into 4 characters */
|
/* loop over data, turning every 3 bytes into 4 characters */
|
||||||
for (i = 0; i + 2 < len; i += 3) {
|
for (i = 0; i + 2 < len; i += 3) {
|
||||||
word = buffer[i] << 16 | buffer[i+1] << 8 | buffer[i+2];
|
word = buffer[i] << 16 | buffer[i + 1] << 8 | buffer[i + 2];
|
||||||
hextet = (word & 0x00FC0000) >> 18;
|
hextet = (word & 0x00FC0000) >> 18;
|
||||||
*c++ = _base64_charmap[hextet];
|
*c++ = _base64_charmap[hextet];
|
||||||
hextet = (word & 0x0003F000) >> 12;
|
hextet = (word & 0x0003F000) >> 12;
|
||||||
@@ -284,26 +277,26 @@ static char *base64_encode(xmpp_ctx_t *ctx,
|
|||||||
}
|
}
|
||||||
/* zero, one or two bytes left */
|
/* zero, one or two bytes left */
|
||||||
switch (len - i) {
|
switch (len - i) {
|
||||||
case 0:
|
case 0:
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
hextet = (buffer[len-1] & 0xFC) >> 2;
|
hextet = (buffer[len - 1] & 0xFC) >> 2;
|
||||||
*c++ = _base64_charmap[hextet];
|
*c++ = _base64_charmap[hextet];
|
||||||
hextet = (buffer[len-1] & 0x03) << 4;
|
hextet = (buffer[len - 1] & 0x03) << 4;
|
||||||
*c++ = _base64_charmap[hextet];
|
*c++ = _base64_charmap[hextet];
|
||||||
*c++ = _base64_charmap[64]; /* pad */
|
*c++ = _base64_charmap[64]; /* pad */
|
||||||
*c++ = _base64_charmap[64]; /* pad */
|
*c++ = _base64_charmap[64]; /* pad */
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
hextet = (buffer[len-2] & 0xFC) >> 2;
|
hextet = (buffer[len - 2] & 0xFC) >> 2;
|
||||||
*c++ = _base64_charmap[hextet];
|
*c++ = _base64_charmap[hextet];
|
||||||
hextet = ((buffer[len-2] & 0x03) << 4) |
|
hextet = ((buffer[len - 2] & 0x03) << 4) |
|
||||||
((buffer[len-1] & 0xF0) >> 4);
|
((buffer[len - 1] & 0xF0) >> 4);
|
||||||
*c++ = _base64_charmap[hextet];
|
*c++ = _base64_charmap[hextet];
|
||||||
hextet = (buffer[len-1] & 0x0F) << 2;
|
hextet = (buffer[len - 1] & 0x0F) << 2;
|
||||||
*c++ = _base64_charmap[hextet];
|
*c++ = _base64_charmap[hextet];
|
||||||
*c++ = _base64_charmap[64]; /* pad */
|
*c++ = _base64_charmap[64]; /* pad */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/* add a terminal null */
|
/* add a terminal null */
|
||||||
*c = '\0';
|
*c = '\0';
|
||||||
@@ -311,30 +304,37 @@ static char *base64_encode(xmpp_ctx_t *ctx,
|
|||||||
return cbuf;
|
return cbuf;
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t base64_decoded_len(const char * const buffer, const size_t len)
|
static size_t base64_decoded_len(const char *const buffer, const size_t len)
|
||||||
{
|
{
|
||||||
size_t nudge = 0;
|
size_t nudge = 0;
|
||||||
unsigned char c;
|
unsigned char c;
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
if (len < 4) return 0;
|
if (len < 4)
|
||||||
|
return 0;
|
||||||
|
|
||||||
/* count the padding characters for the remainder */
|
/* count the padding characters for the remainder */
|
||||||
for (i = len; i > 0; --i) {
|
for (i = len; i > 0; --i) {
|
||||||
c = _base64_invcharmap[(unsigned char)buffer[i-1]];
|
c = _base64_invcharmap[(unsigned char)buffer[i - 1]];
|
||||||
if (c < 64) break;
|
if (c < 64)
|
||||||
if (c == 64) ++nudge;
|
break;
|
||||||
if (c > 64) return 0;
|
if (c == 64)
|
||||||
|
++nudge;
|
||||||
|
if (c > 64)
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
if (nudge > 2) return 0;
|
if (nudge > 2)
|
||||||
|
return 0;
|
||||||
|
|
||||||
/* decoded steam is 3 bytes for every four */
|
/* decoded steam is 3 bytes for every four */
|
||||||
return 3 * (len >> 2) - nudge;
|
return 3 * (len >> 2) - nudge;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void base64_decode(xmpp_ctx_t *ctx,
|
static void base64_decode(xmpp_ctx_t *ctx,
|
||||||
const char * const buffer, const size_t len,
|
const char *const buffer,
|
||||||
unsigned char **out, size_t *outlen)
|
const size_t len,
|
||||||
|
unsigned char **out,
|
||||||
|
size_t *outlen)
|
||||||
{
|
{
|
||||||
size_t dlen;
|
size_t dlen;
|
||||||
unsigned char *dbuf, *d;
|
unsigned char *dbuf, *d;
|
||||||
@@ -342,10 +342,12 @@ static void base64_decode(xmpp_ctx_t *ctx,
|
|||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
/* len must be a multiple of 4 */
|
/* len must be a multiple of 4 */
|
||||||
if (len & 0x03) goto _base64_error;
|
if (len & 0x03)
|
||||||
|
goto _base64_error;
|
||||||
|
|
||||||
dlen = base64_decoded_len(buffer, len);
|
dlen = base64_decoded_len(buffer, len);
|
||||||
if (dlen == 0) goto _base64_error;
|
if (dlen == 0)
|
||||||
|
goto _base64_error;
|
||||||
|
|
||||||
dbuf = xmpp_alloc(ctx, dlen + 1);
|
dbuf = xmpp_alloc(ctx, dlen + 1);
|
||||||
if (dbuf != NULL) {
|
if (dbuf != NULL) {
|
||||||
@@ -353,57 +355,70 @@ static void base64_decode(xmpp_ctx_t *ctx,
|
|||||||
/* loop over each set of 4 characters, decoding 3 bytes */
|
/* loop over each set of 4 characters, decoding 3 bytes */
|
||||||
for (i = 0; i + 3 < len; i += 4) {
|
for (i = 0; i + 3 < len; i += 4) {
|
||||||
hextet = _base64_invcharmap[(unsigned char)buffer[i]];
|
hextet = _base64_invcharmap[(unsigned char)buffer[i]];
|
||||||
if (hextet & 0xC0) break;
|
if (hextet & 0xC0)
|
||||||
|
break;
|
||||||
word = hextet << 18;
|
word = hextet << 18;
|
||||||
hextet = _base64_invcharmap[(unsigned char)buffer[i+1]];
|
hextet = _base64_invcharmap[(unsigned char)buffer[i + 1]];
|
||||||
if (hextet & 0xC0) break;
|
if (hextet & 0xC0)
|
||||||
|
break;
|
||||||
word |= hextet << 12;
|
word |= hextet << 12;
|
||||||
hextet = _base64_invcharmap[(unsigned char)buffer[i+2]];
|
hextet = _base64_invcharmap[(unsigned char)buffer[i + 2]];
|
||||||
if (hextet & 0xC0) break;
|
if (hextet & 0xC0)
|
||||||
|
break;
|
||||||
word |= hextet << 6;
|
word |= hextet << 6;
|
||||||
hextet = _base64_invcharmap[(unsigned char)buffer[i+3]];
|
hextet = _base64_invcharmap[(unsigned char)buffer[i + 3]];
|
||||||
if (hextet & 0xC0) break;
|
if (hextet & 0xC0)
|
||||||
|
break;
|
||||||
word |= hextet;
|
word |= hextet;
|
||||||
*d++ = (word & 0x00FF0000) >> 16;
|
*d++ = (word & 0x00FF0000) >> 16;
|
||||||
*d++ = (word & 0x0000FF00) >> 8;
|
*d++ = (word & 0x0000FF00) >> 8;
|
||||||
*d++ = (word & 0x000000FF);
|
*d++ = (word & 0x000000FF);
|
||||||
}
|
}
|
||||||
if (hextet > 64) goto _base64_decode_error;
|
if (hextet > 64)
|
||||||
|
goto _base64_decode_error;
|
||||||
/* handle the remainder */
|
/* handle the remainder */
|
||||||
switch (dlen % 3) {
|
switch (dlen % 3) {
|
||||||
case 0:
|
case 0:
|
||||||
/* nothing to do */
|
/* nothing to do */
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
/* redo the last quartet, checking for correctness */
|
/* redo the last quartet, checking for correctness */
|
||||||
hextet = _base64_invcharmap[(unsigned char)buffer[len-4]];
|
hextet = _base64_invcharmap[(unsigned char)buffer[len - 4]];
|
||||||
if (hextet & 0xC0) goto _base64_decode_error;
|
if (hextet & 0xC0)
|
||||||
word = hextet << 2;
|
goto _base64_decode_error;
|
||||||
hextet = _base64_invcharmap[(unsigned char)buffer[len-3]];
|
word = hextet << 2;
|
||||||
if (hextet & 0xC0) goto _base64_decode_error;
|
hextet = _base64_invcharmap[(unsigned char)buffer[len - 3]];
|
||||||
word |= hextet >> 4;
|
if (hextet & 0xC0)
|
||||||
*d++ = word & 0xFF;
|
goto _base64_decode_error;
|
||||||
hextet = _base64_invcharmap[(unsigned char)buffer[len-2]];
|
word |= hextet >> 4;
|
||||||
if (hextet != 64) goto _base64_decode_error;
|
*d++ = word & 0xFF;
|
||||||
hextet = _base64_invcharmap[(unsigned char)buffer[len-1]];
|
hextet = _base64_invcharmap[(unsigned char)buffer[len - 2]];
|
||||||
if (hextet != 64) goto _base64_decode_error;
|
if (hextet != 64)
|
||||||
break;
|
goto _base64_decode_error;
|
||||||
case 2:
|
hextet = _base64_invcharmap[(unsigned char)buffer[len - 1]];
|
||||||
/* redo the last quartet, checking for correctness */
|
if (hextet != 64)
|
||||||
hextet = _base64_invcharmap[(unsigned char)buffer[len-4]];
|
goto _base64_decode_error;
|
||||||
if (hextet & 0xC0) goto _base64_decode_error;
|
break;
|
||||||
word = hextet << 10;
|
case 2:
|
||||||
hextet = _base64_invcharmap[(unsigned char)buffer[len-3]];
|
/* redo the last quartet, checking for correctness */
|
||||||
if (hextet & 0xC0) goto _base64_decode_error;
|
hextet = _base64_invcharmap[(unsigned char)buffer[len - 4]];
|
||||||
word |= hextet << 4;
|
if (hextet & 0xC0)
|
||||||
hextet = _base64_invcharmap[(unsigned char)buffer[len-2]];
|
goto _base64_decode_error;
|
||||||
if (hextet & 0xC0) goto _base64_decode_error;
|
word = hextet << 10;
|
||||||
word |= hextet >> 2;
|
hextet = _base64_invcharmap[(unsigned char)buffer[len - 3]];
|
||||||
*d++ = (word & 0xFF00) >> 8;
|
if (hextet & 0xC0)
|
||||||
*d++ = (word & 0x00FF);
|
goto _base64_decode_error;
|
||||||
hextet = _base64_invcharmap[(unsigned char)buffer[len-1]];
|
word |= hextet << 4;
|
||||||
if (hextet != 64) goto _base64_decode_error;
|
hextet = _base64_invcharmap[(unsigned char)buffer[len - 2]];
|
||||||
break;
|
if (hextet & 0xC0)
|
||||||
|
goto _base64_decode_error;
|
||||||
|
word |= hextet >> 2;
|
||||||
|
*d++ = (word & 0xFF00) >> 8;
|
||||||
|
*d++ = (word & 0x00FF);
|
||||||
|
hextet = _base64_invcharmap[(unsigned char)buffer[len - 1]];
|
||||||
|
if (hextet != 64)
|
||||||
|
goto _base64_decode_error;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
*d = '\0';
|
*d = '\0';
|
||||||
}
|
}
|
||||||
@@ -484,8 +499,11 @@ char *xmpp_base64_decode_str(xmpp_ctx_t *ctx, const char *base64, size_t len)
|
|||||||
*
|
*
|
||||||
* @ingroup Encodings
|
* @ingroup Encodings
|
||||||
*/
|
*/
|
||||||
void xmpp_base64_decode_bin(xmpp_ctx_t *ctx, const char *base64, size_t len,
|
void xmpp_base64_decode_bin(xmpp_ctx_t *ctx,
|
||||||
unsigned char **out, size_t *outlen)
|
const char *base64,
|
||||||
|
size_t len,
|
||||||
|
unsigned char **out,
|
||||||
|
size_t *outlen)
|
||||||
{
|
{
|
||||||
base64_decode(ctx, base64, len, out, outlen);
|
base64_decode(ctx, base64, len, out, outlen);
|
||||||
}
|
}
|
||||||
|
|||||||
106
src/ctx.c
106
src/ctx.c
@@ -52,7 +52,7 @@
|
|||||||
|
|
||||||
/* Workaround for visual studio without va_copy support. */
|
/* Workaround for visual studio without va_copy support. */
|
||||||
#if defined(_MSC_VER) && _MSC_VER < 1800 || defined(__HAIKU__)
|
#if defined(_MSC_VER) && _MSC_VER < 1800 || defined(__HAIKU__)
|
||||||
#define va_copy(d,s) ((d) = (s))
|
#define va_copy(d, s) ((d) = (s))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/** Initialize the Strophe library.
|
/** Initialize the Strophe library.
|
||||||
@@ -61,7 +61,7 @@
|
|||||||
*
|
*
|
||||||
* @ingroup Init
|
* @ingroup Init
|
||||||
*/
|
*/
|
||||||
void xmpp_initialize(void)
|
void xmpp_initialize(void)
|
||||||
{
|
{
|
||||||
sock_initialize();
|
sock_initialize();
|
||||||
resolver_initialize();
|
resolver_initialize();
|
||||||
@@ -113,8 +113,7 @@ void xmpp_shutdown(void)
|
|||||||
*/
|
*/
|
||||||
int xmpp_version_check(int major, int minor)
|
int xmpp_version_check(int major, int minor)
|
||||||
{
|
{
|
||||||
return (major == LIBXMPP_VERSION_MAJOR) &&
|
return (major == LIBXMPP_VERSION_MAJOR) && (minor >= LIBXMPP_VERSION_MINOR);
|
||||||
(minor >= LIBXMPP_VERSION_MINOR);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We define the global default allocator, logger, and context here. */
|
/* We define the global default allocator, logger, and context here. */
|
||||||
@@ -122,17 +121,17 @@ int xmpp_version_check(int major, int minor)
|
|||||||
/* Wrap stdlib routines malloc, free, and realloc for default memory
|
/* Wrap stdlib routines malloc, free, and realloc for default memory
|
||||||
* management.
|
* management.
|
||||||
*/
|
*/
|
||||||
static void *_malloc(const size_t size, void * const userdata)
|
static void *_malloc(const size_t size, void *const userdata)
|
||||||
{
|
{
|
||||||
return malloc(size);
|
return malloc(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _free(void *p, void * const userdata)
|
static void _free(void *p, void *const userdata)
|
||||||
{
|
{
|
||||||
free(p);
|
free(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void *_realloc(void *p, const size_t size, void * const userdata)
|
static void *_realloc(void *p, const size_t size, void *const userdata)
|
||||||
{
|
{
|
||||||
return realloc(p, size);
|
return realloc(p, size);
|
||||||
}
|
}
|
||||||
@@ -140,17 +139,13 @@ static void *_realloc(void *p, const size_t size, void * const userdata)
|
|||||||
/* default memory function map */
|
/* default memory function map */
|
||||||
static xmpp_mem_t xmpp_default_mem = {
|
static xmpp_mem_t xmpp_default_mem = {
|
||||||
_malloc, /* use the thinly wrapped stdlib routines by default */
|
_malloc, /* use the thinly wrapped stdlib routines by default */
|
||||||
_free,
|
_free, _realloc, NULL};
|
||||||
_realloc,
|
|
||||||
NULL
|
|
||||||
};
|
|
||||||
|
|
||||||
/* log levels and names */
|
/* log levels and names */
|
||||||
static const char * const _xmpp_log_level_name[4] = {"DEBUG", "INFO", "WARN", "ERROR"};
|
static const char *const _xmpp_log_level_name[4] = {"DEBUG", "INFO", "WARN",
|
||||||
static const xmpp_log_level_t _xmpp_default_logger_levels[] = {XMPP_LEVEL_DEBUG,
|
"ERROR"};
|
||||||
XMPP_LEVEL_INFO,
|
static const xmpp_log_level_t _xmpp_default_logger_levels[] = {
|
||||||
XMPP_LEVEL_WARN,
|
XMPP_LEVEL_DEBUG, XMPP_LEVEL_INFO, XMPP_LEVEL_WARN, XMPP_LEVEL_ERROR};
|
||||||
XMPP_LEVEL_ERROR};
|
|
||||||
|
|
||||||
/** Log a message.
|
/** Log a message.
|
||||||
* The default logger writes to stderr.
|
* The default logger writes to stderr.
|
||||||
@@ -161,22 +156,25 @@ static const xmpp_log_level_t _xmpp_default_logger_levels[] = {XMPP_LEVEL_DEBUG,
|
|||||||
* @param area the area the log message is for
|
* @param area the area the log message is for
|
||||||
* @param msg the log message
|
* @param msg the log message
|
||||||
*/
|
*/
|
||||||
static void xmpp_default_logger(void * const userdata,
|
static void xmpp_default_logger(void *const userdata,
|
||||||
const xmpp_log_level_t level,
|
const xmpp_log_level_t level,
|
||||||
const char * const area,
|
const char *const area,
|
||||||
const char * const msg)
|
const char *const msg)
|
||||||
{
|
{
|
||||||
xmpp_log_level_t filter_level = * (xmpp_log_level_t*)userdata;
|
xmpp_log_level_t filter_level = *(xmpp_log_level_t *)userdata;
|
||||||
if (level >= filter_level)
|
if (level >= filter_level)
|
||||||
fprintf(stderr, "%s %s %s\n", area, _xmpp_log_level_name[level], msg);
|
fprintf(stderr, "%s %s %s\n", area, _xmpp_log_level_name[level], msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const xmpp_log_t _xmpp_default_loggers[] = {
|
static const xmpp_log_t _xmpp_default_loggers[] = {
|
||||||
{&xmpp_default_logger, (void*)&_xmpp_default_logger_levels[XMPP_LEVEL_DEBUG]},
|
{&xmpp_default_logger,
|
||||||
{&xmpp_default_logger, (void*)&_xmpp_default_logger_levels[XMPP_LEVEL_INFO]},
|
(void *)&_xmpp_default_logger_levels[XMPP_LEVEL_DEBUG]},
|
||||||
{&xmpp_default_logger, (void*)&_xmpp_default_logger_levels[XMPP_LEVEL_WARN]},
|
{&xmpp_default_logger,
|
||||||
{&xmpp_default_logger, (void*)&_xmpp_default_logger_levels[XMPP_LEVEL_ERROR]}
|
(void *)&_xmpp_default_logger_levels[XMPP_LEVEL_INFO]},
|
||||||
};
|
{&xmpp_default_logger,
|
||||||
|
(void *)&_xmpp_default_logger_levels[XMPP_LEVEL_WARN]},
|
||||||
|
{&xmpp_default_logger,
|
||||||
|
(void *)&_xmpp_default_logger_levels[XMPP_LEVEL_ERROR]}};
|
||||||
|
|
||||||
/** Get a default logger with filtering.
|
/** Get a default logger with filtering.
|
||||||
* The default logger provides a basic logging setup which writes log
|
* The default logger provides a basic logging setup which writes log
|
||||||
@@ -192,12 +190,13 @@ static const xmpp_log_t _xmpp_default_loggers[] = {
|
|||||||
xmpp_log_t *xmpp_get_default_logger(xmpp_log_level_t level)
|
xmpp_log_t *xmpp_get_default_logger(xmpp_log_level_t level)
|
||||||
{
|
{
|
||||||
/* clamp to the known range */
|
/* clamp to the known range */
|
||||||
if (level > XMPP_LEVEL_ERROR) level = XMPP_LEVEL_ERROR;
|
if (level > XMPP_LEVEL_ERROR)
|
||||||
|
level = XMPP_LEVEL_ERROR;
|
||||||
|
|
||||||
return (xmpp_log_t*)&_xmpp_default_loggers[level];
|
return (xmpp_log_t *)&_xmpp_default_loggers[level];
|
||||||
}
|
}
|
||||||
|
|
||||||
static xmpp_log_t xmpp_default_log = { NULL, NULL };
|
static xmpp_log_t xmpp_default_log = {NULL, NULL};
|
||||||
|
|
||||||
/* convenience functions for accessing the context */
|
/* convenience functions for accessing the context */
|
||||||
|
|
||||||
@@ -209,7 +208,7 @@ static xmpp_log_t xmpp_default_log = { NULL, NULL };
|
|||||||
*
|
*
|
||||||
* @return a pointer to the allocated memory or NULL on an error
|
* @return a pointer to the allocated memory or NULL on an error
|
||||||
*/
|
*/
|
||||||
void *xmpp_alloc(const xmpp_ctx_t * const ctx, const size_t size)
|
void *xmpp_alloc(const xmpp_ctx_t *const ctx, const size_t size)
|
||||||
{
|
{
|
||||||
return ctx->mem->alloc(size, ctx->mem->userdata);
|
return ctx->mem->alloc(size, ctx->mem->userdata);
|
||||||
}
|
}
|
||||||
@@ -220,7 +219,7 @@ void *xmpp_alloc(const xmpp_ctx_t * const ctx, const size_t size)
|
|||||||
* @param ctx a Strophe context object
|
* @param ctx a Strophe context object
|
||||||
* @param p a pointer referencing memory to be freed
|
* @param p a pointer referencing memory to be freed
|
||||||
*/
|
*/
|
||||||
void xmpp_free(const xmpp_ctx_t * const ctx, void *p)
|
void xmpp_free(const xmpp_ctx_t *const ctx, void *p)
|
||||||
{
|
{
|
||||||
ctx->mem->free(p, ctx->mem->userdata);
|
ctx->mem->free(p, ctx->mem->userdata);
|
||||||
}
|
}
|
||||||
@@ -234,8 +233,7 @@ void xmpp_free(const xmpp_ctx_t * const ctx, void *p)
|
|||||||
*
|
*
|
||||||
* @return a pointer to the reallocated memory or NULL on an error
|
* @return a pointer to the reallocated memory or NULL on an error
|
||||||
*/
|
*/
|
||||||
void *xmpp_realloc(const xmpp_ctx_t * const ctx, void *p,
|
void *xmpp_realloc(const xmpp_ctx_t *const ctx, void *p, const size_t size)
|
||||||
const size_t size)
|
|
||||||
{
|
{
|
||||||
return ctx->mem->realloc(p, size, ctx->mem->userdata);
|
return ctx->mem->realloc(p, size, ctx->mem->userdata);
|
||||||
}
|
}
|
||||||
@@ -253,10 +251,10 @@ void *xmpp_realloc(const xmpp_ctx_t * const ctx, void *p,
|
|||||||
* @param fmt a printf-style format string for the message
|
* @param fmt a printf-style format string for the message
|
||||||
* @param ap variable argument list supplied for the format string
|
* @param ap variable argument list supplied for the format string
|
||||||
*/
|
*/
|
||||||
void xmpp_log(const xmpp_ctx_t * const ctx,
|
void xmpp_log(const xmpp_ctx_t *const ctx,
|
||||||
const xmpp_log_level_t level,
|
const xmpp_log_level_t level,
|
||||||
const char * const area,
|
const char *const area,
|
||||||
const char * const fmt,
|
const char *const fmt,
|
||||||
va_list ap)
|
va_list ap)
|
||||||
{
|
{
|
||||||
int oldret, ret;
|
int oldret, ret;
|
||||||
@@ -304,9 +302,9 @@ void xmpp_log(const xmpp_ctx_t * const ctx,
|
|||||||
* @param fmt a printf-style format string followed by a variable list of
|
* @param fmt a printf-style format string followed by a variable list of
|
||||||
* arguments to format
|
* arguments to format
|
||||||
*/
|
*/
|
||||||
void xmpp_error(const xmpp_ctx_t * const ctx,
|
void xmpp_error(const xmpp_ctx_t *const ctx,
|
||||||
const char * const area,
|
const char *const area,
|
||||||
const char * const fmt,
|
const char *const fmt,
|
||||||
...)
|
...)
|
||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
@@ -326,10 +324,10 @@ void xmpp_error(const xmpp_ctx_t * const ctx,
|
|||||||
* @param fmt a printf-style format string followed by a variable list of
|
* @param fmt a printf-style format string followed by a variable list of
|
||||||
* arguments to format
|
* arguments to format
|
||||||
*/
|
*/
|
||||||
void xmpp_warn(const xmpp_ctx_t * const ctx,
|
void xmpp_warn(const xmpp_ctx_t *const ctx,
|
||||||
const char * const area,
|
const char *const area,
|
||||||
const char * const fmt,
|
const char *const fmt,
|
||||||
...)
|
...)
|
||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
|
||||||
@@ -348,10 +346,10 @@ void xmpp_warn(const xmpp_ctx_t * const ctx,
|
|||||||
* @param fmt a printf-style format string followed by a variable list of
|
* @param fmt a printf-style format string followed by a variable list of
|
||||||
* arguments to format
|
* arguments to format
|
||||||
*/
|
*/
|
||||||
void xmpp_info(const xmpp_ctx_t * const ctx,
|
void xmpp_info(const xmpp_ctx_t *const ctx,
|
||||||
const char * const area,
|
const char *const area,
|
||||||
const char * const fmt,
|
const char *const fmt,
|
||||||
...)
|
...)
|
||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
|
||||||
@@ -370,9 +368,9 @@ void xmpp_info(const xmpp_ctx_t * const ctx,
|
|||||||
* @param fmt a printf-style format string followed by a variable list of
|
* @param fmt a printf-style format string followed by a variable list of
|
||||||
* arguments to format
|
* arguments to format
|
||||||
*/
|
*/
|
||||||
void xmpp_debug(const xmpp_ctx_t * const ctx,
|
void xmpp_debug(const xmpp_ctx_t *const ctx,
|
||||||
const char * const area,
|
const char *const area,
|
||||||
const char * const fmt,
|
const char *const fmt,
|
||||||
...)
|
...)
|
||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
@@ -396,8 +394,8 @@ void xmpp_debug(const xmpp_ctx_t * const ctx,
|
|||||||
*
|
*
|
||||||
* @ingroup Context
|
* @ingroup Context
|
||||||
*/
|
*/
|
||||||
xmpp_ctx_t *xmpp_ctx_new(const xmpp_mem_t * const mem,
|
xmpp_ctx_t *xmpp_ctx_new(const xmpp_mem_t *const mem,
|
||||||
const xmpp_log_t * const log)
|
const xmpp_log_t *const log)
|
||||||
{
|
{
|
||||||
xmpp_ctx_t *ctx = NULL;
|
xmpp_ctx_t *ctx = NULL;
|
||||||
|
|
||||||
@@ -436,7 +434,7 @@ xmpp_ctx_t *xmpp_ctx_new(const xmpp_mem_t * const mem,
|
|||||||
*
|
*
|
||||||
* @ingroup Context
|
* @ingroup Context
|
||||||
*/
|
*/
|
||||||
void xmpp_ctx_free(xmpp_ctx_t * const ctx)
|
void xmpp_ctx_free(xmpp_ctx_t *const ctx)
|
||||||
{
|
{
|
||||||
/* mem and log are owned by their suppliers */
|
/* mem and log are owned by their suppliers */
|
||||||
xmpp_rand_free(ctx, ctx->rand);
|
xmpp_rand_free(ctx, ctx->rand);
|
||||||
@@ -450,7 +448,7 @@ void xmpp_ctx_free(xmpp_ctx_t * const ctx)
|
|||||||
*
|
*
|
||||||
* @ingroup Context
|
* @ingroup Context
|
||||||
*/
|
*/
|
||||||
void xmpp_ctx_set_timeout(xmpp_ctx_t * const ctx, const unsigned long timeout)
|
void xmpp_ctx_set_timeout(xmpp_ctx_t *const ctx, const unsigned long timeout)
|
||||||
{
|
{
|
||||||
ctx->timeout = timeout;
|
ctx->timeout = timeout;
|
||||||
}
|
}
|
||||||
|
|||||||
33
src/event.c
33
src/event.c
@@ -38,7 +38,7 @@
|
|||||||
#include <sys/select.h>
|
#include <sys/select.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#define _sleep(x) usleep((x) * 1000)
|
#define _sleep(x) usleep((x)*1000)
|
||||||
#else
|
#else
|
||||||
#include <winsock2.h>
|
#include <winsock2.h>
|
||||||
#ifndef ETIMEDOUT
|
#ifndef ETIMEDOUT
|
||||||
@@ -88,7 +88,8 @@ void xmpp_run_once(xmpp_ctx_t *ctx, const unsigned long timeout)
|
|||||||
uint64_t usec;
|
uint64_t usec;
|
||||||
int tls_read_bytes = 0;
|
int tls_read_bytes = 0;
|
||||||
|
|
||||||
if (ctx->loop_status == XMPP_LOOP_QUIT) return;
|
if (ctx->loop_status == XMPP_LOOP_QUIT)
|
||||||
|
return;
|
||||||
|
|
||||||
/* send queued data */
|
/* send queued data */
|
||||||
connitem = ctx->connlist;
|
connitem = ctx->connlist;
|
||||||
@@ -141,7 +142,8 @@ void xmpp_run_once(xmpp_ctx_t *ctx, const unsigned long timeout)
|
|||||||
/* pop the top item */
|
/* pop the top item */
|
||||||
conn->send_queue_head = sq;
|
conn->send_queue_head = sq;
|
||||||
/* if we've sent everything update the tail */
|
/* if we've sent everything update the tail */
|
||||||
if (!sq) conn->send_queue_tail = NULL;
|
if (!sq)
|
||||||
|
conn->send_queue_tail = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* tear down connection on error */
|
/* tear down connection on error */
|
||||||
@@ -162,7 +164,6 @@ void xmpp_run_once(xmpp_ctx_t *ctx, const unsigned long timeout)
|
|||||||
conn_parser_reset(connitem->conn);
|
conn_parser_reset(connitem->conn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* fire any ready timed handlers, then make sure we don't wait past
|
/* fire any ready timed handlers, then make sure we don't wait past
|
||||||
the time when timed handlers need to be called */
|
the time when timed handlers need to be called */
|
||||||
next = handler_fire_timed(ctx);
|
next = handler_fire_timed(ctx);
|
||||||
@@ -217,7 +218,7 @@ void xmpp_run_once(xmpp_ctx_t *ctx, const unsigned long timeout)
|
|||||||
|
|
||||||
/* check for events */
|
/* check for events */
|
||||||
if (max > 0)
|
if (max > 0)
|
||||||
ret = select(max + 1, &rfds, &wfds, NULL, &tv);
|
ret = select(max + 1, &rfds, &wfds, NULL, &tv);
|
||||||
else {
|
else {
|
||||||
if (timeout > 0)
|
if (timeout > 0)
|
||||||
_sleep(timeout);
|
_sleep(timeout);
|
||||||
@@ -233,7 +234,8 @@ void xmpp_run_once(xmpp_ctx_t *ctx, const unsigned long timeout)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* no events happened */
|
/* no events happened */
|
||||||
if (ret == 0 && tls_read_bytes == 0) return;
|
if (ret == 0 && tls_read_bytes == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
/* process events */
|
/* process events */
|
||||||
connitem = ctx->connlist;
|
connitem = ctx->connlist;
|
||||||
@@ -261,29 +263,35 @@ void xmpp_run_once(xmpp_ctx_t *ctx, const unsigned long timeout)
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
case XMPP_STATE_CONNECTED:
|
case XMPP_STATE_CONNECTED:
|
||||||
if (FD_ISSET(conn->sock, &rfds) || (conn->tls && tls_pending(conn->tls))) {
|
if (FD_ISSET(conn->sock, &rfds) ||
|
||||||
|
(conn->tls && tls_pending(conn->tls))) {
|
||||||
if (conn->tls) {
|
if (conn->tls) {
|
||||||
ret = tls_read(conn->tls, buf, STROPE_MESSAGE_BUFFER_SIZE);
|
ret = tls_read(conn->tls, buf, STROPE_MESSAGE_BUFFER_SIZE);
|
||||||
} else {
|
} else {
|
||||||
ret = sock_read(conn->sock, buf, STROPE_MESSAGE_BUFFER_SIZE);
|
ret =
|
||||||
|
sock_read(conn->sock, buf, STROPE_MESSAGE_BUFFER_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret > 0) {
|
if (ret > 0) {
|
||||||
ret = parser_feed(conn->parser, buf, ret);
|
ret = parser_feed(conn->parser, buf, ret);
|
||||||
if (!ret) {
|
if (!ret) {
|
||||||
xmpp_debug(ctx, "xmpp", "parse error [%s]", buf);
|
xmpp_debug(ctx, "xmpp", "parse error [%s]", buf);
|
||||||
xmpp_send_error(conn, XMPP_SE_INVALID_XML, "parse error");
|
xmpp_send_error(conn, XMPP_SE_INVALID_XML,
|
||||||
|
"parse error");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (conn->tls) {
|
if (conn->tls) {
|
||||||
if (!tls_is_recoverable(tls_error(conn->tls))) {
|
if (!tls_is_recoverable(tls_error(conn->tls))) {
|
||||||
xmpp_debug(ctx, "xmpp", "Unrecoverable TLS error, %d.", tls_error(conn->tls));
|
xmpp_debug(ctx, "xmpp",
|
||||||
|
"Unrecoverable TLS error, %d.",
|
||||||
|
tls_error(conn->tls));
|
||||||
conn->error = tls_error(conn->tls);
|
conn->error = tls_error(conn->tls);
|
||||||
conn_disconnect(conn);
|
conn_disconnect(conn);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* return of 0 means socket closed by server */
|
/* return of 0 means socket closed by server */
|
||||||
xmpp_debug(ctx, "xmpp", "Socket closed by remote host.");
|
xmpp_debug(ctx, "xmpp",
|
||||||
|
"Socket closed by remote host.");
|
||||||
conn->error = ECONNRESET;
|
conn->error = ECONNRESET;
|
||||||
conn_disconnect(conn);
|
conn_disconnect(conn);
|
||||||
}
|
}
|
||||||
@@ -314,7 +322,8 @@ void xmpp_run_once(xmpp_ctx_t *ctx, const unsigned long timeout)
|
|||||||
*/
|
*/
|
||||||
void xmpp_run(xmpp_ctx_t *ctx)
|
void xmpp_run(xmpp_ctx_t *ctx)
|
||||||
{
|
{
|
||||||
if (ctx->loop_status != XMPP_LOOP_NOTSTARTED) return;
|
if (ctx->loop_status != XMPP_LOOP_NOTSTARTED)
|
||||||
|
return;
|
||||||
|
|
||||||
ctx->loop_status = XMPP_LOOP_RUNNING;
|
ctx->loop_status = XMPP_LOOP_RUNNING;
|
||||||
while (ctx->loop_status == XMPP_LOOP_RUNNING) {
|
while (ctx->loop_status == XMPP_LOOP_RUNNING) {
|
||||||
|
|||||||
155
src/handler.c
155
src/handler.c
@@ -33,8 +33,7 @@
|
|||||||
* TODO Convert handler lists to double-linked lists. Current implementation
|
* TODO Convert handler lists to double-linked lists. Current implementation
|
||||||
* works for O(n).
|
* works for O(n).
|
||||||
*/
|
*/
|
||||||
static void _handler_item_remove(xmpp_handlist_t **head,
|
static void _handler_item_remove(xmpp_handlist_t **head, xmpp_handlist_t *item)
|
||||||
xmpp_handlist_t *item)
|
|
||||||
{
|
{
|
||||||
xmpp_handlist_t *i = *head;
|
xmpp_handlist_t *i = *head;
|
||||||
|
|
||||||
@@ -56,8 +55,7 @@ static void _handler_item_remove(xmpp_handlist_t **head,
|
|||||||
* @param conn a Strophe connection object
|
* @param conn a Strophe connection object
|
||||||
* @param stanza a Strophe stanza object
|
* @param stanza a Strophe stanza object
|
||||||
*/
|
*/
|
||||||
void handler_fire_stanza(xmpp_conn_t * const conn,
|
void handler_fire_stanza(xmpp_conn_t *const conn, xmpp_stanza_t *const stanza)
|
||||||
xmpp_stanza_t * const stanza)
|
|
||||||
{
|
{
|
||||||
xmpp_handlist_t *item, *next, *head, *head_old;
|
xmpp_handlist_t *item, *next, *head, *head_old;
|
||||||
const char *id, *ns, *name, *type;
|
const char *id, *ns, *name, *type;
|
||||||
@@ -75,7 +73,8 @@ void handler_fire_stanza(xmpp_conn_t * const conn,
|
|||||||
while (item) {
|
while (item) {
|
||||||
/* don't fire user handlers until authentication succeeds and
|
/* don't fire user handlers until authentication succeeds and
|
||||||
and skip newly added handlers */
|
and skip newly added handlers */
|
||||||
if ((item->user_handler && !conn->authenticated) || !item->enabled) {
|
if ((item->user_handler && !conn->authenticated) ||
|
||||||
|
!item->enabled) {
|
||||||
item = item->next;
|
item = item->next;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -127,9 +126,12 @@ void handler_fire_stanza(xmpp_conn_t * const conn,
|
|||||||
if (!ret) {
|
if (!ret) {
|
||||||
/* handler is one-shot, so delete it */
|
/* handler is one-shot, so delete it */
|
||||||
_handler_item_remove(&conn->handlers, item);
|
_handler_item_remove(&conn->handlers, item);
|
||||||
if (item->u.ns) xmpp_free(conn->ctx, item->u.ns);
|
if (item->u.ns)
|
||||||
if (item->u.name) xmpp_free(conn->ctx, item->u.name);
|
xmpp_free(conn->ctx, item->u.ns);
|
||||||
if (item->u.type) xmpp_free(conn->ctx, item->u.type);
|
if (item->u.name)
|
||||||
|
xmpp_free(conn->ctx, item->u.name);
|
||||||
|
if (item->u.type)
|
||||||
|
xmpp_free(conn->ctx, item->u.type);
|
||||||
xmpp_free(conn->ctx, item);
|
xmpp_free(conn->ctx, item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -144,7 +146,7 @@ void handler_fire_stanza(xmpp_conn_t * const conn,
|
|||||||
*
|
*
|
||||||
* @return the time in milliseconds until the next handler will be ready
|
* @return the time in milliseconds until the next handler will be ready
|
||||||
*/
|
*/
|
||||||
uint64_t handler_fire_timed(xmpp_ctx_t * const ctx)
|
uint64_t handler_fire_timed(xmpp_ctx_t *const ctx)
|
||||||
{
|
{
|
||||||
xmpp_connlist_t *connitem;
|
xmpp_connlist_t *connitem;
|
||||||
xmpp_handlist_t *item, *next;
|
xmpp_handlist_t *item, *next;
|
||||||
@@ -171,7 +173,8 @@ uint64_t handler_fire_timed(xmpp_ctx_t * const ctx)
|
|||||||
while (item) {
|
while (item) {
|
||||||
/* don't fire user handlers until authentication succeeds and
|
/* don't fire user handlers until authentication succeeds and
|
||||||
skip newly added handlers */
|
skip newly added handlers */
|
||||||
if ((item->user_handler && !conn->authenticated) || !item->enabled) {
|
if ((item->user_handler && !conn->authenticated) ||
|
||||||
|
!item->enabled) {
|
||||||
item = item->next;
|
item = item->next;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -221,10 +224,10 @@ void handler_reset_timed(xmpp_conn_t *conn, int user_only)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _timed_handler_add(xmpp_conn_t * const conn,
|
static void _timed_handler_add(xmpp_conn_t *const conn,
|
||||||
xmpp_timed_handler handler,
|
xmpp_timed_handler handler,
|
||||||
const unsigned long period,
|
const unsigned long period,
|
||||||
void * const userdata,
|
void *const userdata,
|
||||||
const int user_handler)
|
const int user_handler)
|
||||||
{
|
{
|
||||||
xmpp_handlist_t *item, *tail;
|
xmpp_handlist_t *item, *tail;
|
||||||
@@ -236,11 +239,13 @@ static void _timed_handler_add(xmpp_conn_t * const conn,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (item) return;
|
if (item)
|
||||||
|
return;
|
||||||
|
|
||||||
/* build new item */
|
/* build new item */
|
||||||
item = xmpp_alloc(conn->ctx, sizeof(xmpp_handlist_t));
|
item = xmpp_alloc(conn->ctx, sizeof(xmpp_handlist_t));
|
||||||
if (!item) return;
|
if (!item)
|
||||||
|
return;
|
||||||
|
|
||||||
item->user_handler = user_handler;
|
item->user_handler = user_handler;
|
||||||
item->handler = handler;
|
item->handler = handler;
|
||||||
@@ -269,12 +274,13 @@ static void _timed_handler_add(xmpp_conn_t * const conn,
|
|||||||
*
|
*
|
||||||
* @ingroup Handlers
|
* @ingroup Handlers
|
||||||
*/
|
*/
|
||||||
void xmpp_timed_handler_delete(xmpp_conn_t * const conn,
|
void xmpp_timed_handler_delete(xmpp_conn_t *const conn,
|
||||||
xmpp_timed_handler handler)
|
xmpp_timed_handler handler)
|
||||||
{
|
{
|
||||||
xmpp_handlist_t *item, *prev;
|
xmpp_handlist_t *item, *prev;
|
||||||
|
|
||||||
if (!conn->timed_handlers) return;
|
if (!conn->timed_handlers)
|
||||||
|
return;
|
||||||
|
|
||||||
prev = NULL;
|
prev = NULL;
|
||||||
item = conn->timed_handlers;
|
item = conn->timed_handlers;
|
||||||
@@ -294,10 +300,11 @@ void xmpp_timed_handler_delete(xmpp_conn_t * const conn,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _id_handler_add(xmpp_conn_t * const conn,
|
static void _id_handler_add(xmpp_conn_t *const conn,
|
||||||
xmpp_handler handler,
|
xmpp_handler handler,
|
||||||
const char * const id,
|
const char *const id,
|
||||||
void * const userdata, int user_handler)
|
void *const userdata,
|
||||||
|
int user_handler)
|
||||||
{
|
{
|
||||||
xmpp_handlist_t *item, *tail;
|
xmpp_handlist_t *item, *tail;
|
||||||
|
|
||||||
@@ -310,11 +317,13 @@ static void _id_handler_add(xmpp_conn_t * const conn,
|
|||||||
}
|
}
|
||||||
item = item->next;
|
item = item->next;
|
||||||
}
|
}
|
||||||
if (item) return;
|
if (item)
|
||||||
|
return;
|
||||||
|
|
||||||
/* build new item */
|
/* build new item */
|
||||||
item = xmpp_alloc(conn->ctx, sizeof(xmpp_handlist_t));
|
item = xmpp_alloc(conn->ctx, sizeof(xmpp_handlist_t));
|
||||||
if (!item) return;
|
if (!item)
|
||||||
|
return;
|
||||||
|
|
||||||
item->user_handler = user_handler;
|
item->user_handler = user_handler;
|
||||||
item->handler = handler;
|
item->handler = handler;
|
||||||
@@ -347,15 +356,16 @@ static void _id_handler_add(xmpp_conn_t * const conn,
|
|||||||
*
|
*
|
||||||
* @ingroup Handlers
|
* @ingroup Handlers
|
||||||
*/
|
*/
|
||||||
void xmpp_id_handler_delete(xmpp_conn_t * const conn,
|
void xmpp_id_handler_delete(xmpp_conn_t *const conn,
|
||||||
xmpp_handler handler,
|
xmpp_handler handler,
|
||||||
const char * const id)
|
const char *const id)
|
||||||
{
|
{
|
||||||
xmpp_handlist_t *item, *prev, *next;
|
xmpp_handlist_t *item, *prev, *next;
|
||||||
|
|
||||||
prev = NULL;
|
prev = NULL;
|
||||||
item = (xmpp_handlist_t *)hash_get(conn->id_handlers, id);
|
item = (xmpp_handlist_t *)hash_get(conn->id_handlers, id);
|
||||||
if (!item) return;
|
if (!item)
|
||||||
|
return;
|
||||||
|
|
||||||
while (item) {
|
while (item) {
|
||||||
next = item->next;
|
next = item->next;
|
||||||
@@ -379,12 +389,13 @@ void xmpp_id_handler_delete(xmpp_conn_t * const conn,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* add a stanza handler */
|
/* add a stanza handler */
|
||||||
static void _handler_add(xmpp_conn_t * const conn,
|
static void _handler_add(xmpp_conn_t *const conn,
|
||||||
xmpp_handler handler,
|
xmpp_handler handler,
|
||||||
const char * const ns,
|
const char *const ns,
|
||||||
const char * const name,
|
const char *const name,
|
||||||
const char * const type,
|
const char *const type,
|
||||||
void * const userdata, int user_handler)
|
void *const userdata,
|
||||||
|
int user_handler)
|
||||||
{
|
{
|
||||||
xmpp_handlist_t *item, *tail;
|
xmpp_handlist_t *item, *tail;
|
||||||
|
|
||||||
@@ -397,11 +408,13 @@ static void _handler_add(xmpp_conn_t * const conn,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (item) return;
|
if (item)
|
||||||
|
return;
|
||||||
|
|
||||||
/* build new item */
|
/* build new item */
|
||||||
item = (xmpp_handlist_t *)xmpp_alloc(conn->ctx, sizeof(xmpp_handlist_t));
|
item = (xmpp_handlist_t *)xmpp_alloc(conn->ctx, sizeof(xmpp_handlist_t));
|
||||||
if (!item) return;
|
if (!item)
|
||||||
|
return;
|
||||||
|
|
||||||
item->user_handler = user_handler;
|
item->user_handler = user_handler;
|
||||||
item->handler = handler;
|
item->handler = handler;
|
||||||
@@ -417,20 +430,25 @@ static void _handler_add(xmpp_conn_t * const conn,
|
|||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
item->u.ns = NULL;
|
item->u.ns = NULL;
|
||||||
|
|
||||||
if (name) {
|
if (name) {
|
||||||
item->u.name = xmpp_strdup(conn->ctx, name);
|
item->u.name = xmpp_strdup(conn->ctx, name);
|
||||||
if (!item->u.name) {
|
if (!item->u.name) {
|
||||||
if (item->u.ns) xmpp_free(conn->ctx, item->u.ns);
|
if (item->u.ns)
|
||||||
|
xmpp_free(conn->ctx, item->u.ns);
|
||||||
xmpp_free(conn->ctx, item);
|
xmpp_free(conn->ctx, item);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
item->u.name = NULL;
|
item->u.name = NULL;
|
||||||
|
|
||||||
if (type) {
|
if (type) {
|
||||||
item->u.type = xmpp_strdup(conn->ctx, type);
|
item->u.type = xmpp_strdup(conn->ctx, type);
|
||||||
if (!item->u.type) {
|
if (!item->u.type) {
|
||||||
if (item->u.ns) xmpp_free(conn->ctx, item->u.ns);
|
if (item->u.ns)
|
||||||
if (item->u.name) xmpp_free(conn->ctx, item->u.name);
|
xmpp_free(conn->ctx, item->u.ns);
|
||||||
|
if (item->u.name)
|
||||||
|
xmpp_free(conn->ctx, item->u.name);
|
||||||
xmpp_free(conn->ctx, item);
|
xmpp_free(conn->ctx, item);
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
@@ -454,12 +472,12 @@ static void _handler_add(xmpp_conn_t * const conn,
|
|||||||
*
|
*
|
||||||
* @ingroup Handlers
|
* @ingroup Handlers
|
||||||
*/
|
*/
|
||||||
void xmpp_handler_delete(xmpp_conn_t * const conn,
|
void xmpp_handler_delete(xmpp_conn_t *const conn, xmpp_handler handler)
|
||||||
xmpp_handler handler)
|
|
||||||
{
|
{
|
||||||
xmpp_handlist_t *prev, *item;
|
xmpp_handlist_t *prev, *item;
|
||||||
|
|
||||||
if (!conn->handlers) return;
|
if (!conn->handlers)
|
||||||
|
return;
|
||||||
|
|
||||||
prev = NULL;
|
prev = NULL;
|
||||||
item = conn->handlers;
|
item = conn->handlers;
|
||||||
@@ -470,9 +488,12 @@ void xmpp_handler_delete(xmpp_conn_t * const conn,
|
|||||||
else
|
else
|
||||||
conn->handlers = item->next;
|
conn->handlers = item->next;
|
||||||
|
|
||||||
if (item->u.ns) xmpp_free(conn->ctx, item->u.ns);
|
if (item->u.ns)
|
||||||
if (item->u.name) xmpp_free(conn->ctx, item->u.name);
|
xmpp_free(conn->ctx, item->u.ns);
|
||||||
if (item->u.type) xmpp_free(conn->ctx, item->u.type);
|
if (item->u.name)
|
||||||
|
xmpp_free(conn->ctx, item->u.name);
|
||||||
|
if (item->u.type)
|
||||||
|
xmpp_free(conn->ctx, item->u.type);
|
||||||
xmpp_free(conn->ctx, item);
|
xmpp_free(conn->ctx, item);
|
||||||
item = prev ? prev->next : conn->handlers;
|
item = prev ? prev->next : conn->handlers;
|
||||||
} else {
|
} else {
|
||||||
@@ -498,10 +519,10 @@ void xmpp_handler_delete(xmpp_conn_t * const conn,
|
|||||||
*
|
*
|
||||||
* @ingroup Handlers
|
* @ingroup Handlers
|
||||||
*/
|
*/
|
||||||
void xmpp_timed_handler_add(xmpp_conn_t * const conn,
|
void xmpp_timed_handler_add(xmpp_conn_t *const conn,
|
||||||
xmpp_timed_handler handler,
|
xmpp_timed_handler handler,
|
||||||
const unsigned long period,
|
const unsigned long period,
|
||||||
void * const userdata)
|
void *const userdata)
|
||||||
{
|
{
|
||||||
_timed_handler_add(conn, handler, period, userdata, 1);
|
_timed_handler_add(conn, handler, period, userdata, 1);
|
||||||
}
|
}
|
||||||
@@ -515,10 +536,10 @@ void xmpp_timed_handler_add(xmpp_conn_t * const conn,
|
|||||||
* @param period the time in milliseconds between firings
|
* @param period the time in milliseconds between firings
|
||||||
* @param userdata an opaque data pointer that will be passed to the handler
|
* @param userdata an opaque data pointer that will be passed to the handler
|
||||||
*/
|
*/
|
||||||
void handler_add_timed(xmpp_conn_t * const conn,
|
void handler_add_timed(xmpp_conn_t *const conn,
|
||||||
xmpp_timed_handler handler,
|
xmpp_timed_handler handler,
|
||||||
const unsigned long period,
|
const unsigned long period,
|
||||||
void * const userdata)
|
void *const userdata)
|
||||||
{
|
{
|
||||||
_timed_handler_add(conn, handler, period, userdata, 0);
|
_timed_handler_add(conn, handler, period, userdata, 0);
|
||||||
}
|
}
|
||||||
@@ -539,10 +560,10 @@ void handler_add_timed(xmpp_conn_t * const conn,
|
|||||||
*
|
*
|
||||||
* @ingroup Handlers
|
* @ingroup Handlers
|
||||||
*/
|
*/
|
||||||
void xmpp_id_handler_add(xmpp_conn_t * const conn,
|
void xmpp_id_handler_add(xmpp_conn_t *const conn,
|
||||||
xmpp_handler handler,
|
xmpp_handler handler,
|
||||||
const char * const id,
|
const char *const id,
|
||||||
void * const userdata)
|
void *const userdata)
|
||||||
{
|
{
|
||||||
_id_handler_add(conn, handler, id, userdata, 1);
|
_id_handler_add(conn, handler, id, userdata, 1);
|
||||||
}
|
}
|
||||||
@@ -556,10 +577,10 @@ void xmpp_id_handler_add(xmpp_conn_t * const conn,
|
|||||||
* @param id a string with the id
|
* @param id a string with the id
|
||||||
* @param userdata an opaque data pointer that will be passed to the handler
|
* @param userdata an opaque data pointer that will be passed to the handler
|
||||||
*/
|
*/
|
||||||
void handler_add_id(xmpp_conn_t * const conn,
|
void handler_add_id(xmpp_conn_t *const conn,
|
||||||
xmpp_handler handler,
|
xmpp_handler handler,
|
||||||
const char * const id,
|
const char *const id,
|
||||||
void * const userdata)
|
void *const userdata)
|
||||||
{
|
{
|
||||||
_id_handler_add(conn, handler, id, userdata, 0);
|
_id_handler_add(conn, handler, id, userdata, 0);
|
||||||
}
|
}
|
||||||
@@ -586,12 +607,12 @@ void handler_add_id(xmpp_conn_t * const conn,
|
|||||||
*
|
*
|
||||||
* @ingroup Handlers
|
* @ingroup Handlers
|
||||||
*/
|
*/
|
||||||
void xmpp_handler_add(xmpp_conn_t * const conn,
|
void xmpp_handler_add(xmpp_conn_t *const conn,
|
||||||
xmpp_handler handler,
|
xmpp_handler handler,
|
||||||
const char * const ns,
|
const char *const ns,
|
||||||
const char * const name,
|
const char *const name,
|
||||||
const char * const type,
|
const char *const type,
|
||||||
void * const userdata)
|
void *const userdata)
|
||||||
{
|
{
|
||||||
_handler_add(conn, handler, ns, name, type, userdata, 1);
|
_handler_add(conn, handler, ns, name, type, userdata, 1);
|
||||||
}
|
}
|
||||||
@@ -607,12 +628,12 @@ void xmpp_handler_add(xmpp_conn_t * const conn,
|
|||||||
* @param type a string with the 'type' attribute value to match
|
* @param type a string with the 'type' attribute value to match
|
||||||
* @param userdata an opaque data pointer that will be passed to the handler
|
* @param userdata an opaque data pointer that will be passed to the handler
|
||||||
*/
|
*/
|
||||||
void handler_add(xmpp_conn_t * const conn,
|
void handler_add(xmpp_conn_t *const conn,
|
||||||
xmpp_handler handler,
|
xmpp_handler handler,
|
||||||
const char * const ns,
|
const char *const ns,
|
||||||
const char * const name,
|
const char *const name,
|
||||||
const char * const type,
|
const char *const type,
|
||||||
void * const userdata)
|
void *const userdata)
|
||||||
{
|
{
|
||||||
_handler_add(conn, handler, ns, name, type, userdata, 0);
|
_handler_add(conn, handler, ns, name, type, userdata, 0);
|
||||||
}
|
}
|
||||||
@@ -636,9 +657,12 @@ void handler_system_delete_all(xmpp_conn_t *conn)
|
|||||||
if (!item->user_handler) {
|
if (!item->user_handler) {
|
||||||
next = item->next;
|
next = item->next;
|
||||||
_handler_item_remove(&conn->handlers, item);
|
_handler_item_remove(&conn->handlers, item);
|
||||||
if (item->u.ns) xmpp_free(conn->ctx, item->u.ns);
|
if (item->u.ns)
|
||||||
if (item->u.name) xmpp_free(conn->ctx, item->u.name);
|
xmpp_free(conn->ctx, item->u.ns);
|
||||||
if (item->u.type) xmpp_free(conn->ctx, item->u.type);
|
if (item->u.name)
|
||||||
|
xmpp_free(conn->ctx, item->u.name);
|
||||||
|
if (item->u.type)
|
||||||
|
xmpp_free(conn->ctx, item->u.type);
|
||||||
xmpp_free(conn->ctx, item);
|
xmpp_free(conn->ctx, item);
|
||||||
item = next;
|
item = next;
|
||||||
} else
|
} else
|
||||||
@@ -686,5 +710,6 @@ void handler_system_delete_all(xmpp_conn_t *conn)
|
|||||||
xmpp_free(conn->ctx, key2);
|
xmpp_free(conn->ctx, key2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (iter) hash_iter_release(iter);
|
if (iter)
|
||||||
|
hash_iter_release(iter);
|
||||||
}
|
}
|
||||||
|
|||||||
257
src/hash.c
257
src/hash.c
@@ -46,171 +46,176 @@ struct _hash_iterator_t {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/** allocate and initialize a new hash table */
|
/** allocate and initialize a new hash table */
|
||||||
hash_t *hash_new(xmpp_ctx_t * const ctx, const int size,
|
hash_t *
|
||||||
hash_free_func free_func)
|
hash_new(xmpp_ctx_t *const ctx, const int size, hash_free_func free_func)
|
||||||
{
|
{
|
||||||
hash_t *result = NULL;
|
hash_t *result = NULL;
|
||||||
|
|
||||||
result = xmpp_alloc(ctx, sizeof(hash_t));
|
result = xmpp_alloc(ctx, sizeof(hash_t));
|
||||||
if (result != NULL) {
|
if (result != NULL) {
|
||||||
result->entries = xmpp_alloc(ctx, size * sizeof(hashentry_t *));
|
result->entries = xmpp_alloc(ctx, size * sizeof(hashentry_t *));
|
||||||
if (result->entries == NULL) {
|
if (result->entries == NULL) {
|
||||||
xmpp_free(ctx, result);
|
xmpp_free(ctx, result);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
memset(result->entries, 0, size * sizeof(hashentry_t *));
|
memset(result->entries, 0, size * sizeof(hashentry_t *));
|
||||||
result->length = size;
|
result->length = size;
|
||||||
|
|
||||||
result->ctx = ctx;
|
result->ctx = ctx;
|
||||||
result->free = free_func;
|
result->free = free_func;
|
||||||
result->num_keys = 0;
|
result->num_keys = 0;
|
||||||
/* give the caller a reference */
|
/* give the caller a reference */
|
||||||
result->ref = 1;
|
result->ref = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** obtain a new reference to an existing hash table */
|
/** obtain a new reference to an existing hash table */
|
||||||
hash_t *hash_clone(hash_t * const table)
|
hash_t *hash_clone(hash_t *const table)
|
||||||
{
|
{
|
||||||
table->ref++;
|
table->ref++;
|
||||||
return table;
|
return table;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** release a hash table that is no longer needed */
|
/** release a hash table that is no longer needed */
|
||||||
void hash_release(hash_t * const table)
|
void hash_release(hash_t *const table)
|
||||||
{
|
{
|
||||||
xmpp_ctx_t *ctx = table->ctx;
|
xmpp_ctx_t *ctx = table->ctx;
|
||||||
hashentry_t *entry, *next;
|
hashentry_t *entry, *next;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (table->ref > 1)
|
if (table->ref > 1)
|
||||||
table->ref--;
|
table->ref--;
|
||||||
else {
|
else {
|
||||||
for (i = 0; i < table->length; i++) {
|
for (i = 0; i < table->length; i++) {
|
||||||
entry = table->entries[i];
|
entry = table->entries[i];
|
||||||
while (entry != NULL) {
|
while (entry != NULL) {
|
||||||
next = entry->next;
|
next = entry->next;
|
||||||
xmpp_free(ctx, entry->key);
|
xmpp_free(ctx, entry->key);
|
||||||
if (table->free) table->free(ctx, entry->value);
|
if (table->free)
|
||||||
xmpp_free(ctx, entry);
|
table->free(ctx, entry->value);
|
||||||
entry = next;
|
xmpp_free(ctx, entry);
|
||||||
}
|
entry = next;
|
||||||
}
|
}
|
||||||
xmpp_free(ctx, table->entries);
|
}
|
||||||
xmpp_free(ctx, table);
|
xmpp_free(ctx, table->entries);
|
||||||
|
xmpp_free(ctx, table);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** hash a key for our table lookup */
|
/** hash a key for our table lookup */
|
||||||
static int _hash_key(hash_t *table, const char *key)
|
static int _hash_key(hash_t *table, const char *key)
|
||||||
{
|
{
|
||||||
unsigned hash = 0;
|
unsigned hash = 0;
|
||||||
unsigned shift = 0;
|
unsigned shift = 0;
|
||||||
const unsigned char *c = (const unsigned char *)key;
|
const unsigned char *c = (const unsigned char *)key;
|
||||||
|
|
||||||
while (*c != 0) {
|
while (*c != 0) {
|
||||||
/* assume 32 bit ints */
|
/* assume 32 bit ints */
|
||||||
hash ^= ((unsigned)*c++ << shift);
|
hash ^= ((unsigned)*c++ << shift);
|
||||||
shift += 8;
|
shift += 8;
|
||||||
if (shift > 24) shift = 0;
|
if (shift > 24)
|
||||||
}
|
shift = 0;
|
||||||
return hash % (unsigned)table->length;
|
}
|
||||||
|
return hash % (unsigned)table->length;
|
||||||
}
|
}
|
||||||
|
|
||||||
hashentry_t *_hash_entry_find(hash_t *table, const char *key)
|
hashentry_t *_hash_entry_find(hash_t *table, const char *key)
|
||||||
{
|
{
|
||||||
hashentry_t *entry;
|
hashentry_t *entry;
|
||||||
int table_index = _hash_key(table, key);
|
int table_index = _hash_key(table, key);
|
||||||
|
|
||||||
/* look up the hash entry */
|
/* look up the hash entry */
|
||||||
entry = table->entries[table_index];
|
entry = table->entries[table_index];
|
||||||
while (entry != NULL) {
|
while (entry != NULL) {
|
||||||
/* traverse the linked list looking for the key */
|
/* traverse the linked list looking for the key */
|
||||||
if (!strcmp(key, entry->key)) {
|
if (!strcmp(key, entry->key)) {
|
||||||
/* match */
|
/* match */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
entry = entry->next;
|
entry = entry->next;
|
||||||
}
|
}
|
||||||
return entry;
|
return entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** add a key, value pair to a hash table.
|
/** add a key, value pair to a hash table.
|
||||||
* each key can appear only once; the value of any
|
* each key can appear only once; the value of any
|
||||||
* identical key will be replaced
|
* identical key will be replaced
|
||||||
*/
|
*/
|
||||||
int hash_add(hash_t *table, const char * const key, void *data)
|
int hash_add(hash_t *table, const char *const key, void *data)
|
||||||
{
|
{
|
||||||
xmpp_ctx_t *ctx = table->ctx;
|
xmpp_ctx_t *ctx = table->ctx;
|
||||||
hashentry_t *entry = NULL;
|
hashentry_t *entry = NULL;
|
||||||
int table_index = _hash_key(table, key);
|
int table_index = _hash_key(table, key);
|
||||||
|
|
||||||
/* find and replace existing entry, if any */
|
/* find and replace existing entry, if any */
|
||||||
entry = _hash_entry_find(table, key);
|
entry = _hash_entry_find(table, key);
|
||||||
|
|
||||||
if (entry == NULL) {
|
if (entry == NULL) {
|
||||||
/* allocate and fill a new entry */
|
/* allocate and fill a new entry */
|
||||||
entry = xmpp_alloc(ctx, sizeof(hashentry_t));
|
entry = xmpp_alloc(ctx, sizeof(hashentry_t));
|
||||||
if (!entry) return -1;
|
if (!entry)
|
||||||
entry->key = xmpp_strdup(ctx, key);
|
return -1;
|
||||||
if (!entry->key) {
|
entry->key = xmpp_strdup(ctx, key);
|
||||||
xmpp_free(ctx, entry);
|
if (!entry->key) {
|
||||||
return -1;
|
xmpp_free(ctx, entry);
|
||||||
}
|
return -1;
|
||||||
/* insert ourselves in the linked list */
|
}
|
||||||
entry->next = table->entries[table_index];
|
/* insert ourselves in the linked list */
|
||||||
table->entries[table_index] = entry;
|
entry->next = table->entries[table_index];
|
||||||
table->num_keys++;
|
table->entries[table_index] = entry;
|
||||||
} else {
|
table->num_keys++;
|
||||||
if (table->free) table->free(ctx, entry->value);
|
} else {
|
||||||
}
|
if (table->free)
|
||||||
|
table->free(ctx, entry->value);
|
||||||
|
}
|
||||||
|
|
||||||
entry->value = data;
|
entry->value = data;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** look up a key in a hash table */
|
/** look up a key in a hash table */
|
||||||
void *hash_get(hash_t *table, const char *key)
|
void *hash_get(hash_t *table, const char *key)
|
||||||
{
|
{
|
||||||
hashentry_t *entry;
|
hashentry_t *entry;
|
||||||
|
|
||||||
entry = _hash_entry_find(table, key);
|
entry = _hash_entry_find(table, key);
|
||||||
return entry == NULL ? NULL : entry->value;
|
return entry == NULL ? NULL : entry->value;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** delete a key from a hash table */
|
/** delete a key from a hash table */
|
||||||
int hash_drop(hash_t *table, const char *key)
|
int hash_drop(hash_t *table, const char *key)
|
||||||
{
|
{
|
||||||
xmpp_ctx_t *ctx = table->ctx;
|
xmpp_ctx_t *ctx = table->ctx;
|
||||||
hashentry_t *entry, *prev;
|
hashentry_t *entry, *prev;
|
||||||
int table_index = _hash_key(table, key);
|
int table_index = _hash_key(table, key);
|
||||||
|
|
||||||
/* look up the hash entry */
|
/* look up the hash entry */
|
||||||
entry = table->entries[table_index];
|
entry = table->entries[table_index];
|
||||||
prev = NULL;
|
prev = NULL;
|
||||||
while (entry != NULL) {
|
while (entry != NULL) {
|
||||||
/* traverse the linked list looking for the key */
|
/* traverse the linked list looking for the key */
|
||||||
if (!strcmp(key, entry->key)) {
|
if (!strcmp(key, entry->key)) {
|
||||||
/* match, remove the entry */
|
/* match, remove the entry */
|
||||||
xmpp_free(ctx, entry->key);
|
xmpp_free(ctx, entry->key);
|
||||||
if (table->free) table->free(ctx, entry->value);
|
if (table->free)
|
||||||
if (prev == NULL) {
|
table->free(ctx, entry->value);
|
||||||
table->entries[table_index] = entry->next;
|
if (prev == NULL) {
|
||||||
} else {
|
table->entries[table_index] = entry->next;
|
||||||
prev->next = entry->next;
|
} else {
|
||||||
}
|
prev->next = entry->next;
|
||||||
xmpp_free(ctx, entry);
|
}
|
||||||
table->num_keys--;
|
xmpp_free(ctx, entry);
|
||||||
return 0;
|
table->num_keys--;
|
||||||
}
|
return 0;
|
||||||
prev = entry;
|
}
|
||||||
entry = entry->next;
|
prev = entry;
|
||||||
}
|
entry = entry->next;
|
||||||
/* no match */
|
}
|
||||||
return -1;
|
/* no match */
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int hash_num_keys(hash_t *table)
|
int hash_num_keys(hash_t *table)
|
||||||
@@ -226,16 +231,15 @@ hash_iterator_t *hash_iter_new(hash_t *table)
|
|||||||
|
|
||||||
iter = xmpp_alloc(ctx, sizeof(*iter));
|
iter = xmpp_alloc(ctx, sizeof(*iter));
|
||||||
if (iter != NULL) {
|
if (iter != NULL) {
|
||||||
iter->ref = 1;
|
iter->ref = 1;
|
||||||
iter->table = hash_clone(table);
|
iter->table = hash_clone(table);
|
||||||
iter->entry = NULL;
|
iter->entry = NULL;
|
||||||
iter->index = -1;
|
iter->index = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return iter;
|
return iter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** release an iterator that is no longer needed */
|
/** release an iterator that is no longer needed */
|
||||||
void hash_iter_release(hash_iterator_t *iter)
|
void hash_iter_release(hash_iterator_t *iter)
|
||||||
{
|
{
|
||||||
@@ -244,37 +248,38 @@ void hash_iter_release(hash_iterator_t *iter)
|
|||||||
iter->ref--;
|
iter->ref--;
|
||||||
|
|
||||||
if (iter->ref == 0) { // ref is unsigned!!!
|
if (iter->ref == 0) { // ref is unsigned!!!
|
||||||
hash_release(iter->table);
|
hash_release(iter->table);
|
||||||
xmpp_free(ctx, iter);
|
xmpp_free(ctx, iter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** return the next hash table key from the iterator.
|
/** return the next hash table key from the iterator.
|
||||||
the returned key should not be freed */
|
the returned key should not be freed */
|
||||||
const char * hash_iter_next(hash_iterator_t *iter)
|
const char *hash_iter_next(hash_iterator_t *iter)
|
||||||
{
|
{
|
||||||
hash_t *table = iter->table;
|
hash_t *table = iter->table;
|
||||||
hashentry_t *entry = iter->entry;
|
hashentry_t *entry = iter->entry;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
/* advance until we find the next entry */
|
/* advance until we find the next entry */
|
||||||
if (entry != NULL) entry = entry->next;
|
if (entry != NULL)
|
||||||
|
entry = entry->next;
|
||||||
if (entry == NULL) {
|
if (entry == NULL) {
|
||||||
/* we're off the end of list, search for a new entry */
|
/* we're off the end of list, search for a new entry */
|
||||||
i = iter->index + 1;
|
i = iter->index + 1;
|
||||||
while (i < iter->table->length) {
|
while (i < iter->table->length) {
|
||||||
entry = table->entries[i];
|
entry = table->entries[i];
|
||||||
if (entry != NULL) {
|
if (entry != NULL) {
|
||||||
iter->index = i;
|
iter->index = i;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (entry == NULL) {
|
if (entry == NULL) {
|
||||||
/* no more keys! */
|
/* no more keys! */
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* remember our current match */
|
/* remember our current match */
|
||||||
|
|||||||
18
src/hash.h
18
src/hash.h
@@ -1,7 +1,7 @@
|
|||||||
/* hash.h
|
/* hash.h
|
||||||
** strophe XMPP client library -- hash table interface
|
** strophe XMPP client library -- hash table interface
|
||||||
**
|
**
|
||||||
** Copyright (C) 2005-2009 Collecta, Inc.
|
** Copyright (C) 2005-2009 Collecta, Inc.
|
||||||
**
|
**
|
||||||
** This software is provided AS-IS with no warranty, either express
|
** This software is provided AS-IS with no warranty, either express
|
||||||
** or implied.
|
** or implied.
|
||||||
@@ -18,23 +18,23 @@
|
|||||||
|
|
||||||
typedef struct _hash_t hash_t;
|
typedef struct _hash_t hash_t;
|
||||||
|
|
||||||
typedef void (*hash_free_func)(const xmpp_ctx_t * const ctx, void *p);
|
typedef void (*hash_free_func)(const xmpp_ctx_t *const ctx, void *p);
|
||||||
|
|
||||||
/** allocate and initialize a new hash table */
|
/** allocate and initialize a new hash table */
|
||||||
hash_t *hash_new(xmpp_ctx_t * const ctx, const int size,
|
hash_t *
|
||||||
hash_free_func free_func);
|
hash_new(xmpp_ctx_t *const ctx, const int size, hash_free_func free_func);
|
||||||
|
|
||||||
/** allocate a new reference to an existing hash table */
|
/** allocate a new reference to an existing hash table */
|
||||||
hash_t *hash_clone(hash_t * const table);
|
hash_t *hash_clone(hash_t *const table);
|
||||||
|
|
||||||
/** release a hash table when no longer needed */
|
/** release a hash table when no longer needed */
|
||||||
void hash_release(hash_t * const table);
|
void hash_release(hash_t *const table);
|
||||||
|
|
||||||
/** add a key, value pair to a hash table.
|
/** add a key, value pair to a hash table.
|
||||||
* each key can appear only once; the value of any
|
* each key can appear only once; the value of any
|
||||||
* identical key will be replaced
|
* identical key will be replaced
|
||||||
*/
|
*/
|
||||||
int hash_add(hash_t *table, const char * const key, void *data);
|
int hash_add(hash_t *table, const char *const key, void *data);
|
||||||
|
|
||||||
/** look up a key in a hash table */
|
/** look up a key in a hash table */
|
||||||
void *hash_get(hash_t *table, const char *key);
|
void *hash_get(hash_t *table, const char *key);
|
||||||
@@ -56,6 +56,6 @@ void hash_iter_release(hash_iterator_t *iter);
|
|||||||
|
|
||||||
/** return the next hash table key from the iterator.
|
/** return the next hash table key from the iterator.
|
||||||
the returned key should not be freed */
|
the returned key should not be freed */
|
||||||
const char * hash_iter_next(hash_iterator_t *iter);
|
const char *hash_iter_next(hash_iterator_t *iter);
|
||||||
|
|
||||||
#endif /* __LIBXMPPP_HASH_H__ */
|
#endif /* __LIBXMPPP_HASH_H__ */
|
||||||
|
|||||||
54
src/jid.c
54
src/jid.c
@@ -28,15 +28,17 @@
|
|||||||
* @return an allocated string with the full JID or NULL if no domain
|
* @return an allocated string with the full JID or NULL if no domain
|
||||||
* is specified
|
* is specified
|
||||||
*/
|
*/
|
||||||
char *xmpp_jid_new(xmpp_ctx_t *ctx, const char *node,
|
char *xmpp_jid_new(xmpp_ctx_t *ctx,
|
||||||
const char *domain,
|
const char *node,
|
||||||
const char *resource)
|
const char *domain,
|
||||||
|
const char *resource)
|
||||||
{
|
{
|
||||||
char *result;
|
char *result;
|
||||||
size_t len, nlen, dlen, rlen;
|
size_t len, nlen, dlen, rlen;
|
||||||
|
|
||||||
/* jid must at least have a domain */
|
/* jid must at least have a domain */
|
||||||
if (domain == NULL) return NULL;
|
if (domain == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
/* accumulate lengths */
|
/* accumulate lengths */
|
||||||
dlen = strlen(domain);
|
dlen = strlen(domain);
|
||||||
@@ -47,16 +49,16 @@ char *xmpp_jid_new(xmpp_ctx_t *ctx, const char *node,
|
|||||||
/* concat components */
|
/* concat components */
|
||||||
result = xmpp_alloc(ctx, len + 1);
|
result = xmpp_alloc(ctx, len + 1);
|
||||||
if (result != NULL) {
|
if (result != NULL) {
|
||||||
if (node != NULL) {
|
if (node != NULL) {
|
||||||
memcpy(result, node, nlen - 1);
|
memcpy(result, node, nlen - 1);
|
||||||
result[nlen-1] = '@';
|
result[nlen - 1] = '@';
|
||||||
}
|
}
|
||||||
memcpy(result + nlen, domain, dlen);
|
memcpy(result + nlen, domain, dlen);
|
||||||
if (resource != NULL) {
|
if (resource != NULL) {
|
||||||
result[nlen+dlen] = '/';
|
result[nlen + dlen] = '/';
|
||||||
memcpy(result+nlen+dlen+1, resource, rlen - 1);
|
memcpy(result + nlen + dlen + 1, resource, rlen - 1);
|
||||||
}
|
}
|
||||||
result[len] = '\0';
|
result[len] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
@@ -77,8 +79,8 @@ char *xmpp_jid_bare(xmpp_ctx_t *ctx, const char *jid)
|
|||||||
len = strcspn(jid, "/");
|
len = strcspn(jid, "/");
|
||||||
result = xmpp_alloc(ctx, len + 1);
|
result = xmpp_alloc(ctx, len + 1);
|
||||||
if (result != NULL) {
|
if (result != NULL) {
|
||||||
memcpy(result, jid, len);
|
memcpy(result, jid, len);
|
||||||
result[len] = '\0';
|
result[len] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
@@ -99,11 +101,11 @@ char *xmpp_jid_node(xmpp_ctx_t *ctx, const char *jid)
|
|||||||
|
|
||||||
c = strchr(jid, '@');
|
c = strchr(jid, '@');
|
||||||
if (c != NULL) {
|
if (c != NULL) {
|
||||||
result = xmpp_alloc(ctx, (c-jid) + 1);
|
result = xmpp_alloc(ctx, (c - jid) + 1);
|
||||||
if (result != NULL) {
|
if (result != NULL) {
|
||||||
memcpy(result, jid, (c-jid));
|
memcpy(result, jid, (c - jid));
|
||||||
result[c-jid] = '\0';
|
result[c - jid] = '\0';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
@@ -124,17 +126,17 @@ char *xmpp_jid_domain(xmpp_ctx_t *ctx, const char *jid)
|
|||||||
|
|
||||||
c = strchr(jid, '@');
|
c = strchr(jid, '@');
|
||||||
if (c == NULL) {
|
if (c == NULL) {
|
||||||
/* no node, assume domain */
|
/* no node, assume domain */
|
||||||
c = jid;
|
c = jid;
|
||||||
} else {
|
} else {
|
||||||
/* advance past the separator */
|
/* advance past the separator */
|
||||||
c++;
|
c++;
|
||||||
}
|
}
|
||||||
dlen = strcspn(c, "/"); /* do not include resource */
|
dlen = strcspn(c, "/"); /* do not include resource */
|
||||||
result = xmpp_alloc(ctx, dlen + 1);
|
result = xmpp_alloc(ctx, dlen + 1);
|
||||||
if (result != NULL) {
|
if (result != NULL) {
|
||||||
memcpy(result, c, dlen);
|
memcpy(result, c, dlen);
|
||||||
result[dlen] = '\0';
|
result[dlen] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|||||||
26
src/md5.c
26
src/md5.c
@@ -29,19 +29,19 @@
|
|||||||
#include "md5.h"
|
#include "md5.h"
|
||||||
|
|
||||||
/* little-endian word access macros */
|
/* little-endian word access macros */
|
||||||
#define GET_32BIT_LSB_FIRST(cp) \
|
#define GET_32BIT_LSB_FIRST(cp) \
|
||||||
(((uint32_t)(unsigned char)(cp)[0]) | \
|
(((uint32_t)(unsigned char)(cp)[0]) | \
|
||||||
((uint32_t)(unsigned char)(cp)[1] << 8 ) | \
|
((uint32_t)(unsigned char)(cp)[1] << 8) | \
|
||||||
((uint32_t)(unsigned char)(cp)[2] << 16) | \
|
((uint32_t)(unsigned char)(cp)[2] << 16) | \
|
||||||
((uint32_t)(unsigned char)(cp)[3] << 24))
|
((uint32_t)(unsigned char)(cp)[3] << 24))
|
||||||
|
|
||||||
#define PUT_32BIT_LSB_FIRST(cp, value) \
|
#define PUT_32BIT_LSB_FIRST(cp, value) \
|
||||||
do { \
|
do { \
|
||||||
(cp)[0] = (value) & 0xFF; \
|
(cp)[0] = (value)&0xFF; \
|
||||||
(cp)[1] = ((value) >> 8) & 0xFF; \
|
(cp)[1] = ((value) >> 8) & 0xFF; \
|
||||||
(cp)[2] = ((value) >> 16) & 0xFF; \
|
(cp)[2] = ((value) >> 16) & 0xFF; \
|
||||||
(cp)[3] = ((value) >> 24) & 0xFF; \
|
(cp)[3] = ((value) >> 24) & 0xFF; \
|
||||||
} while(0)
|
} while (0)
|
||||||
|
|
||||||
static void MD5Transform(uint32_t buf[4], const unsigned char inext[64]);
|
static void MD5Transform(uint32_t buf[4], const unsigned char inext[64]);
|
||||||
|
|
||||||
@@ -74,10 +74,10 @@ void MD5Update(struct MD5Context *ctx, unsigned char const *buf, uint32_t len)
|
|||||||
|
|
||||||
t = ctx->bits[0];
|
t = ctx->bits[0];
|
||||||
if ((ctx->bits[0] = (t + ((uint32_t)len << 3)) & 0xffffffff) < t)
|
if ((ctx->bits[0] = (t + ((uint32_t)len << 3)) & 0xffffffff) < t)
|
||||||
ctx->bits[1]++; /* Carry from low to high */
|
ctx->bits[1]++; /* Carry from low to high */
|
||||||
ctx->bits[1] += len >> 29;
|
ctx->bits[1] += len >> 29;
|
||||||
|
|
||||||
t = (t >> 3) & 0x3f; /* Bytes already in shsInfo->data */
|
t = (t >> 3) & 0x3f; /* Bytes already in shsInfo->data */
|
||||||
|
|
||||||
/* Handle any leading odd-sized chunks */
|
/* Handle any leading odd-sized chunks */
|
||||||
|
|
||||||
@@ -150,7 +150,7 @@ void MD5Final(unsigned char digest[16], struct MD5Context *ctx)
|
|||||||
PUT_32BIT_LSB_FIRST(digest + 4, ctx->buf[1]);
|
PUT_32BIT_LSB_FIRST(digest + 4, ctx->buf[1]);
|
||||||
PUT_32BIT_LSB_FIRST(digest + 8, ctx->buf[2]);
|
PUT_32BIT_LSB_FIRST(digest + 8, ctx->buf[2]);
|
||||||
PUT_32BIT_LSB_FIRST(digest + 12, ctx->buf[3]);
|
PUT_32BIT_LSB_FIRST(digest + 12, ctx->buf[3]);
|
||||||
memset(ctx, 0, sizeof(*ctx)); /* In case it's sensitive */
|
memset(ctx, 0, sizeof(*ctx)); /* In case it's sensitive */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The four core functions - F1 is optimized somewhat */
|
/* The four core functions - F1 is optimized somewhat */
|
||||||
@@ -172,7 +172,7 @@ void MD5Final(unsigned char digest[16], struct MD5Context *ctx)
|
|||||||
w = w<<s | w>>(32-s), printf(" - w: %x\n", w), w += x )
|
w = w<<s | w>>(32-s), printf(" - w: %x\n", w), w += x )
|
||||||
*/
|
*/
|
||||||
#define MD5STEP(f, w, x, y, z, data, s) \
|
#define MD5STEP(f, w, x, y, z, data, s) \
|
||||||
( w += f(x, y, z) + data, w = w<<s | w>>(32-s), w += x )
|
(w += f(x, y, z) + data, w = w << s | w >> (32 - s), w += x)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The core of the MD5 algorithm, this alters an existing MD5 hash to
|
* The core of the MD5 algorithm, this alters an existing MD5 hash to
|
||||||
@@ -185,7 +185,7 @@ static void MD5Transform(uint32_t buf[4], const unsigned char inext[64])
|
|||||||
uint32_t in[16];
|
uint32_t in[16];
|
||||||
|
|
||||||
for (i = 0; i < 16; i++)
|
for (i = 0; i < 16; i++)
|
||||||
in[i] = GET_32BIT_LSB_FIRST(inext + 4 * i);
|
in[i] = GET_32BIT_LSB_FIRST(inext + 4 * i);
|
||||||
|
|
||||||
a = buf[0];
|
a = buf[0];
|
||||||
b = buf[1];
|
b = buf[1];
|
||||||
|
|||||||
@@ -21,7 +21,8 @@ struct MD5Context {
|
|||||||
};
|
};
|
||||||
|
|
||||||
void MD5Init(struct MD5Context *context);
|
void MD5Init(struct MD5Context *context);
|
||||||
void MD5Update(struct MD5Context *context, unsigned char const *buf,
|
void MD5Update(struct MD5Context *context,
|
||||||
|
unsigned char const *buf,
|
||||||
uint32_t len);
|
uint32_t len);
|
||||||
void MD5Final(unsigned char digest[16], struct MD5Context *context);
|
void MD5Final(unsigned char digest[16], struct MD5Context *context);
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
/* ostypes.h
|
/* ostypes.h
|
||||||
** strophe XMPP client library -- type definitions for platforms
|
** strophe XMPP client library -- type definitions for platforms
|
||||||
** without stdint.h
|
** without stdint.h
|
||||||
**
|
**
|
||||||
** Copyright (C) 2005-2009 Collecta, Inc.
|
** Copyright (C) 2005-2009 Collecta, Inc.
|
||||||
**
|
**
|
||||||
** This software is provided AS-IS with no warranty, either express
|
** This software is provided AS-IS with no warranty, either express
|
||||||
** or implied.
|
** or implied.
|
||||||
@@ -17,9 +17,9 @@
|
|||||||
#ifndef __LIBSTROPHE_OSTYPES_H__
|
#ifndef __LIBSTROPHE_OSTYPES_H__
|
||||||
#define __LIBSTROPHE_OSTYPES_H__
|
#define __LIBSTROPHE_OSTYPES_H__
|
||||||
|
|
||||||
#include <stddef.h> /* size_t */
|
#include <stddef.h> /* size_t */
|
||||||
|
|
||||||
#if defined (_MSC_VER) && _MSC_VER < 1600
|
#if defined(_MSC_VER) && _MSC_VER < 1600
|
||||||
typedef signed char int8_t;
|
typedef signed char int8_t;
|
||||||
typedef short int int16_t;
|
typedef short int int16_t;
|
||||||
typedef int int32_t;
|
typedef int int32_t;
|
||||||
@@ -28,7 +28,7 @@ typedef __int64 int64_t;
|
|||||||
typedef unsigned char uint8_t;
|
typedef unsigned char uint8_t;
|
||||||
typedef unsigned short int uint16_t;
|
typedef unsigned short int uint16_t;
|
||||||
typedef unsigned int uint32_t;
|
typedef unsigned int uint32_t;
|
||||||
typedef unsigned __int64 uint64_t;
|
typedef unsigned __int64 uint64_t;
|
||||||
|
|
||||||
#ifndef UINT16_MAX
|
#ifndef UINT16_MAX
|
||||||
#define UINT16_MAX ((uint16_t)0xffff)
|
#define UINT16_MAX ((uint16_t)0xffff)
|
||||||
|
|||||||
13
src/parser.h
13
src/parser.h
@@ -1,7 +1,7 @@
|
|||||||
/* parser.h
|
/* parser.h
|
||||||
** strophe XMPP client library -- parser structures and functions
|
** strophe XMPP client library -- parser structures and functions
|
||||||
**
|
**
|
||||||
** Copyright (C) 2005-2009 Collecta, Inc.
|
** Copyright (C) 2005-2009 Collecta, Inc.
|
||||||
**
|
**
|
||||||
** This software is provided AS-IS with no warranty, either express or
|
** This software is provided AS-IS with no warranty, either express or
|
||||||
** implied.
|
** implied.
|
||||||
@@ -22,19 +22,18 @@ typedef struct _parser_t parser_t;
|
|||||||
|
|
||||||
typedef void (*parser_start_callback)(char *name,
|
typedef void (*parser_start_callback)(char *name,
|
||||||
char **attrs,
|
char **attrs,
|
||||||
void * const userdata);
|
void *const userdata);
|
||||||
typedef void (*parser_end_callback)(char *name, void * const userdata);
|
typedef void (*parser_end_callback)(char *name, void *const userdata);
|
||||||
typedef void (*parser_stanza_callback)(xmpp_stanza_t *stanza,
|
typedef void (*parser_stanza_callback)(xmpp_stanza_t *stanza,
|
||||||
void * const userdata);
|
void *const userdata);
|
||||||
|
|
||||||
|
parser_t *parser_new(xmpp_ctx_t *ctx,
|
||||||
parser_t *parser_new(xmpp_ctx_t *ctx,
|
|
||||||
parser_start_callback startcb,
|
parser_start_callback startcb,
|
||||||
parser_end_callback endcb,
|
parser_end_callback endcb,
|
||||||
parser_stanza_callback stanzacb,
|
parser_stanza_callback stanzacb,
|
||||||
void *userdata);
|
void *userdata);
|
||||||
void parser_free(parser_t *parser);
|
void parser_free(parser_t *parser);
|
||||||
char* parser_attr_name(xmpp_ctx_t *ctx, char *nsname);
|
char *parser_attr_name(xmpp_ctx_t *ctx, char *nsname);
|
||||||
int parser_reset(parser_t *parser);
|
int parser_reset(parser_t *parser);
|
||||||
int parser_feed(parser_t *parser, char *chunk, int len);
|
int parser_feed(parser_t *parser, char *chunk, int len);
|
||||||
|
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ struct _parser_t {
|
|||||||
void *userdata;
|
void *userdata;
|
||||||
int depth;
|
int depth;
|
||||||
xmpp_stanza_t *stanza;
|
xmpp_stanza_t *stanza;
|
||||||
char* inner_text;
|
char *inner_text;
|
||||||
/* number of allocated bytes */
|
/* number of allocated bytes */
|
||||||
int inner_text_size;
|
int inner_text_size;
|
||||||
/* excluding terminal '\0' */
|
/* excluding terminal '\0' */
|
||||||
@@ -94,14 +94,15 @@ static char *_xml_name(xmpp_ctx_t *ctx, const char *nsname)
|
|||||||
size_t len;
|
size_t len;
|
||||||
|
|
||||||
c = strchr(nsname, namespace_sep);
|
c = strchr(nsname, namespace_sep);
|
||||||
if (c == NULL) return xmpp_strdup(ctx, nsname);
|
if (c == NULL)
|
||||||
|
return xmpp_strdup(ctx, nsname);
|
||||||
|
|
||||||
c++;
|
c++;
|
||||||
len = strlen(c);
|
len = strlen(c);
|
||||||
result = xmpp_alloc(ctx, len + 1);
|
result = xmpp_alloc(ctx, len + 1);
|
||||||
if (result != NULL) {
|
if (result != NULL) {
|
||||||
memcpy(result, c, len);
|
memcpy(result, c, len);
|
||||||
result[len] = '\0';
|
result[len] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
@@ -115,11 +116,11 @@ static char *_xml_namespace(xmpp_ctx_t *ctx, const char *nsname)
|
|||||||
|
|
||||||
c = strchr(nsname, namespace_sep);
|
c = strchr(nsname, namespace_sep);
|
||||||
if (c != NULL) {
|
if (c != NULL) {
|
||||||
result = xmpp_alloc(ctx, (c-nsname) + 1);
|
result = xmpp_alloc(ctx, (c - nsname) + 1);
|
||||||
if (result != NULL) {
|
if (result != NULL) {
|
||||||
memcpy(result, nsname, (c-nsname));
|
memcpy(result, nsname, (c - nsname));
|
||||||
result[c-nsname] = '\0';
|
result[c - nsname] = '\0';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
@@ -130,12 +131,13 @@ static void _set_attributes(xmpp_stanza_t *stanza, const XML_Char **attrs)
|
|||||||
char *attr;
|
char *attr;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (!attrs) return;
|
if (!attrs)
|
||||||
|
return;
|
||||||
|
|
||||||
for (i = 0; attrs[i]; i += 2) {
|
for (i = 0; attrs[i]; i += 2) {
|
||||||
/* namespaced attributes aren't used in xmpp, discard namespace */
|
/* namespaced attributes aren't used in xmpp, discard namespace */
|
||||||
attr = _xml_name(stanza->ctx, attrs[i]);
|
attr = _xml_name(stanza->ctx, attrs[i]);
|
||||||
xmpp_stanza_set_attribute(stanza, attr, attrs[i+1]);
|
xmpp_stanza_set_attribute(stanza, attr, attrs[i + 1]);
|
||||||
xmpp_free(stanza->ctx, attr);
|
xmpp_free(stanza->ctx, attr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -160,9 +162,8 @@ static void complete_inner_text(parser_t *parser)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _start_element(void *userdata,
|
static void
|
||||||
const XML_Char *nsname,
|
_start_element(void *userdata, const XML_Char *nsname, const XML_Char **attrs)
|
||||||
const XML_Char **attrs)
|
|
||||||
{
|
{
|
||||||
parser_t *parser = (parser_t *)userdata;
|
parser_t *parser = (parser_t *)userdata;
|
||||||
xmpp_stanza_t *child;
|
xmpp_stanza_t *child;
|
||||||
@@ -174,8 +175,7 @@ static void _start_element(void *userdata,
|
|||||||
if (parser->depth == 0) {
|
if (parser->depth == 0) {
|
||||||
/* notify the owner */
|
/* notify the owner */
|
||||||
if (parser->startcb)
|
if (parser->startcb)
|
||||||
parser->startcb(name, (char **)attrs,
|
parser->startcb(name, (char **)attrs, parser->userdata);
|
||||||
parser->userdata);
|
|
||||||
} else {
|
} else {
|
||||||
/* build stanzas at depth 1 */
|
/* build stanzas at depth 1 */
|
||||||
if (!parser->stanza && parser->depth != 1) {
|
if (!parser->stanza && parser->depth != 1) {
|
||||||
@@ -201,8 +201,10 @@ static void _start_element(void *userdata,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ns) xmpp_free(parser->ctx, ns);
|
if (ns)
|
||||||
if (name) xmpp_free(parser->ctx, name);
|
xmpp_free(parser->ctx, ns);
|
||||||
|
if (name)
|
||||||
|
xmpp_free(parser->ctx, name);
|
||||||
|
|
||||||
parser->depth++;
|
parser->depth++;
|
||||||
}
|
}
|
||||||
@@ -224,8 +226,7 @@ static void _end_element(void *userdata, const XML_Char *name)
|
|||||||
parser->stanza = parser->stanza->parent;
|
parser->stanza = parser->stanza->parent;
|
||||||
} else {
|
} else {
|
||||||
if (parser->stanzacb)
|
if (parser->stanzacb)
|
||||||
parser->stanzacb(parser->stanza,
|
parser->stanzacb(parser->stanza, parser->userdata);
|
||||||
parser->userdata);
|
|
||||||
xmpp_stanza_release(parser->stanza);
|
xmpp_stanza_release(parser->stanza);
|
||||||
parser->stanza = NULL;
|
parser->stanza = NULL;
|
||||||
}
|
}
|
||||||
@@ -237,13 +238,14 @@ static void _characters(void *userdata, const XML_Char *s, int len)
|
|||||||
parser_t *parser = (parser_t *)userdata;
|
parser_t *parser = (parser_t *)userdata;
|
||||||
char *p;
|
char *p;
|
||||||
|
|
||||||
if (parser->depth < 2) return;
|
if (parser->depth < 2)
|
||||||
|
return;
|
||||||
|
|
||||||
/* Join all parts to a single resulting string. Stanza is created in
|
/* Join all parts to a single resulting string. Stanza is created in
|
||||||
* _start_element() and _end_element(). */
|
* _start_element() and _end_element(). */
|
||||||
if (parser->inner_text_used + len >= parser->inner_text_size) {
|
if (parser->inner_text_used + len >= parser->inner_text_size) {
|
||||||
parser->inner_text_size = parser->inner_text_used + len + 1 +
|
parser->inner_text_size =
|
||||||
INNER_TEXT_PADDING;
|
parser->inner_text_used + len + 1 + INNER_TEXT_PADDING;
|
||||||
p = xmpp_realloc(parser->ctx, parser->inner_text,
|
p = xmpp_realloc(parser->ctx, parser->inner_text,
|
||||||
parser->inner_text_size);
|
parser->inner_text_size);
|
||||||
if (p == NULL) {
|
if (p == NULL) {
|
||||||
@@ -288,7 +290,7 @@ parser_t *parser_new(xmpp_ctx_t *ctx,
|
|||||||
return parser;
|
return parser;
|
||||||
}
|
}
|
||||||
|
|
||||||
char* parser_attr_name(xmpp_ctx_t *ctx, char *nsname)
|
char *parser_attr_name(xmpp_ctx_t *ctx, char *nsname)
|
||||||
{
|
{
|
||||||
return _xml_name(ctx, nsname);
|
return _xml_name(ctx, nsname);
|
||||||
}
|
}
|
||||||
@@ -300,7 +302,7 @@ void parser_free(parser_t *parser)
|
|||||||
XML_ParserFree(parser->expat);
|
XML_ParserFree(parser->expat);
|
||||||
|
|
||||||
if (parser->inner_text) {
|
if (parser->inner_text) {
|
||||||
xmpp_free (parser->ctx, parser->inner_text);
|
xmpp_free(parser->ctx, parser->inner_text);
|
||||||
parser->inner_text = NULL;
|
parser->inner_text = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -36,53 +36,56 @@ struct _parser_t {
|
|||||||
xmpp_stanza_t *stanza;
|
xmpp_stanza_t *stanza;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void _set_attributes(xmpp_stanza_t *stanza, int nattrs,
|
static void
|
||||||
const xmlChar **attrs)
|
_set_attributes(xmpp_stanza_t *stanza, int nattrs, const xmlChar **attrs)
|
||||||
{
|
{
|
||||||
int i, len;
|
int i, len;
|
||||||
char *value;
|
char *value;
|
||||||
|
|
||||||
if (!attrs) return;
|
if (!attrs)
|
||||||
|
return;
|
||||||
|
|
||||||
/* SAX2 uses array of localname/prefix/uri/value_begin/value_end */
|
/* SAX2 uses array of localname/prefix/uri/value_begin/value_end */
|
||||||
for (i = 0; i < nattrs*5; i += 5) {
|
for (i = 0; i < nattrs * 5; i += 5) {
|
||||||
len = attrs[i+4] - attrs[i+3];
|
len = attrs[i + 4] - attrs[i + 3];
|
||||||
value = xmpp_alloc(stanza->ctx, len + 1);
|
value = xmpp_alloc(stanza->ctx, len + 1);
|
||||||
if (value) {
|
if (value) {
|
||||||
memcpy(value, attrs[i+3], len);
|
memcpy(value, attrs[i + 3], len);
|
||||||
value[len] = '\0';
|
value[len] = '\0';
|
||||||
xmpp_stanza_set_attribute(stanza, (const char *)attrs[i], value);
|
xmpp_stanza_set_attribute(stanza, (const char *)attrs[i], value);
|
||||||
xmpp_free(stanza->ctx, value);
|
xmpp_free(stanza->ctx, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* SAX2 gives us the attrs in an incredibly inconvenient array,
|
/* SAX2 gives us the attrs in an incredibly inconvenient array,
|
||||||
* convert it to what the start callback is expecting */
|
* convert it to what the start callback is expecting */
|
||||||
static char **_convert_attrs(parser_t *parser, int nattrs,
|
static char **
|
||||||
const xmlChar **attrs)
|
_convert_attrs(parser_t *parser, int nattrs, const xmlChar **attrs)
|
||||||
{
|
{
|
||||||
int c, i, o, len;
|
int c, i, o, len;
|
||||||
char *value;
|
char *value;
|
||||||
char **ret;
|
char **ret;
|
||||||
|
|
||||||
if (!attrs) return NULL;
|
if (!attrs)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
ret = xmpp_alloc(parser->ctx, (nattrs+1)*2*sizeof(char*));
|
ret = xmpp_alloc(parser->ctx, (nattrs + 1) * 2 * sizeof(char *));
|
||||||
if (!ret) return NULL;
|
if (!ret)
|
||||||
memset(ret, 0, (nattrs+1)*2*sizeof(char*));
|
return NULL;
|
||||||
|
memset(ret, 0, (nattrs + 1) * 2 * sizeof(char *));
|
||||||
|
|
||||||
for (c = 0; c < nattrs; c++) {
|
for (c = 0; c < nattrs; c++) {
|
||||||
i = c * 5;
|
i = c * 5;
|
||||||
o = c * 2;
|
o = c * 2;
|
||||||
|
|
||||||
len = attrs[i+4] - attrs[i+3];
|
len = attrs[i + 4] - attrs[i + 3];
|
||||||
value = xmpp_alloc(parser->ctx, len + 1);
|
value = xmpp_alloc(parser->ctx, len + 1);
|
||||||
if (value) {
|
if (value) {
|
||||||
memcpy(value, attrs[i+3], len);
|
memcpy(value, attrs[i + 3], len);
|
||||||
value[len] = '\0';
|
value[len] = '\0';
|
||||||
ret[o] = xmpp_strdup(parser->ctx, (char*)attrs[i]);
|
ret[o] = xmpp_strdup(parser->ctx, (char *)attrs[i]);
|
||||||
ret[o+1] = value;
|
ret[o + 1] = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -97,18 +100,24 @@ static void _free_cbattrs(parser_t *parser, char **attrs)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
for (i = 0; attrs[i]; i += 2) {
|
for (i = 0; attrs[i]; i += 2) {
|
||||||
if (attrs[i]) xmpp_free(parser->ctx, attrs[i]);
|
if (attrs[i])
|
||||||
if (attrs[i+1]) xmpp_free(parser->ctx, attrs[i+1]);
|
xmpp_free(parser->ctx, attrs[i]);
|
||||||
|
if (attrs[i + 1])
|
||||||
|
xmpp_free(parser->ctx, attrs[i + 1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
xmpp_free(parser->ctx, attrs);
|
xmpp_free(parser->ctx, attrs);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _start_element(void *userdata,
|
static void _start_element(void *userdata,
|
||||||
const xmlChar *name, const xmlChar *prefix,
|
const xmlChar *name,
|
||||||
const xmlChar *uri, int nnamespaces,
|
const xmlChar *prefix,
|
||||||
const xmlChar **namespaces, int nattrs,
|
const xmlChar *uri,
|
||||||
int ndefaulted, const xmlChar **attrs)
|
int nnamespaces,
|
||||||
|
const xmlChar **namespaces,
|
||||||
|
int nattrs,
|
||||||
|
int ndefaulted,
|
||||||
|
const xmlChar **attrs)
|
||||||
{
|
{
|
||||||
parser_t *parser = (parser_t *)userdata;
|
parser_t *parser = (parser_t *)userdata;
|
||||||
xmpp_stanza_t *child;
|
xmpp_stanza_t *child;
|
||||||
@@ -118,53 +127,54 @@ static void _start_element(void *userdata,
|
|||||||
/* notify the owner */
|
/* notify the owner */
|
||||||
if (parser->startcb) {
|
if (parser->startcb) {
|
||||||
cbattrs = _convert_attrs(parser, nattrs, attrs);
|
cbattrs = _convert_attrs(parser, nattrs, attrs);
|
||||||
parser->startcb((char *)name, cbattrs,
|
parser->startcb((char *)name, cbattrs, parser->userdata);
|
||||||
parser->userdata);
|
|
||||||
_free_cbattrs(parser, cbattrs);
|
_free_cbattrs(parser, cbattrs);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* build stanzas at depth 1 */
|
/* build stanzas at depth 1 */
|
||||||
if (!parser->stanza && parser->depth != 1) {
|
if (!parser->stanza && parser->depth != 1) {
|
||||||
/* something terrible happened */
|
/* something terrible happened */
|
||||||
/* FIXME: we should probably trigger a disconnect */
|
/* FIXME: we should probably trigger a disconnect */
|
||||||
xmpp_error(parser->ctx, "parser", "oops, where did our stanza go?");
|
xmpp_error(parser->ctx, "parser", "oops, where did our stanza go?");
|
||||||
} else if (!parser->stanza) {
|
} else if (!parser->stanza) {
|
||||||
/* starting a new toplevel stanza */
|
/* starting a new toplevel stanza */
|
||||||
parser->stanza = xmpp_stanza_new(parser->ctx);
|
parser->stanza = xmpp_stanza_new(parser->ctx);
|
||||||
if (!parser->stanza) {
|
if (!parser->stanza) {
|
||||||
/* FIXME: can't allocate, disconnect */
|
/* FIXME: can't allocate, disconnect */
|
||||||
}
|
}
|
||||||
xmpp_stanza_set_name(parser->stanza, (char *)name);
|
xmpp_stanza_set_name(parser->stanza, (char *)name);
|
||||||
_set_attributes(parser->stanza, nattrs, attrs);
|
_set_attributes(parser->stanza, nattrs, attrs);
|
||||||
if (uri)
|
if (uri)
|
||||||
xmpp_stanza_set_ns(parser->stanza, (char *)uri);
|
xmpp_stanza_set_ns(parser->stanza, (char *)uri);
|
||||||
} else {
|
} else {
|
||||||
/* starting a child of conn->stanza */
|
/* starting a child of conn->stanza */
|
||||||
child = xmpp_stanza_new(parser->ctx);
|
child = xmpp_stanza_new(parser->ctx);
|
||||||
if (!child) {
|
if (!child) {
|
||||||
/* FIXME: can't allocate, disconnect */
|
/* FIXME: can't allocate, disconnect */
|
||||||
}
|
}
|
||||||
xmpp_stanza_set_name(child, (char *)name);
|
xmpp_stanza_set_name(child, (char *)name);
|
||||||
_set_attributes(child, nattrs, attrs);
|
_set_attributes(child, nattrs, attrs);
|
||||||
if (uri)
|
if (uri)
|
||||||
xmpp_stanza_set_ns(child, (char *)uri);
|
xmpp_stanza_set_ns(child, (char *)uri);
|
||||||
|
|
||||||
/* add child to parent */
|
/* add child to parent */
|
||||||
xmpp_stanza_add_child(parser->stanza, child);
|
xmpp_stanza_add_child(parser->stanza, child);
|
||||||
|
|
||||||
/* the child is owned by the toplevel stanza now */
|
/* the child is owned by the toplevel stanza now */
|
||||||
xmpp_stanza_release(child);
|
xmpp_stanza_release(child);
|
||||||
|
|
||||||
/* make child the current stanza */
|
/* make child the current stanza */
|
||||||
parser->stanza = child;
|
parser->stanza = child;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
parser->depth++;
|
parser->depth++;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _end_element(void *userdata, const xmlChar *name,
|
static void _end_element(void *userdata,
|
||||||
const xmlChar *prefix, const xmlChar *uri)
|
const xmlChar *name,
|
||||||
|
const xmlChar *prefix,
|
||||||
|
const xmlChar *uri)
|
||||||
{
|
{
|
||||||
parser_t *parser = (parser_t *)userdata;
|
parser_t *parser = (parser_t *)userdata;
|
||||||
|
|
||||||
@@ -175,16 +185,15 @@ static void _end_element(void *userdata, const xmlChar *name,
|
|||||||
if (parser->endcb)
|
if (parser->endcb)
|
||||||
parser->endcb((char *)name, parser->userdata);
|
parser->endcb((char *)name, parser->userdata);
|
||||||
} else {
|
} else {
|
||||||
if (parser->stanza->parent) {
|
if (parser->stanza->parent) {
|
||||||
/* we're finishing a child stanza, so set current to the parent */
|
/* we're finishing a child stanza, so set current to the parent */
|
||||||
parser->stanza = parser->stanza->parent;
|
parser->stanza = parser->stanza->parent;
|
||||||
} else {
|
} else {
|
||||||
if (parser->stanzacb)
|
if (parser->stanzacb)
|
||||||
parser->stanzacb(parser->stanza,
|
parser->stanzacb(parser->stanza, parser->userdata);
|
||||||
parser->userdata);
|
|
||||||
xmpp_stanza_release(parser->stanza);
|
xmpp_stanza_release(parser->stanza);
|
||||||
parser->stanza = NULL;
|
parser->stanza = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -194,13 +203,14 @@ static void _characters(void *userdata, const xmlChar *chr, int len)
|
|||||||
xmpp_stanza_t *stanza;
|
xmpp_stanza_t *stanza;
|
||||||
|
|
||||||
/* skip unimportant whitespace, etc */
|
/* skip unimportant whitespace, etc */
|
||||||
if (parser->depth < 2) return;
|
if (parser->depth < 2)
|
||||||
|
return;
|
||||||
|
|
||||||
/* create and populate stanza */
|
/* create and populate stanza */
|
||||||
stanza = xmpp_stanza_new(parser->ctx);
|
stanza = xmpp_stanza_new(parser->ctx);
|
||||||
if (!stanza) {
|
if (!stanza) {
|
||||||
/* FIXME: allocation error, disconnect */
|
/* FIXME: allocation error, disconnect */
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
xmpp_stanza_set_text_with_size(stanza, (char *)chr, len);
|
xmpp_stanza_set_text_with_size(stanza, (char *)chr, len);
|
||||||
|
|
||||||
@@ -239,7 +249,7 @@ parser_t *parser_new(xmpp_ctx_t *ctx,
|
|||||||
return parser;
|
return parser;
|
||||||
}
|
}
|
||||||
|
|
||||||
char* parser_attr_name(xmpp_ctx_t *ctx, char *nsname)
|
char *parser_attr_name(xmpp_ctx_t *ctx, char *nsname)
|
||||||
{
|
{
|
||||||
return xmpp_strdup(ctx, nsname);
|
return xmpp_strdup(ctx, nsname);
|
||||||
}
|
}
|
||||||
@@ -260,13 +270,13 @@ int parser_reset(parser_t *parser)
|
|||||||
if (parser->xmlctx)
|
if (parser->xmlctx)
|
||||||
xmlFreeParserCtxt(parser->xmlctx);
|
xmlFreeParserCtxt(parser->xmlctx);
|
||||||
if (parser->stanza)
|
if (parser->stanza)
|
||||||
xmpp_stanza_release(parser->stanza);
|
xmpp_stanza_release(parser->stanza);
|
||||||
|
|
||||||
parser->stanza = NULL;
|
parser->stanza = NULL;
|
||||||
parser->depth = 0;
|
parser->depth = 0;
|
||||||
|
|
||||||
parser->xmlctx = xmlCreatePushParserCtxt(&parser->handlers,
|
parser->xmlctx =
|
||||||
parser, NULL, 0, NULL);
|
xmlCreatePushParserCtxt(&parser->handlers, parser, NULL, 0, NULL);
|
||||||
|
|
||||||
return parser->xmlctx ? 1 : 0;
|
return parser->xmlctx ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|||||||
56
src/rand.c
56
src/rand.c
@@ -20,15 +20,15 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <string.h> /* memeset */
|
#include <string.h> /* memeset */
|
||||||
#include <time.h> /* clock, time */
|
#include <time.h> /* clock, time */
|
||||||
|
|
||||||
#include "common.h" /* xmpp_alloc, xmpp_free */
|
#include "common.h" /* xmpp_alloc, xmpp_free */
|
||||||
#include "ostypes.h" /* uint8_t, uint32_t, size_t */
|
#include "ostypes.h" /* uint8_t, uint32_t, size_t */
|
||||||
#include "sha1.h"
|
#include "sha1.h"
|
||||||
#include "snprintf.h" /* xmpp_snprintf */
|
#include "snprintf.h" /* xmpp_snprintf */
|
||||||
|
|
||||||
#include "rand.h" /* xmpp_rand_t */
|
#include "rand.h" /* xmpp_rand_t */
|
||||||
|
|
||||||
#define outlen SHA1_DIGEST_SIZE
|
#define outlen SHA1_DIGEST_SIZE
|
||||||
#define seedlen (440 / 8)
|
#define seedlen (440 / 8)
|
||||||
@@ -55,15 +55,15 @@ struct _xmpp_rand_t {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/* returns smallest number mupliple of y that not less than x */
|
/* returns smallest number mupliple of y that not less than x */
|
||||||
#define round_up(x, y) (((x) + (y) - 1) / (y) * (y))
|
#define round_up(x, y) (((x) + (y)-1) / (y) * (y))
|
||||||
/* returns smallest integer number that not less than x/y */
|
/* returns smallest integer number that not less than x/y */
|
||||||
#define div_round_up(x, y) (((x) + (y) - 1) / (y))
|
#define div_round_up(x, y) (((x) + (y)-1) / (y))
|
||||||
|
|
||||||
/* adds two arrays as numbers in big-endian representation and stores
|
/* adds two arrays as numbers in big-endian representation and stores
|
||||||
* result in the first one.
|
* result in the first one.
|
||||||
*/
|
*/
|
||||||
static void arr_add(uint8_t *arr1, size_t arr1_len,
|
static void
|
||||||
uint8_t *arr2, size_t arr2_len)
|
arr_add(uint8_t *arr1, size_t arr1_len, uint8_t *arr2, size_t arr2_len)
|
||||||
{
|
{
|
||||||
size_t i;
|
size_t i;
|
||||||
uint32_t acc;
|
uint32_t acc;
|
||||||
@@ -89,8 +89,10 @@ static void store_be32(uint32_t val, uint8_t be[4])
|
|||||||
be[3] = (uint8_t)(val & 0xff);
|
be[3] = (uint8_t)(val & 0xff);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Hash_df(uint8_t *input_string, size_t input_string_len,
|
static void Hash_df(uint8_t *input_string,
|
||||||
uint8_t *output_string, size_t no_of_bytes_to_return)
|
size_t input_string_len,
|
||||||
|
uint8_t *output_string,
|
||||||
|
size_t no_of_bytes_to_return)
|
||||||
{
|
{
|
||||||
uint8_t counter;
|
uint8_t counter;
|
||||||
uint8_t temp[round_up(seedlen, outlen)];
|
uint8_t temp[round_up(seedlen, outlen)];
|
||||||
@@ -119,7 +121,8 @@ static void Hash_df(uint8_t *input_string, size_t input_string_len,
|
|||||||
static void Hash_DRBG_Instantiate(Hash_DRBG_CTX *ctx,
|
static void Hash_DRBG_Instantiate(Hash_DRBG_CTX *ctx,
|
||||||
uint8_t *entropy_input,
|
uint8_t *entropy_input,
|
||||||
size_t entropy_input_len,
|
size_t entropy_input_len,
|
||||||
uint8_t *nonce, size_t nonce_len)
|
uint8_t *nonce,
|
||||||
|
size_t nonce_len)
|
||||||
{
|
{
|
||||||
uint8_t seed_material[ENTROPY_MAX + NONCE_MAX];
|
uint8_t seed_material[ENTROPY_MAX + NONCE_MAX];
|
||||||
uint8_t seed0[seedlen + 1];
|
uint8_t seed0[seedlen + 1];
|
||||||
@@ -162,8 +165,8 @@ static void Hash_DRBG_Reseed(Hash_DRBG_CTX *ctx,
|
|||||||
ctx->reseed_counter = 1;
|
ctx->reseed_counter = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Hashgen(uint8_t *V, uint8_t *output,
|
static void
|
||||||
size_t requested_number_of_bytes)
|
Hashgen(uint8_t *V, uint8_t *output, size_t requested_number_of_bytes)
|
||||||
{
|
{
|
||||||
uint8_t data[seedlen];
|
uint8_t data[seedlen];
|
||||||
uint8_t W[GENERATE_MAX];
|
uint8_t W[GENERATE_MAX];
|
||||||
@@ -187,7 +190,8 @@ static void Hashgen(uint8_t *V, uint8_t *output,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* assume additional_input is zero length string */
|
/* assume additional_input is zero length string */
|
||||||
static int Hash_DRBG_Generate(Hash_DRBG_CTX *ctx, uint8_t *output,
|
static int Hash_DRBG_Generate(Hash_DRBG_CTX *ctx,
|
||||||
|
uint8_t *output,
|
||||||
size_t requested_number_of_bytes)
|
size_t requested_number_of_bytes)
|
||||||
{
|
{
|
||||||
uint8_t H[outlen];
|
uint8_t H[outlen];
|
||||||
@@ -211,14 +215,14 @@ static int Hash_DRBG_Generate(Hash_DRBG_CTX *ctx, uint8_t *output,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define ENTROPY_ACCUMULATE(ptr, last, type, arg) \
|
#define ENTROPY_ACCUMULATE(ptr, last, type, arg) \
|
||||||
do { \
|
do { \
|
||||||
type __arg = (type)(arg); \
|
type __arg = (type)(arg); \
|
||||||
if ((char*)ptr + sizeof(__arg) < (char*)last) { \
|
if ((char *)ptr + sizeof(__arg) < (char *)last) { \
|
||||||
*(type*)ptr = __arg; \
|
*(type *)ptr = __arg; \
|
||||||
ptr = (void*)((char*)ptr + sizeof(__arg)); \
|
ptr = (void *)((char *)ptr + sizeof(__arg)); \
|
||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
static void xmpp_rand_reseed(xmpp_rand_t *rand)
|
static void xmpp_rand_reseed(xmpp_rand_t *rand)
|
||||||
{
|
{
|
||||||
@@ -291,8 +295,8 @@ int xmpp_rand(xmpp_rand_t *rand)
|
|||||||
|
|
||||||
static void rand_byte2hex(unsigned char byte, char *hex)
|
static void rand_byte2hex(unsigned char byte, char *hex)
|
||||||
{
|
{
|
||||||
static const char hex_tbl[16] = { '0', '1', '2', '3', '4', '5', '6', '7',
|
static const char hex_tbl[16] = {'0', '1', '2', '3', '4', '5', '6', '7',
|
||||||
'8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
|
'8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
|
||||||
|
|
||||||
hex[0] = hex_tbl[(byte >> 4) & 0x0f];
|
hex[0] = hex_tbl[(byte >> 4) & 0x0f];
|
||||||
hex[1] = hex_tbl[byte & 0x0f];
|
hex[1] = hex_tbl[byte & 0x0f];
|
||||||
|
|||||||
@@ -16,8 +16,8 @@
|
|||||||
#ifndef __LIBSTROPHE_RAND_H__
|
#ifndef __LIBSTROPHE_RAND_H__
|
||||||
#define __LIBSTROPHE_RAND_H__
|
#define __LIBSTROPHE_RAND_H__
|
||||||
|
|
||||||
#include <stddef.h> /* size_t */
|
#include <stddef.h> /* size_t */
|
||||||
#include "strophe.h" /* xmpp_ctx_t */
|
#include "strophe.h" /* xmpp_ctx_t */
|
||||||
|
|
||||||
typedef struct _xmpp_rand_t xmpp_rand_t;
|
typedef struct _xmpp_rand_t xmpp_rand_t;
|
||||||
|
|
||||||
|
|||||||
681
src/resolver.c
681
src/resolver.c
@@ -16,8 +16,8 @@
|
|||||||
#if !defined(_WIN32) && !defined(HAVE_CARES)
|
#if !defined(_WIN32) && !defined(HAVE_CARES)
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <arpa/nameser.h>
|
#include <arpa/nameser.h>
|
||||||
#include <resolv.h> /* res_query */
|
#include <resolv.h> /* res_query */
|
||||||
#endif /* _WIN32 && HAVE_CARES */
|
#endif /* _WIN32 && HAVE_CARES */
|
||||||
|
|
||||||
#ifdef HAVE_CARES
|
#ifdef HAVE_CARES
|
||||||
#include <ares.h>
|
#include <ares.h>
|
||||||
@@ -31,11 +31,11 @@
|
|||||||
#endif /* !_WIN32 */
|
#endif /* !_WIN32 */
|
||||||
#endif /* HAVE_CARES */
|
#endif /* HAVE_CARES */
|
||||||
|
|
||||||
#include <string.h> /* strncpy */
|
#include <string.h> /* strncpy */
|
||||||
|
|
||||||
#include "ostypes.h"
|
#include "ostypes.h"
|
||||||
#include "snprintf.h"
|
#include "snprintf.h"
|
||||||
#include "util.h" /* xmpp_min */
|
#include "util.h" /* xmpp_min */
|
||||||
#include "resolver.h"
|
#include "resolver.h"
|
||||||
|
|
||||||
#define MESSAGE_HEADER_LEN 12
|
#define MESSAGE_HEADER_LEN 12
|
||||||
@@ -52,7 +52,8 @@ static int resolver_ares_srv_lookup_buf(xmpp_ctx_t *ctx,
|
|||||||
const unsigned char *buf,
|
const unsigned char *buf,
|
||||||
size_t len,
|
size_t len,
|
||||||
resolver_srv_rr_t **srv_rr_list);
|
resolver_srv_rr_t **srv_rr_list);
|
||||||
static int resolver_ares_srv_lookup(xmpp_ctx_t *ctx, const char *fulldomain,
|
static int resolver_ares_srv_lookup(xmpp_ctx_t *ctx,
|
||||||
|
const char *fulldomain,
|
||||||
resolver_srv_rr_t **srv_rr_list);
|
resolver_srv_rr_t **srv_rr_list);
|
||||||
#endif /* HAVE_CARES */
|
#endif /* HAVE_CARES */
|
||||||
|
|
||||||
@@ -64,10 +65,12 @@ static int resolver_raw_srv_lookup_buf(xmpp_ctx_t *ctx,
|
|||||||
#endif /* !HAVE_CARES */
|
#endif /* !HAVE_CARES */
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
static int resolver_win32_srv_lookup(xmpp_ctx_t *ctx, const char *fulldomain,
|
static int resolver_win32_srv_lookup(xmpp_ctx_t *ctx,
|
||||||
|
const char *fulldomain,
|
||||||
resolver_srv_rr_t **srv_rr_list);
|
resolver_srv_rr_t **srv_rr_list);
|
||||||
static int resolver_win32_srv_query(const char *fulldomain,
|
static int resolver_win32_srv_query(const char *fulldomain,
|
||||||
unsigned char *buf, size_t len);
|
unsigned char *buf,
|
||||||
|
size_t len);
|
||||||
#endif /* _WIN32 */
|
#endif /* _WIN32 */
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
@@ -118,8 +121,7 @@ static void resolver_srv_list_sort(resolver_srv_rr_t **srv_rr_list)
|
|||||||
*/
|
*/
|
||||||
if ((rr_current->priority > rr_next->priority) ||
|
if ((rr_current->priority > rr_next->priority) ||
|
||||||
(rr_current->priority == rr_next->priority &&
|
(rr_current->priority == rr_next->priority &&
|
||||||
rr_current->weight < rr_next->weight))
|
rr_current->weight < rr_next->weight)) {
|
||||||
{
|
|
||||||
/* Swap node */
|
/* Swap node */
|
||||||
swap = 1;
|
swap = 1;
|
||||||
if (rr_prev != NULL) {
|
if (rr_prev != NULL) {
|
||||||
@@ -145,8 +147,10 @@ static void resolver_srv_list_sort(resolver_srv_rr_t **srv_rr_list)
|
|||||||
*srv_rr_list = rr_head;
|
*srv_rr_list = rr_head;
|
||||||
}
|
}
|
||||||
|
|
||||||
int resolver_srv_lookup_buf(xmpp_ctx_t *ctx, const unsigned char *buf,
|
int resolver_srv_lookup_buf(xmpp_ctx_t *ctx,
|
||||||
size_t len, resolver_srv_rr_t **srv_rr_list)
|
const unsigned char *buf,
|
||||||
|
size_t len,
|
||||||
|
resolver_srv_rr_t **srv_rr_list)
|
||||||
{
|
{
|
||||||
int set;
|
int set;
|
||||||
|
|
||||||
@@ -160,8 +164,11 @@ int resolver_srv_lookup_buf(xmpp_ctx_t *ctx, const unsigned char *buf,
|
|||||||
return set;
|
return set;
|
||||||
}
|
}
|
||||||
|
|
||||||
int resolver_srv_lookup(xmpp_ctx_t *ctx, const char *service, const char *proto,
|
int resolver_srv_lookup(xmpp_ctx_t *ctx,
|
||||||
const char *domain, resolver_srv_rr_t **srv_rr_list)
|
const char *service,
|
||||||
|
const char *proto,
|
||||||
|
const char *domain,
|
||||||
|
resolver_srv_rr_t **srv_rr_list)
|
||||||
{
|
{
|
||||||
#define RESOLVER_BUF_MAX 65536
|
#define RESOLVER_BUF_MAX 65536
|
||||||
unsigned char *buf;
|
unsigned char *buf;
|
||||||
@@ -172,8 +179,8 @@ int resolver_srv_lookup(xmpp_ctx_t *ctx, const char *service, const char *proto,
|
|||||||
(void)buf;
|
(void)buf;
|
||||||
(void)len;
|
(void)len;
|
||||||
|
|
||||||
xmpp_snprintf(fulldomain, sizeof(fulldomain),
|
xmpp_snprintf(fulldomain, sizeof(fulldomain), "_%s._%s.%s", service, proto,
|
||||||
"_%s._%s.%s", service, proto, domain);
|
domain);
|
||||||
|
|
||||||
*srv_rr_list = NULL;
|
*srv_rr_list = NULL;
|
||||||
|
|
||||||
@@ -193,7 +200,7 @@ int resolver_srv_lookup(xmpp_ctx_t *ctx, const char *service, const char *proto,
|
|||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
len = resolver_win32_srv_query(fulldomain, buf, RESOLVER_BUF_MAX);
|
len = resolver_win32_srv_query(fulldomain, buf, RESOLVER_BUF_MAX);
|
||||||
#else /* _WIN32 */
|
#else /* _WIN32 */
|
||||||
len = res_query(fulldomain, MESSAGE_C_IN, MESSAGE_T_SRV, buf,
|
len = res_query(fulldomain, MESSAGE_C_IN, MESSAGE_T_SRV, buf,
|
||||||
RESOLVER_BUF_MAX);
|
RESOLVER_BUF_MAX);
|
||||||
#endif /* _WIN32 */
|
#endif /* _WIN32 */
|
||||||
@@ -259,9 +266,11 @@ static uint8_t message_header_rcode(const struct message_header *header)
|
|||||||
* Returns length of the non-truncated resulting string, may be bigger than
|
* Returns length of the non-truncated resulting string, may be bigger than
|
||||||
* name_max.
|
* name_max.
|
||||||
*/
|
*/
|
||||||
static size_t message_name_append_safe(char *name, size_t name_len,
|
static size_t message_name_append_safe(char *name,
|
||||||
|
size_t name_len,
|
||||||
size_t name_max,
|
size_t name_max,
|
||||||
const char *tail, size_t tail_len)
|
const char *tail,
|
||||||
|
size_t tail_len)
|
||||||
{
|
{
|
||||||
size_t copy_len;
|
size_t copy_len;
|
||||||
|
|
||||||
@@ -274,9 +283,11 @@ static size_t message_name_append_safe(char *name, size_t name_len,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Returns length of the compressed name. This is NOT the same as strlen(). */
|
/* Returns length of the compressed name. This is NOT the same as strlen(). */
|
||||||
static unsigned message_name_get(const unsigned char *buf, size_t buf_len,
|
static unsigned message_name_get(const unsigned char *buf,
|
||||||
|
size_t buf_len,
|
||||||
unsigned buf_offset,
|
unsigned buf_offset,
|
||||||
char *name, size_t name_max)
|
char *name,
|
||||||
|
size_t name_max)
|
||||||
{
|
{
|
||||||
size_t name_len = 0;
|
size_t name_len = 0;
|
||||||
unsigned i = buf_offset;
|
unsigned i = buf_offset;
|
||||||
@@ -284,26 +295,29 @@ static unsigned message_name_get(const unsigned char *buf, size_t buf_len,
|
|||||||
unsigned rc;
|
unsigned rc;
|
||||||
unsigned char label_len;
|
unsigned char label_len;
|
||||||
|
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
if (i >= buf_len) return 0;
|
if (i >= buf_len)
|
||||||
|
return 0;
|
||||||
label_len = buf[i++];
|
label_len = buf[i++];
|
||||||
if (label_len == 0) break;
|
if (label_len == 0)
|
||||||
|
break;
|
||||||
|
|
||||||
/* Label */
|
/* Label */
|
||||||
if ((label_len & 0xc0) == 0) {
|
if ((label_len & 0xc0) == 0) {
|
||||||
if (i + label_len - 1 >= buf_len) return 0;
|
if (i + label_len - 1 >= buf_len)
|
||||||
|
return 0;
|
||||||
if (name != NULL) {
|
if (name != NULL) {
|
||||||
name_len = message_name_append_safe(name, name_len, name_max,
|
name_len = message_name_append_safe(name, name_len, name_max,
|
||||||
(char *)&buf[i], label_len);
|
(char *)&buf[i], label_len);
|
||||||
name_len = message_name_append_safe(name, name_len, name_max,
|
name_len =
|
||||||
".", 1);
|
message_name_append_safe(name, name_len, name_max, ".", 1);
|
||||||
}
|
}
|
||||||
i += label_len;
|
i += label_len;
|
||||||
|
|
||||||
/* Pointer */
|
/* Pointer */
|
||||||
} else if ((label_len & 0xc0) == 0xc0) {
|
} else if ((label_len & 0xc0) == 0xc0) {
|
||||||
if (i >= buf_len) return 0;
|
if (i >= buf_len)
|
||||||
|
return 0;
|
||||||
pointer = (label_len & 0x3f) << 8 | buf[i++];
|
pointer = (label_len & 0x3f) << 8 | buf[i++];
|
||||||
if (name != NULL && name_len >= name_max && name_max > 0) {
|
if (name != NULL && name_len >= name_max && name_max > 0) {
|
||||||
/* We have filled the name buffer. Don't pass it recursively. */
|
/* We have filled the name buffer. Don't pass it recursively. */
|
||||||
@@ -311,20 +325,22 @@ static unsigned message_name_get(const unsigned char *buf, size_t buf_len,
|
|||||||
name = NULL;
|
name = NULL;
|
||||||
name_max = 0;
|
name_max = 0;
|
||||||
}
|
}
|
||||||
rc = message_name_get(buf, buf_len, pointer,
|
rc = message_name_get(
|
||||||
name != NULL ? &name[name_len] : NULL,
|
buf, buf_len, pointer, name != NULL ? &name[name_len] : NULL,
|
||||||
name_max > name_len ? name_max - name_len : 0);
|
name_max > name_len ? name_max - name_len : 0);
|
||||||
if (rc == 0) return 0;
|
if (rc == 0)
|
||||||
|
return 0;
|
||||||
/* Pointer is always the last. */
|
/* Pointer is always the last. */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* The 10 and 01 combinations are reserved for future use. */
|
/* The 10 and 01 combinations are reserved for future use. */
|
||||||
} else {
|
} else {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (label_len == 0) {
|
if (label_len == 0) {
|
||||||
if (name_len == 0) name_len = 1;
|
if (name_len == 0)
|
||||||
|
name_len = 1;
|
||||||
/*
|
/*
|
||||||
* At this point name_len is length of the resulting name,
|
* At this point name_len is length of the resulting name,
|
||||||
* including '\0'. This value can be exported to allocate buffer
|
* including '\0'. This value can be exported to allocate buffer
|
||||||
@@ -342,20 +358,21 @@ static unsigned message_name_get(const unsigned char *buf, size_t buf_len,
|
|||||||
return i - buf_offset;
|
return i - buf_offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned message_name_len(const unsigned char *buf, size_t buf_len,
|
static unsigned
|
||||||
unsigned buf_offset)
|
message_name_len(const unsigned char *buf, size_t buf_len, unsigned buf_offset)
|
||||||
{
|
{
|
||||||
return message_name_get(buf, buf_len, buf_offset, NULL, SIZE_MAX);
|
return message_name_get(buf, buf_len, buf_offset, NULL, SIZE_MAX);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define BUF_OVERFLOW_CHECK(ptr, len) do { \
|
#define BUF_OVERFLOW_CHECK(ptr, len) \
|
||||||
if ((ptr) >= (len)) { \
|
do { \
|
||||||
if (*srv_rr_list != NULL) \
|
if ((ptr) >= (len)) { \
|
||||||
resolver_srv_free(ctx, *srv_rr_list); \
|
if (*srv_rr_list != NULL) \
|
||||||
*srv_rr_list = NULL; \
|
resolver_srv_free(ctx, *srv_rr_list); \
|
||||||
return XMPP_DOMAIN_NOT_FOUND; \
|
*srv_rr_list = NULL; \
|
||||||
} \
|
return XMPP_DOMAIN_NOT_FOUND; \
|
||||||
} while (0)
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
static int resolver_raw_srv_lookup_buf(xmpp_ctx_t *ctx,
|
static int resolver_raw_srv_lookup_buf(xmpp_ctx_t *ctx,
|
||||||
const unsigned char *buf,
|
const unsigned char *buf,
|
||||||
@@ -384,8 +401,7 @@ static int resolver_raw_srv_lookup_buf(xmpp_ctx_t *ctx,
|
|||||||
header.nscount = xmpp_ntohs_ptr(&buf[8]);
|
header.nscount = xmpp_ntohs_ptr(&buf[8]);
|
||||||
header.arcount = xmpp_ntohs_ptr(&buf[10]);
|
header.arcount = xmpp_ntohs_ptr(&buf[10]);
|
||||||
if (message_header_qr(&header) != MESSAGE_RESPONSE ||
|
if (message_header_qr(&header) != MESSAGE_RESPONSE ||
|
||||||
message_header_rcode(&header) != 0)
|
message_header_rcode(&header) != 0) {
|
||||||
{
|
|
||||||
return XMPP_DOMAIN_NOT_FOUND;
|
return XMPP_DOMAIN_NOT_FOUND;
|
||||||
}
|
}
|
||||||
j = MESSAGE_HEADER_LEN;
|
j = MESSAGE_HEADER_LEN;
|
||||||
@@ -395,7 +411,8 @@ static int resolver_raw_srv_lookup_buf(xmpp_ctx_t *ctx,
|
|||||||
BUF_OVERFLOW_CHECK(j, len);
|
BUF_OVERFLOW_CHECK(j, len);
|
||||||
name_len = message_name_len(buf, len, j);
|
name_len = message_name_len(buf, len, j);
|
||||||
/* error in name format */
|
/* error in name format */
|
||||||
if (name_len == 0) return XMPP_DOMAIN_NOT_FOUND;
|
if (name_len == 0)
|
||||||
|
return XMPP_DOMAIN_NOT_FOUND;
|
||||||
j += name_len + 4;
|
j += name_len + 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -403,7 +420,8 @@ static int resolver_raw_srv_lookup_buf(xmpp_ctx_t *ctx,
|
|||||||
BUF_OVERFLOW_CHECK(j, len);
|
BUF_OVERFLOW_CHECK(j, len);
|
||||||
name_len = message_name_len(buf, len, j);
|
name_len = message_name_len(buf, len, j);
|
||||||
/* error in name format */
|
/* error in name format */
|
||||||
if (name_len == 0) return XMPP_DOMAIN_NOT_FOUND;
|
if (name_len == 0)
|
||||||
|
return XMPP_DOMAIN_NOT_FOUND;
|
||||||
j += name_len;
|
j += name_len;
|
||||||
BUF_OVERFLOW_CHECK(j + 16, len);
|
BUF_OVERFLOW_CHECK(j + 16, len);
|
||||||
type = xmpp_ntohs_ptr(&buf[j]);
|
type = xmpp_ntohs_ptr(&buf[j]);
|
||||||
@@ -477,8 +495,8 @@ static int resolver_ares_srv_lookup_buf(xmpp_ctx_t *ctx,
|
|||||||
return *srv_rr_list == NULL ? XMPP_DOMAIN_NOT_FOUND : XMPP_DOMAIN_FOUND;
|
return *srv_rr_list == NULL ? XMPP_DOMAIN_NOT_FOUND : XMPP_DOMAIN_FOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ares_srv_lookup_callback(void *arg, int status, int timeouts,
|
static void ares_srv_lookup_callback(
|
||||||
unsigned char *buf, int len)
|
void *arg, int status, int timeouts, unsigned char *buf, int len)
|
||||||
{
|
{
|
||||||
struct resolver_ares_ctx *actx = arg;
|
struct resolver_ares_ctx *actx = arg;
|
||||||
|
|
||||||
@@ -489,7 +507,8 @@ static void ares_srv_lookup_callback(void *arg, int status, int timeouts,
|
|||||||
&actx->srv_rr_list);
|
&actx->srv_rr_list);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int resolver_ares_srv_lookup(xmpp_ctx_t *ctx, const char *fulldomain,
|
static int resolver_ares_srv_lookup(xmpp_ctx_t *ctx,
|
||||||
|
const char *fulldomain,
|
||||||
resolver_srv_rr_t **srv_rr_list)
|
resolver_srv_rr_t **srv_rr_list)
|
||||||
{
|
{
|
||||||
struct resolver_ares_ctx actx;
|
struct resolver_ares_ctx actx;
|
||||||
@@ -546,133 +565,136 @@ static int resolver_ares_srv_lookup(xmpp_ctx_t *ctx, const char *fulldomain,
|
|||||||
#include <windns.h>
|
#include <windns.h>
|
||||||
#include <Iphlpapi.h>
|
#include <Iphlpapi.h>
|
||||||
|
|
||||||
struct dnsquery_header
|
struct dnsquery_header {
|
||||||
{
|
unsigned short id;
|
||||||
unsigned short id;
|
unsigned char qr;
|
||||||
unsigned char qr;
|
unsigned char opcode;
|
||||||
unsigned char opcode;
|
unsigned char aa;
|
||||||
unsigned char aa;
|
unsigned char tc;
|
||||||
unsigned char tc;
|
unsigned char rd;
|
||||||
unsigned char rd;
|
unsigned char ra;
|
||||||
unsigned char ra;
|
unsigned char z;
|
||||||
unsigned char z;
|
unsigned char rcode;
|
||||||
unsigned char rcode;
|
unsigned short qdcount;
|
||||||
unsigned short qdcount;
|
unsigned short ancount;
|
||||||
unsigned short ancount;
|
unsigned short nscount;
|
||||||
unsigned short nscount;
|
unsigned short arcount;
|
||||||
unsigned short arcount;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct dnsquery_question
|
struct dnsquery_question {
|
||||||
{
|
char qname[1024];
|
||||||
char qname[1024];
|
unsigned short qtype;
|
||||||
unsigned short qtype;
|
unsigned short qclass;
|
||||||
unsigned short qclass;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static void netbuf_add_16bitnum(unsigned char *buf, int buflen, int *offset, unsigned short num)
|
static void netbuf_add_16bitnum(unsigned char *buf,
|
||||||
|
int buflen,
|
||||||
|
int *offset,
|
||||||
|
unsigned short num)
|
||||||
{
|
{
|
||||||
unsigned char *start = buf + *offset;
|
unsigned char *start = buf + *offset;
|
||||||
unsigned char *p = start;
|
unsigned char *p = start;
|
||||||
|
|
||||||
/* assuming big endian */
|
/* assuming big endian */
|
||||||
*p++ = (num >> 8) & 0xff;
|
*p++ = (num >> 8) & 0xff;
|
||||||
*p++ = (num) & 0xff;
|
*p++ = (num)&0xff;
|
||||||
|
|
||||||
*offset += 2;
|
*offset += 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void netbuf_add_domain_name(unsigned char *buf, int buflen, int *offset,
|
static void
|
||||||
char *name)
|
netbuf_add_domain_name(unsigned char *buf, int buflen, int *offset, char *name)
|
||||||
{
|
{
|
||||||
unsigned char *start = buf + *offset;
|
unsigned char *start = buf + *offset;
|
||||||
unsigned char *p = start;
|
unsigned char *p = start;
|
||||||
unsigned char *wordstart, *wordend;
|
unsigned char *wordstart, *wordend;
|
||||||
|
|
||||||
wordstart = (unsigned char *)name;
|
wordstart = (unsigned char *)name;
|
||||||
|
|
||||||
while (*wordstart)
|
while (*wordstart) {
|
||||||
{
|
int len;
|
||||||
int len;
|
wordend = wordstart;
|
||||||
wordend = wordstart;
|
while (*wordend && *wordend != '.') {
|
||||||
while (*wordend && *wordend != '.')
|
wordend++;
|
||||||
{
|
}
|
||||||
wordend++;
|
|
||||||
}
|
|
||||||
|
|
||||||
len = (int)(wordend - wordstart);
|
len = (int)(wordend - wordstart);
|
||||||
|
|
||||||
if (len > 0x3F)
|
if (len > 0x3F) {
|
||||||
{
|
len = 0x3F;
|
||||||
len = 0x3F;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
*p++ = len;
|
*p++ = len;
|
||||||
|
|
||||||
while (wordstart != wordend)
|
while (wordstart != wordend) {
|
||||||
{
|
*p++ = *wordstart++;
|
||||||
*p++ = *wordstart++;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (*wordstart == '.')
|
if (*wordstart == '.') {
|
||||||
{
|
wordstart++;
|
||||||
wordstart++;
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
*p++ = '\0';
|
*p++ = '\0';
|
||||||
|
|
||||||
*offset += (int)(p - start);
|
*offset += (int)(p - start);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void netbuf_add_dnsquery_header(unsigned char *buf, int buflen, int *offset, struct dnsquery_header *header)
|
static void netbuf_add_dnsquery_header(unsigned char *buf,
|
||||||
|
int buflen,
|
||||||
|
int *offset,
|
||||||
|
struct dnsquery_header *header)
|
||||||
{
|
{
|
||||||
unsigned char *p;
|
unsigned char *p;
|
||||||
|
|
||||||
netbuf_add_16bitnum(buf, buflen, offset, header->id);
|
netbuf_add_16bitnum(buf, buflen, offset, header->id);
|
||||||
|
|
||||||
p = buf + *offset;
|
p = buf + *offset;
|
||||||
*p++ = ((header->qr & 0x01) << 7)
|
*p++ = ((header->qr & 0x01) << 7) | ((header->opcode & 0x0F) << 3) |
|
||||||
| ((header->opcode & 0x0F) << 3)
|
((header->aa & 0x01) << 2) | ((header->tc & 0x01) << 1) |
|
||||||
| ((header->aa & 0x01) << 2)
|
((header->rd & 0x01));
|
||||||
| ((header->tc & 0x01) << 1)
|
*p++ = ((header->ra & 0x01) << 7) | ((header->z & 0x07) << 4) |
|
||||||
| ((header->rd & 0x01));
|
((header->rcode & 0x0F));
|
||||||
*p++ = ((header->ra & 0x01) << 7)
|
*offset += 2;
|
||||||
| ((header->z & 0x07) << 4)
|
|
||||||
| ((header->rcode & 0x0F));
|
|
||||||
*offset += 2;
|
|
||||||
|
|
||||||
netbuf_add_16bitnum(buf, buflen, offset, header->qdcount);
|
netbuf_add_16bitnum(buf, buflen, offset, header->qdcount);
|
||||||
netbuf_add_16bitnum(buf, buflen, offset, header->ancount);
|
netbuf_add_16bitnum(buf, buflen, offset, header->ancount);
|
||||||
netbuf_add_16bitnum(buf, buflen, offset, header->nscount);
|
netbuf_add_16bitnum(buf, buflen, offset, header->nscount);
|
||||||
netbuf_add_16bitnum(buf, buflen, offset, header->arcount);
|
netbuf_add_16bitnum(buf, buflen, offset, header->arcount);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void netbuf_add_dnsquery_question(unsigned char *buf, int buflen, int *offset, struct dnsquery_question *question)
|
static void netbuf_add_dnsquery_question(unsigned char *buf,
|
||||||
|
int buflen,
|
||||||
|
int *offset,
|
||||||
|
struct dnsquery_question *question)
|
||||||
{
|
{
|
||||||
netbuf_add_domain_name(buf, buflen, offset, question->qname);
|
netbuf_add_domain_name(buf, buflen, offset, question->qname);
|
||||||
netbuf_add_16bitnum(buf, buflen, offset, question->qtype);
|
netbuf_add_16bitnum(buf, buflen, offset, question->qtype);
|
||||||
netbuf_add_16bitnum(buf, buflen, offset, question->qclass);
|
netbuf_add_16bitnum(buf, buflen, offset, question->qclass);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int resolver_win32_srv_lookup(xmpp_ctx_t *ctx, const char *fulldomain,
|
static int resolver_win32_srv_lookup(xmpp_ctx_t *ctx,
|
||||||
|
const char *fulldomain,
|
||||||
resolver_srv_rr_t **srv_rr_list)
|
resolver_srv_rr_t **srv_rr_list)
|
||||||
{
|
{
|
||||||
resolver_srv_rr_t *rr;
|
resolver_srv_rr_t *rr;
|
||||||
HINSTANCE hdnsapi = NULL;
|
HINSTANCE hdnsapi = NULL;
|
||||||
|
|
||||||
DNS_STATUS (WINAPI * pDnsQuery_A)(PCSTR, WORD, DWORD, PIP4_ARRAY, DNS_RECORDA**, PVOID*);
|
DNS_STATUS(WINAPI * pDnsQuery_A)
|
||||||
void (WINAPI * pDnsRecordListFree)(DNS_RECORDA*, DNS_FREE_TYPE);
|
(PCSTR, WORD, DWORD, PIP4_ARRAY, DNS_RECORDA **, PVOID *);
|
||||||
|
void(WINAPI * pDnsRecordListFree)(DNS_RECORDA *, DNS_FREE_TYPE);
|
||||||
|
|
||||||
if (hdnsapi = LoadLibrary("dnsapi.dll")) {
|
if (hdnsapi = LoadLibrary("dnsapi.dll")) {
|
||||||
pDnsQuery_A = (void *)GetProcAddress(hdnsapi, "DnsQuery_A");
|
pDnsQuery_A = (void *)GetProcAddress(hdnsapi, "DnsQuery_A");
|
||||||
pDnsRecordListFree = (void *)GetProcAddress(hdnsapi, "DnsRecordListFree");
|
pDnsRecordListFree =
|
||||||
|
(void *)GetProcAddress(hdnsapi, "DnsRecordListFree");
|
||||||
|
|
||||||
if (pDnsQuery_A && pDnsRecordListFree) {
|
if (pDnsQuery_A && pDnsRecordListFree) {
|
||||||
DNS_RECORDA *dnsrecords = NULL;
|
DNS_RECORDA *dnsrecords = NULL;
|
||||||
DNS_STATUS error;
|
DNS_STATUS error;
|
||||||
|
|
||||||
error = pDnsQuery_A(fulldomain, DNS_TYPE_SRV, DNS_QUERY_STANDARD, NULL, &dnsrecords, NULL);
|
error = pDnsQuery_A(fulldomain, DNS_TYPE_SRV, DNS_QUERY_STANDARD,
|
||||||
|
NULL, &dnsrecords, NULL);
|
||||||
|
|
||||||
if (error == 0) {
|
if (error == 0) {
|
||||||
DNS_RECORDA *current = dnsrecords;
|
DNS_RECORDA *current = dnsrecords;
|
||||||
@@ -704,252 +726,243 @@ static int resolver_win32_srv_lookup(xmpp_ctx_t *ctx, const char *fulldomain,
|
|||||||
return *srv_rr_list != NULL ? XMPP_DOMAIN_FOUND : XMPP_DOMAIN_NOT_FOUND;
|
return *srv_rr_list != NULL ? XMPP_DOMAIN_FOUND : XMPP_DOMAIN_NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int resolver_win32_srv_query(const char *fulldomain,
|
static int
|
||||||
unsigned char *buf, size_t len)
|
resolver_win32_srv_query(const char *fulldomain, unsigned char *buf, size_t len)
|
||||||
{
|
{
|
||||||
int set = 0;
|
int set = 0;
|
||||||
int insize = 0;
|
int insize = 0;
|
||||||
|
|
||||||
/* if dnsapi didn't work/isn't there, try querying the dns server manually */
|
/* if dnsapi didn't work/isn't there, try querying the dns server manually
|
||||||
if (!set)
|
*/
|
||||||
{
|
if (!set) {
|
||||||
struct dnsquery_header header;
|
struct dnsquery_header header;
|
||||||
struct dnsquery_question question;
|
struct dnsquery_question question;
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
int addrlen;
|
int addrlen;
|
||||||
sock_t sock;
|
sock_t sock;
|
||||||
struct sockaddr_in dnsaddr;
|
struct sockaddr_in dnsaddr;
|
||||||
char dnsserverips[16][256];
|
char dnsserverips[16][256];
|
||||||
int numdnsservers = 0;
|
int numdnsservers = 0;
|
||||||
int j;
|
int j;
|
||||||
|
|
||||||
/* Try getting the DNS server ips from GetNetworkParams() in iphlpapi first */
|
/* Try getting the DNS server ips from GetNetworkParams() in iphlpapi
|
||||||
if (!numdnsservers)
|
* first */
|
||||||
{
|
if (!numdnsservers) {
|
||||||
HINSTANCE hiphlpapi = NULL;
|
HINSTANCE hiphlpapi = NULL;
|
||||||
DWORD (WINAPI * pGetNetworkParams)(PFIXED_INFO, PULONG);
|
DWORD(WINAPI * pGetNetworkParams)(PFIXED_INFO, PULONG);
|
||||||
|
|
||||||
if (hiphlpapi = LoadLibrary("Iphlpapi.dll"))
|
if (hiphlpapi = LoadLibrary("Iphlpapi.dll")) {
|
||||||
{
|
pGetNetworkParams =
|
||||||
pGetNetworkParams = (void *)GetProcAddress(hiphlpapi, "GetNetworkParams");
|
(void *)GetProcAddress(hiphlpapi, "GetNetworkParams");
|
||||||
|
|
||||||
if (pGetNetworkParams)
|
if (pGetNetworkParams) {
|
||||||
{
|
FIXED_INFO *fi;
|
||||||
FIXED_INFO *fi;
|
ULONG len;
|
||||||
ULONG len;
|
DWORD error;
|
||||||
DWORD error;
|
char buffer[65535];
|
||||||
char buffer[65535];
|
|
||||||
|
|
||||||
len = 65535;
|
len = 65535;
|
||||||
fi = (FIXED_INFO *)buffer;
|
fi = (FIXED_INFO *)buffer;
|
||||||
|
|
||||||
if ((error = pGetNetworkParams(fi, &len)) == ERROR_SUCCESS)
|
if ((error = pGetNetworkParams(fi, &len)) ==
|
||||||
{
|
ERROR_SUCCESS) {
|
||||||
IP_ADDR_STRING *pias = &(fi->DnsServerList);
|
IP_ADDR_STRING *pias = &(fi->DnsServerList);
|
||||||
|
|
||||||
while (pias && numdnsservers < 16)
|
while (pias && numdnsservers < 16) {
|
||||||
{
|
strcpy(dnsserverips[numdnsservers++],
|
||||||
strcpy(dnsserverips[numdnsservers++], pias->IpAddress.String);
|
pias->IpAddress.String);
|
||||||
pias = pias->Next;
|
pias = pias->Next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
FreeLibrary(hiphlpapi);
|
FreeLibrary(hiphlpapi);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Next, try getting the DNS server ips from the registry */
|
/* Next, try getting the DNS server ips from the registry */
|
||||||
if (!numdnsservers)
|
if (!numdnsservers) {
|
||||||
{
|
HKEY search;
|
||||||
HKEY search;
|
LONG error;
|
||||||
LONG error;
|
|
||||||
|
|
||||||
error = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters", 0, KEY_READ, &search);
|
error = RegOpenKeyEx(
|
||||||
|
HKEY_LOCAL_MACHINE,
|
||||||
|
"SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters", 0,
|
||||||
|
KEY_READ, &search);
|
||||||
|
|
||||||
if (error != ERROR_SUCCESS)
|
if (error != ERROR_SUCCESS) {
|
||||||
{
|
error = RegOpenKeyEx(
|
||||||
error = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\VxD\\MSTCP", 0, KEY_READ, &search);
|
HKEY_LOCAL_MACHINE,
|
||||||
}
|
"SYSTEM\\CurrentControlSet\\Services\\VxD\\MSTCP", 0,
|
||||||
|
KEY_READ, &search);
|
||||||
|
}
|
||||||
|
|
||||||
if (error == ERROR_SUCCESS)
|
if (error == ERROR_SUCCESS) {
|
||||||
{
|
char name[512];
|
||||||
char name[512];
|
DWORD len = 512;
|
||||||
DWORD len = 512;
|
|
||||||
|
|
||||||
error = RegQueryValueEx(search, "NameServer", NULL, NULL, (LPBYTE)name, &len);
|
error = RegQueryValueEx(search, "NameServer", NULL, NULL,
|
||||||
|
(LPBYTE)name, &len);
|
||||||
|
|
||||||
if (error != ERROR_SUCCESS)
|
if (error != ERROR_SUCCESS) {
|
||||||
{
|
error = RegQueryValueEx(search, "DhcpNameServer", NULL,
|
||||||
error = RegQueryValueEx(search, "DhcpNameServer", NULL, NULL, (LPBYTE)name, &len);
|
NULL, (LPBYTE)name, &len);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (error == ERROR_SUCCESS)
|
if (error == ERROR_SUCCESS) {
|
||||||
{
|
char *parse = "0123456789.", *start, *end;
|
||||||
char *parse = "0123456789.", *start, *end;
|
start = name;
|
||||||
start = name;
|
end = name;
|
||||||
end = name;
|
name[len] = '\0';
|
||||||
name[len] = '\0';
|
|
||||||
|
|
||||||
while (*start && numdnsservers < 16)
|
while (*start && numdnsservers < 16) {
|
||||||
{
|
while (strchr(parse, *end)) {
|
||||||
while (strchr(parse, *end))
|
end++;
|
||||||
{
|
}
|
||||||
end++;
|
|
||||||
}
|
|
||||||
|
|
||||||
strncpy(dnsserverips[numdnsservers++], start, end - start);
|
strncpy(dnsserverips[numdnsservers++], start,
|
||||||
|
end - start);
|
||||||
|
|
||||||
while (*end && !strchr(parse, *end))
|
while (*end && !strchr(parse, *end)) {
|
||||||
{
|
end++;
|
||||||
end++;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
start = end;
|
start = end;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RegCloseKey(search);
|
RegCloseKey(search);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!numdnsservers)
|
if (!numdnsservers) {
|
||||||
{
|
HKEY searchlist;
|
||||||
HKEY searchlist;
|
LONG error;
|
||||||
LONG error;
|
|
||||||
|
|
||||||
error = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces", 0, KEY_READ, &searchlist);
|
error = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
|
||||||
|
"SYSTEM\\CurrentControlSet\\Services\\Tcpip\\P"
|
||||||
|
"arameters\\Interfaces",
|
||||||
|
0, KEY_READ, &searchlist);
|
||||||
|
|
||||||
if (error == ERROR_SUCCESS)
|
if (error == ERROR_SUCCESS) {
|
||||||
{
|
unsigned int i;
|
||||||
unsigned int i;
|
DWORD numinterfaces = 0;
|
||||||
DWORD numinterfaces = 0;
|
|
||||||
|
|
||||||
RegQueryInfoKey(searchlist, NULL, NULL, NULL, &numinterfaces, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
|
RegQueryInfoKey(searchlist, NULL, NULL, NULL, &numinterfaces,
|
||||||
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL);
|
||||||
|
|
||||||
for (i = 0; i < numinterfaces; i++)
|
for (i = 0; i < numinterfaces; i++) {
|
||||||
{
|
char name[512];
|
||||||
char name[512];
|
DWORD len = 512;
|
||||||
DWORD len = 512;
|
HKEY searchentry;
|
||||||
HKEY searchentry;
|
|
||||||
|
|
||||||
RegEnumKeyEx(searchlist, i, (LPTSTR)name, &len, NULL, NULL, NULL, NULL);
|
RegEnumKeyEx(searchlist, i, (LPTSTR)name, &len, NULL, NULL,
|
||||||
|
NULL, NULL);
|
||||||
|
|
||||||
if (RegOpenKeyEx(searchlist, name, 0, KEY_READ, &searchentry) == ERROR_SUCCESS)
|
if (RegOpenKeyEx(searchlist, name, 0, KEY_READ,
|
||||||
{
|
&searchentry) == ERROR_SUCCESS) {
|
||||||
if (RegQueryValueEx(searchentry, "DhcpNameServer", NULL, NULL, (LPBYTE)name, &len) == ERROR_SUCCESS)
|
if (RegQueryValueEx(searchentry, "DhcpNameServer", NULL,
|
||||||
{
|
NULL, (LPBYTE)name,
|
||||||
char *parse = "0123456789.", *start, *end;
|
&len) == ERROR_SUCCESS) {
|
||||||
start = name;
|
char *parse = "0123456789.", *start, *end;
|
||||||
end = name;
|
start = name;
|
||||||
name[len] = '\0';
|
end = name;
|
||||||
|
name[len] = '\0';
|
||||||
|
|
||||||
while (*start && numdnsservers < 16)
|
while (*start && numdnsservers < 16) {
|
||||||
{
|
while (strchr(parse, *end)) {
|
||||||
while (strchr(parse, *end))
|
end++;
|
||||||
{
|
}
|
||||||
end++;
|
|
||||||
}
|
|
||||||
|
|
||||||
strncpy(dnsserverips[numdnsservers++], start, end - start);
|
strncpy(dnsserverips[numdnsservers++], start,
|
||||||
|
end - start);
|
||||||
|
|
||||||
while (*end && !strchr(parse, *end))
|
while (*end && !strchr(parse, *end)) {
|
||||||
{
|
end++;
|
||||||
end++;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
start = end;
|
start = end;
|
||||||
}
|
}
|
||||||
}
|
} else if (RegQueryValueEx(searchentry, "NameServer",
|
||||||
else if (RegQueryValueEx(searchentry, "NameServer", NULL, NULL, (LPBYTE)name, &len) == ERROR_SUCCESS)
|
NULL, NULL, (LPBYTE)name,
|
||||||
{
|
&len) == ERROR_SUCCESS) {
|
||||||
char *parse = "0123456789.", *start, *end;
|
char *parse = "0123456789.", *start, *end;
|
||||||
start = name;
|
start = name;
|
||||||
end = name;
|
end = name;
|
||||||
name[len] = '\0';
|
name[len] = '\0';
|
||||||
|
|
||||||
while (*start && numdnsservers < 16)
|
while (*start && numdnsservers < 16) {
|
||||||
{
|
while (strchr(parse, *end)) {
|
||||||
while (strchr(parse, *end))
|
end++;
|
||||||
{
|
}
|
||||||
end++;
|
|
||||||
}
|
|
||||||
|
|
||||||
strncpy(dnsserverips[numdnsservers++], start, end - start);
|
strncpy(dnsserverips[numdnsservers++], start,
|
||||||
|
end - start);
|
||||||
|
|
||||||
while (*end && !strchr(parse, *end))
|
while (*end && !strchr(parse, *end)) {
|
||||||
{
|
end++;
|
||||||
end++;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
start = end;
|
start = end;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
RegCloseKey(searchentry);
|
RegCloseKey(searchentry);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
RegCloseKey(searchlist);
|
RegCloseKey(searchlist);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If we have a DNS server, use it */
|
/* If we have a DNS server, use it */
|
||||||
if (numdnsservers)
|
if (numdnsservers) {
|
||||||
{
|
ULONG nonblocking = 1;
|
||||||
ULONG nonblocking = 1;
|
int i;
|
||||||
int i;
|
|
||||||
|
|
||||||
memset(&header, 0, sizeof(header));
|
memset(&header, 0, sizeof(header));
|
||||||
header.id = 12345; /* FIXME: Get a better id here */
|
header.id = 12345; /* FIXME: Get a better id here */
|
||||||
header.rd = 1;
|
header.rd = 1;
|
||||||
header.qdcount = 1;
|
header.qdcount = 1;
|
||||||
|
|
||||||
netbuf_add_dnsquery_header(buf, (int)len, &offset, &header);
|
netbuf_add_dnsquery_header(buf, (int)len, &offset, &header);
|
||||||
|
|
||||||
memset(&question, 0, sizeof(question));
|
memset(&question, 0, sizeof(question));
|
||||||
strncpy(question.qname, fulldomain, 1024);
|
strncpy(question.qname, fulldomain, 1024);
|
||||||
question.qtype = 33; /* SRV */
|
question.qtype = 33; /* SRV */
|
||||||
question.qclass = 1; /* INTERNET! */
|
question.qclass = 1; /* INTERNET! */
|
||||||
|
|
||||||
netbuf_add_dnsquery_question(buf, (int)len, &offset, &question);
|
netbuf_add_dnsquery_question(buf, (int)len, &offset, &question);
|
||||||
|
|
||||||
insize = 0;
|
insize = 0;
|
||||||
for (i = 0; i < numdnsservers && insize <= 0; i++)
|
for (i = 0; i < numdnsservers && insize <= 0; i++) {
|
||||||
{
|
sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
||||||
sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
ioctlsocket(sock, FIONBIO, &nonblocking);
|
||||||
ioctlsocket(sock, FIONBIO, &nonblocking);
|
|
||||||
|
|
||||||
memset(&dnsaddr, 0, sizeof(dnsaddr));
|
memset(&dnsaddr, 0, sizeof(dnsaddr));
|
||||||
|
|
||||||
dnsaddr.sin_family = AF_INET;
|
dnsaddr.sin_family = AF_INET;
|
||||||
dnsaddr.sin_port = htons(53);
|
dnsaddr.sin_port = htons(53);
|
||||||
dnsaddr.sin_addr.s_addr = inet_addr(dnsserverips[i]);
|
dnsaddr.sin_addr.s_addr = inet_addr(dnsserverips[i]);
|
||||||
|
|
||||||
addrlen = sizeof(dnsaddr);
|
addrlen = sizeof(dnsaddr);
|
||||||
sendto(sock, (char *)buf, offset, 0, (struct sockaddr *)&dnsaddr, addrlen);
|
sendto(sock, (char *)buf, offset, 0,
|
||||||
for (j = 0; j < 50; j++)
|
(struct sockaddr *)&dnsaddr, addrlen);
|
||||||
{
|
for (j = 0; j < 50; j++) {
|
||||||
insize = recvfrom(sock, (char *)buf, (int)len, 0, (struct sockaddr *)&dnsaddr, &addrlen);
|
insize = recvfrom(sock, (char *)buf, (int)len, 0,
|
||||||
if (insize == SOCKET_ERROR)
|
(struct sockaddr *)&dnsaddr, &addrlen);
|
||||||
{
|
if (insize == SOCKET_ERROR) {
|
||||||
if (sock_error() == WSAEWOULDBLOCK)
|
if (sock_error() == WSAEWOULDBLOCK) {
|
||||||
{
|
Sleep(100);
|
||||||
Sleep(100);
|
} else {
|
||||||
}
|
break;
|
||||||
else
|
}
|
||||||
{
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
closesocket(sock);
|
|
||||||
}
|
|
||||||
set = insize > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
closesocket(sock);
|
||||||
|
}
|
||||||
|
set = insize > 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return set ? insize : -1;
|
return set ? insize : -1;
|
||||||
|
|||||||
@@ -46,8 +46,10 @@ void resolver_shutdown(void);
|
|||||||
*
|
*
|
||||||
* @return XMPP_DOMAIN_FOUND on success or XMPP_DOMAIN_NOT_FOUND on fail
|
* @return XMPP_DOMAIN_FOUND on success or XMPP_DOMAIN_NOT_FOUND on fail
|
||||||
*/
|
*/
|
||||||
int resolver_srv_lookup_buf(xmpp_ctx_t *ctx, const unsigned char *buf,
|
int resolver_srv_lookup_buf(xmpp_ctx_t *ctx,
|
||||||
size_t len, resolver_srv_rr_t **srv_rr_list);
|
const unsigned char *buf,
|
||||||
|
size_t len,
|
||||||
|
resolver_srv_rr_t **srv_rr_list);
|
||||||
/** Resolve SRV record.
|
/** Resolve SRV record.
|
||||||
*
|
*
|
||||||
* @param ctx a Strophe context object
|
* @param ctx a Strophe context object
|
||||||
@@ -58,8 +60,11 @@ int resolver_srv_lookup_buf(xmpp_ctx_t *ctx, const unsigned char *buf,
|
|||||||
*
|
*
|
||||||
* @return XMPP_DOMAIN_FOUND on success or XMPP_DOMAIN_NOT_FOUND on fail
|
* @return XMPP_DOMAIN_FOUND on success or XMPP_DOMAIN_NOT_FOUND on fail
|
||||||
*/
|
*/
|
||||||
int resolver_srv_lookup(xmpp_ctx_t *ctx, const char *service, const char *proto,
|
int resolver_srv_lookup(xmpp_ctx_t *ctx,
|
||||||
const char *domain, resolver_srv_rr_t **srv_rr_list);
|
const char *service,
|
||||||
|
const char *proto,
|
||||||
|
const char *domain,
|
||||||
|
resolver_srv_rr_t **srv_rr_list);
|
||||||
|
|
||||||
/** Release a list returned by resolver_srv_lookup() or
|
/** Release a list returned by resolver_srv_lookup() or
|
||||||
* resolver_srv_lookup_buf().
|
* resolver_srv_lookup_buf().
|
||||||
|
|||||||
221
src/sasl.c
221
src/sasl.c
@@ -29,16 +29,16 @@
|
|||||||
/* strtok_s() has appeared in visual studio 2005.
|
/* strtok_s() has appeared in visual studio 2005.
|
||||||
Use own implementation for older versions. */
|
Use own implementation for older versions. */
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
# if (_MSC_VER >= 1400)
|
#if (_MSC_VER >= 1400)
|
||||||
# define strtok_r strtok_s
|
#define strtok_r strtok_s
|
||||||
# else
|
#else
|
||||||
# define strtok_r xmpp_strtok_r
|
#define strtok_r xmpp_strtok_r
|
||||||
# endif
|
#endif
|
||||||
#endif /* _MSC_VER */
|
#endif /* _MSC_VER */
|
||||||
|
|
||||||
|
|
||||||
/** generate authentication string for the SASL PLAIN mechanism */
|
/** generate authentication string for the SASL PLAIN mechanism */
|
||||||
char *sasl_plain(xmpp_ctx_t *ctx, const char *authid, const char *password) {
|
char *sasl_plain(xmpp_ctx_t *ctx, const char *authid, const char *password)
|
||||||
|
{
|
||||||
size_t idlen, passlen;
|
size_t idlen, passlen;
|
||||||
size_t msglen;
|
size_t msglen;
|
||||||
char *result = NULL;
|
char *result = NULL;
|
||||||
@@ -52,12 +52,12 @@ char *sasl_plain(xmpp_ctx_t *ctx, const char *authid, const char *password) {
|
|||||||
msglen = 2 + idlen + passlen;
|
msglen = 2 + idlen + passlen;
|
||||||
msg = xmpp_alloc(ctx, msglen);
|
msg = xmpp_alloc(ctx, msglen);
|
||||||
if (msg != NULL) {
|
if (msg != NULL) {
|
||||||
msg[0] = '\0';
|
msg[0] = '\0';
|
||||||
memcpy(msg+1, authid, idlen);
|
memcpy(msg + 1, authid, idlen);
|
||||||
msg[1+idlen] = '\0';
|
msg[1 + idlen] = '\0';
|
||||||
memcpy(msg+1+idlen+1, password, passlen);
|
memcpy(msg + 1 + idlen + 1, password, passlen);
|
||||||
result = xmpp_base64_encode(ctx, (unsigned char *)msg, msglen);
|
result = xmpp_base64_encode(ctx, (unsigned char *)msg, msglen);
|
||||||
xmpp_free(ctx, msg);
|
xmpp_free(ctx, msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
@@ -72,8 +72,8 @@ static char *_make_string(xmpp_ctx_t *ctx, const char *s, const unsigned len)
|
|||||||
|
|
||||||
result = xmpp_alloc(ctx, len + 1);
|
result = xmpp_alloc(ctx, len + 1);
|
||||||
if (result != NULL) {
|
if (result != NULL) {
|
||||||
memcpy(result, s, len);
|
memcpy(result, s, len);
|
||||||
result[len] = '\0';
|
result[len] = '\0';
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -86,10 +86,10 @@ static char *_make_quoted(xmpp_ctx_t *ctx, const char *s)
|
|||||||
|
|
||||||
result = xmpp_alloc(ctx, len + 3);
|
result = xmpp_alloc(ctx, len + 3);
|
||||||
if (result != NULL) {
|
if (result != NULL) {
|
||||||
result[0] = '"';
|
result[0] = '"';
|
||||||
memcpy(result+1, s, len);
|
memcpy(result + 1, s, len);
|
||||||
result[len+1] = '"';
|
result[len + 1] = '"';
|
||||||
result[len+2] = '\0';
|
result[len + 2] = '\0';
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -104,51 +104,56 @@ static hash_t *_parse_digest_challenge(xmpp_ctx_t *ctx, const char *msg)
|
|||||||
|
|
||||||
text = (unsigned char *)xmpp_base64_decode_str(ctx, msg, strlen(msg));
|
text = (unsigned char *)xmpp_base64_decode_str(ctx, msg, strlen(msg));
|
||||||
if (text == NULL) {
|
if (text == NULL) {
|
||||||
xmpp_error(ctx, "SASL", "couldn't Base64 decode challenge!");
|
xmpp_error(ctx, "SASL", "couldn't Base64 decode challenge!");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = hash_new(ctx, 10, xmpp_free);
|
result = hash_new(ctx, 10, xmpp_free);
|
||||||
if (result != NULL) {
|
if (result != NULL) {
|
||||||
s = text;
|
s = text;
|
||||||
while (*s != '\0') {
|
while (*s != '\0') {
|
||||||
/* skip any leading commas and spaces */
|
/* skip any leading commas and spaces */
|
||||||
while ((*s == ',') || (*s == ' ')) s++;
|
while ((*s == ',') || (*s == ' '))
|
||||||
/* accumulate a key ending at '=' */
|
s++;
|
||||||
t = s;
|
/* accumulate a key ending at '=' */
|
||||||
while ((*t != '=') && (*t != '\0')) t++;
|
t = s;
|
||||||
if (*t == '\0') break; /* bad string */
|
while ((*t != '=') && (*t != '\0'))
|
||||||
key = _make_string(ctx, (char *)s, (t-s));
|
t++;
|
||||||
if (key == NULL) break;
|
if (*t == '\0')
|
||||||
|
break; /* bad string */
|
||||||
|
key = _make_string(ctx, (char *)s, (t - s));
|
||||||
|
if (key == NULL)
|
||||||
|
break;
|
||||||
/* advance our start pointer past the key */
|
/* advance our start pointer past the key */
|
||||||
s = t + 1;
|
s = t + 1;
|
||||||
t = s;
|
t = s;
|
||||||
/* if we see quotes, grab the string in between */
|
/* if we see quotes, grab the string in between */
|
||||||
if ((*s == '\'') || (*s == '"')) {
|
if ((*s == '\'') || (*s == '"')) {
|
||||||
t++;
|
t++;
|
||||||
while ((*t != *s) && (*t != '\0'))
|
while ((*t != *s) && (*t != '\0'))
|
||||||
t++;
|
t++;
|
||||||
value = _make_string(ctx, (char *)s+1, (t-s-1));
|
value = _make_string(ctx, (char *)s + 1, (t - s - 1));
|
||||||
if (*t == *s) {
|
if (*t == *s) {
|
||||||
s = t + 1;
|
s = t + 1;
|
||||||
} else {
|
} else {
|
||||||
s = t;
|
s = t;
|
||||||
}
|
}
|
||||||
/* otherwise, accumulate a value ending in ',' or '\0' */
|
/* otherwise, accumulate a value ending in ',' or '\0' */
|
||||||
} else {
|
} else {
|
||||||
while ((*t != ',') && (*t != '\0')) t++;
|
while ((*t != ',') && (*t != '\0'))
|
||||||
value = _make_string(ctx, (char *)s, (t-s));
|
t++;
|
||||||
s = t;
|
value = _make_string(ctx, (char *)s, (t - s));
|
||||||
}
|
s = t;
|
||||||
if (value == NULL) {
|
}
|
||||||
xmpp_free(ctx, key);
|
if (value == NULL) {
|
||||||
break;
|
xmpp_free(ctx, key);
|
||||||
}
|
break;
|
||||||
/* TODO: check for collisions per spec */
|
}
|
||||||
hash_add(result, key, value);
|
/* TODO: check for collisions per spec */
|
||||||
/* hash table now owns the value, free the key */
|
hash_add(result, key, value);
|
||||||
xmpp_free(ctx, key);
|
/* hash table now owns the value, free the key */
|
||||||
}
|
xmpp_free(ctx, key);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
xmpp_free(ctx, text);
|
xmpp_free(ctx, text);
|
||||||
|
|
||||||
@@ -162,63 +167,75 @@ static void _digest_to_hex(const char *digest, char *hex)
|
|||||||
const char hexdigit[] = "0123456789abcdef";
|
const char hexdigit[] = "0123456789abcdef";
|
||||||
|
|
||||||
for (i = 0; i < 16; i++) {
|
for (i = 0; i < 16; i++) {
|
||||||
*hex++ = hexdigit[ (digest[i] >> 4) & 0x0F ];
|
*hex++ = hexdigit[(digest[i] >> 4) & 0x0F];
|
||||||
*hex++ = hexdigit[ digest[i] & 0x0F ];
|
*hex++ = hexdigit[digest[i] & 0x0F];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** append 'key="value"' to a buffer, growing as necessary */
|
/** append 'key="value"' to a buffer, growing as necessary */
|
||||||
static char *_add_key(xmpp_ctx_t *ctx, hash_t *table, const char *key,
|
static char *_add_key(xmpp_ctx_t *ctx,
|
||||||
char *buf, int *len, int quote)
|
hash_t *table,
|
||||||
|
const char *key,
|
||||||
|
char *buf,
|
||||||
|
int *len,
|
||||||
|
int quote)
|
||||||
{
|
{
|
||||||
int olen,nlen;
|
int olen, nlen;
|
||||||
int keylen, valuelen;
|
int keylen, valuelen;
|
||||||
const char *value, *qvalue;
|
const char *value, *qvalue;
|
||||||
char *c;
|
char *c;
|
||||||
|
|
||||||
/* allocate a zero-length string if necessary */
|
/* allocate a zero-length string if necessary */
|
||||||
if (buf == NULL) {
|
if (buf == NULL) {
|
||||||
buf = xmpp_alloc(ctx, 1);
|
buf = xmpp_alloc(ctx, 1);
|
||||||
buf[0] = '\0';
|
buf[0] = '\0';
|
||||||
}
|
}
|
||||||
if (buf == NULL) return NULL;
|
if (buf == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
/* get current string length */
|
/* get current string length */
|
||||||
olen = strlen(buf);
|
olen = strlen(buf);
|
||||||
value = hash_get(table, key);
|
value = hash_get(table, key);
|
||||||
if (value == NULL) {
|
if (value == NULL) {
|
||||||
xmpp_error(ctx, "SASL", "couldn't retrieve value for '%s'", key);
|
xmpp_error(ctx, "SASL", "couldn't retrieve value for '%s'", key);
|
||||||
value = "";
|
value = "";
|
||||||
}
|
}
|
||||||
if (quote) {
|
if (quote) {
|
||||||
qvalue = _make_quoted(ctx, value);
|
qvalue = _make_quoted(ctx, value);
|
||||||
} else {
|
} else {
|
||||||
qvalue = value;
|
qvalue = value;
|
||||||
}
|
}
|
||||||
/* added length is key + '=' + value */
|
/* added length is key + '=' + value */
|
||||||
/* (+ ',' if we're not the first entry */
|
/* (+ ',' if we're not the first entry */
|
||||||
keylen = strlen(key);
|
keylen = strlen(key);
|
||||||
valuelen = strlen(qvalue);
|
valuelen = strlen(qvalue);
|
||||||
nlen = (olen ? 1 : 0) + keylen + 1 + valuelen + 1;
|
nlen = (olen ? 1 : 0) + keylen + 1 + valuelen + 1;
|
||||||
buf = xmpp_realloc(ctx, buf, olen+nlen);
|
buf = xmpp_realloc(ctx, buf, olen + nlen);
|
||||||
|
|
||||||
if (buf != NULL) {
|
if (buf != NULL) {
|
||||||
c = buf + olen;
|
c = buf + olen;
|
||||||
if (olen) *c++ = ',';
|
if (olen)
|
||||||
memcpy(c, key, keylen); c += keylen;
|
*c++ = ',';
|
||||||
*c++ = '=';
|
memcpy(c, key, keylen);
|
||||||
memcpy(c, qvalue, valuelen); c += valuelen;
|
c += keylen;
|
||||||
*c++ = '\0';
|
*c++ = '=';
|
||||||
|
memcpy(c, qvalue, valuelen);
|
||||||
|
c += valuelen;
|
||||||
|
*c++ = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (quote) xmpp_free(ctx, (char *)qvalue);
|
if (quote)
|
||||||
|
xmpp_free(ctx, (char *)qvalue);
|
||||||
|
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** generate auth response string for the SASL DIGEST-MD5 mechanism */
|
/** generate auth response string for the SASL DIGEST-MD5 mechanism */
|
||||||
char *sasl_digest_md5(xmpp_ctx_t *ctx, const char *challenge,
|
char *sasl_digest_md5(xmpp_ctx_t *ctx,
|
||||||
const char *jid, const char *password) {
|
const char *challenge,
|
||||||
|
const char *jid,
|
||||||
|
const char *password)
|
||||||
|
{
|
||||||
hash_t *table;
|
hash_t *table;
|
||||||
char *result = NULL;
|
char *result = NULL;
|
||||||
char *node, *domain, *realm;
|
char *node, *domain, *realm;
|
||||||
@@ -231,21 +248,21 @@ char *sasl_digest_md5(xmpp_ctx_t *ctx, const char *challenge,
|
|||||||
char cnonce[13];
|
char cnonce[13];
|
||||||
|
|
||||||
/* our digest response is
|
/* our digest response is
|
||||||
Hex( KD( HEX(MD5(A1)),
|
Hex( KD( HEX(MD5(A1)),
|
||||||
nonce ':' nc ':' cnonce ':' qop ':' HEX(MD5(A2))
|
nonce ':' nc ':' cnonce ':' qop ':' HEX(MD5(A2))
|
||||||
))
|
))
|
||||||
|
|
||||||
where KD(k, s) = MD5(k ':' s),
|
where KD(k, s) = MD5(k ':' s),
|
||||||
A1 = MD5( node ':' realm ':' password ) ':' nonce ':' cnonce
|
A1 = MD5( node ':' realm ':' password ) ':' nonce ':' cnonce
|
||||||
A2 = "AUTHENTICATE" ':' "xmpp/" domain
|
A2 = "AUTHENTICATE" ':' "xmpp/" domain
|
||||||
|
|
||||||
If there is an authzid it is ':'-appended to A1 */
|
If there is an authzid it is ':'-appended to A1 */
|
||||||
|
|
||||||
/* parse the challenge */
|
/* parse the challenge */
|
||||||
table = _parse_digest_challenge(ctx, challenge);
|
table = _parse_digest_challenge(ctx, challenge);
|
||||||
if (table == NULL) {
|
if (table == NULL) {
|
||||||
xmpp_error(ctx, "SASL", "couldn't parse digest challenge");
|
xmpp_error(ctx, "SASL", "couldn't parse digest challenge");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
node = xmpp_jid_node(ctx, jid);
|
node = xmpp_jid_node(ctx, jid);
|
||||||
@@ -255,8 +272,8 @@ char *sasl_digest_md5(xmpp_ctx_t *ctx, const char *challenge,
|
|||||||
server */
|
server */
|
||||||
realm = hash_get(table, "realm");
|
realm = hash_get(table, "realm");
|
||||||
if (realm == NULL || strlen(realm) == 0) {
|
if (realm == NULL || strlen(realm) == 0) {
|
||||||
hash_add(table, "realm", xmpp_strdup(ctx, domain));
|
hash_add(table, "realm", xmpp_strdup(ctx, domain));
|
||||||
realm = hash_get(table, "realm");
|
realm = hash_get(table, "realm");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* add our response fields */
|
/* add our response fields */
|
||||||
@@ -268,8 +285,8 @@ char *sasl_digest_md5(xmpp_ctx_t *ctx, const char *challenge,
|
|||||||
hash_add(table, "qop", xmpp_strdup(ctx, "auth"));
|
hash_add(table, "qop", xmpp_strdup(ctx, "auth"));
|
||||||
value = xmpp_alloc(ctx, 5 + strlen(domain) + 1);
|
value = xmpp_alloc(ctx, 5 + strlen(domain) + 1);
|
||||||
memcpy(value, "xmpp/", 5);
|
memcpy(value, "xmpp/", 5);
|
||||||
memcpy(value+5, domain, strlen(domain));
|
memcpy(value + 5, domain, strlen(domain));
|
||||||
value[5+strlen(domain)] = '\0';
|
value[5 + strlen(domain)] = '\0';
|
||||||
hash_add(table, "digest-uri", value);
|
hash_add(table, "digest-uri", value);
|
||||||
|
|
||||||
/* generate response */
|
/* generate response */
|
||||||
@@ -304,8 +321,8 @@ char *sasl_digest_md5(xmpp_ctx_t *ctx, const char *challenge,
|
|||||||
value = hash_get(table, "digest-uri");
|
value = hash_get(table, "digest-uri");
|
||||||
MD5Update(&MD5, (unsigned char *)value, strlen(value));
|
MD5Update(&MD5, (unsigned char *)value, strlen(value));
|
||||||
if (strcmp(hash_get(table, "qop"), "auth") != 0) {
|
if (strcmp(hash_get(table, "qop"), "auth") != 0) {
|
||||||
MD5Update(&MD5, (unsigned char *)":00000000000000000000000000000000",
|
MD5Update(&MD5, (unsigned char *)":00000000000000000000000000000000",
|
||||||
33);
|
33);
|
||||||
}
|
}
|
||||||
MD5Final(digest, &MD5);
|
MD5Final(digest, &MD5);
|
||||||
|
|
||||||
@@ -332,7 +349,7 @@ char *sasl_digest_md5(xmpp_ctx_t *ctx, const char *challenge,
|
|||||||
MD5Update(&MD5, (unsigned char *)hex, 32);
|
MD5Update(&MD5, (unsigned char *)hex, 32);
|
||||||
MD5Final(digest, &MD5);
|
MD5Final(digest, &MD5);
|
||||||
|
|
||||||
response = xmpp_alloc(ctx, 32+1);
|
response = xmpp_alloc(ctx, 32 + 1);
|
||||||
_digest_to_hex((char *)digest, hex);
|
_digest_to_hex((char *)digest, hex);
|
||||||
memcpy(response, hex, 32);
|
memcpy(response, hex, 32);
|
||||||
response[32] = '\0';
|
response[32] = '\0';
|
||||||
@@ -363,8 +380,10 @@ char *sasl_digest_md5(xmpp_ctx_t *ctx, const char *challenge,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** generate auth response string for the SASL SCRAM-SHA-1 mechanism */
|
/** generate auth response string for the SASL SCRAM-SHA-1 mechanism */
|
||||||
char *sasl_scram_sha1(xmpp_ctx_t *ctx, const char *challenge,
|
char *sasl_scram_sha1(xmpp_ctx_t *ctx,
|
||||||
const char *first_bare, const char *jid,
|
const char *challenge,
|
||||||
|
const char *first_bare,
|
||||||
|
const char *jid,
|
||||||
const char *password)
|
const char *password)
|
||||||
{
|
{
|
||||||
uint8_t key[SHA1_DIGEST_SIZE];
|
uint8_t key[SHA1_DIGEST_SIZE];
|
||||||
@@ -430,8 +449,8 @@ char *sasl_scram_sha1(xmpp_ctx_t *ctx, const char *challenge,
|
|||||||
xmpp_snprintf(auth, auth_len, "%s,%s,%s", first_bare + 3, challenge,
|
xmpp_snprintf(auth, auth_len, "%s,%s,%s", first_bare + 3, challenge,
|
||||||
response);
|
response);
|
||||||
|
|
||||||
SCRAM_SHA1_ClientKey((uint8_t *)password, strlen(password),
|
SCRAM_SHA1_ClientKey((uint8_t *)password, strlen(password), (uint8_t *)sval,
|
||||||
(uint8_t *)sval, sval_len, (uint32_t)ival, key);
|
sval_len, (uint32_t)ival, key);
|
||||||
SCRAM_SHA1_ClientSignature(key, (uint8_t *)auth, strlen(auth), sign);
|
SCRAM_SHA1_ClientSignature(key, (uint8_t *)auth, strlen(auth), sign);
|
||||||
for (j = 0; j < SHA1_DIGEST_SIZE; j++) {
|
for (j = 0; j < SHA1_DIGEST_SIZE; j++) {
|
||||||
sign[j] ^= key[j];
|
sign[j] ^= key[j];
|
||||||
@@ -450,8 +469,8 @@ char *sasl_scram_sha1(xmpp_ctx_t *ctx, const char *challenge,
|
|||||||
strcat(response, sign_b64);
|
strcat(response, sign_b64);
|
||||||
xmpp_free(ctx, sign_b64);
|
xmpp_free(ctx, sign_b64);
|
||||||
|
|
||||||
response_b64 = xmpp_base64_encode(ctx, (unsigned char *)response,
|
response_b64 =
|
||||||
strlen(response));
|
xmpp_base64_encode(ctx, (unsigned char *)response, strlen(response));
|
||||||
if (!response_b64) {
|
if (!response_b64) {
|
||||||
goto out_response;
|
goto out_response;
|
||||||
}
|
}
|
||||||
|
|||||||
16
src/sasl.h
16
src/sasl.h
@@ -1,7 +1,7 @@
|
|||||||
/* sasl.h
|
/* sasl.h
|
||||||
** strophe XMPP client library -- SASL authentication helpers
|
** strophe XMPP client library -- SASL authentication helpers
|
||||||
**
|
**
|
||||||
** Copyright (C) 2005-2009 Collecta, Inc.
|
** Copyright (C) 2005-2009 Collecta, Inc.
|
||||||
**
|
**
|
||||||
** This software is provided AS-IS with no warranty, either express
|
** This software is provided AS-IS with no warranty, either express
|
||||||
** or implied.
|
** or implied.
|
||||||
@@ -21,10 +21,14 @@
|
|||||||
/** low-level sasl routines */
|
/** low-level sasl routines */
|
||||||
|
|
||||||
char *sasl_plain(xmpp_ctx_t *ctx, const char *authid, const char *password);
|
char *sasl_plain(xmpp_ctx_t *ctx, const char *authid, const char *password);
|
||||||
char *sasl_digest_md5(xmpp_ctx_t *ctx, const char *challenge,
|
char *sasl_digest_md5(xmpp_ctx_t *ctx,
|
||||||
const char *jid, const char *password);
|
const char *challenge,
|
||||||
char *sasl_scram_sha1(xmpp_ctx_t *ctx, const char *challenge,
|
const char *jid,
|
||||||
const char *first_bare, const char *jid,
|
const char *password);
|
||||||
|
char *sasl_scram_sha1(xmpp_ctx_t *ctx,
|
||||||
|
const char *challenge,
|
||||||
|
const char *first_bare,
|
||||||
|
const char *jid,
|
||||||
const char *password);
|
const char *password);
|
||||||
|
|
||||||
#endif /* _LIBXMPP_SASL_H__ */
|
#endif /* _LIBXMPP_SASL_H__ */
|
||||||
|
|||||||
25
src/scram.c
25
src/scram.c
@@ -29,8 +29,10 @@
|
|||||||
static const uint8_t ipad = 0x36;
|
static const uint8_t ipad = 0x36;
|
||||||
static const uint8_t opad = 0x5C;
|
static const uint8_t opad = 0x5C;
|
||||||
|
|
||||||
static void crypto_HMAC_SHA1(const uint8_t *key, size_t key_len,
|
static void crypto_HMAC_SHA1(const uint8_t *key,
|
||||||
const uint8_t *text, size_t len,
|
size_t key_len,
|
||||||
|
const uint8_t *text,
|
||||||
|
size_t len,
|
||||||
uint8_t *digest)
|
uint8_t *digest)
|
||||||
{
|
{
|
||||||
uint8_t key_pad[HMAC_BLOCK_SIZE];
|
uint8_t key_pad[HMAC_BLOCK_SIZE];
|
||||||
@@ -64,11 +66,14 @@ static void crypto_HMAC_SHA1(const uint8_t *key, size_t key_len,
|
|||||||
crypto_SHA1_Final(&ctx, digest);
|
crypto_SHA1_Final(&ctx, digest);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SCRAM_SHA1_Hi(const uint8_t *text, size_t len,
|
static void SCRAM_SHA1_Hi(const uint8_t *text,
|
||||||
const uint8_t *salt, size_t salt_len, uint32_t i,
|
size_t len,
|
||||||
|
const uint8_t *salt,
|
||||||
|
size_t salt_len,
|
||||||
|
uint32_t i,
|
||||||
uint8_t *digest)
|
uint8_t *digest)
|
||||||
{
|
{
|
||||||
int k;
|
int k;
|
||||||
uint32_t j;
|
uint32_t j;
|
||||||
uint8_t tmp[128];
|
uint8_t tmp[128];
|
||||||
|
|
||||||
@@ -97,8 +102,11 @@ static void SCRAM_SHA1_Hi(const uint8_t *text, size_t len,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SCRAM_SHA1_ClientKey(const uint8_t *password, size_t len,
|
void SCRAM_SHA1_ClientKey(const uint8_t *password,
|
||||||
const uint8_t *salt, size_t salt_len, uint32_t i,
|
size_t len,
|
||||||
|
const uint8_t *salt,
|
||||||
|
size_t salt_len,
|
||||||
|
uint32_t i,
|
||||||
uint8_t *key)
|
uint8_t *key)
|
||||||
{
|
{
|
||||||
uint8_t salted[SHA1_DIGEST_SIZE];
|
uint8_t salted[SHA1_DIGEST_SIZE];
|
||||||
@@ -111,7 +119,8 @@ void SCRAM_SHA1_ClientKey(const uint8_t *password, size_t len,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void SCRAM_SHA1_ClientSignature(const uint8_t *ClientKey,
|
void SCRAM_SHA1_ClientSignature(const uint8_t *ClientKey,
|
||||||
const uint8_t *AuthMessage, size_t len,
|
const uint8_t *AuthMessage,
|
||||||
|
size_t len,
|
||||||
uint8_t *sign)
|
uint8_t *sign)
|
||||||
{
|
{
|
||||||
uint8_t stored[SHA1_DIGEST_SIZE];
|
uint8_t stored[SHA1_DIGEST_SIZE];
|
||||||
|
|||||||
10
src/scram.h
10
src/scram.h
@@ -21,12 +21,16 @@
|
|||||||
|
|
||||||
#include "sha1.h"
|
#include "sha1.h"
|
||||||
|
|
||||||
void SCRAM_SHA1_ClientKey(const uint8_t *password, size_t len,
|
void SCRAM_SHA1_ClientKey(const uint8_t *password,
|
||||||
const uint8_t *salt, size_t salt_len, uint32_t i,
|
size_t len,
|
||||||
|
const uint8_t *salt,
|
||||||
|
size_t salt_len,
|
||||||
|
uint32_t i,
|
||||||
uint8_t *key);
|
uint8_t *key);
|
||||||
|
|
||||||
void SCRAM_SHA1_ClientSignature(const uint8_t *ClientKey,
|
void SCRAM_SHA1_ClientSignature(const uint8_t *ClientKey,
|
||||||
const uint8_t *AuthMessage, size_t len,
|
const uint8_t *AuthMessage,
|
||||||
|
size_t len,
|
||||||
uint8_t *sign);
|
uint8_t *sign);
|
||||||
|
|
||||||
void SCRAM_SHA1_ClientProof(const uint8_t *ClientKey,
|
void SCRAM_SHA1_ClientProof(const uint8_t *ClientKey,
|
||||||
|
|||||||
90
src/sha1.c
90
src/sha1.c
@@ -14,10 +14,10 @@ Still 100% Public Domain
|
|||||||
|
|
||||||
Corrected a problem which generated improper hash values on 16 bit machines
|
Corrected a problem which generated improper hash values on 16 bit machines
|
||||||
Routine SHA1Update changed from
|
Routine SHA1Update changed from
|
||||||
void SHA1Update(SHA1_CTX* context, unsigned char* data, unsigned int
|
void SHA1Update(SHA1_CTX* context, unsigned char* data, unsigned int
|
||||||
len)
|
len)
|
||||||
to
|
to
|
||||||
void SHA1Update(SHA1_CTX* context, unsigned char* data, unsigned
|
void SHA1Update(SHA1_CTX* context, unsigned char* data, unsigned
|
||||||
long len)
|
long len)
|
||||||
|
|
||||||
The 'len' parameter was declared an int which works fine on 32 bit machines.
|
The 'len' parameter was declared an int which works fine on 32 bit machines.
|
||||||
@@ -86,27 +86,38 @@ static void SHA1_Transform(uint32_t state[5], const uint8_t buffer[64]);
|
|||||||
/* blk0() and blk() perform the initial expand. */
|
/* blk0() and blk() perform the initial expand. */
|
||||||
/* I got the idea of expanding during the round function from SSLeay */
|
/* I got the idea of expanding during the round function from SSLeay */
|
||||||
#define blk0(i) (block->l[i] = host_to_be(block->l[i]))
|
#define blk0(i) (block->l[i] = host_to_be(block->l[i]))
|
||||||
#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \
|
#define blk(i) \
|
||||||
^block->l[(i+2)&15]^block->l[i&15],1))
|
(block->l[i & 15] = rol(block->l[(i + 13) & 15] ^ block->l[(i + 8) & 15] ^ \
|
||||||
|
block->l[(i + 2) & 15] ^ block->l[i & 15], \
|
||||||
|
1))
|
||||||
|
|
||||||
/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
|
/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
|
||||||
#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30);
|
#define R0(v, w, x, y, z, i) \
|
||||||
#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30);
|
z += ((w & (x ^ y)) ^ y) + blk0(i) + 0x5A827999 + rol(v, 5); \
|
||||||
#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30);
|
w = rol(w, 30);
|
||||||
#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30);
|
#define R1(v, w, x, y, z, i) \
|
||||||
#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30);
|
z += ((w & (x ^ y)) ^ y) + blk(i) + 0x5A827999 + rol(v, 5); \
|
||||||
|
w = rol(w, 30);
|
||||||
|
#define R2(v, w, x, y, z, i) \
|
||||||
|
z += (w ^ x ^ y) + blk(i) + 0x6ED9EBA1 + rol(v, 5); \
|
||||||
|
w = rol(w, 30);
|
||||||
|
#define R3(v, w, x, y, z, i) \
|
||||||
|
z += (((w | x) & y) | (w & x)) + blk(i) + 0x8F1BBCDC + rol(v, 5); \
|
||||||
|
w = rol(w, 30);
|
||||||
|
#define R4(v, w, x, y, z, i) \
|
||||||
|
z += (w ^ x ^ y) + blk(i) + 0xCA62C1D6 + rol(v, 5); \
|
||||||
|
w = rol(w, 30);
|
||||||
|
|
||||||
static uint32_t host_to_be(uint32_t i)
|
static uint32_t host_to_be(uint32_t i)
|
||||||
{
|
{
|
||||||
#define le_to_be(i) ((rol((i),24) & 0xFF00FF00) | (rol((i),8) & 0x00FF00FF))
|
#define le_to_be(i) ((rol((i), 24) & 0xFF00FF00) | (rol((i), 8) & 0x00FF00FF))
|
||||||
#if defined(__BIG_ENDIAN__) || \
|
#if defined(__BIG_ENDIAN__) || \
|
||||||
(defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && \
|
(defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && \
|
||||||
__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
|
__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
|
||||||
return i;
|
return i;
|
||||||
#elif defined(__LITTLE_ENDIAN__) || \
|
#elif defined(__LITTLE_ENDIAN__) || \
|
||||||
(defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && \
|
(defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && \
|
||||||
__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
|
__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
|
||||||
return le_to_be(i);
|
return le_to_be(i);
|
||||||
#else /* fallback to run-time check */
|
#else /* fallback to run-time check */
|
||||||
static const union {
|
static const union {
|
||||||
@@ -126,14 +137,14 @@ static void SHA1_Transform(uint32_t state[5], const uint8_t buffer[64])
|
|||||||
uint8_t c[64];
|
uint8_t c[64];
|
||||||
uint32_t l[16];
|
uint32_t l[16];
|
||||||
} CHAR64LONG16;
|
} CHAR64LONG16;
|
||||||
CHAR64LONG16* block;
|
CHAR64LONG16 *block;
|
||||||
|
|
||||||
#ifdef SHA1HANDSOFF
|
#ifdef SHA1HANDSOFF
|
||||||
static uint8_t workspace[64];
|
static uint8_t workspace[64];
|
||||||
block = (CHAR64LONG16*)workspace;
|
block = (CHAR64LONG16 *)workspace;
|
||||||
memcpy(block, buffer, 64);
|
memcpy(block, buffer, 64);
|
||||||
#else
|
#else
|
||||||
block = (CHAR64LONG16*)buffer;
|
block = (CHAR64LONG16 *)buffer;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Copy context->state[] to working vars */
|
/* Copy context->state[] to working vars */
|
||||||
@@ -144,6 +155,7 @@ static void SHA1_Transform(uint32_t state[5], const uint8_t buffer[64])
|
|||||||
e = state[4];
|
e = state[4];
|
||||||
|
|
||||||
/* 4 rounds of 20 operations each. Loop unrolled. */
|
/* 4 rounds of 20 operations each. Loop unrolled. */
|
||||||
|
/* clang-format off */
|
||||||
R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3);
|
R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3);
|
||||||
R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7);
|
R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7);
|
||||||
R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11);
|
R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11);
|
||||||
@@ -164,6 +176,7 @@ static void SHA1_Transform(uint32_t state[5], const uint8_t buffer[64])
|
|||||||
R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71);
|
R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71);
|
||||||
R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75);
|
R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75);
|
||||||
R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79);
|
R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79);
|
||||||
|
/* clang-format on */
|
||||||
|
|
||||||
/* Add the working vars back into context.state[] */
|
/* Add the working vars back into context.state[] */
|
||||||
state[0] += a;
|
state[0] += a;
|
||||||
@@ -176,9 +189,8 @@ static void SHA1_Transform(uint32_t state[5], const uint8_t buffer[64])
|
|||||||
a = b = c = d = e = 0;
|
a = b = c = d = e = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* SHA1Init - Initialize new context */
|
/* SHA1Init - Initialize new context */
|
||||||
void crypto_SHA1_Init(SHA1_CTX* context)
|
void crypto_SHA1_Init(SHA1_CTX *context)
|
||||||
{
|
{
|
||||||
/* SHA1 initialization constants */
|
/* SHA1 initialization constants */
|
||||||
context->state[0] = 0x67452301;
|
context->state[0] = 0x67452301;
|
||||||
@@ -189,9 +201,9 @@ void crypto_SHA1_Init(SHA1_CTX* context)
|
|||||||
context->count[0] = context->count[1] = 0;
|
context->count[0] = context->count[1] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Run your data through this. */
|
/* Run your data through this. */
|
||||||
void crypto_SHA1_Update(SHA1_CTX* context, const uint8_t* data,
|
void crypto_SHA1_Update(SHA1_CTX *context,
|
||||||
|
const uint8_t *data,
|
||||||
const size_t len)
|
const size_t len)
|
||||||
{
|
{
|
||||||
size_t i, j;
|
size_t i, j;
|
||||||
@@ -201,51 +213,51 @@ void crypto_SHA1_Update(SHA1_CTX* context, const uint8_t* data,
|
|||||||
context->count[1]++;
|
context->count[1]++;
|
||||||
context->count[1] += (uint32_t)(len >> 29);
|
context->count[1] += (uint32_t)(len >> 29);
|
||||||
if ((j + len) > 63) {
|
if ((j + len) > 63) {
|
||||||
memcpy(&context->buffer[j], data, (i = 64-j));
|
memcpy(&context->buffer[j], data, (i = 64 - j));
|
||||||
SHA1_Transform(context->state, context->buffer);
|
SHA1_Transform(context->state, context->buffer);
|
||||||
for ( ; i + 63 < len; i += 64) {
|
for (; i + 63 < len; i += 64) {
|
||||||
SHA1_Transform(context->state, data + i);
|
SHA1_Transform(context->state, data + i);
|
||||||
}
|
}
|
||||||
j = 0;
|
j = 0;
|
||||||
}
|
} else
|
||||||
else i = 0;
|
i = 0;
|
||||||
memcpy(&context->buffer[j], &data[i], len - i);
|
memcpy(&context->buffer[j], &data[i], len - i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Add padding and return the message digest. */
|
/* Add padding and return the message digest. */
|
||||||
void crypto_SHA1_Final(SHA1_CTX* context, uint8_t* digest)
|
void crypto_SHA1_Final(SHA1_CTX *context, uint8_t *digest)
|
||||||
{
|
{
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
uint8_t finalcount[8];
|
uint8_t finalcount[8];
|
||||||
|
|
||||||
for (i = 0; i < 8; i++) {
|
for (i = 0; i < 8; i++) {
|
||||||
finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)]
|
finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)] >>
|
||||||
>> ((3-(i & 3)) * 8) ) & 255); /* Endian independent */
|
((3 - (i & 3)) * 8)) &
|
||||||
|
255); /* Endian independent */
|
||||||
}
|
}
|
||||||
crypto_SHA1_Update(context, (uint8_t *)"\200", 1);
|
crypto_SHA1_Update(context, (uint8_t *)"\200", 1);
|
||||||
while ((context->count[0] & 504) != 448) {
|
while ((context->count[0] & 504) != 448) {
|
||||||
crypto_SHA1_Update(context, (uint8_t *)"\0", 1);
|
crypto_SHA1_Update(context, (uint8_t *)"\0", 1);
|
||||||
}
|
}
|
||||||
crypto_SHA1_Update(context, finalcount, 8); /* Should cause a SHA1_Transform() */
|
crypto_SHA1_Update(context, finalcount,
|
||||||
|
8); /* Should cause a SHA1_Transform() */
|
||||||
for (i = 0; i < SHA1_DIGEST_SIZE; i++) {
|
for (i = 0; i < SHA1_DIGEST_SIZE; i++) {
|
||||||
digest[i] = (uint8_t)
|
digest[i] =
|
||||||
((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255);
|
(uint8_t)((context->state[i >> 2] >> ((3 - (i & 3)) * 8)) & 255);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Wipe variables */
|
/* Wipe variables */
|
||||||
memset(context->buffer, 0, 64);
|
memset(context->buffer, 0, 64);
|
||||||
memset(context->state, 0, 20);
|
memset(context->state, 0, 20);
|
||||||
memset(context->count, 0, 8);
|
memset(context->count, 0, 8);
|
||||||
memset(finalcount, 0, 8); /* SWR */
|
memset(finalcount, 0, 8); /* SWR */
|
||||||
|
|
||||||
#ifdef SHA1HANDSOFF /* make SHA1Transform overwrite its own static vars */
|
#ifdef SHA1HANDSOFF /* make SHA1Transform overwrite its own static vars */
|
||||||
SHA1_Transform(context->state, context->buffer);
|
SHA1_Transform(context->state, context->buffer);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void crypto_SHA1(const uint8_t *data, size_t len, uint8_t *digest)
|
||||||
void crypto_SHA1(const uint8_t* data, size_t len, uint8_t* digest)
|
|
||||||
{
|
{
|
||||||
SHA1_CTX ctx;
|
SHA1_CTX ctx;
|
||||||
crypto_SHA1_Init(&ctx);
|
crypto_SHA1_Init(&ctx);
|
||||||
|
|||||||
11
src/sha1.h
11
src/sha1.h
@@ -18,16 +18,17 @@ extern "C" {
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t state[5];
|
uint32_t state[5];
|
||||||
uint32_t count[2];
|
uint32_t count[2];
|
||||||
uint8_t buffer[64];
|
uint8_t buffer[64];
|
||||||
} SHA1_CTX;
|
} SHA1_CTX;
|
||||||
|
|
||||||
#define SHA1_DIGEST_SIZE 20
|
#define SHA1_DIGEST_SIZE 20
|
||||||
|
|
||||||
void crypto_SHA1_Init(SHA1_CTX* context);
|
void crypto_SHA1_Init(SHA1_CTX *context);
|
||||||
void crypto_SHA1_Update(SHA1_CTX* context, const uint8_t* data,
|
void crypto_SHA1_Update(SHA1_CTX *context,
|
||||||
|
const uint8_t *data,
|
||||||
const size_t len);
|
const size_t len);
|
||||||
void crypto_SHA1_Final(SHA1_CTX* context, uint8_t* digest);
|
void crypto_SHA1_Final(SHA1_CTX *context, uint8_t *digest);
|
||||||
void crypto_SHA1(const uint8_t* data, size_t len, uint8_t* digest);
|
void crypto_SHA1(const uint8_t *data, size_t len, uint8_t *digest);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
1084
src/snprintf.c
1084
src/snprintf.c
File diff suppressed because it is too large
Load Diff
32
src/sock.c
32
src/sock.c
@@ -22,7 +22,7 @@
|
|||||||
#include <winsock2.h>
|
#include <winsock2.h>
|
||||||
#include <ws2tcpip.h>
|
#include <ws2tcpip.h>
|
||||||
#include <Iphlpapi.h>
|
#include <Iphlpapi.h>
|
||||||
#include <Mstcpip.h> /* tcp_keepalive */
|
#include <Mstcpip.h> /* tcp_keepalive */
|
||||||
#else
|
#else
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
@@ -69,7 +69,7 @@ static int _in_progress(int error)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
sock_t sock_connect(const char * const host, const unsigned short port)
|
sock_t sock_connect(const char *const host, const unsigned short port)
|
||||||
{
|
{
|
||||||
sock_t sock;
|
sock_t sock;
|
||||||
char service[6];
|
char service[6];
|
||||||
@@ -123,7 +123,8 @@ int sock_set_keepalive(const sock_t sock, int timeout, int interval)
|
|||||||
ka.onoff = optval;
|
ka.onoff = optval;
|
||||||
ka.keepalivetime = timeout * 1000;
|
ka.keepalivetime = timeout * 1000;
|
||||||
ka.keepaliveinterval = interval * 1000;
|
ka.keepaliveinterval = interval * 1000;
|
||||||
ret = WSAIoctl(sock, SIO_KEEPALIVE_VALS, &ka, sizeof(ka), NULL, 0, &dw, NULL, NULL);
|
ret = WSAIoctl(sock, SIO_KEEPALIVE_VALS, &ka, sizeof(ka), NULL, 0, &dw,
|
||||||
|
NULL, NULL);
|
||||||
#else
|
#else
|
||||||
ret = setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, &optval, sizeof(optval));
|
ret = setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, &optval, sizeof(optval));
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
@@ -131,15 +132,19 @@ int sock_set_keepalive(const sock_t sock, int timeout, int interval)
|
|||||||
|
|
||||||
if (optval) {
|
if (optval) {
|
||||||
#ifdef TCP_KEEPIDLE
|
#ifdef TCP_KEEPIDLE
|
||||||
ret = setsockopt(sock, IPPROTO_TCP, TCP_KEEPIDLE, &timeout, sizeof(timeout));
|
ret = setsockopt(sock, IPPROTO_TCP, TCP_KEEPIDLE, &timeout,
|
||||||
|
sizeof(timeout));
|
||||||
#elif defined(TCP_KEEPALIVE)
|
#elif defined(TCP_KEEPALIVE)
|
||||||
/* QNX receives `struct timeval' as argument, but it seems OSX does int */
|
/* QNX receives `struct timeval' as argument, but it seems OSX does int
|
||||||
ret = setsockopt(sock, IPPROTO_TCP, TCP_KEEPALIVE, &timeout, sizeof(timeout));
|
*/
|
||||||
|
ret = setsockopt(sock, IPPROTO_TCP, TCP_KEEPALIVE, &timeout,
|
||||||
|
sizeof(timeout));
|
||||||
#endif /* TCP_KEEPIDLE */
|
#endif /* TCP_KEEPIDLE */
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
#ifdef TCP_KEEPINTVL
|
#ifdef TCP_KEEPINTVL
|
||||||
ret = setsockopt(sock, IPPROTO_TCP, TCP_KEEPINTVL, &interval, sizeof(interval));
|
ret = setsockopt(sock, IPPROTO_TCP, TCP_KEEPINTVL, &interval,
|
||||||
|
sizeof(interval));
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
#endif /* TCP_KEEPINTVL */
|
#endif /* TCP_KEEPINTVL */
|
||||||
@@ -185,12 +190,12 @@ int sock_set_nonblocking(const sock_t sock)
|
|||||||
return _sock_set_blocking_mode(sock, 0);
|
return _sock_set_blocking_mode(sock, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int sock_read(const sock_t sock, void * const buff, const size_t len)
|
int sock_read(const sock_t sock, void *const buff, const size_t len)
|
||||||
{
|
{
|
||||||
return recv(sock, buff, len, 0);
|
return recv(sock, buff, len, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int sock_write(const sock_t sock, const void * const buff, const size_t len)
|
int sock_write(const sock_t sock, const void *const buff, const size_t len)
|
||||||
{
|
{
|
||||||
return send(sock, buff, len, 0);
|
return send(sock, buff, len, 0);
|
||||||
}
|
}
|
||||||
@@ -217,17 +222,18 @@ int sock_connect_error(const sock_t sock)
|
|||||||
|
|
||||||
/* we don't actually care about the peer name, we're just checking if
|
/* we don't actually care about the peer name, we're just checking if
|
||||||
* we're connected or not */
|
* we're connected or not */
|
||||||
if (getpeername(sock, &sa, &len) == 0)
|
if (getpeername(sock, &sa, &len) == 0) {
|
||||||
{
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* it's possible that the error wasn't ENOTCONN, so if it wasn't,
|
/* it's possible that the error wasn't ENOTCONN, so if it wasn't,
|
||||||
* return that */
|
* return that */
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
if (sock_error() != WSAENOTCONN) return sock_error();
|
if (sock_error() != WSAENOTCONN)
|
||||||
|
return sock_error();
|
||||||
#else
|
#else
|
||||||
if (sock_error() != ENOTCONN) return sock_error();
|
if (sock_error() != ENOTCONN)
|
||||||
|
return sock_error();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* load the correct error into errno through error slippage */
|
/* load the correct error into errno through error slippage */
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/* sock.h
|
/* sock.h
|
||||||
** strophe XMPP client library -- socket abstraction header
|
** strophe XMPP client library -- socket abstraction header
|
||||||
**
|
**
|
||||||
** Copyright (C) 2005-2009 Collecta, Inc.
|
** Copyright (C) 2005-2009 Collecta, Inc.
|
||||||
**
|
**
|
||||||
** This software is provided AS-IS with no warranty, either express
|
** This software is provided AS-IS with no warranty, either express
|
||||||
** or implied.
|
** or implied.
|
||||||
@@ -30,13 +30,13 @@ void sock_shutdown(void);
|
|||||||
|
|
||||||
int sock_error(void);
|
int sock_error(void);
|
||||||
|
|
||||||
sock_t sock_connect(const char * const host, const unsigned short port);
|
sock_t sock_connect(const char *const host, const unsigned short port);
|
||||||
int sock_close(const sock_t sock);
|
int sock_close(const sock_t sock);
|
||||||
|
|
||||||
int sock_set_blocking(const sock_t sock);
|
int sock_set_blocking(const sock_t sock);
|
||||||
int sock_set_nonblocking(const sock_t sock);
|
int sock_set_nonblocking(const sock_t sock);
|
||||||
int sock_read(const sock_t sock, void * const buff, const size_t len);
|
int sock_read(const sock_t sock, void *const buff, const size_t len);
|
||||||
int sock_write(const sock_t sock, const void * const buff, const size_t len);
|
int sock_write(const sock_t sock, const void *const buff, const size_t len);
|
||||||
int sock_is_recoverable(const int error);
|
int sock_is_recoverable(const int error);
|
||||||
/* checks for an error after connect, return 0 if connect successful */
|
/* checks for an error after connect, return 0 if connect successful */
|
||||||
int sock_connect_error(const sock_t sock);
|
int sock_connect_error(const sock_t sock);
|
||||||
|
|||||||
483
src/stanza.c
483
src/stanza.c
@@ -63,7 +63,7 @@ xmpp_stanza_t *xmpp_stanza_new(xmpp_ctx_t *ctx)
|
|||||||
*
|
*
|
||||||
* @ingroup Stanza
|
* @ingroup Stanza
|
||||||
*/
|
*/
|
||||||
xmpp_stanza_t *xmpp_stanza_clone(xmpp_stanza_t * const stanza)
|
xmpp_stanza_t *xmpp_stanza_clone(xmpp_stanza_t *const stanza)
|
||||||
{
|
{
|
||||||
stanza->ref++;
|
stanza->ref++;
|
||||||
|
|
||||||
@@ -73,8 +73,8 @@ xmpp_stanza_t *xmpp_stanza_clone(xmpp_stanza_t * const stanza)
|
|||||||
/*
|
/*
|
||||||
* Copy the attributes of stanza src into stanza dst. Return -1 on error.
|
* Copy the attributes of stanza src into stanza dst. Return -1 on error.
|
||||||
*/
|
*/
|
||||||
static int _stanza_copy_attributes(xmpp_stanza_t * dst,
|
static int _stanza_copy_attributes(xmpp_stanza_t *dst,
|
||||||
const xmpp_stanza_t * const src)
|
const xmpp_stanza_t *const src)
|
||||||
{
|
{
|
||||||
hash_iterator_t *iter;
|
hash_iterator_t *iter;
|
||||||
const char *key;
|
const char *key;
|
||||||
@@ -82,11 +82,13 @@ static int _stanza_copy_attributes(xmpp_stanza_t * dst,
|
|||||||
int rc = XMPP_EOK;
|
int rc = XMPP_EOK;
|
||||||
|
|
||||||
iter = hash_iter_new(src->attributes);
|
iter = hash_iter_new(src->attributes);
|
||||||
if (!iter) rc = XMPP_EMEM;
|
if (!iter)
|
||||||
|
rc = XMPP_EMEM;
|
||||||
|
|
||||||
while (rc == XMPP_EOK && (key = hash_iter_next(iter))) {
|
while (rc == XMPP_EOK && (key = hash_iter_next(iter))) {
|
||||||
val = hash_get(src->attributes, key);
|
val = hash_get(src->attributes, key);
|
||||||
if (!val) rc = XMPP_EINT;
|
if (!val)
|
||||||
|
rc = XMPP_EINT;
|
||||||
if (rc == XMPP_EOK)
|
if (rc == XMPP_EOK)
|
||||||
rc = xmpp_stanza_set_attribute(dst, key, val);
|
rc = xmpp_stanza_set_attribute(dst, key, val);
|
||||||
}
|
}
|
||||||
@@ -111,18 +113,20 @@ static int _stanza_copy_attributes(xmpp_stanza_t * dst,
|
|||||||
*
|
*
|
||||||
* @ingroup Stanza
|
* @ingroup Stanza
|
||||||
*/
|
*/
|
||||||
xmpp_stanza_t *xmpp_stanza_copy(const xmpp_stanza_t * const stanza)
|
xmpp_stanza_t *xmpp_stanza_copy(const xmpp_stanza_t *const stanza)
|
||||||
{
|
{
|
||||||
xmpp_stanza_t *copy, *child, *copychild, *tail;
|
xmpp_stanza_t *copy, *child, *copychild, *tail;
|
||||||
|
|
||||||
copy = xmpp_stanza_new(stanza->ctx);
|
copy = xmpp_stanza_new(stanza->ctx);
|
||||||
if (!copy) goto copy_error;
|
if (!copy)
|
||||||
|
goto copy_error;
|
||||||
|
|
||||||
copy->type = stanza->type;
|
copy->type = stanza->type;
|
||||||
|
|
||||||
if (stanza->data) {
|
if (stanza->data) {
|
||||||
copy->data = xmpp_strdup(stanza->ctx, stanza->data);
|
copy->data = xmpp_strdup(stanza->ctx, stanza->data);
|
||||||
if (!copy->data) goto copy_error;
|
if (!copy->data)
|
||||||
|
goto copy_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (stanza->attributes) {
|
if (stanza->attributes) {
|
||||||
@@ -133,7 +137,8 @@ xmpp_stanza_t *xmpp_stanza_copy(const xmpp_stanza_t * const stanza)
|
|||||||
tail = copy->children;
|
tail = copy->children;
|
||||||
for (child = stanza->children; child; child = child->next) {
|
for (child = stanza->children; child; child = child->next) {
|
||||||
copychild = xmpp_stanza_copy(child);
|
copychild = xmpp_stanza_copy(child);
|
||||||
if (!copychild) goto copy_error;
|
if (!copychild)
|
||||||
|
goto copy_error;
|
||||||
copychild->parent = copy;
|
copychild->parent = copy;
|
||||||
|
|
||||||
if (tail) {
|
if (tail) {
|
||||||
@@ -148,7 +153,8 @@ xmpp_stanza_t *xmpp_stanza_copy(const xmpp_stanza_t * const stanza)
|
|||||||
|
|
||||||
copy_error:
|
copy_error:
|
||||||
/* release all the hitherto allocated memory */
|
/* release all the hitherto allocated memory */
|
||||||
if (copy) xmpp_stanza_release(copy);
|
if (copy)
|
||||||
|
xmpp_stanza_release(copy);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -162,7 +168,7 @@ copy_error:
|
|||||||
*
|
*
|
||||||
* @ingroup Stanza
|
* @ingroup Stanza
|
||||||
*/
|
*/
|
||||||
int xmpp_stanza_release(xmpp_stanza_t * const stanza)
|
int xmpp_stanza_release(xmpp_stanza_t *const stanza)
|
||||||
{
|
{
|
||||||
int released = 0;
|
int released = 0;
|
||||||
xmpp_stanza_t *child, *tchild;
|
xmpp_stanza_t *child, *tchild;
|
||||||
@@ -179,8 +185,10 @@ int xmpp_stanza_release(xmpp_stanza_t * const stanza)
|
|||||||
xmpp_stanza_release(tchild);
|
xmpp_stanza_release(tchild);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (stanza->attributes) hash_release(stanza->attributes);
|
if (stanza->attributes)
|
||||||
if (stanza->data) xmpp_free(stanza->ctx, stanza->data);
|
hash_release(stanza->attributes);
|
||||||
|
if (stanza->data)
|
||||||
|
xmpp_free(stanza->ctx, stanza->data);
|
||||||
xmpp_free(stanza->ctx, stanza);
|
xmpp_free(stanza->ctx, stanza);
|
||||||
released = 1;
|
released = 1;
|
||||||
}
|
}
|
||||||
@@ -196,7 +204,7 @@ int xmpp_stanza_release(xmpp_stanza_t * const stanza)
|
|||||||
*
|
*
|
||||||
* @ingroup Stanza
|
* @ingroup Stanza
|
||||||
*/
|
*/
|
||||||
xmpp_ctx_t *xmpp_stanza_get_context(const xmpp_stanza_t * const stanza)
|
xmpp_ctx_t *xmpp_stanza_get_context(const xmpp_stanza_t *const stanza)
|
||||||
{
|
{
|
||||||
return stanza->ctx;
|
return stanza->ctx;
|
||||||
}
|
}
|
||||||
@@ -209,7 +217,7 @@ xmpp_ctx_t *xmpp_stanza_get_context(const xmpp_stanza_t * const stanza)
|
|||||||
*
|
*
|
||||||
* @ingroup Stanza
|
* @ingroup Stanza
|
||||||
*/
|
*/
|
||||||
int xmpp_stanza_is_text(xmpp_stanza_t * const stanza)
|
int xmpp_stanza_is_text(xmpp_stanza_t *const stanza)
|
||||||
{
|
{
|
||||||
return (stanza && stanza->type == XMPP_STANZA_TEXT);
|
return (stanza && stanza->type == XMPP_STANZA_TEXT);
|
||||||
}
|
}
|
||||||
@@ -222,7 +230,7 @@ int xmpp_stanza_is_text(xmpp_stanza_t * const stanza)
|
|||||||
*
|
*
|
||||||
* @ingroup Stanza
|
* @ingroup Stanza
|
||||||
*/
|
*/
|
||||||
int xmpp_stanza_is_tag(xmpp_stanza_t * const stanza)
|
int xmpp_stanza_is_tag(xmpp_stanza_t *const stanza)
|
||||||
{
|
{
|
||||||
return (stanza && stanza->type == XMPP_STANZA_TAG);
|
return (stanza && stanza->type == XMPP_STANZA_TAG);
|
||||||
}
|
}
|
||||||
@@ -233,7 +241,7 @@ int xmpp_stanza_is_tag(xmpp_stanza_t * const stanza)
|
|||||||
* On failure, returns NULL.
|
* On failure, returns NULL.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static char *_escape_xml(xmpp_ctx_t * const ctx, char *text)
|
static char *_escape_xml(xmpp_ctx_t *const ctx, char *text)
|
||||||
{
|
{
|
||||||
size_t len = 0;
|
size_t len = 0;
|
||||||
char *src;
|
char *src;
|
||||||
@@ -241,44 +249,44 @@ static char *_escape_xml(xmpp_ctx_t * const ctx, char *text)
|
|||||||
char *buf;
|
char *buf;
|
||||||
for (src = text; *src != '\0'; src++) {
|
for (src = text; *src != '\0'; src++) {
|
||||||
switch (*src) {
|
switch (*src) {
|
||||||
case '<': /* "<" */
|
case '<': /* "<" */
|
||||||
case '>': /* ">" */
|
case '>': /* ">" */
|
||||||
len += 4;
|
len += 4;
|
||||||
break;
|
break;
|
||||||
case '&': /* "&" */
|
case '&': /* "&" */
|
||||||
len += 5;
|
len += 5;
|
||||||
break;
|
break;
|
||||||
case '"':
|
case '"':
|
||||||
len += 6; /*""" */
|
len += 6; /*""" */
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
len++;
|
len++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ((buf = xmpp_alloc(ctx, (len+1) * sizeof(char))) == NULL)
|
if ((buf = xmpp_alloc(ctx, (len + 1) * sizeof(char))) == NULL)
|
||||||
return NULL; /* Error */
|
return NULL; /* Error */
|
||||||
dst = buf;
|
dst = buf;
|
||||||
for (src = text; *src != '\0'; src++) {
|
for (src = text; *src != '\0'; src++) {
|
||||||
switch (*src) {
|
switch (*src) {
|
||||||
case '<':
|
case '<':
|
||||||
strcpy(dst, "<");
|
strcpy(dst, "<");
|
||||||
dst += 4;
|
dst += 4;
|
||||||
break;
|
break;
|
||||||
case '>':
|
case '>':
|
||||||
strcpy(dst, ">");
|
strcpy(dst, ">");
|
||||||
dst += 4;
|
dst += 4;
|
||||||
break;
|
break;
|
||||||
case '&':
|
case '&':
|
||||||
strcpy(dst, "&");
|
strcpy(dst, "&");
|
||||||
dst += 5;
|
dst += 5;
|
||||||
break;
|
break;
|
||||||
case '"':
|
case '"':
|
||||||
strcpy(dst, """);
|
strcpy(dst, """);
|
||||||
dst += 6;
|
dst += 6;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
*dst = *src;
|
*dst = *src;
|
||||||
dst++;
|
dst++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*dst = '\0';
|
*dst = '\0';
|
||||||
@@ -286,9 +294,11 @@ static char *_escape_xml(xmpp_ctx_t * const ctx, char *text)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* small helper function */
|
/* small helper function */
|
||||||
static void _render_update(int *written, const int length,
|
static void _render_update(int *written,
|
||||||
|
const int length,
|
||||||
const int lastwrite,
|
const int lastwrite,
|
||||||
size_t *left, char **ptr)
|
size_t *left,
|
||||||
|
char **ptr)
|
||||||
{
|
{
|
||||||
*written += lastwrite;
|
*written += lastwrite;
|
||||||
|
|
||||||
@@ -307,7 +317,8 @@ static void _render_update(int *written, const int length,
|
|||||||
* and return values > buflen indicate buffer was not large enough
|
* and return values > buflen indicate buffer was not large enough
|
||||||
*/
|
*/
|
||||||
static int _render_stanza_recursive(xmpp_stanza_t *stanza,
|
static int _render_stanza_recursive(xmpp_stanza_t *stanza,
|
||||||
char * const buf, size_t const buflen)
|
char *const buf,
|
||||||
|
size_t const buflen)
|
||||||
{
|
{
|
||||||
char *ptr = buf;
|
char *ptr = buf;
|
||||||
size_t left = buflen;
|
size_t left = buflen;
|
||||||
@@ -319,23 +330,29 @@ static int _render_stanza_recursive(xmpp_stanza_t *stanza,
|
|||||||
|
|
||||||
written = 0;
|
written = 0;
|
||||||
|
|
||||||
if (stanza->type == XMPP_STANZA_UNKNOWN) return XMPP_EINVOP;
|
if (stanza->type == XMPP_STANZA_UNKNOWN)
|
||||||
|
return XMPP_EINVOP;
|
||||||
|
|
||||||
if (stanza->type == XMPP_STANZA_TEXT) {
|
if (stanza->type == XMPP_STANZA_TEXT) {
|
||||||
if (!stanza->data) return XMPP_EINVOP;
|
if (!stanza->data)
|
||||||
|
return XMPP_EINVOP;
|
||||||
|
|
||||||
tmp = _escape_xml(stanza->ctx, stanza->data);
|
tmp = _escape_xml(stanza->ctx, stanza->data);
|
||||||
if (tmp == NULL) return XMPP_EMEM;
|
if (tmp == NULL)
|
||||||
|
return XMPP_EMEM;
|
||||||
ret = xmpp_snprintf(ptr, left, "%s", tmp);
|
ret = xmpp_snprintf(ptr, left, "%s", tmp);
|
||||||
xmpp_free(stanza->ctx, tmp);
|
xmpp_free(stanza->ctx, tmp);
|
||||||
if (ret < 0) return XMPP_EMEM;
|
if (ret < 0)
|
||||||
|
return XMPP_EMEM;
|
||||||
_render_update(&written, buflen, ret, &left, &ptr);
|
_render_update(&written, buflen, ret, &left, &ptr);
|
||||||
} else { /* stanza->type == XMPP_STANZA_TAG */
|
} else { /* stanza->type == XMPP_STANZA_TAG */
|
||||||
if (!stanza->data) return XMPP_EINVOP;
|
if (!stanza->data)
|
||||||
|
return XMPP_EINVOP;
|
||||||
|
|
||||||
/* write beginning of tag and attributes */
|
/* write beginning of tag and attributes */
|
||||||
ret = xmpp_snprintf(ptr, left, "<%s", stanza->data);
|
ret = xmpp_snprintf(ptr, left, "<%s", stanza->data);
|
||||||
if (ret < 0) return XMPP_EMEM;
|
if (ret < 0)
|
||||||
|
return XMPP_EMEM;
|
||||||
_render_update(&written, buflen, ret, &left, &ptr);
|
_render_update(&written, buflen, ret, &left, &ptr);
|
||||||
|
|
||||||
if (stanza->attributes && hash_num_keys(stanza->attributes) > 0) {
|
if (stanza->attributes && hash_num_keys(stanza->attributes) > 0) {
|
||||||
@@ -343,20 +360,20 @@ static int _render_stanza_recursive(xmpp_stanza_t *stanza,
|
|||||||
while ((key = hash_iter_next(iter))) {
|
while ((key = hash_iter_next(iter))) {
|
||||||
if (!strcmp(key, "xmlns")) {
|
if (!strcmp(key, "xmlns")) {
|
||||||
/* don't output namespace if parent stanza is the same */
|
/* don't output namespace if parent stanza is the same */
|
||||||
if (stanza->parent &&
|
if (stanza->parent && stanza->parent->attributes &&
|
||||||
stanza->parent->attributes &&
|
|
||||||
hash_get(stanza->parent->attributes, key) &&
|
hash_get(stanza->parent->attributes, key) &&
|
||||||
!strcmp((char*)hash_get(stanza->attributes, key),
|
!strcmp(
|
||||||
(char*)hash_get(stanza->parent->attributes, key)))
|
(char *)hash_get(stanza->attributes, key),
|
||||||
|
(char *)hash_get(stanza->parent->attributes, key)))
|
||||||
continue;
|
continue;
|
||||||
/* or if this is the stream namespace */
|
/* or if this is the stream namespace */
|
||||||
if (!stanza->parent &&
|
if (!stanza->parent &&
|
||||||
!strcmp((char*)hash_get(stanza->attributes, key),
|
!strcmp((char *)hash_get(stanza->attributes, key),
|
||||||
XMPP_NS_CLIENT))
|
XMPP_NS_CLIENT))
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
tmp = _escape_xml(stanza->ctx,
|
tmp = _escape_xml(stanza->ctx,
|
||||||
(char *)hash_get(stanza->attributes, key));
|
(char *)hash_get(stanza->attributes, key));
|
||||||
if (tmp == NULL) {
|
if (tmp == NULL) {
|
||||||
hash_iter_release(iter);
|
hash_iter_release(iter);
|
||||||
return XMPP_EMEM;
|
return XMPP_EMEM;
|
||||||
@@ -375,21 +392,24 @@ static int _render_stanza_recursive(xmpp_stanza_t *stanza,
|
|||||||
if (!stanza->children) {
|
if (!stanza->children) {
|
||||||
/* write end if singleton tag */
|
/* write end if singleton tag */
|
||||||
ret = xmpp_snprintf(ptr, left, "/>");
|
ret = xmpp_snprintf(ptr, left, "/>");
|
||||||
if (ret < 0) return XMPP_EMEM;
|
if (ret < 0)
|
||||||
|
return XMPP_EMEM;
|
||||||
_render_update(&written, buflen, ret, &left, &ptr);
|
_render_update(&written, buflen, ret, &left, &ptr);
|
||||||
} else {
|
} else {
|
||||||
/* this stanza has child stanzas */
|
/* this stanza has child stanzas */
|
||||||
|
|
||||||
/* write end of start tag */
|
/* write end of start tag */
|
||||||
ret = xmpp_snprintf(ptr, left, ">");
|
ret = xmpp_snprintf(ptr, left, ">");
|
||||||
if (ret < 0) return XMPP_EMEM;
|
if (ret < 0)
|
||||||
|
return XMPP_EMEM;
|
||||||
_render_update(&written, buflen, ret, &left, &ptr);
|
_render_update(&written, buflen, ret, &left, &ptr);
|
||||||
|
|
||||||
/* iterate and recurse over child stanzas */
|
/* iterate and recurse over child stanzas */
|
||||||
child = stanza->children;
|
child = stanza->children;
|
||||||
while (child) {
|
while (child) {
|
||||||
ret = _render_stanza_recursive(child, ptr, left);
|
ret = _render_stanza_recursive(child, ptr, left);
|
||||||
if (ret < 0) return ret;
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
_render_update(&written, buflen, ret, &left, &ptr);
|
_render_update(&written, buflen, ret, &left, &ptr);
|
||||||
|
|
||||||
@@ -398,7 +418,8 @@ static int _render_stanza_recursive(xmpp_stanza_t *stanza,
|
|||||||
|
|
||||||
/* write end tag */
|
/* write end tag */
|
||||||
ret = xmpp_snprintf(ptr, left, "</%s>", stanza->data);
|
ret = xmpp_snprintf(ptr, left, "</%s>", stanza->data);
|
||||||
if (ret < 0) return XMPP_EMEM;
|
if (ret < 0)
|
||||||
|
return XMPP_EMEM;
|
||||||
|
|
||||||
_render_update(&written, buflen, ret, &left, &ptr);
|
_render_update(&written, buflen, ret, &left, &ptr);
|
||||||
}
|
}
|
||||||
@@ -423,8 +444,8 @@ static int _render_stanza_recursive(xmpp_stanza_t *stanza,
|
|||||||
* @ingroup Stanza
|
* @ingroup Stanza
|
||||||
*/
|
*/
|
||||||
int xmpp_stanza_to_text(xmpp_stanza_t *stanza,
|
int xmpp_stanza_to_text(xmpp_stanza_t *stanza,
|
||||||
char ** const buf,
|
char **const buf,
|
||||||
size_t * const buflen)
|
size_t *const buflen)
|
||||||
{
|
{
|
||||||
char *buffer, *tmp;
|
char *buffer, *tmp;
|
||||||
size_t length;
|
size_t length;
|
||||||
@@ -485,12 +506,13 @@ int xmpp_stanza_to_text(xmpp_stanza_t *stanza,
|
|||||||
*
|
*
|
||||||
* @ingroup Stanza
|
* @ingroup Stanza
|
||||||
*/
|
*/
|
||||||
int xmpp_stanza_set_name(xmpp_stanza_t *stanza,
|
int xmpp_stanza_set_name(xmpp_stanza_t *stanza, const char *const name)
|
||||||
const char * const name)
|
|
||||||
{
|
{
|
||||||
if (stanza->type == XMPP_STANZA_TEXT) return XMPP_EINVOP;
|
if (stanza->type == XMPP_STANZA_TEXT)
|
||||||
|
return XMPP_EINVOP;
|
||||||
|
|
||||||
if (stanza->data) xmpp_free(stanza->ctx, stanza->data);
|
if (stanza->data)
|
||||||
|
xmpp_free(stanza->ctx, stanza->data);
|
||||||
|
|
||||||
stanza->type = XMPP_STANZA_TAG;
|
stanza->type = XMPP_STANZA_TAG;
|
||||||
stanza->data = xmpp_strdup(stanza->ctx, name);
|
stanza->data = xmpp_strdup(stanza->ctx, name);
|
||||||
@@ -508,9 +530,10 @@ int xmpp_stanza_set_name(xmpp_stanza_t *stanza,
|
|||||||
*
|
*
|
||||||
* @ingroup Stanza
|
* @ingroup Stanza
|
||||||
*/
|
*/
|
||||||
const char *xmpp_stanza_get_name(xmpp_stanza_t * const stanza)
|
const char *xmpp_stanza_get_name(xmpp_stanza_t *const stanza)
|
||||||
{
|
{
|
||||||
if (stanza->type == XMPP_STANZA_TEXT) return NULL;
|
if (stanza->type == XMPP_STANZA_TEXT)
|
||||||
|
return NULL;
|
||||||
return stanza->data;
|
return stanza->data;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -522,7 +545,7 @@ const char *xmpp_stanza_get_name(xmpp_stanza_t * const stanza)
|
|||||||
*
|
*
|
||||||
* @ingroup Stanza
|
* @ingroup Stanza
|
||||||
*/
|
*/
|
||||||
int xmpp_stanza_get_attribute_count(xmpp_stanza_t * const stanza)
|
int xmpp_stanza_get_attribute_count(xmpp_stanza_t *const stanza)
|
||||||
{
|
{
|
||||||
if (stanza->attributes == NULL) {
|
if (stanza->attributes == NULL) {
|
||||||
return 0;
|
return 0;
|
||||||
@@ -545,8 +568,9 @@ int xmpp_stanza_get_attribute_count(xmpp_stanza_t * const stanza)
|
|||||||
*
|
*
|
||||||
* @ingroup Stanza
|
* @ingroup Stanza
|
||||||
*/
|
*/
|
||||||
int xmpp_stanza_get_attributes(xmpp_stanza_t * const stanza,
|
int xmpp_stanza_get_attributes(xmpp_stanza_t *const stanza,
|
||||||
const char **attr, int attrlen)
|
const char **attr,
|
||||||
|
int attrlen)
|
||||||
{
|
{
|
||||||
hash_iterator_t *iter;
|
hash_iterator_t *iter;
|
||||||
const char *key;
|
const char *key;
|
||||||
@@ -586,18 +610,20 @@ int xmpp_stanza_get_attributes(xmpp_stanza_t * const stanza,
|
|||||||
*
|
*
|
||||||
* @ingroup Stanza
|
* @ingroup Stanza
|
||||||
*/
|
*/
|
||||||
int xmpp_stanza_set_attribute(xmpp_stanza_t * const stanza,
|
int xmpp_stanza_set_attribute(xmpp_stanza_t *const stanza,
|
||||||
const char * const key,
|
const char *const key,
|
||||||
const char * const value)
|
const char *const value)
|
||||||
{
|
{
|
||||||
char *val;
|
char *val;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
if (stanza->type != XMPP_STANZA_TAG) return XMPP_EINVOP;
|
if (stanza->type != XMPP_STANZA_TAG)
|
||||||
|
return XMPP_EINVOP;
|
||||||
|
|
||||||
if (!stanza->attributes) {
|
if (!stanza->attributes) {
|
||||||
stanza->attributes = hash_new(stanza->ctx, 8, xmpp_free);
|
stanza->attributes = hash_new(stanza->ctx, 8, xmpp_free);
|
||||||
if (!stanza->attributes) return XMPP_EMEM;
|
if (!stanza->attributes)
|
||||||
|
return XMPP_EMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
val = xmpp_strdup(stanza->ctx, value);
|
val = xmpp_strdup(stanza->ctx, value);
|
||||||
@@ -625,8 +651,7 @@ int xmpp_stanza_set_attribute(xmpp_stanza_t * const stanza,
|
|||||||
*
|
*
|
||||||
* @ingroup Stanza
|
* @ingroup Stanza
|
||||||
*/
|
*/
|
||||||
int xmpp_stanza_set_ns(xmpp_stanza_t * const stanza,
|
int xmpp_stanza_set_ns(xmpp_stanza_t *const stanza, const char *const ns)
|
||||||
const char * const ns)
|
|
||||||
{
|
{
|
||||||
return xmpp_stanza_set_attribute(stanza, "xmlns", ns);
|
return xmpp_stanza_set_attribute(stanza, "xmlns", ns);
|
||||||
}
|
}
|
||||||
@@ -646,7 +671,8 @@ int xmpp_stanza_set_ns(xmpp_stanza_t * const stanza,
|
|||||||
*
|
*
|
||||||
* @ingroup Stanza
|
* @ingroup Stanza
|
||||||
*/
|
*/
|
||||||
int xmpp_stanza_add_child_ex(xmpp_stanza_t *stanza, xmpp_stanza_t *child,
|
int xmpp_stanza_add_child_ex(xmpp_stanza_t *stanza,
|
||||||
|
xmpp_stanza_t *child,
|
||||||
int do_clone)
|
int do_clone)
|
||||||
{
|
{
|
||||||
xmpp_stanza_t *s;
|
xmpp_stanza_t *s;
|
||||||
@@ -662,7 +688,8 @@ int xmpp_stanza_add_child_ex(xmpp_stanza_t *stanza, xmpp_stanza_t *child,
|
|||||||
stanza->children = child;
|
stanza->children = child;
|
||||||
else {
|
else {
|
||||||
s = stanza->children;
|
s = stanza->children;
|
||||||
while (s->next) s = s->next;
|
while (s->next)
|
||||||
|
s = s->next;
|
||||||
s->next = child;
|
s->next = child;
|
||||||
child->prev = s;
|
child->prev = s;
|
||||||
}
|
}
|
||||||
@@ -699,14 +726,15 @@ int xmpp_stanza_add_child(xmpp_stanza_t *stanza, xmpp_stanza_t *child)
|
|||||||
*
|
*
|
||||||
* @ingroup Stanza
|
* @ingroup Stanza
|
||||||
*/
|
*/
|
||||||
int xmpp_stanza_set_text(xmpp_stanza_t *stanza,
|
int xmpp_stanza_set_text(xmpp_stanza_t *stanza, const char *const text)
|
||||||
const char * const text)
|
|
||||||
{
|
{
|
||||||
if (stanza->type == XMPP_STANZA_TAG) return XMPP_EINVOP;
|
if (stanza->type == XMPP_STANZA_TAG)
|
||||||
|
return XMPP_EINVOP;
|
||||||
|
|
||||||
stanza->type = XMPP_STANZA_TEXT;
|
stanza->type = XMPP_STANZA_TEXT;
|
||||||
|
|
||||||
if (stanza->data) xmpp_free(stanza->ctx, stanza->data);
|
if (stanza->data)
|
||||||
|
xmpp_free(stanza->ctx, stanza->data);
|
||||||
stanza->data = xmpp_strdup(stanza->ctx, text);
|
stanza->data = xmpp_strdup(stanza->ctx, text);
|
||||||
|
|
||||||
return stanza->data == NULL ? XMPP_EMEM : XMPP_EOK;
|
return stanza->data == NULL ? XMPP_EMEM : XMPP_EOK;
|
||||||
@@ -727,16 +755,19 @@ int xmpp_stanza_set_text(xmpp_stanza_t *stanza,
|
|||||||
* @ingroup Stanza
|
* @ingroup Stanza
|
||||||
*/
|
*/
|
||||||
int xmpp_stanza_set_text_with_size(xmpp_stanza_t *stanza,
|
int xmpp_stanza_set_text_with_size(xmpp_stanza_t *stanza,
|
||||||
const char * const text,
|
const char *const text,
|
||||||
const size_t size)
|
const size_t size)
|
||||||
{
|
{
|
||||||
if (stanza->type == XMPP_STANZA_TAG) return XMPP_EINVOP;
|
if (stanza->type == XMPP_STANZA_TAG)
|
||||||
|
return XMPP_EINVOP;
|
||||||
|
|
||||||
stanza->type = XMPP_STANZA_TEXT;
|
stanza->type = XMPP_STANZA_TEXT;
|
||||||
|
|
||||||
if (stanza->data) xmpp_free(stanza->ctx, stanza->data);
|
if (stanza->data)
|
||||||
|
xmpp_free(stanza->ctx, stanza->data);
|
||||||
stanza->data = xmpp_alloc(stanza->ctx, size + 1);
|
stanza->data = xmpp_alloc(stanza->ctx, size + 1);
|
||||||
if (!stanza->data) return XMPP_EMEM;
|
if (!stanza->data)
|
||||||
|
return XMPP_EMEM;
|
||||||
|
|
||||||
memcpy(stanza->data, text, size);
|
memcpy(stanza->data, text, size);
|
||||||
stanza->data[size] = 0;
|
stanza->data[size] = 0;
|
||||||
@@ -754,7 +785,7 @@ int xmpp_stanza_set_text_with_size(xmpp_stanza_t *stanza,
|
|||||||
*
|
*
|
||||||
* @ingroup Stanza
|
* @ingroup Stanza
|
||||||
*/
|
*/
|
||||||
const char *xmpp_stanza_get_id(xmpp_stanza_t * const stanza)
|
const char *xmpp_stanza_get_id(xmpp_stanza_t *const stanza)
|
||||||
{
|
{
|
||||||
return xmpp_stanza_get_attribute(stanza, "id");
|
return xmpp_stanza_get_attribute(stanza, "id");
|
||||||
}
|
}
|
||||||
@@ -769,7 +800,7 @@ const char *xmpp_stanza_get_id(xmpp_stanza_t * const stanza)
|
|||||||
*
|
*
|
||||||
* @ingroup Stanza
|
* @ingroup Stanza
|
||||||
*/
|
*/
|
||||||
const char *xmpp_stanza_get_ns(xmpp_stanza_t * const stanza)
|
const char *xmpp_stanza_get_ns(xmpp_stanza_t *const stanza)
|
||||||
{
|
{
|
||||||
return xmpp_stanza_get_attribute(stanza, "xmlns");
|
return xmpp_stanza_get_attribute(stanza, "xmlns");
|
||||||
}
|
}
|
||||||
@@ -784,7 +815,7 @@ const char *xmpp_stanza_get_ns(xmpp_stanza_t * const stanza)
|
|||||||
*
|
*
|
||||||
* @ingroup Stanza
|
* @ingroup Stanza
|
||||||
*/
|
*/
|
||||||
const char *xmpp_stanza_get_type(xmpp_stanza_t * const stanza)
|
const char *xmpp_stanza_get_type(xmpp_stanza_t *const stanza)
|
||||||
{
|
{
|
||||||
return xmpp_stanza_get_attribute(stanza, "type");
|
return xmpp_stanza_get_attribute(stanza, "type");
|
||||||
}
|
}
|
||||||
@@ -799,7 +830,7 @@ const char *xmpp_stanza_get_type(xmpp_stanza_t * const stanza)
|
|||||||
*
|
*
|
||||||
* @ingroup Stanza
|
* @ingroup Stanza
|
||||||
*/
|
*/
|
||||||
const char *xmpp_stanza_get_to(xmpp_stanza_t * const stanza)
|
const char *xmpp_stanza_get_to(xmpp_stanza_t *const stanza)
|
||||||
{
|
{
|
||||||
return xmpp_stanza_get_attribute(stanza, "to");
|
return xmpp_stanza_get_attribute(stanza, "to");
|
||||||
}
|
}
|
||||||
@@ -814,7 +845,7 @@ const char *xmpp_stanza_get_to(xmpp_stanza_t * const stanza)
|
|||||||
*
|
*
|
||||||
* @ingroup Stanza
|
* @ingroup Stanza
|
||||||
*/
|
*/
|
||||||
const char *xmpp_stanza_get_from(xmpp_stanza_t * const stanza)
|
const char *xmpp_stanza_get_from(xmpp_stanza_t *const stanza)
|
||||||
{
|
{
|
||||||
return xmpp_stanza_get_attribute(stanza, "from");
|
return xmpp_stanza_get_attribute(stanza, "from");
|
||||||
}
|
}
|
||||||
@@ -830,8 +861,8 @@ const char *xmpp_stanza_get_from(xmpp_stanza_t * const stanza)
|
|||||||
*
|
*
|
||||||
* @ingroup Stanza
|
* @ingroup Stanza
|
||||||
*/
|
*/
|
||||||
xmpp_stanza_t *xmpp_stanza_get_child_by_name(xmpp_stanza_t * const stanza,
|
xmpp_stanza_t *xmpp_stanza_get_child_by_name(xmpp_stanza_t *const stanza,
|
||||||
const char * const name)
|
const char *const name)
|
||||||
{
|
{
|
||||||
xmpp_stanza_t *child;
|
xmpp_stanza_t *child;
|
||||||
|
|
||||||
@@ -856,8 +887,8 @@ xmpp_stanza_t *xmpp_stanza_get_child_by_name(xmpp_stanza_t * const stanza,
|
|||||||
*
|
*
|
||||||
* @ingroup Stanza
|
* @ingroup Stanza
|
||||||
*/
|
*/
|
||||||
xmpp_stanza_t *xmpp_stanza_get_child_by_ns(xmpp_stanza_t * const stanza,
|
xmpp_stanza_t *xmpp_stanza_get_child_by_ns(xmpp_stanza_t *const stanza,
|
||||||
const char * const ns)
|
const char *const ns)
|
||||||
{
|
{
|
||||||
xmpp_stanza_t *child;
|
xmpp_stanza_t *child;
|
||||||
const char *child_ns;
|
const char *child_ns;
|
||||||
@@ -884,9 +915,9 @@ xmpp_stanza_t *xmpp_stanza_get_child_by_ns(xmpp_stanza_t * const stanza,
|
|||||||
*
|
*
|
||||||
* @ingroup Stanza
|
* @ingroup Stanza
|
||||||
*/
|
*/
|
||||||
xmpp_stanza_t *xmpp_stanza_get_child_by_name_and_ns(xmpp_stanza_t * const stanza,
|
xmpp_stanza_t *xmpp_stanza_get_child_by_name_and_ns(xmpp_stanza_t *const stanza,
|
||||||
const char * const name,
|
const char *const name,
|
||||||
const char * const ns)
|
const char *const ns)
|
||||||
{
|
{
|
||||||
xmpp_stanza_t *child;
|
xmpp_stanza_t *child;
|
||||||
const char *child_ns;
|
const char *child_ns;
|
||||||
@@ -915,7 +946,7 @@ xmpp_stanza_t *xmpp_stanza_get_child_by_name_and_ns(xmpp_stanza_t * const stanza
|
|||||||
*
|
*
|
||||||
* @ingroup Stanza
|
* @ingroup Stanza
|
||||||
*/
|
*/
|
||||||
xmpp_stanza_t *xmpp_stanza_get_children(xmpp_stanza_t * const stanza)
|
xmpp_stanza_t *xmpp_stanza_get_children(xmpp_stanza_t *const stanza)
|
||||||
{
|
{
|
||||||
return stanza->children;
|
return stanza->children;
|
||||||
}
|
}
|
||||||
@@ -928,7 +959,7 @@ xmpp_stanza_t *xmpp_stanza_get_children(xmpp_stanza_t * const stanza)
|
|||||||
*
|
*
|
||||||
* @ingroup Stanza
|
* @ingroup Stanza
|
||||||
*/
|
*/
|
||||||
xmpp_stanza_t *xmpp_stanza_get_next(xmpp_stanza_t * const stanza)
|
xmpp_stanza_t *xmpp_stanza_get_next(xmpp_stanza_t *const stanza)
|
||||||
{
|
{
|
||||||
return stanza->next;
|
return stanza->next;
|
||||||
}
|
}
|
||||||
@@ -944,7 +975,7 @@ xmpp_stanza_t *xmpp_stanza_get_next(xmpp_stanza_t * const stanza)
|
|||||||
*
|
*
|
||||||
* @ingroup Stanza
|
* @ingroup Stanza
|
||||||
*/
|
*/
|
||||||
char *xmpp_stanza_get_text(xmpp_stanza_t * const stanza)
|
char *xmpp_stanza_get_text(xmpp_stanza_t *const stanza)
|
||||||
{
|
{
|
||||||
size_t len, clen;
|
size_t len, clen;
|
||||||
xmpp_stanza_t *child;
|
xmpp_stanza_t *child;
|
||||||
@@ -962,10 +993,12 @@ char *xmpp_stanza_get_text(xmpp_stanza_t * const stanza)
|
|||||||
if (child->type == XMPP_STANZA_TEXT)
|
if (child->type == XMPP_STANZA_TEXT)
|
||||||
len += strlen(child->data);
|
len += strlen(child->data);
|
||||||
|
|
||||||
if (len == 0) return NULL;
|
if (len == 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
text = (char *)xmpp_alloc(stanza->ctx, len + 1);
|
text = (char *)xmpp_alloc(stanza->ctx, len + 1);
|
||||||
if (!text) return NULL;
|
if (!text)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
len = 0;
|
len = 0;
|
||||||
for (child = stanza->children; child; child = child->next)
|
for (child = stanza->children; child; child = child->next)
|
||||||
@@ -993,7 +1026,7 @@ char *xmpp_stanza_get_text(xmpp_stanza_t * const stanza)
|
|||||||
*
|
*
|
||||||
* @ingroup Stanza
|
* @ingroup Stanza
|
||||||
*/
|
*/
|
||||||
const char *xmpp_stanza_get_text_ptr(xmpp_stanza_t * const stanza)
|
const char *xmpp_stanza_get_text_ptr(xmpp_stanza_t *const stanza)
|
||||||
{
|
{
|
||||||
if (stanza->type == XMPP_STANZA_TEXT)
|
if (stanza->type == XMPP_STANZA_TEXT)
|
||||||
return stanza->data;
|
return stanza->data;
|
||||||
@@ -1012,8 +1045,7 @@ const char *xmpp_stanza_get_text_ptr(xmpp_stanza_t * const stanza)
|
|||||||
*
|
*
|
||||||
* @ingroup Stanza
|
* @ingroup Stanza
|
||||||
*/
|
*/
|
||||||
int xmpp_stanza_set_id(xmpp_stanza_t * const stanza,
|
int xmpp_stanza_set_id(xmpp_stanza_t *const stanza, const char *const id)
|
||||||
const char * const id)
|
|
||||||
{
|
{
|
||||||
return xmpp_stanza_set_attribute(stanza, "id", id);
|
return xmpp_stanza_set_attribute(stanza, "id", id);
|
||||||
}
|
}
|
||||||
@@ -1029,8 +1061,7 @@ int xmpp_stanza_set_id(xmpp_stanza_t * const stanza,
|
|||||||
*
|
*
|
||||||
* @ingroup Stanza
|
* @ingroup Stanza
|
||||||
*/
|
*/
|
||||||
int xmpp_stanza_set_type(xmpp_stanza_t * const stanza,
|
int xmpp_stanza_set_type(xmpp_stanza_t *const stanza, const char *const type)
|
||||||
const char * const type)
|
|
||||||
{
|
{
|
||||||
return xmpp_stanza_set_attribute(stanza, "type", type);
|
return xmpp_stanza_set_attribute(stanza, "type", type);
|
||||||
}
|
}
|
||||||
@@ -1047,8 +1078,7 @@ int xmpp_stanza_set_type(xmpp_stanza_t * const stanza,
|
|||||||
*
|
*
|
||||||
* @ingroup Stanza
|
* @ingroup Stanza
|
||||||
*/
|
*/
|
||||||
int xmpp_stanza_set_to(xmpp_stanza_t * const stanza,
|
int xmpp_stanza_set_to(xmpp_stanza_t *const stanza, const char *const to)
|
||||||
const char * const to)
|
|
||||||
{
|
{
|
||||||
return xmpp_stanza_set_attribute(stanza, "to", to);
|
return xmpp_stanza_set_attribute(stanza, "to", to);
|
||||||
}
|
}
|
||||||
@@ -1065,8 +1095,7 @@ int xmpp_stanza_set_to(xmpp_stanza_t * const stanza,
|
|||||||
*
|
*
|
||||||
* @ingroup Stanza
|
* @ingroup Stanza
|
||||||
*/
|
*/
|
||||||
int xmpp_stanza_set_from(xmpp_stanza_t * const stanza,
|
int xmpp_stanza_set_from(xmpp_stanza_t *const stanza, const char *const from)
|
||||||
const char * const from)
|
|
||||||
{
|
{
|
||||||
return xmpp_stanza_set_attribute(stanza, "from", from);
|
return xmpp_stanza_set_attribute(stanza, "from", from);
|
||||||
}
|
}
|
||||||
@@ -1082,8 +1111,8 @@ int xmpp_stanza_set_from(xmpp_stanza_t * const stanza,
|
|||||||
*
|
*
|
||||||
* @ingroup Stanza
|
* @ingroup Stanza
|
||||||
*/
|
*/
|
||||||
const char *xmpp_stanza_get_attribute(xmpp_stanza_t * const stanza,
|
const char *xmpp_stanza_get_attribute(xmpp_stanza_t *const stanza,
|
||||||
const char * const name)
|
const char *const name)
|
||||||
{
|
{
|
||||||
if (stanza->type != XMPP_STANZA_TAG)
|
if (stanza->type != XMPP_STANZA_TAG)
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -1103,8 +1132,8 @@ const char *xmpp_stanza_get_attribute(xmpp_stanza_t * const stanza,
|
|||||||
*
|
*
|
||||||
* @ingroup Stanza
|
* @ingroup Stanza
|
||||||
*/
|
*/
|
||||||
int xmpp_stanza_del_attribute(xmpp_stanza_t * const stanza,
|
int xmpp_stanza_del_attribute(xmpp_stanza_t *const stanza,
|
||||||
const char * const name)
|
const char *const name)
|
||||||
{
|
{
|
||||||
if (stanza->type != XMPP_STANZA_TAG)
|
if (stanza->type != XMPP_STANZA_TAG)
|
||||||
return -1;
|
return -1;
|
||||||
@@ -1127,23 +1156,26 @@ int xmpp_stanza_del_attribute(xmpp_stanza_t * const stanza,
|
|||||||
*
|
*
|
||||||
* @ingroup Stanza
|
* @ingroup Stanza
|
||||||
*/
|
*/
|
||||||
xmpp_stanza_t *xmpp_stanza_reply(xmpp_stanza_t * const stanza)
|
xmpp_stanza_t *xmpp_stanza_reply(xmpp_stanza_t *const stanza)
|
||||||
{
|
{
|
||||||
xmpp_stanza_t *copy = NULL;
|
xmpp_stanza_t *copy = NULL;
|
||||||
const char *from;
|
const char *from;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
from = xmpp_stanza_get_from(stanza);
|
from = xmpp_stanza_get_from(stanza);
|
||||||
if (!from) goto copy_error;
|
if (!from)
|
||||||
|
goto copy_error;
|
||||||
|
|
||||||
copy = xmpp_stanza_new(stanza->ctx);
|
copy = xmpp_stanza_new(stanza->ctx);
|
||||||
if (!copy) goto copy_error;
|
if (!copy)
|
||||||
|
goto copy_error;
|
||||||
|
|
||||||
copy->type = stanza->type;
|
copy->type = stanza->type;
|
||||||
|
|
||||||
if (stanza->data) {
|
if (stanza->data) {
|
||||||
copy->data = xmpp_strdup(stanza->ctx, stanza->data);
|
copy->data = xmpp_strdup(stanza->ctx, stanza->data);
|
||||||
if (!copy->data) goto copy_error;
|
if (!copy->data)
|
||||||
|
goto copy_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (stanza->attributes) {
|
if (stanza->attributes) {
|
||||||
@@ -1154,19 +1186,22 @@ xmpp_stanza_t *xmpp_stanza_reply(xmpp_stanza_t * const stanza)
|
|||||||
xmpp_stanza_del_attribute(copy, "to");
|
xmpp_stanza_del_attribute(copy, "to");
|
||||||
xmpp_stanza_del_attribute(copy, "from");
|
xmpp_stanza_del_attribute(copy, "from");
|
||||||
rc = xmpp_stanza_set_to(copy, from);
|
rc = xmpp_stanza_set_to(copy, from);
|
||||||
if (rc != XMPP_EOK) goto copy_error;
|
if (rc != XMPP_EOK)
|
||||||
|
goto copy_error;
|
||||||
|
|
||||||
return copy;
|
return copy;
|
||||||
|
|
||||||
copy_error:
|
copy_error:
|
||||||
if (copy) xmpp_stanza_release(copy);
|
if (copy)
|
||||||
|
xmpp_stanza_release(copy);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static xmpp_stanza_t *
|
static xmpp_stanza_t *_stanza_new_with_attrs(xmpp_ctx_t *ctx,
|
||||||
_stanza_new_with_attrs(xmpp_ctx_t *ctx, const char * const name,
|
const char *const name,
|
||||||
const char * const type, const char * const id,
|
const char *const type,
|
||||||
const char * const to)
|
const char *const id,
|
||||||
|
const char *const to)
|
||||||
{
|
{
|
||||||
xmpp_stanza_t *stanza = xmpp_stanza_new(ctx);
|
xmpp_stanza_t *stanza = xmpp_stanza_new(ctx);
|
||||||
int ret;
|
int ret;
|
||||||
@@ -1199,8 +1234,10 @@ _stanza_new_with_attrs(xmpp_ctx_t *ctx, const char * const name,
|
|||||||
*
|
*
|
||||||
* @ingroup Stanza
|
* @ingroup Stanza
|
||||||
*/
|
*/
|
||||||
xmpp_stanza_t *xmpp_message_new(xmpp_ctx_t *ctx, const char * const type,
|
xmpp_stanza_t *xmpp_message_new(xmpp_ctx_t *ctx,
|
||||||
const char * const to, const char * const id)
|
const char *const type,
|
||||||
|
const char *const to,
|
||||||
|
const char *const id)
|
||||||
{
|
{
|
||||||
return _stanza_new_with_attrs(ctx, "message", type, id, to);
|
return _stanza_new_with_attrs(ctx, "message", type, id, to);
|
||||||
}
|
}
|
||||||
@@ -1239,7 +1276,7 @@ char *xmpp_message_get_body(xmpp_stanza_t *msg)
|
|||||||
*
|
*
|
||||||
* @ingroup Stanza
|
* @ingroup Stanza
|
||||||
*/
|
*/
|
||||||
int xmpp_message_set_body(xmpp_stanza_t *msg, const char * const text)
|
int xmpp_message_set_body(xmpp_stanza_t *msg, const char *const text)
|
||||||
{
|
{
|
||||||
xmpp_ctx_t *ctx = msg->ctx;
|
xmpp_ctx_t *ctx = msg->ctx;
|
||||||
xmpp_stanza_t *body;
|
xmpp_stanza_t *body;
|
||||||
@@ -1285,8 +1322,8 @@ int xmpp_message_set_body(xmpp_stanza_t *msg, const char * const text)
|
|||||||
*
|
*
|
||||||
* @ingroup Stanza
|
* @ingroup Stanza
|
||||||
*/
|
*/
|
||||||
xmpp_stanza_t *xmpp_iq_new(xmpp_ctx_t *ctx, const char * const type,
|
xmpp_stanza_t *
|
||||||
const char * const id)
|
xmpp_iq_new(xmpp_ctx_t *ctx, const char *const type, const char *const id)
|
||||||
{
|
{
|
||||||
return _stanza_new_with_attrs(ctx, "iq", type, id, NULL);
|
return _stanza_new_with_attrs(ctx, "iq", type, id, NULL);
|
||||||
}
|
}
|
||||||
@@ -1317,88 +1354,90 @@ xmpp_stanza_t *xmpp_presence_new(xmpp_ctx_t *ctx)
|
|||||||
*
|
*
|
||||||
* @ingroup Stanza
|
* @ingroup Stanza
|
||||||
*/
|
*/
|
||||||
xmpp_stanza_t *xmpp_error_new(xmpp_ctx_t *ctx, xmpp_error_type_t const type,
|
xmpp_stanza_t *xmpp_error_new(xmpp_ctx_t *ctx,
|
||||||
const char * const text)
|
xmpp_error_type_t const type,
|
||||||
|
const char *const text)
|
||||||
{
|
{
|
||||||
xmpp_stanza_t *error = _stanza_new_with_attrs(ctx, "stream:error", NULL, NULL, NULL);
|
xmpp_stanza_t *error =
|
||||||
|
_stanza_new_with_attrs(ctx, "stream:error", NULL, NULL, NULL);
|
||||||
xmpp_stanza_t *error_type = xmpp_stanza_new(ctx);
|
xmpp_stanza_t *error_type = xmpp_stanza_new(ctx);
|
||||||
|
|
||||||
switch(type) {
|
switch (type) {
|
||||||
case XMPP_SE_BAD_FORMAT:
|
case XMPP_SE_BAD_FORMAT:
|
||||||
xmpp_stanza_set_name(error_type, "bad-format");
|
xmpp_stanza_set_name(error_type, "bad-format");
|
||||||
break;
|
break;
|
||||||
case XMPP_SE_BAD_NS_PREFIX:
|
case XMPP_SE_BAD_NS_PREFIX:
|
||||||
xmpp_stanza_set_name(error_type, "bad-namespace-prefix");
|
xmpp_stanza_set_name(error_type, "bad-namespace-prefix");
|
||||||
break;
|
break;
|
||||||
case XMPP_SE_CONFLICT:
|
case XMPP_SE_CONFLICT:
|
||||||
xmpp_stanza_set_name(error_type, "conflict");
|
xmpp_stanza_set_name(error_type, "conflict");
|
||||||
break;
|
break;
|
||||||
case XMPP_SE_CONN_TIMEOUT:
|
case XMPP_SE_CONN_TIMEOUT:
|
||||||
xmpp_stanza_set_name(error_type, "connection-timeout");
|
xmpp_stanza_set_name(error_type, "connection-timeout");
|
||||||
break;
|
break;
|
||||||
case XMPP_SE_HOST_GONE:
|
case XMPP_SE_HOST_GONE:
|
||||||
xmpp_stanza_set_name(error_type, "host-gone");
|
xmpp_stanza_set_name(error_type, "host-gone");
|
||||||
break;
|
break;
|
||||||
case XMPP_SE_HOST_UNKNOWN:
|
case XMPP_SE_HOST_UNKNOWN:
|
||||||
xmpp_stanza_set_name(error_type, "host-unknown");
|
xmpp_stanza_set_name(error_type, "host-unknown");
|
||||||
break;
|
break;
|
||||||
case XMPP_SE_IMPROPER_ADDR:
|
case XMPP_SE_IMPROPER_ADDR:
|
||||||
xmpp_stanza_set_name(error_type, "improper-addressing");
|
xmpp_stanza_set_name(error_type, "improper-addressing");
|
||||||
break;
|
break;
|
||||||
case XMPP_SE_INTERNAL_SERVER_ERROR:
|
case XMPP_SE_INTERNAL_SERVER_ERROR:
|
||||||
xmpp_stanza_set_name(error_type, "internal-server-error");
|
xmpp_stanza_set_name(error_type, "internal-server-error");
|
||||||
break;
|
break;
|
||||||
case XMPP_SE_INVALID_FROM:
|
case XMPP_SE_INVALID_FROM:
|
||||||
xmpp_stanza_set_name(error_type, "invalid-from");
|
xmpp_stanza_set_name(error_type, "invalid-from");
|
||||||
break;
|
break;
|
||||||
case XMPP_SE_INVALID_ID:
|
case XMPP_SE_INVALID_ID:
|
||||||
xmpp_stanza_set_name(error_type, "invalid-id");
|
xmpp_stanza_set_name(error_type, "invalid-id");
|
||||||
break;
|
break;
|
||||||
case XMPP_SE_INVALID_NS:
|
case XMPP_SE_INVALID_NS:
|
||||||
xmpp_stanza_set_name(error_type, "invalid-namespace");
|
xmpp_stanza_set_name(error_type, "invalid-namespace");
|
||||||
break;
|
break;
|
||||||
case XMPP_SE_INVALID_XML:
|
case XMPP_SE_INVALID_XML:
|
||||||
xmpp_stanza_set_name(error_type, "invalid-xml");
|
xmpp_stanza_set_name(error_type, "invalid-xml");
|
||||||
break;
|
break;
|
||||||
case XMPP_SE_NOT_AUTHORIZED:
|
case XMPP_SE_NOT_AUTHORIZED:
|
||||||
xmpp_stanza_set_name(error_type, "not-authorized");
|
xmpp_stanza_set_name(error_type, "not-authorized");
|
||||||
break;
|
break;
|
||||||
case XMPP_SE_POLICY_VIOLATION:
|
case XMPP_SE_POLICY_VIOLATION:
|
||||||
xmpp_stanza_set_name(error_type, "policy-violation");
|
xmpp_stanza_set_name(error_type, "policy-violation");
|
||||||
break;
|
break;
|
||||||
case XMPP_SE_REMOTE_CONN_FAILED:
|
case XMPP_SE_REMOTE_CONN_FAILED:
|
||||||
xmpp_stanza_set_name(error_type, "remote-connection-failed");
|
xmpp_stanza_set_name(error_type, "remote-connection-failed");
|
||||||
break;
|
break;
|
||||||
case XMPP_SE_RESOURCE_CONSTRAINT:
|
case XMPP_SE_RESOURCE_CONSTRAINT:
|
||||||
xmpp_stanza_set_name(error_type, "resource-constraint");
|
xmpp_stanza_set_name(error_type, "resource-constraint");
|
||||||
break;
|
break;
|
||||||
case XMPP_SE_RESTRICTED_XML:
|
case XMPP_SE_RESTRICTED_XML:
|
||||||
xmpp_stanza_set_name(error_type, "restricted-xml");
|
xmpp_stanza_set_name(error_type, "restricted-xml");
|
||||||
break;
|
break;
|
||||||
case XMPP_SE_SEE_OTHER_HOST:
|
case XMPP_SE_SEE_OTHER_HOST:
|
||||||
xmpp_stanza_set_name(error_type, "see-other-host");
|
xmpp_stanza_set_name(error_type, "see-other-host");
|
||||||
break;
|
break;
|
||||||
case XMPP_SE_SYSTEM_SHUTDOWN:
|
case XMPP_SE_SYSTEM_SHUTDOWN:
|
||||||
xmpp_stanza_set_name(error_type, "system-shutdown");
|
xmpp_stanza_set_name(error_type, "system-shutdown");
|
||||||
break;
|
break;
|
||||||
case XMPP_SE_UNDEFINED_CONDITION:
|
case XMPP_SE_UNDEFINED_CONDITION:
|
||||||
xmpp_stanza_set_name(error_type, "undefined-condition");
|
xmpp_stanza_set_name(error_type, "undefined-condition");
|
||||||
break;
|
break;
|
||||||
case XMPP_SE_UNSUPPORTED_ENCODING:
|
case XMPP_SE_UNSUPPORTED_ENCODING:
|
||||||
xmpp_stanza_set_name(error_type, "unsupported-encoding");
|
xmpp_stanza_set_name(error_type, "unsupported-encoding");
|
||||||
break;
|
break;
|
||||||
case XMPP_SE_UNSUPPORTED_STANZA_TYPE:
|
case XMPP_SE_UNSUPPORTED_STANZA_TYPE:
|
||||||
xmpp_stanza_set_name(error_type, "unsupported-stanza-type");
|
xmpp_stanza_set_name(error_type, "unsupported-stanza-type");
|
||||||
break;
|
break;
|
||||||
case XMPP_SE_UNSUPPORTED_VERSION:
|
case XMPP_SE_UNSUPPORTED_VERSION:
|
||||||
xmpp_stanza_set_name(error_type, "unsupported-version");
|
xmpp_stanza_set_name(error_type, "unsupported-version");
|
||||||
break;
|
break;
|
||||||
case XMPP_SE_XML_NOT_WELL_FORMED:
|
case XMPP_SE_XML_NOT_WELL_FORMED:
|
||||||
xmpp_stanza_set_name(error_type, "xml-not-well-formed");
|
xmpp_stanza_set_name(error_type, "xml-not-well-formed");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
xmpp_stanza_set_name(error_type, "internal-server-error");
|
xmpp_stanza_set_name(error_type, "internal-server-error");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
xmpp_stanza_set_ns(error_type, XMPP_NS_STREAMS_IETF);
|
xmpp_stanza_set_ns(error_type, XMPP_NS_STREAMS_IETF);
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/* tls.h
|
/* tls.h
|
||||||
** strophe XMPP client library -- TLS abstraction header
|
** strophe XMPP client library -- TLS abstraction header
|
||||||
**
|
**
|
||||||
** Copyright (C) 2005-2009 Collecta, Inc.
|
** Copyright (C) 2005-2009 Collecta, Inc.
|
||||||
**
|
**
|
||||||
** This software is provided AS-IS with no warranty, either express
|
** This software is provided AS-IS with no warranty, either express
|
||||||
** or implied.
|
** or implied.
|
||||||
@@ -35,8 +35,8 @@ int tls_stop(tls_t *tls);
|
|||||||
int tls_error(tls_t *tls);
|
int tls_error(tls_t *tls);
|
||||||
|
|
||||||
int tls_pending(tls_t *tls);
|
int tls_pending(tls_t *tls);
|
||||||
int tls_read(tls_t *tls, void * const buff, const size_t len);
|
int tls_read(tls_t *tls, void *const buff, const size_t len);
|
||||||
int tls_write(tls_t *tls, const void * const buff, const size_t len);
|
int tls_write(tls_t *tls, const void *const buff, const size_t len);
|
||||||
|
|
||||||
int tls_clear_pending_write(tls_t *tls);
|
int tls_clear_pending_write(tls_t *tls);
|
||||||
int tls_is_recoverable(int error);
|
int tls_is_recoverable(int error);
|
||||||
|
|||||||
@@ -70,12 +70,12 @@ int tls_pending(tls_t *tls)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int tls_read(tls_t *tls, void * const buff, const size_t len)
|
int tls_read(tls_t *tls, void *const buff, const size_t len)
|
||||||
{
|
{
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int tls_write(tls_t *tls, const void * const buff, const size_t len)
|
int tls_write(tls_t *tls, const void *const buff, const size_t len)
|
||||||
{
|
{
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -79,8 +79,8 @@ int tls_set_credentials(tls_t *tls, const char *cafilename)
|
|||||||
int err;
|
int err;
|
||||||
|
|
||||||
/* set trusted credentials -- takes a .pem filename */
|
/* set trusted credentials -- takes a .pem filename */
|
||||||
err = gnutls_certificate_set_x509_trust_file(tls->cred,
|
err = gnutls_certificate_set_x509_trust_file(tls->cred, cafilename,
|
||||||
cafilename, GNUTLS_X509_FMT_PEM);
|
GNUTLS_X509_FMT_PEM);
|
||||||
if (err >= 0) {
|
if (err >= 0) {
|
||||||
err = gnutls_credentials_set(tls->session, GNUTLS_CRD_CERTIFICATE,
|
err = gnutls_credentials_set(tls->session, GNUTLS_CRD_CERTIFICATE,
|
||||||
tls->cred);
|
tls->cred);
|
||||||
@@ -117,10 +117,10 @@ int tls_is_recoverable(int error)
|
|||||||
|
|
||||||
int tls_pending(tls_t *tls)
|
int tls_pending(tls_t *tls)
|
||||||
{
|
{
|
||||||
return gnutls_record_check_pending (tls->session);
|
return gnutls_record_check_pending(tls->session);
|
||||||
}
|
}
|
||||||
|
|
||||||
int tls_read(tls_t *tls, void * const buff, const size_t len)
|
int tls_read(tls_t *tls, void *const buff, const size_t len)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
@@ -130,7 +130,7 @@ int tls_read(tls_t *tls, void * const buff, const size_t len)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int tls_write(tls_t *tls, const void * const buff, const size_t len)
|
int tls_write(tls_t *tls, const void *const buff, const size_t len)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
* TLS implementation with OpenSSL.
|
* TLS implementation with OpenSSL.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <errno.h> /* EINTR */
|
#include <errno.h> /* EINTR */
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
@@ -39,11 +39,11 @@
|
|||||||
#if (defined LIBRESSL_VERSION_NUMBER && OPENSSL_VERSION_NUMBER == 0x20000000L)
|
#if (defined LIBRESSL_VERSION_NUMBER && OPENSSL_VERSION_NUMBER == 0x20000000L)
|
||||||
#undef OPENSSL_VERSION_NUMBER
|
#undef OPENSSL_VERSION_NUMBER
|
||||||
#if (LIBRESSL_VERSION_NUMBER >= 0x2080000fL)
|
#if (LIBRESSL_VERSION_NUMBER >= 0x2080000fL)
|
||||||
#define OPENSSL_VERSION_NUMBER 0x1010000fL
|
#define OPENSSL_VERSION_NUMBER 0x1010000fL
|
||||||
#elif (LIBRESSL_VERSION_NUMBER >= 0x2070000fL)
|
#elif (LIBRESSL_VERSION_NUMBER >= 0x2070000fL)
|
||||||
#define OPENSSL_VERSION_NUMBER 0x1000200fL
|
#define OPENSSL_VERSION_NUMBER 0x1000200fL
|
||||||
#else
|
#else
|
||||||
#define OPENSSL_VERSION_NUMBER 0x1000107fL
|
#define OPENSSL_VERSION_NUMBER 0x1000107fL
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -169,9 +169,11 @@ tls_t *tls_new(xmpp_conn_t *conn)
|
|||||||
* Allow only complete wildcards. RFC 6125 discourages wildcard usage
|
* Allow only complete wildcards. RFC 6125 discourages wildcard usage
|
||||||
* completely, and lists internationalized domain names as a reason
|
* completely, and lists internationalized domain names as a reason
|
||||||
* against partial wildcards.
|
* against partial wildcards.
|
||||||
* See https://tools.ietf.org/html/rfc6125#section-7.2 for more information.
|
* See https://tools.ietf.org/html/rfc6125#section-7.2 for more
|
||||||
|
* information.
|
||||||
*/
|
*/
|
||||||
X509_VERIFY_PARAM_set_hostflags(param, X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS);
|
X509_VERIFY_PARAM_set_hostflags(param,
|
||||||
|
X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS);
|
||||||
X509_VERIFY_PARAM_set1_host(param, conn->domain, 0);
|
X509_VERIFY_PARAM_set1_host(param, conn->domain, 0);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -271,10 +273,9 @@ int tls_stop(tls_t *tls)
|
|||||||
|
|
||||||
int tls_is_recoverable(int error)
|
int tls_is_recoverable(int error)
|
||||||
{
|
{
|
||||||
return (error == SSL_ERROR_NONE || error == SSL_ERROR_WANT_READ
|
return (error == SSL_ERROR_NONE || error == SSL_ERROR_WANT_READ ||
|
||||||
|| error == SSL_ERROR_WANT_WRITE
|
error == SSL_ERROR_WANT_WRITE || error == SSL_ERROR_WANT_CONNECT ||
|
||||||
|| error == SSL_ERROR_WANT_CONNECT
|
error == SSL_ERROR_WANT_ACCEPT);
|
||||||
|| error == SSL_ERROR_WANT_ACCEPT);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int tls_pending(tls_t *tls)
|
int tls_pending(tls_t *tls)
|
||||||
@@ -282,7 +283,7 @@ int tls_pending(tls_t *tls)
|
|||||||
return SSL_pending(tls->ssl);
|
return SSL_pending(tls->ssl);
|
||||||
}
|
}
|
||||||
|
|
||||||
int tls_read(tls_t *tls, void * const buff, const size_t len)
|
int tls_read(tls_t *tls, void *const buff, const size_t len)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
@@ -292,7 +293,7 @@ int tls_read(tls_t *tls, void * const buff, const size_t len)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int tls_write(tls_t *tls, const void * const buff, const size_t len)
|
int tls_write(tls_t *tls, const void *const buff, const size_t len)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
@@ -315,7 +316,8 @@ static void _tls_sock_wait(tls_t *tls, int error)
|
|||||||
int nfds;
|
int nfds;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (error == SSL_ERROR_NONE) return;
|
if (error == SSL_ERROR_NONE)
|
||||||
|
return;
|
||||||
|
|
||||||
FD_ZERO(&rfds);
|
FD_ZERO(&rfds);
|
||||||
FD_ZERO(&wfds);
|
FD_ZERO(&wfds);
|
||||||
@@ -323,8 +325,9 @@ static void _tls_sock_wait(tls_t *tls, int error)
|
|||||||
FD_SET(tls->sock, &rfds);
|
FD_SET(tls->sock, &rfds);
|
||||||
if (error == SSL_ERROR_WANT_WRITE)
|
if (error == SSL_ERROR_WANT_WRITE)
|
||||||
FD_SET(tls->sock, &wfds);
|
FD_SET(tls->sock, &wfds);
|
||||||
nfds = (error == SSL_ERROR_WANT_READ || error == SSL_ERROR_WANT_WRITE) ?
|
nfds = (error == SSL_ERROR_WANT_READ || error == SSL_ERROR_WANT_WRITE)
|
||||||
tls->sock + 1 : 0;
|
? tls->sock + 1
|
||||||
|
: 0;
|
||||||
do {
|
do {
|
||||||
tv.tv_sec = TLS_TIMEOUT_SEC;
|
tv.tv_sec = TLS_TIMEOUT_SEC;
|
||||||
tv.tv_usec = TLS_TIMEOUT_USEC;
|
tv.tv_usec = TLS_TIMEOUT_USEC;
|
||||||
|
|||||||
@@ -84,13 +84,13 @@ tls_t *tls_new(xmpp_conn_t *conn)
|
|||||||
|
|
||||||
/* no TLS support on win9x/me, despite what anyone says */
|
/* no TLS support on win9x/me, despite what anyone says */
|
||||||
if (osvi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) {
|
if (osvi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
tls = xmpp_alloc(ctx, sizeof(*tls));
|
tls = xmpp_alloc(ctx, sizeof(*tls));
|
||||||
|
|
||||||
if (!tls) {
|
if (!tls) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(tls, 0, sizeof(*tls));
|
memset(tls, 0, sizeof(*tls));
|
||||||
@@ -98,30 +98,29 @@ tls_t *tls_new(xmpp_conn_t *conn)
|
|||||||
tls->conn = conn;
|
tls->conn = conn;
|
||||||
tls->sock = sock;
|
tls->sock = sock;
|
||||||
|
|
||||||
if (!(tls->hsec32 = LoadLibrary ("secur32.dll"))) {
|
if (!(tls->hsec32 = LoadLibrary("secur32.dll"))) {
|
||||||
tls_free(tls);
|
tls_free(tls);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(pInitSecurityInterface =
|
if (!(pInitSecurityInterface =
|
||||||
(void *)GetProcAddress(tls->hsec32, "InitSecurityInterfaceA"))) {
|
(void *)GetProcAddress(tls->hsec32, "InitSecurityInterfaceA"))) {
|
||||||
tls_free(tls);
|
tls_free(tls);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
tls->sft = pInitSecurityInterface();
|
tls->sft = pInitSecurityInterface();
|
||||||
|
|
||||||
if (!tls->sft) {
|
if (!tls->sft) {
|
||||||
tls_free(tls);
|
tls_free(tls);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = tls->sft->QuerySecurityPackageInfo(UNISP_NAME, &(tls->spi));
|
ret = tls->sft->QuerySecurityPackageInfo(UNISP_NAME, &(tls->spi));
|
||||||
|
|
||||||
if (ret != SEC_E_OK)
|
if (ret != SEC_E_OK) {
|
||||||
{
|
tls_free(tls);
|
||||||
tls_free(tls);
|
return NULL;
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
xmpp_debug(ctx, "TLSS", "QuerySecurityPackageInfo() success");
|
xmpp_debug(ctx, "TLSS", "QuerySecurityPackageInfo() success");
|
||||||
@@ -140,13 +139,13 @@ tls_t *tls_new(xmpp_conn_t *conn)
|
|||||||
(void)algs;
|
(void)algs;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ret = tls->sft->AcquireCredentialsHandleA(NULL, UNISP_NAME,
|
ret = tls->sft->AcquireCredentialsHandleA(
|
||||||
SECPKG_CRED_OUTBOUND, NULL, &scred, NULL, NULL, &(tls->hcred), NULL);
|
NULL, UNISP_NAME, SECPKG_CRED_OUTBOUND, NULL, &scred, NULL, NULL,
|
||||||
|
&(tls->hcred), NULL);
|
||||||
|
|
||||||
if (ret != SEC_E_OK)
|
if (ret != SEC_E_OK) {
|
||||||
{
|
tls_free(tls);
|
||||||
tls_free(tls);
|
return NULL;
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
xmpp_debug(ctx, "TLSS", "AcquireCredentialsHandle() success");
|
xmpp_debug(ctx, "TLSS", "AcquireCredentialsHandle() success");
|
||||||
@@ -155,25 +154,25 @@ tls_t *tls_new(xmpp_conn_t *conn)
|
|||||||
|
|
||||||
/* This bunch of queries should trip up wine until someone fixes
|
/* This bunch of queries should trip up wine until someone fixes
|
||||||
* schannel support there */
|
* schannel support there */
|
||||||
ret = tls->sft->QueryCredentialsAttributes(&(tls->hcred), SECPKG_ATTR_SUPPORTED_ALGS, &spc_sa);
|
ret = tls->sft->QueryCredentialsAttributes(
|
||||||
if (ret != SEC_E_OK)
|
&(tls->hcred), SECPKG_ATTR_SUPPORTED_ALGS, &spc_sa);
|
||||||
{
|
if (ret != SEC_E_OK) {
|
||||||
tls_free(tls);
|
tls_free(tls);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = tls->sft->QueryCredentialsAttributes(&(tls->hcred), SECPKG_ATTR_CIPHER_STRENGTHS, &spc_cs);
|
ret = tls->sft->QueryCredentialsAttributes(
|
||||||
if (ret != SEC_E_OK)
|
&(tls->hcred), SECPKG_ATTR_CIPHER_STRENGTHS, &spc_cs);
|
||||||
{
|
if (ret != SEC_E_OK) {
|
||||||
tls_free(tls);
|
tls_free(tls);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = tls->sft->QueryCredentialsAttributes(&(tls->hcred), SECPKG_ATTR_SUPPORTED_PROTOCOLS, &spc_sp);
|
ret = tls->sft->QueryCredentialsAttributes(
|
||||||
if (ret != SEC_E_OK)
|
&(tls->hcred), SECPKG_ATTR_SUPPORTED_PROTOCOLS, &spc_sp);
|
||||||
{
|
if (ret != SEC_E_OK) {
|
||||||
tls_free(tls);
|
tls_free(tls);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return tls;
|
return tls;
|
||||||
@@ -182,26 +181,26 @@ tls_t *tls_new(xmpp_conn_t *conn)
|
|||||||
void tls_free(tls_t *tls)
|
void tls_free(tls_t *tls)
|
||||||
{
|
{
|
||||||
if (tls->recvbuffer) {
|
if (tls->recvbuffer) {
|
||||||
xmpp_free(tls->ctx, tls->recvbuffer);
|
xmpp_free(tls->ctx, tls->recvbuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tls->readybuffer) {
|
if (tls->readybuffer) {
|
||||||
xmpp_free(tls->ctx, tls->readybuffer);
|
xmpp_free(tls->ctx, tls->readybuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tls->sendbuffer) {
|
if (tls->sendbuffer) {
|
||||||
xmpp_free(tls->ctx, tls->sendbuffer);
|
xmpp_free(tls->ctx, tls->sendbuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tls->init) {
|
if (tls->init) {
|
||||||
tls->sft->FreeCredentialsHandle(&(tls->hcred));
|
tls->sft->FreeCredentialsHandle(&(tls->hcred));
|
||||||
}
|
}
|
||||||
|
|
||||||
tls->sft = NULL;
|
tls->sft = NULL;
|
||||||
|
|
||||||
if (tls->hsec32) {
|
if (tls->hsec32) {
|
||||||
FreeLibrary(tls->hsec32);
|
FreeLibrary(tls->hsec32);
|
||||||
tls->hsec32 = NULL;
|
tls->hsec32 = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
xmpp_free(tls->ctx, tls);
|
xmpp_free(tls->ctx, tls);
|
||||||
@@ -225,10 +224,10 @@ int tls_start(tls_t *tls)
|
|||||||
/* use the domain there as our name */
|
/* use the domain there as our name */
|
||||||
name = tls->conn->domain;
|
name = tls->conn->domain;
|
||||||
|
|
||||||
ctxtreq = ISC_REQ_SEQUENCE_DETECT | ISC_REQ_REPLAY_DETECT
|
ctxtreq = ISC_REQ_SEQUENCE_DETECT | ISC_REQ_REPLAY_DETECT |
|
||||||
| ISC_REQ_CONFIDENTIALITY | ISC_RET_EXTENDED_ERROR
|
ISC_REQ_CONFIDENTIALITY | ISC_RET_EXTENDED_ERROR |
|
||||||
| ISC_REQ_ALLOCATE_MEMORY | ISC_REQ_STREAM
|
ISC_REQ_ALLOCATE_MEMORY | ISC_REQ_STREAM |
|
||||||
| ISC_REQ_MANUAL_CRED_VALIDATION | ISC_REQ_INTEGRITY;
|
ISC_REQ_MANUAL_CRED_VALIDATION | ISC_REQ_INTEGRITY;
|
||||||
|
|
||||||
memset(&(sbout[0]), 0, sizeof(sbout[0]));
|
memset(&(sbout[0]), 0, sizeof(sbout[0]));
|
||||||
sbout[0].BufferType = SECBUFFER_TOKEN;
|
sbout[0].BufferType = SECBUFFER_TOKEN;
|
||||||
@@ -251,134 +250,127 @@ int tls_start(tls_t *tls)
|
|||||||
sbdin.cBuffers = 2;
|
sbdin.cBuffers = 2;
|
||||||
sbdin.pBuffers = sbin;
|
sbdin.pBuffers = sbin;
|
||||||
|
|
||||||
ret = tls->sft->InitializeSecurityContextA(&(tls->hcred), NULL, name, ctxtreq, 0, 0,
|
ret = tls->sft->InitializeSecurityContextA(
|
||||||
NULL, 0, &(tls->hctxt), &sbdout,
|
&(tls->hcred), NULL, name, ctxtreq, 0, 0, NULL, 0, &(tls->hctxt),
|
||||||
&ctxtattr, NULL);
|
&sbdout, &ctxtattr, NULL);
|
||||||
|
|
||||||
unsigned char *p = sbin[0].pvBuffer;
|
unsigned char *p = sbin[0].pvBuffer;
|
||||||
int len = 0;
|
int len = 0;
|
||||||
|
|
||||||
while (ret == SEC_I_CONTINUE_NEEDED
|
while (ret == SEC_I_CONTINUE_NEEDED ||
|
||||||
|| ret == SEC_I_INCOMPLETE_CREDENTIALS
|
ret == SEC_I_INCOMPLETE_CREDENTIALS ||
|
||||||
|| ret == SEC_E_INCOMPLETE_MESSAGE) {
|
ret == SEC_E_INCOMPLETE_MESSAGE) {
|
||||||
int inbytes = 0;
|
int inbytes = 0;
|
||||||
|
|
||||||
if (ret != SEC_E_INCOMPLETE_MESSAGE) {
|
if (ret != SEC_E_INCOMPLETE_MESSAGE) {
|
||||||
len = 0;
|
len = 0;
|
||||||
p = sbin[0].pvBuffer;
|
p = sbin[0].pvBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sbdout.pBuffers[0].cbBuffer) {
|
if (sbdout.pBuffers[0].cbBuffer) {
|
||||||
unsigned char *writebuff = sbdout.pBuffers[0].pvBuffer;
|
unsigned char *writebuff = sbdout.pBuffers[0].pvBuffer;
|
||||||
unsigned int writelen = sbdout.pBuffers[0].cbBuffer;
|
unsigned int writelen = sbdout.pBuffers[0].cbBuffer;
|
||||||
|
|
||||||
sent = sock_write(tls->sock, writebuff, writelen);
|
sent = sock_write(tls->sock, writebuff, writelen);
|
||||||
if (sent == -1) {
|
if (sent == -1) {
|
||||||
tls->lasterror = sock_error();
|
tls->lasterror = sock_error();
|
||||||
}
|
} else {
|
||||||
else
|
writebuff += sent;
|
||||||
{
|
writelen -= sent;
|
||||||
writebuff += sent;
|
}
|
||||||
writelen -= sent;
|
tls->sft->FreeContextBuffer(sbdout.pBuffers[0].pvBuffer);
|
||||||
}
|
sbdout.pBuffers[0].pvBuffer = NULL;
|
||||||
tls->sft->FreeContextBuffer(sbdout.pBuffers[0].pvBuffer);
|
sbdout.pBuffers[0].cbBuffer = 0;
|
||||||
sbdout.pBuffers[0].pvBuffer = NULL;
|
}
|
||||||
sbdout.pBuffers[0].cbBuffer = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* poll for a bit until the remote server stops sending data, ie it
|
/* poll for a bit until the remote server stops sending data, ie it
|
||||||
* finishes sending the token */
|
* finishes sending the token */
|
||||||
inbytes = 1;
|
inbytes = 1;
|
||||||
{
|
{
|
||||||
fd_set fds;
|
fd_set fds;
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
|
|
||||||
tv.tv_sec = 2;
|
tv.tv_sec = 2;
|
||||||
tv.tv_usec = 0;
|
tv.tv_usec = 0;
|
||||||
|
|
||||||
FD_ZERO(&fds);
|
FD_ZERO(&fds);
|
||||||
FD_SET(tls->sock, &fds);
|
FD_SET(tls->sock, &fds);
|
||||||
|
|
||||||
select(tls->sock, &fds, NULL, NULL, &tv);
|
select(tls->sock, &fds, NULL, NULL, &tv);
|
||||||
}
|
}
|
||||||
|
|
||||||
while (inbytes > 0) {
|
while (inbytes > 0) {
|
||||||
fd_set fds;
|
fd_set fds;
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
|
|
||||||
tv.tv_sec = 0;
|
tv.tv_sec = 0;
|
||||||
tv.tv_usec = 1000;
|
tv.tv_usec = 1000;
|
||||||
|
|
||||||
FD_ZERO(&fds);
|
FD_ZERO(&fds);
|
||||||
FD_SET(tls->sock, &fds);
|
FD_SET(tls->sock, &fds);
|
||||||
|
|
||||||
select(tls->sock, &fds, NULL, NULL, &tv);
|
select(tls->sock, &fds, NULL, NULL, &tv);
|
||||||
|
|
||||||
inbytes = sock_read(tls->sock, p, tls->spi->cbMaxToken - len);
|
inbytes = sock_read(tls->sock, p, tls->spi->cbMaxToken - len);
|
||||||
|
|
||||||
if (inbytes > 0) {
|
if (inbytes > 0) {
|
||||||
len += inbytes;
|
len += inbytes;
|
||||||
p += inbytes;
|
p += inbytes;
|
||||||
}
|
} else {
|
||||||
else
|
tls->lasterror = sock_error();
|
||||||
{
|
}
|
||||||
tls->lasterror = sock_error();
|
}
|
||||||
}
|
|
||||||
|
|
||||||
}
|
sbin[0].cbBuffer = len;
|
||||||
|
|
||||||
sbin[0].cbBuffer = len;
|
ret = tls->sft->InitializeSecurityContextA(
|
||||||
|
&(tls->hcred), &(tls->hctxt), name, ctxtreq, 0, 0, &sbdin, 0,
|
||||||
ret = tls->sft->InitializeSecurityContextA(&(tls->hcred), &(tls->hctxt), name,
|
&(tls->hctxt), &sbdout, &ctxtattr, NULL);
|
||||||
ctxtreq, 0, 0, &sbdin, 0,
|
|
||||||
&(tls->hctxt), &sbdout,
|
|
||||||
&ctxtattr, NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret == SEC_E_OK) {
|
if (ret == SEC_E_OK) {
|
||||||
if (sbdout.pBuffers[0].cbBuffer) {
|
if (sbdout.pBuffers[0].cbBuffer) {
|
||||||
unsigned char *writebuff = sbdout.pBuffers[0].pvBuffer;
|
unsigned char *writebuff = sbdout.pBuffers[0].pvBuffer;
|
||||||
unsigned int writelen = sbdout.pBuffers[0].cbBuffer;
|
unsigned int writelen = sbdout.pBuffers[0].cbBuffer;
|
||||||
sent = sock_write(tls->sock, writebuff, writelen);
|
sent = sock_write(tls->sock, writebuff, writelen);
|
||||||
if (sent == -1) {
|
if (sent == -1) {
|
||||||
tls->lasterror = sock_error();
|
tls->lasterror = sock_error();
|
||||||
}
|
} else {
|
||||||
else
|
writebuff += sent;
|
||||||
{
|
writelen -= sent;
|
||||||
writebuff += sent;
|
}
|
||||||
writelen -= sent;
|
tls->sft->FreeContextBuffer(sbdout.pBuffers[0].pvBuffer);
|
||||||
}
|
sbdout.pBuffers[0].pvBuffer = NULL;
|
||||||
tls->sft->FreeContextBuffer(sbdout.pBuffers[0].pvBuffer);
|
sbdout.pBuffers[0].cbBuffer = 0;
|
||||||
sbdout.pBuffers[0].pvBuffer = NULL;
|
}
|
||||||
sbdout.pBuffers[0].cbBuffer = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
xmpp_free(tls->ctx, sbin[0].pvBuffer);
|
xmpp_free(tls->ctx, sbin[0].pvBuffer);
|
||||||
|
|
||||||
if (ret != SEC_E_OK) {
|
if (ret != SEC_E_OK) {
|
||||||
tls->lasterror = ret;
|
tls->lasterror = ret;
|
||||||
xmpp_error(tls->ctx, "TLSS", "Schannel error 0x%lx", (unsigned long)ret);
|
xmpp_error(tls->ctx, "TLSS", "Schannel error 0x%lx",
|
||||||
return 0;
|
(unsigned long)ret);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
tls->sft->QueryContextAttributes(&(tls->hctxt), SECPKG_ATTR_STREAM_SIZES,
|
tls->sft->QueryContextAttributes(&(tls->hctxt), SECPKG_ATTR_STREAM_SIZES,
|
||||||
&(tls->spcss));
|
&(tls->spcss));
|
||||||
|
|
||||||
tls->recvbuffermaxlen = tls->spcss.cbHeader + tls->spcss.cbMaximumMessage
|
tls->recvbuffermaxlen = tls->spcss.cbHeader + tls->spcss.cbMaximumMessage +
|
||||||
+ tls->spcss.cbTrailer;
|
tls->spcss.cbTrailer;
|
||||||
tls->recvbuffer = xmpp_alloc(tls->ctx, tls->recvbuffermaxlen);
|
tls->recvbuffer = xmpp_alloc(tls->ctx, tls->recvbuffermaxlen);
|
||||||
tls->recvbufferpos = 0;
|
tls->recvbufferpos = 0;
|
||||||
|
|
||||||
tls->sendbuffermaxlen = tls->spcss.cbHeader + tls->spcss.cbMaximumMessage
|
tls->sendbuffermaxlen = tls->spcss.cbHeader + tls->spcss.cbMaximumMessage +
|
||||||
+ tls->spcss.cbTrailer;
|
tls->spcss.cbTrailer;
|
||||||
tls->sendbuffer = xmpp_alloc(tls->ctx, tls->sendbuffermaxlen);
|
tls->sendbuffer = xmpp_alloc(tls->ctx, tls->sendbuffermaxlen);
|
||||||
tls->sendbufferpos = 0;
|
tls->sendbufferpos = 0;
|
||||||
tls->sendbufferlen = 0;
|
tls->sendbufferlen = 0;
|
||||||
|
|
||||||
tls->readybuffer = xmpp_alloc(tls->ctx, tls->spcss.cbMaximumMessage);
|
tls->readybuffer = xmpp_alloc(tls->ctx, tls->spcss.cbMaximumMessage);
|
||||||
tls->readybufferpos = 0;
|
tls->readybufferpos = 0;
|
||||||
tls->readybufferlen = 0;
|
tls->readybufferlen = 0;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -395,67 +387,67 @@ int tls_error(tls_t *tls)
|
|||||||
|
|
||||||
int tls_is_recoverable(int error)
|
int tls_is_recoverable(int error)
|
||||||
{
|
{
|
||||||
return (error == SEC_E_OK || error == SEC_E_INCOMPLETE_MESSAGE
|
return (error == SEC_E_OK || error == SEC_E_INCOMPLETE_MESSAGE ||
|
||||||
|| error == WSAEWOULDBLOCK || error == WSAEMSGSIZE
|
error == WSAEWOULDBLOCK || error == WSAEMSGSIZE ||
|
||||||
|| error == WSAEINPROGRESS);
|
error == WSAEINPROGRESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
int tls_pending(tls_t *tls) {
|
int tls_pending(tls_t *tls)
|
||||||
// There are 3 cases:
|
{
|
||||||
// - there is data in ready buffer, so it is by default pending
|
// There are 3 cases:
|
||||||
// - there is data in recv buffer. If it is not decrypted yet, means it
|
// - there is data in ready buffer, so it is by default pending
|
||||||
// was incomplete. This should be processed again only if there is data
|
// - there is data in recv buffer. If it is not decrypted yet, means it
|
||||||
// on the physical connection
|
// was incomplete. This should be processed again only if there is data
|
||||||
// - there is data on the physical connection. This case is treated
|
// on the physical connection
|
||||||
// outside the tls (in event.c)
|
// - there is data on the physical connection. This case is treated
|
||||||
|
// outside the tls (in event.c)
|
||||||
|
|
||||||
if (tls->readybufferpos < tls->readybufferlen) {
|
if (tls->readybufferpos < tls->readybufferlen) {
|
||||||
return tls->readybufferlen - tls->readybufferpos;
|
return tls->readybufferlen - tls->readybufferpos;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int tls_read(tls_t *tls, void * const buff, const size_t len)
|
int tls_read(tls_t *tls, void *const buff, const size_t len)
|
||||||
{
|
{
|
||||||
int bytes;
|
int bytes;
|
||||||
|
|
||||||
/* first, if we've got some ready data, put that in the buffer */
|
/* first, if we've got some ready data, put that in the buffer */
|
||||||
if (tls->readybufferpos < tls->readybufferlen)
|
if (tls->readybufferpos < tls->readybufferlen) {
|
||||||
{
|
if (len < tls->readybufferlen - tls->readybufferpos) {
|
||||||
if (len < tls->readybufferlen - tls->readybufferpos) {
|
bytes = len;
|
||||||
bytes = len;
|
} else {
|
||||||
} else {
|
bytes = tls->readybufferlen - tls->readybufferpos;
|
||||||
bytes = tls->readybufferlen - tls->readybufferpos;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(buff, tls->readybuffer + tls->readybufferpos, bytes);
|
memcpy(buff, tls->readybuffer + tls->readybufferpos, bytes);
|
||||||
|
|
||||||
if (len < tls->readybufferlen - tls->readybufferpos) {
|
if (len < tls->readybufferlen - tls->readybufferpos) {
|
||||||
tls->readybufferpos += bytes;
|
tls->readybufferpos += bytes;
|
||||||
return bytes;
|
return bytes;
|
||||||
} else {
|
} else {
|
||||||
unsigned char *newbuff = buff;
|
unsigned char *newbuff = buff;
|
||||||
int read;
|
int read;
|
||||||
tls->readybufferpos += bytes;
|
tls->readybufferpos += bytes;
|
||||||
newbuff += bytes;
|
newbuff += bytes;
|
||||||
read = tls_read(tls, newbuff, len - bytes);
|
read = tls_read(tls, newbuff, len - bytes);
|
||||||
|
|
||||||
if (read == -1) {
|
if (read == -1) {
|
||||||
if (tls_is_recoverable(tls->lasterror)) {
|
if (tls_is_recoverable(tls->lasterror)) {
|
||||||
return bytes;
|
return bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return bytes + read;
|
return bytes + read;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* next, top up our recv buffer */
|
/* next, top up our recv buffer */
|
||||||
bytes = sock_read(tls->sock, tls->recvbuffer + tls->recvbufferpos,
|
bytes = sock_read(tls->sock, tls->recvbuffer + tls->recvbufferpos,
|
||||||
tls->recvbuffermaxlen - tls->recvbufferpos);
|
tls->recvbuffermaxlen - tls->recvbufferpos);
|
||||||
|
|
||||||
if (bytes == 0) {
|
if (bytes == 0) {
|
||||||
tls->lasterror = WSAECONNRESET;
|
tls->lasterror = WSAECONNRESET;
|
||||||
@@ -463,76 +455,75 @@ int tls_read(tls_t *tls, void * const buff, const size_t len)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (bytes == -1) {
|
if (bytes == -1) {
|
||||||
if (!tls_is_recoverable(sock_error())) {
|
if (!tls_is_recoverable(sock_error())) {
|
||||||
tls->lasterror = sock_error();
|
tls->lasterror = sock_error();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bytes > 0) {
|
if (bytes > 0) {
|
||||||
tls->recvbufferpos += bytes;
|
tls->recvbufferpos += bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* next, try to decrypt the recv buffer */
|
/* next, try to decrypt the recv buffer */
|
||||||
if (tls->recvbufferpos > 0) {
|
if (tls->recvbufferpos > 0) {
|
||||||
SecBufferDesc sbddec;
|
SecBufferDesc sbddec;
|
||||||
SecBuffer sbdec[4];
|
SecBuffer sbdec[4];
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
memset(&sbddec, 0, sizeof(sbddec));
|
memset(&sbddec, 0, sizeof(sbddec));
|
||||||
sbddec.ulVersion = SECBUFFER_VERSION;
|
sbddec.ulVersion = SECBUFFER_VERSION;
|
||||||
sbddec.cBuffers = 4;
|
sbddec.cBuffers = 4;
|
||||||
sbddec.pBuffers = sbdec;
|
sbddec.pBuffers = sbdec;
|
||||||
|
|
||||||
memset(&(sbdec[0]), 0, sizeof(sbdec[0]));
|
memset(&(sbdec[0]), 0, sizeof(sbdec[0]));
|
||||||
sbdec[0].BufferType = SECBUFFER_DATA;
|
sbdec[0].BufferType = SECBUFFER_DATA;
|
||||||
sbdec[0].pvBuffer = tls->recvbuffer;
|
sbdec[0].pvBuffer = tls->recvbuffer;
|
||||||
sbdec[0].cbBuffer = tls->recvbufferpos;
|
sbdec[0].cbBuffer = tls->recvbufferpos;
|
||||||
|
|
||||||
memset(&(sbdec[1]), 0, sizeof(sbdec[1]));
|
memset(&(sbdec[1]), 0, sizeof(sbdec[1]));
|
||||||
sbdec[1].BufferType = SECBUFFER_EMPTY;
|
sbdec[1].BufferType = SECBUFFER_EMPTY;
|
||||||
|
|
||||||
memset(&(sbdec[2]), 0, sizeof(sbdec[2]));
|
memset(&(sbdec[2]), 0, sizeof(sbdec[2]));
|
||||||
sbdec[2].BufferType = SECBUFFER_EMPTY;
|
sbdec[2].BufferType = SECBUFFER_EMPTY;
|
||||||
|
|
||||||
memset(&(sbdec[3]), 0, sizeof(sbdec[3]));
|
memset(&(sbdec[3]), 0, sizeof(sbdec[3]));
|
||||||
sbdec[3].BufferType = SECBUFFER_EMPTY;
|
sbdec[3].BufferType = SECBUFFER_EMPTY;
|
||||||
|
|
||||||
ret = tls->sft->DecryptMessage(&(tls->hctxt), &sbddec, 0, NULL);
|
ret = tls->sft->DecryptMessage(&(tls->hctxt), &sbddec, 0, NULL);
|
||||||
|
|
||||||
if (ret == SEC_E_OK) {
|
if (ret == SEC_E_OK) {
|
||||||
memcpy(tls->readybuffer, sbdec[1].pvBuffer, sbdec[1].cbBuffer);
|
memcpy(tls->readybuffer, sbdec[1].pvBuffer, sbdec[1].cbBuffer);
|
||||||
tls->readybufferpos = 0;
|
tls->readybufferpos = 0;
|
||||||
tls->readybufferlen = sbdec[1].cbBuffer;
|
tls->readybufferlen = sbdec[1].cbBuffer;
|
||||||
/* have we got some data left over? If so, copy it to the start
|
/* have we got some data left over? If so, copy it to the start
|
||||||
* of the recv buffer */
|
* of the recv buffer */
|
||||||
if (sbdec[3].BufferType == SECBUFFER_EXTRA) {
|
if (sbdec[3].BufferType == SECBUFFER_EXTRA) {
|
||||||
memcpy(tls->recvbuffer, sbdec[3].pvBuffer, sbdec[3].cbBuffer);
|
memcpy(tls->recvbuffer, sbdec[3].pvBuffer, sbdec[3].cbBuffer);
|
||||||
tls->recvbufferpos = sbdec[3].cbBuffer;
|
tls->recvbufferpos = sbdec[3].cbBuffer;
|
||||||
} else {
|
} else {
|
||||||
tls->recvbufferpos = 0;
|
tls->recvbufferpos = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return tls_read(tls, buff, len);
|
return tls_read(tls, buff, len);
|
||||||
} else if (ret == SEC_E_INCOMPLETE_MESSAGE) {
|
} else if (ret == SEC_E_INCOMPLETE_MESSAGE) {
|
||||||
tls->lasterror = SEC_E_INCOMPLETE_MESSAGE;
|
tls->lasterror = SEC_E_INCOMPLETE_MESSAGE;
|
||||||
return -1;
|
return -1;
|
||||||
} else if (ret == SEC_I_RENEGOTIATE) {
|
} else if (ret == SEC_I_RENEGOTIATE) {
|
||||||
ret = tls_start(tls);
|
ret = tls_start(tls);
|
||||||
if (!ret)
|
if (!ret) {
|
||||||
{
|
return -1;
|
||||||
return -1;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* fake an incomplete message so we're called again */
|
/* fake an incomplete message so we're called again */
|
||||||
tls->lasterror = SEC_E_INCOMPLETE_MESSAGE;
|
tls->lasterror = SEC_E_INCOMPLETE_MESSAGE;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* something bad happened, so we bail */
|
/* something bad happened, so we bail */
|
||||||
tls->lasterror = ret;
|
tls->lasterror = ret;
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
tls->lasterror = SEC_E_INCOMPLETE_MESSAGE;
|
tls->lasterror = SEC_E_INCOMPLETE_MESSAGE;
|
||||||
@@ -542,29 +533,28 @@ int tls_read(tls_t *tls, void * const buff, const size_t len)
|
|||||||
|
|
||||||
int tls_clear_pending_write(tls_t *tls)
|
int tls_clear_pending_write(tls_t *tls)
|
||||||
{
|
{
|
||||||
if (tls->sendbufferpos < tls->sendbufferlen)
|
if (tls->sendbufferpos < tls->sendbufferlen) {
|
||||||
{
|
int bytes;
|
||||||
int bytes;
|
|
||||||
|
|
||||||
bytes = sock_write(tls->sock, tls->sendbuffer + tls->sendbufferpos,
|
bytes = sock_write(tls->sock, tls->sendbuffer + tls->sendbufferpos,
|
||||||
tls->sendbufferlen - tls->sendbufferpos);
|
tls->sendbufferlen - tls->sendbufferpos);
|
||||||
|
|
||||||
if (bytes == -1) {
|
if (bytes == -1) {
|
||||||
tls->lasterror = sock_error();
|
tls->lasterror = sock_error();
|
||||||
return -1;
|
return -1;
|
||||||
} else if (bytes > 0) {
|
} else if (bytes > 0) {
|
||||||
tls->sendbufferpos += bytes;
|
tls->sendbufferpos += bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tls->sendbufferpos < tls->sendbufferlen) {
|
if (tls->sendbufferpos < tls->sendbufferlen) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int tls_write(tls_t *tls, const void * const buff, const size_t len)
|
int tls_write(tls_t *tls, const void *const buff, const size_t len)
|
||||||
{
|
{
|
||||||
SecBufferDesc sbdenc;
|
SecBufferDesc sbdenc;
|
||||||
SecBuffer sbenc[4];
|
SecBuffer sbenc[4];
|
||||||
@@ -573,7 +563,7 @@ int tls_write(tls_t *tls, const void * const buff, const size_t len)
|
|||||||
|
|
||||||
ret = tls_clear_pending_write(tls);
|
ret = tls_clear_pending_write(tls);
|
||||||
if (ret <= 0) {
|
if (ret <= 0) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
tls->sendbufferpos = 0;
|
tls->sendbufferpos = 0;
|
||||||
@@ -601,51 +591,49 @@ int tls_write(tls_t *tls, const void * const buff, const size_t len)
|
|||||||
|
|
||||||
sbenc[1].pvBuffer = tls->sendbuffer + tls->spcss.cbHeader;
|
sbenc[1].pvBuffer = tls->sendbuffer + tls->spcss.cbHeader;
|
||||||
|
|
||||||
while (remain > 0)
|
while (remain > 0) {
|
||||||
{
|
if (remain > tls->spcss.cbMaximumMessage) {
|
||||||
if (remain > tls->spcss.cbMaximumMessage) {
|
sbenc[1].cbBuffer = tls->spcss.cbMaximumMessage;
|
||||||
sbenc[1].cbBuffer = tls->spcss.cbMaximumMessage;
|
} else {
|
||||||
} else {
|
sbenc[1].cbBuffer = remain;
|
||||||
sbenc[1].cbBuffer = remain;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
sbenc[2].pvBuffer = (unsigned char *)sbenc[1].pvBuffer
|
sbenc[2].pvBuffer =
|
||||||
+ sbenc[1].cbBuffer;
|
(unsigned char *)sbenc[1].pvBuffer + sbenc[1].cbBuffer;
|
||||||
sbenc[2].cbBuffer = tls->spcss.cbTrailer;
|
sbenc[2].cbBuffer = tls->spcss.cbTrailer;
|
||||||
|
|
||||||
memcpy(sbenc[1].pvBuffer, p, sbenc[1].cbBuffer);
|
memcpy(sbenc[1].pvBuffer, p, sbenc[1].cbBuffer);
|
||||||
p += tls->spcss.cbMaximumMessage;
|
p += tls->spcss.cbMaximumMessage;
|
||||||
|
|
||||||
tls->sendbufferlen = sbenc[0].cbBuffer + sbenc[1].cbBuffer
|
tls->sendbufferlen =
|
||||||
+ sbenc[2].cbBuffer;
|
sbenc[0].cbBuffer + sbenc[1].cbBuffer + sbenc[2].cbBuffer;
|
||||||
|
|
||||||
ret = tls->sft->EncryptMessage(&(tls->hctxt), 0, &sbdenc, 0);
|
ret = tls->sft->EncryptMessage(&(tls->hctxt), 0, &sbdenc, 0);
|
||||||
|
|
||||||
if (ret != SEC_E_OK) {
|
if (ret != SEC_E_OK) {
|
||||||
tls->lasterror = ret;
|
tls->lasterror = ret;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
tls->sendbufferpos = 0;
|
tls->sendbufferpos = 0;
|
||||||
|
|
||||||
ret = tls_clear_pending_write(tls);
|
ret = tls_clear_pending_write(tls);
|
||||||
|
|
||||||
if (ret == -1 && !tls_is_recoverable(tls_error(tls))) {
|
if (ret == -1 && !tls_is_recoverable(tls_error(tls))) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (remain > tls->spcss.cbMaximumMessage) {
|
if (remain > tls->spcss.cbMaximumMessage) {
|
||||||
sent += tls->spcss.cbMaximumMessage;
|
sent += tls->spcss.cbMaximumMessage;
|
||||||
remain -= tls->spcss.cbMaximumMessage;
|
remain -= tls->spcss.cbMaximumMessage;
|
||||||
} else {
|
} else {
|
||||||
sent += remain;
|
sent += remain;
|
||||||
remain = 0;
|
remain = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret == 0 || (ret == -1 && tls_is_recoverable(tls_error(tls)))) {
|
|
||||||
return sent;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (ret == 0 || (ret == -1 && tls_is_recoverable(tls_error(tls)))) {
|
||||||
|
return sent;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return sent;
|
return sent;
|
||||||
|
|||||||
@@ -38,7 +38,7 @@
|
|||||||
*
|
*
|
||||||
* @return a new allocates string with the same data as s or NULL on error
|
* @return a new allocates string with the same data as s or NULL on error
|
||||||
*/
|
*/
|
||||||
char *xmpp_strdup(const xmpp_ctx_t * const ctx, const char * const s)
|
char *xmpp_strdup(const xmpp_ctx_t *const ctx, const char *const s)
|
||||||
{
|
{
|
||||||
size_t len;
|
size_t len;
|
||||||
char *copy;
|
char *copy;
|
||||||
@@ -135,7 +135,7 @@ uint64_t time_elapsed(uint64_t t1, uint64_t t2)
|
|||||||
*
|
*
|
||||||
* @param conn a Strophe connection object
|
* @param conn a Strophe connection object
|
||||||
*/
|
*/
|
||||||
void disconnect_mem_error(xmpp_conn_t * const conn)
|
void disconnect_mem_error(xmpp_conn_t *const conn)
|
||||||
{
|
{
|
||||||
xmpp_error(conn->ctx, "xmpp", "Memory allocation error");
|
xmpp_error(conn->ctx, "xmpp", "Memory allocation error");
|
||||||
xmpp_disconnect(conn);
|
xmpp_disconnect(conn);
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/* util.h
|
/* util.h
|
||||||
** strophe XMPP client library -- various utility functions
|
** strophe XMPP client library -- various utility functions
|
||||||
**
|
**
|
||||||
** Copyright (C) 2005-2009 Collecta, Inc.
|
** Copyright (C) 2005-2009 Collecta, Inc.
|
||||||
**
|
**
|
||||||
** This software is provided AS-IS with no warranty, either express
|
** This software is provided AS-IS with no warranty, either express
|
||||||
** or implied.
|
** or implied.
|
||||||
|
|||||||
321
strophe.h
321
strophe.h
@@ -16,7 +16,7 @@
|
|||||||
#ifndef __LIBSTROPHE_STROPHE_H__
|
#ifndef __LIBSTROPHE_STROPHE_H__
|
||||||
#define __LIBSTROPHE_STROPHE_H__
|
#define __LIBSTROPHE_STROPHE_H__
|
||||||
|
|
||||||
#include <stddef.h> /* size_t */
|
#include <stddef.h> /* size_t */
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
@@ -118,18 +118,18 @@ typedef struct _xmpp_log_t xmpp_log_t;
|
|||||||
/* opaque run time context containing the above hooks */
|
/* opaque run time context containing the above hooks */
|
||||||
typedef struct _xmpp_ctx_t xmpp_ctx_t;
|
typedef struct _xmpp_ctx_t xmpp_ctx_t;
|
||||||
|
|
||||||
xmpp_ctx_t *xmpp_ctx_new(const xmpp_mem_t * const mem,
|
xmpp_ctx_t *xmpp_ctx_new(const xmpp_mem_t *const mem,
|
||||||
const xmpp_log_t * const log);
|
const xmpp_log_t *const log);
|
||||||
void xmpp_ctx_free(xmpp_ctx_t * const ctx);
|
void xmpp_ctx_free(xmpp_ctx_t *const ctx);
|
||||||
|
|
||||||
/* free some blocks returned by other APIs, for example the
|
/* free some blocks returned by other APIs, for example the
|
||||||
buffer you get from xmpp_stanza_to_text */
|
buffer you get from xmpp_stanza_to_text */
|
||||||
void xmpp_free(const xmpp_ctx_t * const ctx, void *p);
|
void xmpp_free(const xmpp_ctx_t *const ctx, void *p);
|
||||||
|
|
||||||
struct _xmpp_mem_t {
|
struct _xmpp_mem_t {
|
||||||
void *(*alloc)(const size_t size, void * const userdata);
|
void *(*alloc)(const size_t size, void *const userdata);
|
||||||
void (*free)(void *p, void * const userdata);
|
void (*free)(void *p, void *const userdata);
|
||||||
void *(*realloc)(void *p, const size_t size, void * const userdata);
|
void *(*realloc)(void *p, const size_t size, void *const userdata);
|
||||||
void *userdata;
|
void *userdata;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -140,16 +140,12 @@ typedef enum {
|
|||||||
XMPP_LEVEL_ERROR
|
XMPP_LEVEL_ERROR
|
||||||
} xmpp_log_level_t;
|
} xmpp_log_level_t;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum { XMPP_UNKNOWN, XMPP_CLIENT, XMPP_COMPONENT } xmpp_conn_type_t;
|
||||||
XMPP_UNKNOWN,
|
|
||||||
XMPP_CLIENT,
|
|
||||||
XMPP_COMPONENT
|
|
||||||
} xmpp_conn_type_t;
|
|
||||||
|
|
||||||
typedef void (*xmpp_log_handler)(void * const userdata,
|
typedef void (*xmpp_log_handler)(void *const userdata,
|
||||||
const xmpp_log_level_t level,
|
const xmpp_log_level_t level,
|
||||||
const char * const area,
|
const char *const area,
|
||||||
const char * const msg);
|
const char *const msg);
|
||||||
|
|
||||||
struct _xmpp_log_t {
|
struct _xmpp_log_t {
|
||||||
xmpp_log_handler handler;
|
xmpp_log_handler handler;
|
||||||
@@ -166,17 +162,17 @@ typedef struct _xmpp_conn_t xmpp_conn_t;
|
|||||||
typedef struct _xmpp_stanza_t xmpp_stanza_t;
|
typedef struct _xmpp_stanza_t xmpp_stanza_t;
|
||||||
|
|
||||||
/* connection flags */
|
/* connection flags */
|
||||||
#define XMPP_CONN_FLAG_DISABLE_TLS (1UL << 0)
|
#define XMPP_CONN_FLAG_DISABLE_TLS (1UL << 0)
|
||||||
#define XMPP_CONN_FLAG_MANDATORY_TLS (1UL << 1)
|
#define XMPP_CONN_FLAG_MANDATORY_TLS (1UL << 1)
|
||||||
#define XMPP_CONN_FLAG_LEGACY_SSL (1UL << 2)
|
#define XMPP_CONN_FLAG_LEGACY_SSL (1UL << 2)
|
||||||
/** @def XMPP_CONN_FLAG_TRUST_TLS
|
/** @def XMPP_CONN_FLAG_TRUST_TLS
|
||||||
* Trust server's certificate even if it is invalid.
|
* Trust server's certificate even if it is invalid.
|
||||||
*/
|
*/
|
||||||
#define XMPP_CONN_FLAG_TRUST_TLS (1UL << 3)
|
#define XMPP_CONN_FLAG_TRUST_TLS (1UL << 3)
|
||||||
/** @def XMPP_CONN_FLAG_LEGACY_AUTH
|
/** @def XMPP_CONN_FLAG_LEGACY_AUTH
|
||||||
* Enable legacy authentication support.
|
* Enable legacy authentication support.
|
||||||
*/
|
*/
|
||||||
#define XMPP_CONN_FLAG_LEGACY_AUTH (1UL << 4)
|
#define XMPP_CONN_FLAG_LEGACY_AUTH (1UL << 4)
|
||||||
|
|
||||||
/* connect callback */
|
/* connect callback */
|
||||||
typedef enum {
|
typedef enum {
|
||||||
@@ -219,98 +215,101 @@ typedef struct {
|
|||||||
xmpp_stanza_t *stanza;
|
xmpp_stanza_t *stanza;
|
||||||
} xmpp_stream_error_t;
|
} xmpp_stream_error_t;
|
||||||
|
|
||||||
typedef void (*xmpp_conn_handler)(xmpp_conn_t * const conn,
|
typedef void (*xmpp_conn_handler)(xmpp_conn_t *const conn,
|
||||||
const xmpp_conn_event_t event,
|
const xmpp_conn_event_t event,
|
||||||
const int error,
|
const int error,
|
||||||
xmpp_stream_error_t * const stream_error,
|
xmpp_stream_error_t *const stream_error,
|
||||||
void * const userdata);
|
void *const userdata);
|
||||||
|
|
||||||
void xmpp_send_error(xmpp_conn_t * const conn, xmpp_error_type_t const type, char * const text);
|
void xmpp_send_error(xmpp_conn_t *const conn,
|
||||||
xmpp_conn_t *xmpp_conn_new(xmpp_ctx_t * const ctx);
|
xmpp_error_type_t const type,
|
||||||
xmpp_conn_t *xmpp_conn_clone(xmpp_conn_t * const conn);
|
char *const text);
|
||||||
int xmpp_conn_release(xmpp_conn_t * const conn);
|
xmpp_conn_t *xmpp_conn_new(xmpp_ctx_t *const ctx);
|
||||||
|
xmpp_conn_t *xmpp_conn_clone(xmpp_conn_t *const conn);
|
||||||
|
int xmpp_conn_release(xmpp_conn_t *const conn);
|
||||||
|
|
||||||
long xmpp_conn_get_flags(const xmpp_conn_t * const conn);
|
long xmpp_conn_get_flags(const xmpp_conn_t *const conn);
|
||||||
int xmpp_conn_set_flags(xmpp_conn_t * const conn, long flags);
|
int xmpp_conn_set_flags(xmpp_conn_t *const conn, long flags);
|
||||||
const char *xmpp_conn_get_jid(const xmpp_conn_t * const conn);
|
const char *xmpp_conn_get_jid(const xmpp_conn_t *const conn);
|
||||||
const char *xmpp_conn_get_bound_jid(const xmpp_conn_t * const conn);
|
const char *xmpp_conn_get_bound_jid(const xmpp_conn_t *const conn);
|
||||||
void xmpp_conn_set_jid(xmpp_conn_t * const conn, const char * const jid);
|
void xmpp_conn_set_jid(xmpp_conn_t *const conn, const char *const jid);
|
||||||
const char *xmpp_conn_get_pass(const xmpp_conn_t * const conn);
|
const char *xmpp_conn_get_pass(const xmpp_conn_t *const conn);
|
||||||
void xmpp_conn_set_pass(xmpp_conn_t * const conn, const char * const pass);
|
void xmpp_conn_set_pass(xmpp_conn_t *const conn, const char *const pass);
|
||||||
xmpp_ctx_t *xmpp_conn_get_context(xmpp_conn_t * const conn);
|
xmpp_ctx_t *xmpp_conn_get_context(xmpp_conn_t *const conn);
|
||||||
void xmpp_conn_disable_tls(xmpp_conn_t * const conn);
|
void xmpp_conn_disable_tls(xmpp_conn_t *const conn);
|
||||||
int xmpp_conn_is_secured(xmpp_conn_t * const conn);
|
int xmpp_conn_is_secured(xmpp_conn_t *const conn);
|
||||||
void xmpp_conn_set_keepalive(xmpp_conn_t * const conn, int timeout, int interval);
|
void xmpp_conn_set_keepalive(xmpp_conn_t *const conn,
|
||||||
int xmpp_conn_is_connecting(xmpp_conn_t * const conn);
|
int timeout,
|
||||||
int xmpp_conn_is_connected(xmpp_conn_t * const conn);
|
int interval);
|
||||||
int xmpp_conn_is_disconnected(xmpp_conn_t * const conn);
|
int xmpp_conn_is_connecting(xmpp_conn_t *const conn);
|
||||||
|
int xmpp_conn_is_connected(xmpp_conn_t *const conn);
|
||||||
|
int xmpp_conn_is_disconnected(xmpp_conn_t *const conn);
|
||||||
|
|
||||||
int xmpp_connect_client(xmpp_conn_t * const conn,
|
int xmpp_connect_client(xmpp_conn_t *const conn,
|
||||||
const char * const altdomain,
|
const char *const altdomain,
|
||||||
unsigned short altport,
|
unsigned short altport,
|
||||||
xmpp_conn_handler callback,
|
xmpp_conn_handler callback,
|
||||||
void * const userdata);
|
void *const userdata);
|
||||||
|
|
||||||
int xmpp_connect_component(xmpp_conn_t * const conn, const char * const server,
|
int xmpp_connect_component(xmpp_conn_t *const conn,
|
||||||
unsigned short port, xmpp_conn_handler callback,
|
const char *const server,
|
||||||
void * const userdata);
|
unsigned short port,
|
||||||
|
xmpp_conn_handler callback,
|
||||||
|
void *const userdata);
|
||||||
|
|
||||||
int xmpp_connect_raw(xmpp_conn_t * const conn,
|
int xmpp_connect_raw(xmpp_conn_t *const conn,
|
||||||
const char * const altdomain,
|
const char *const altdomain,
|
||||||
unsigned short altport,
|
unsigned short altport,
|
||||||
xmpp_conn_handler callback,
|
xmpp_conn_handler callback,
|
||||||
void * const userdata);
|
void *const userdata);
|
||||||
int xmpp_conn_open_stream_default(xmpp_conn_t * const conn);
|
int xmpp_conn_open_stream_default(xmpp_conn_t *const conn);
|
||||||
int xmpp_conn_open_stream(xmpp_conn_t * const conn, char **attributes,
|
int xmpp_conn_open_stream(xmpp_conn_t *const conn,
|
||||||
|
char **attributes,
|
||||||
size_t attributes_len);
|
size_t attributes_len);
|
||||||
int xmpp_conn_tls_start(xmpp_conn_t * const conn);
|
int xmpp_conn_tls_start(xmpp_conn_t *const conn);
|
||||||
|
|
||||||
void xmpp_disconnect(xmpp_conn_t * const conn);
|
void xmpp_disconnect(xmpp_conn_t *const conn);
|
||||||
|
|
||||||
void xmpp_send(xmpp_conn_t * const conn,
|
void xmpp_send(xmpp_conn_t *const conn, xmpp_stanza_t *const stanza);
|
||||||
xmpp_stanza_t * const stanza);
|
|
||||||
|
|
||||||
void xmpp_send_raw_string(xmpp_conn_t * const conn,
|
|
||||||
const char * const fmt, ...);
|
|
||||||
void xmpp_send_raw(xmpp_conn_t * const conn,
|
|
||||||
const char * const data, const size_t len);
|
|
||||||
|
|
||||||
|
void xmpp_send_raw_string(xmpp_conn_t *const conn, const char *const fmt, ...);
|
||||||
|
void xmpp_send_raw(xmpp_conn_t *const conn,
|
||||||
|
const char *const data,
|
||||||
|
const size_t len);
|
||||||
|
|
||||||
/* handlers */
|
/* handlers */
|
||||||
|
|
||||||
/* if the handle returns false it is removed */
|
/* if the handle returns false it is removed */
|
||||||
typedef int (*xmpp_timed_handler)(xmpp_conn_t * const conn,
|
typedef int (*xmpp_timed_handler)(xmpp_conn_t *const conn,
|
||||||
void * const userdata);
|
void *const userdata);
|
||||||
|
|
||||||
void xmpp_timed_handler_add(xmpp_conn_t * const conn,
|
|
||||||
xmpp_timed_handler handler,
|
|
||||||
const unsigned long period,
|
|
||||||
void * const userdata);
|
|
||||||
void xmpp_timed_handler_delete(xmpp_conn_t * const conn,
|
|
||||||
xmpp_timed_handler handler);
|
|
||||||
|
|
||||||
|
void xmpp_timed_handler_add(xmpp_conn_t *const conn,
|
||||||
|
xmpp_timed_handler handler,
|
||||||
|
const unsigned long period,
|
||||||
|
void *const userdata);
|
||||||
|
void xmpp_timed_handler_delete(xmpp_conn_t *const conn,
|
||||||
|
xmpp_timed_handler handler);
|
||||||
|
|
||||||
/* if the handler returns false it is removed */
|
/* if the handler returns false it is removed */
|
||||||
typedef int (*xmpp_handler)(xmpp_conn_t * const conn,
|
typedef int (*xmpp_handler)(xmpp_conn_t *const conn,
|
||||||
xmpp_stanza_t * const stanza,
|
xmpp_stanza_t *const stanza,
|
||||||
void * const userdata);
|
void *const userdata);
|
||||||
|
|
||||||
void xmpp_handler_add(xmpp_conn_t * const conn,
|
void xmpp_handler_add(xmpp_conn_t *const conn,
|
||||||
xmpp_handler handler,
|
xmpp_handler handler,
|
||||||
const char * const ns,
|
const char *const ns,
|
||||||
const char * const name,
|
const char *const name,
|
||||||
const char * const type,
|
const char *const type,
|
||||||
void * const userdata);
|
void *const userdata);
|
||||||
void xmpp_handler_delete(xmpp_conn_t * const conn,
|
void xmpp_handler_delete(xmpp_conn_t *const conn, xmpp_handler handler);
|
||||||
xmpp_handler handler);
|
|
||||||
|
|
||||||
void xmpp_id_handler_add(xmpp_conn_t * const conn,
|
void xmpp_id_handler_add(xmpp_conn_t *const conn,
|
||||||
xmpp_handler handler,
|
xmpp_handler handler,
|
||||||
const char * const id,
|
const char *const id,
|
||||||
void * const userdata);
|
void *const userdata);
|
||||||
void xmpp_id_handler_delete(xmpp_conn_t * const conn,
|
void xmpp_id_handler_delete(xmpp_conn_t *const conn,
|
||||||
xmpp_handler handler,
|
xmpp_handler handler,
|
||||||
const char * const id);
|
const char *const id);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
void xmpp_register_stanza_handler(conn, stanza, xmlns, type, handler)
|
void xmpp_register_stanza_handler(conn, stanza, xmlns, type, handler)
|
||||||
@@ -322,93 +321,98 @@ void xmpp_register_stanza_handler(conn, stanza, xmlns, type, handler)
|
|||||||
xmpp_stanza_t *xmpp_stanza_new(xmpp_ctx_t *ctx);
|
xmpp_stanza_t *xmpp_stanza_new(xmpp_ctx_t *ctx);
|
||||||
|
|
||||||
/* clone a stanza */
|
/* clone a stanza */
|
||||||
xmpp_stanza_t *xmpp_stanza_clone(xmpp_stanza_t * const stanza);
|
xmpp_stanza_t *xmpp_stanza_clone(xmpp_stanza_t *const stanza);
|
||||||
|
|
||||||
/* copies a stanza and all children */
|
/* copies a stanza and all children */
|
||||||
xmpp_stanza_t *xmpp_stanza_copy(const xmpp_stanza_t * const stanza);
|
xmpp_stanza_t *xmpp_stanza_copy(const xmpp_stanza_t *const stanza);
|
||||||
|
|
||||||
/* free a stanza object and it's contents */
|
/* free a stanza object and it's contents */
|
||||||
int xmpp_stanza_release(xmpp_stanza_t * const stanza);
|
int xmpp_stanza_release(xmpp_stanza_t *const stanza);
|
||||||
|
|
||||||
xmpp_ctx_t *xmpp_stanza_get_context(const xmpp_stanza_t * const stanza);
|
xmpp_ctx_t *xmpp_stanza_get_context(const xmpp_stanza_t *const stanza);
|
||||||
|
|
||||||
int xmpp_stanza_is_text(xmpp_stanza_t * const stanza);
|
int xmpp_stanza_is_text(xmpp_stanza_t *const stanza);
|
||||||
int xmpp_stanza_is_tag(xmpp_stanza_t * const stanza);
|
int xmpp_stanza_is_tag(xmpp_stanza_t *const stanza);
|
||||||
|
|
||||||
/* marshall a stanza into text for transmission or display */
|
/* marshall a stanza into text for transmission or display */
|
||||||
int xmpp_stanza_to_text(xmpp_stanza_t *stanza,
|
int xmpp_stanza_to_text(xmpp_stanza_t *stanza,
|
||||||
char ** const buf, size_t * const buflen);
|
char **const buf,
|
||||||
|
size_t *const buflen);
|
||||||
|
|
||||||
xmpp_stanza_t *xmpp_stanza_get_children(xmpp_stanza_t * const stanza);
|
xmpp_stanza_t *xmpp_stanza_get_children(xmpp_stanza_t *const stanza);
|
||||||
xmpp_stanza_t *xmpp_stanza_get_child_by_name(xmpp_stanza_t * const stanza,
|
xmpp_stanza_t *xmpp_stanza_get_child_by_name(xmpp_stanza_t *const stanza,
|
||||||
const char * const name);
|
const char *const name);
|
||||||
xmpp_stanza_t *xmpp_stanza_get_child_by_ns(xmpp_stanza_t * const stanza,
|
xmpp_stanza_t *xmpp_stanza_get_child_by_ns(xmpp_stanza_t *const stanza,
|
||||||
const char * const ns);
|
const char *const ns);
|
||||||
xmpp_stanza_t *xmpp_stanza_get_child_by_name_and_ns(xmpp_stanza_t * const stanza,
|
xmpp_stanza_t *xmpp_stanza_get_child_by_name_and_ns(xmpp_stanza_t *const stanza,
|
||||||
const char * const name,
|
const char *const name,
|
||||||
const char * const ns);
|
const char *const ns);
|
||||||
xmpp_stanza_t *xmpp_stanza_get_next(xmpp_stanza_t * const stanza);
|
xmpp_stanza_t *xmpp_stanza_get_next(xmpp_stanza_t *const stanza);
|
||||||
int xmpp_stanza_add_child(xmpp_stanza_t *stanza, xmpp_stanza_t *child);
|
int xmpp_stanza_add_child(xmpp_stanza_t *stanza, xmpp_stanza_t *child);
|
||||||
int xmpp_stanza_add_child_ex(xmpp_stanza_t *stanza, xmpp_stanza_t *child,
|
int xmpp_stanza_add_child_ex(xmpp_stanza_t *stanza,
|
||||||
|
xmpp_stanza_t *child,
|
||||||
int do_clone);
|
int do_clone);
|
||||||
|
|
||||||
const char *xmpp_stanza_get_attribute(xmpp_stanza_t * const stanza,
|
const char *xmpp_stanza_get_attribute(xmpp_stanza_t *const stanza,
|
||||||
const char * const name);
|
const char *const name);
|
||||||
int xmpp_stanza_get_attribute_count(xmpp_stanza_t * const stanza);
|
int xmpp_stanza_get_attribute_count(xmpp_stanza_t *const stanza);
|
||||||
int xmpp_stanza_get_attributes(xmpp_stanza_t * const stanza,
|
int xmpp_stanza_get_attributes(xmpp_stanza_t *const stanza,
|
||||||
const char **attr, int attrlen);
|
const char **attr,
|
||||||
|
int attrlen);
|
||||||
/* concatenate all child text nodes. this function
|
/* concatenate all child text nodes. this function
|
||||||
* returns a string that must be freed by the caller */
|
* returns a string that must be freed by the caller */
|
||||||
char *xmpp_stanza_get_text(xmpp_stanza_t * const stanza);
|
char *xmpp_stanza_get_text(xmpp_stanza_t *const stanza);
|
||||||
const char *xmpp_stanza_get_text_ptr(xmpp_stanza_t * const stanza);
|
const char *xmpp_stanza_get_text_ptr(xmpp_stanza_t *const stanza);
|
||||||
const char *xmpp_stanza_get_name(xmpp_stanza_t * const stanza);
|
const char *xmpp_stanza_get_name(xmpp_stanza_t *const stanza);
|
||||||
/* set_attribute adds/replaces attributes */
|
/* set_attribute adds/replaces attributes */
|
||||||
int xmpp_stanza_set_attribute(xmpp_stanza_t * const stanza,
|
int xmpp_stanza_set_attribute(xmpp_stanza_t *const stanza,
|
||||||
const char * const key,
|
const char *const key,
|
||||||
const char * const value);
|
const char *const value);
|
||||||
int xmpp_stanza_set_name(xmpp_stanza_t *stanza,
|
int xmpp_stanza_set_name(xmpp_stanza_t *stanza, const char *const name);
|
||||||
const char * const name);
|
int xmpp_stanza_set_text(xmpp_stanza_t *stanza, const char *const text);
|
||||||
int xmpp_stanza_set_text(xmpp_stanza_t *stanza,
|
|
||||||
const char * const text);
|
|
||||||
int xmpp_stanza_set_text_with_size(xmpp_stanza_t *stanza,
|
int xmpp_stanza_set_text_with_size(xmpp_stanza_t *stanza,
|
||||||
const char * const text,
|
const char *const text,
|
||||||
const size_t size);
|
const size_t size);
|
||||||
int xmpp_stanza_del_attribute(xmpp_stanza_t * const stanza,
|
int xmpp_stanza_del_attribute(xmpp_stanza_t *const stanza,
|
||||||
const char * const name);
|
const char *const name);
|
||||||
|
|
||||||
/* common stanza helpers */
|
/* common stanza helpers */
|
||||||
const char *xmpp_stanza_get_ns(xmpp_stanza_t * const stanza);
|
const char *xmpp_stanza_get_ns(xmpp_stanza_t *const stanza);
|
||||||
const char *xmpp_stanza_get_type(xmpp_stanza_t * const stanza);
|
const char *xmpp_stanza_get_type(xmpp_stanza_t *const stanza);
|
||||||
const char *xmpp_stanza_get_id(xmpp_stanza_t * const stanza);
|
const char *xmpp_stanza_get_id(xmpp_stanza_t *const stanza);
|
||||||
const char *xmpp_stanza_get_to(xmpp_stanza_t * const stanza);
|
const char *xmpp_stanza_get_to(xmpp_stanza_t *const stanza);
|
||||||
const char *xmpp_stanza_get_from(xmpp_stanza_t * const stanza);
|
const char *xmpp_stanza_get_from(xmpp_stanza_t *const stanza);
|
||||||
int xmpp_stanza_set_ns(xmpp_stanza_t * const stanza, const char * const ns);
|
int xmpp_stanza_set_ns(xmpp_stanza_t *const stanza, const char *const ns);
|
||||||
int xmpp_stanza_set_id(xmpp_stanza_t * const stanza, const char * const id);
|
int xmpp_stanza_set_id(xmpp_stanza_t *const stanza, const char *const id);
|
||||||
int xmpp_stanza_set_type(xmpp_stanza_t * const stanza, const char * const type);
|
int xmpp_stanza_set_type(xmpp_stanza_t *const stanza, const char *const type);
|
||||||
int xmpp_stanza_set_to(xmpp_stanza_t * const stanza, const char * const to);
|
int xmpp_stanza_set_to(xmpp_stanza_t *const stanza, const char *const to);
|
||||||
int xmpp_stanza_set_from(xmpp_stanza_t * const stanza, const char * const from);
|
int xmpp_stanza_set_from(xmpp_stanza_t *const stanza, const char *const from);
|
||||||
|
|
||||||
/* allocate and initialize a stanza in reply to another */
|
/* allocate and initialize a stanza in reply to another */
|
||||||
xmpp_stanza_t *xmpp_stanza_reply(xmpp_stanza_t * const stanza);
|
xmpp_stanza_t *xmpp_stanza_reply(xmpp_stanza_t *const stanza);
|
||||||
|
|
||||||
/* stanza subclasses */
|
/* stanza subclasses */
|
||||||
xmpp_stanza_t *xmpp_message_new(xmpp_ctx_t *ctx, const char * const type,
|
xmpp_stanza_t *xmpp_message_new(xmpp_ctx_t *ctx,
|
||||||
const char * const to, const char * const id);
|
const char *const type,
|
||||||
|
const char *const to,
|
||||||
|
const char *const id);
|
||||||
char *xmpp_message_get_body(xmpp_stanza_t *msg);
|
char *xmpp_message_get_body(xmpp_stanza_t *msg);
|
||||||
int xmpp_message_set_body(xmpp_stanza_t *msg, const char * const text);
|
int xmpp_message_set_body(xmpp_stanza_t *msg, const char *const text);
|
||||||
|
|
||||||
xmpp_stanza_t *xmpp_iq_new(xmpp_ctx_t *ctx, const char * const type,
|
xmpp_stanza_t *
|
||||||
const char * const id);
|
xmpp_iq_new(xmpp_ctx_t *ctx, const char *const type, const char *const id);
|
||||||
xmpp_stanza_t *xmpp_presence_new(xmpp_ctx_t *ctx);
|
xmpp_stanza_t *xmpp_presence_new(xmpp_ctx_t *ctx);
|
||||||
xmpp_stanza_t *xmpp_error_new(xmpp_ctx_t *ctx, xmpp_error_type_t const type,
|
xmpp_stanza_t *xmpp_error_new(xmpp_ctx_t *ctx,
|
||||||
const char * const text);
|
xmpp_error_type_t const type,
|
||||||
|
const char *const text);
|
||||||
|
|
||||||
/* jid */
|
/* jid */
|
||||||
|
|
||||||
/* these return new strings that must be xmpp_free()'d */
|
/* these return new strings that must be xmpp_free()'d */
|
||||||
char *xmpp_jid_new(xmpp_ctx_t *ctx, const char *node,
|
char *xmpp_jid_new(xmpp_ctx_t *ctx,
|
||||||
const char *domain,
|
const char *node,
|
||||||
const char *resource);
|
const char *domain,
|
||||||
|
const char *resource);
|
||||||
char *xmpp_jid_bare(xmpp_ctx_t *ctx, const char *jid);
|
char *xmpp_jid_bare(xmpp_ctx_t *ctx, const char *jid);
|
||||||
char *xmpp_jid_node(xmpp_ctx_t *ctx, const char *jid);
|
char *xmpp_jid_node(xmpp_ctx_t *ctx, const char *jid);
|
||||||
char *xmpp_jid_domain(xmpp_ctx_t *ctx, const char *jid);
|
char *xmpp_jid_domain(xmpp_ctx_t *ctx, const char *jid);
|
||||||
@@ -416,10 +420,10 @@ char *xmpp_jid_resource(xmpp_ctx_t *ctx, const char *jid);
|
|||||||
|
|
||||||
/* event loop */
|
/* event loop */
|
||||||
|
|
||||||
void xmpp_run_once(xmpp_ctx_t *ctx, const unsigned long timeout);
|
void xmpp_run_once(xmpp_ctx_t *ctx, const unsigned long timeout);
|
||||||
void xmpp_run(xmpp_ctx_t *ctx);
|
void xmpp_run(xmpp_ctx_t *ctx);
|
||||||
void xmpp_stop(xmpp_ctx_t *ctx);
|
void xmpp_stop(xmpp_ctx_t *ctx);
|
||||||
void xmpp_ctx_set_timeout(xmpp_ctx_t * const ctx, const unsigned long timeout);
|
void xmpp_ctx_set_timeout(xmpp_ctx_t *const ctx, const unsigned long timeout);
|
||||||
|
|
||||||
/* UUID */
|
/* UUID */
|
||||||
|
|
||||||
@@ -435,7 +439,8 @@ char *xmpp_uuid_gen(xmpp_ctx_t *ctx);
|
|||||||
typedef struct _xmpp_sha1_t xmpp_sha1_t;
|
typedef struct _xmpp_sha1_t xmpp_sha1_t;
|
||||||
|
|
||||||
char *xmpp_sha1(xmpp_ctx_t *ctx, const unsigned char *data, size_t len);
|
char *xmpp_sha1(xmpp_ctx_t *ctx, const unsigned char *data, size_t len);
|
||||||
void xmpp_sha1_digest(const unsigned char *data, size_t len,
|
void xmpp_sha1_digest(const unsigned char *data,
|
||||||
|
size_t len,
|
||||||
unsigned char *digest);
|
unsigned char *digest);
|
||||||
|
|
||||||
xmpp_sha1_t *xmpp_sha1_new(xmpp_ctx_t *ctx);
|
xmpp_sha1_t *xmpp_sha1_new(xmpp_ctx_t *ctx);
|
||||||
@@ -448,10 +453,14 @@ void xmpp_sha1_to_digest(xmpp_sha1_t *sha1, unsigned char *digest);
|
|||||||
|
|
||||||
/* Base64 */
|
/* Base64 */
|
||||||
|
|
||||||
char *xmpp_base64_encode(xmpp_ctx_t *ctx, const unsigned char *data, size_t len);
|
char *
|
||||||
|
xmpp_base64_encode(xmpp_ctx_t *ctx, const unsigned char *data, size_t len);
|
||||||
char *xmpp_base64_decode_str(xmpp_ctx_t *ctx, const char *base64, size_t len);
|
char *xmpp_base64_decode_str(xmpp_ctx_t *ctx, const char *base64, size_t len);
|
||||||
void xmpp_base64_decode_bin(xmpp_ctx_t *ctx, const char *base64, size_t len,
|
void xmpp_base64_decode_bin(xmpp_ctx_t *ctx,
|
||||||
unsigned char **out, size_t *outlen);
|
const char *base64,
|
||||||
|
size_t len,
|
||||||
|
unsigned char **out,
|
||||||
|
size_t *outlen);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
199
strophepp.h
199
strophepp.h
@@ -18,116 +18,119 @@
|
|||||||
|
|
||||||
#include "strophe.h"
|
#include "strophe.h"
|
||||||
|
|
||||||
namespace XMPP {
|
namespace XMPP
|
||||||
class Context {
|
{
|
||||||
private:
|
class Context
|
||||||
xmpp_mem_t m_mem;
|
{
|
||||||
xmpp_log_t m_log;
|
private:
|
||||||
xmpp_ctx_t *m_ctx;
|
xmpp_mem_t m_mem;
|
||||||
|
xmpp_log_t m_log;
|
||||||
|
xmpp_ctx_t *m_ctx;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Context();
|
Context();
|
||||||
virtual ~Context();
|
virtual ~Context();
|
||||||
|
|
||||||
virtual void *alloc(const size_t size);
|
virtual void *alloc(const size_t size);
|
||||||
virtual void *realloc(void *p, const size_t size);
|
virtual void *realloc(void *p, const size_t size);
|
||||||
virtual void free(void *p);
|
virtual void free(void *p);
|
||||||
virtual void log(const xmpp_log_level_t level,
|
virtual void log(const xmpp_log_level_t level,
|
||||||
const char * const area,
|
const char *const area,
|
||||||
const char * const msg);
|
const char *const msg);
|
||||||
|
|
||||||
xmpp_ctx_t *getContext();
|
xmpp_ctx_t *getContext();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static void *callAlloc(const size_t size, void * const userdata);
|
static void *callAlloc(const size_t size, void *const userdata);
|
||||||
static void *callRealloc(void *p, const size_t size,
|
static void *callRealloc(void *p, const size_t size, void *const userdata);
|
||||||
void * const userdata);
|
static void callFree(void *p, void *const userdata);
|
||||||
static void callFree(void *p, void * const userdata);
|
static void callLog(void *const userdata,
|
||||||
static void callLog(void * const userdata,
|
const xmpp_log_level_t level,
|
||||||
const xmpp_log_level_t level,
|
const char *const area,
|
||||||
const char * const area,
|
const char *const msg);
|
||||||
const char * const msg);
|
};
|
||||||
};
|
|
||||||
|
|
||||||
class Stanza {
|
class Stanza
|
||||||
private:
|
{
|
||||||
Context *m_ctx;
|
private:
|
||||||
xmpp_stanza_t *m_stanza;
|
Context *m_ctx;
|
||||||
|
xmpp_stanza_t *m_stanza;
|
||||||
|
|
||||||
void *operator new(size_t size, Context *ctx);
|
void *operator new(size_t size, Context *ctx);
|
||||||
void operator delete(void *p);
|
void operator delete(void *p);
|
||||||
Stanza(Context *ctx);
|
Stanza(Context *ctx);
|
||||||
virtual ~Stanza();
|
virtual ~Stanza();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static Stanza *create(Context *ctx);
|
static Stanza *create(Context *ctx);
|
||||||
void release();
|
void release();
|
||||||
Stanza *clone();
|
Stanza *clone();
|
||||||
Stanza *copy();
|
Stanza *copy();
|
||||||
|
|
||||||
int toText(const char ** const buf, size_t * const buflen);
|
int toText(const char **const buf, size_t *const buflen);
|
||||||
Stanza *getChildren();
|
Stanza *getChildren();
|
||||||
Stanza *getChildByName(const char * const name);
|
Stanza *getChildByName(const char *const name);
|
||||||
Stanza *getNext();
|
Stanza *getNext();
|
||||||
char *getAttribute(const char * const name);
|
char *getAttribute(const char *const name);
|
||||||
char *getNamespace();
|
char *getNamespace();
|
||||||
char *getText();
|
char *getText();
|
||||||
char *getName();
|
char *getName();
|
||||||
void addChild(Stanza *child);
|
void addChild(Stanza *child);
|
||||||
void setNamespace(const char * const ns);
|
void setNamespace(const char *const ns);
|
||||||
void setAttribute(const char * const key, const char * const value);
|
void setAttribute(const char *const key, const char *const value);
|
||||||
void setName(const char * const name);
|
void setName(const char *const name);
|
||||||
void setText(const char * const text);
|
void setText(const char *const text);
|
||||||
void setText(const char * const text, const size_t size);
|
void setText(const char *const text, const size_t size);
|
||||||
char *getType();
|
char *getType();
|
||||||
char *getId();
|
char *getId();
|
||||||
char *getTo();
|
char *getTo();
|
||||||
char *getFrom();
|
char *getFrom();
|
||||||
void setType(const char * const type);
|
void setType(const char *const type);
|
||||||
void setId(const char * const id);
|
void setId(const char *const id);
|
||||||
void setTo(const char * const to);
|
void setTo(const char *const to);
|
||||||
void setFrom(const char * const from);
|
void setFrom(const char *const from);
|
||||||
};
|
};
|
||||||
|
|
||||||
class Connection {
|
class Connection
|
||||||
private:
|
{
|
||||||
Context *m_ctx;
|
private:
|
||||||
xmpp_conn_t *conn;
|
Context *m_ctx;
|
||||||
|
xmpp_conn_t *conn;
|
||||||
|
|
||||||
void *operator new(size_t size, Context *ctx);
|
void *operator new(size_t size, Context *ctx);
|
||||||
Connection(Context *ctx);
|
Connection(Context *ctx);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static Connection *create(Context *ctx);
|
static Connection *create(Context *ctx);
|
||||||
virtual ~Connection();
|
virtual ~Connection();
|
||||||
Connection *clone();
|
Connection *clone();
|
||||||
void operator delete(void *p);
|
void operator delete(void *p);
|
||||||
|
|
||||||
const char *getJID();
|
const char *getJID();
|
||||||
void setJID(const char * const jid);
|
void setJID(const char *const jid);
|
||||||
const char *getPass();
|
const char *getPass();
|
||||||
void setPass(const char * const pass);
|
void setPass(const char *const pass);
|
||||||
bool connectClient(const char * const domain,
|
bool connectClient(const char *const domain,
|
||||||
xmpp_conn_handler callback,
|
xmpp_conn_handler callback,
|
||||||
void * const userdata);
|
void *const userdata);
|
||||||
void disconnect();
|
void disconnect();
|
||||||
void send(Stanza *stanza);
|
void send(Stanza *stanza);
|
||||||
|
|
||||||
void addTimedHandler(xmpp_timed_handler handler,
|
void addTimedHandler(xmpp_timed_handler handler,
|
||||||
const unsigned long perdio,
|
const unsigned long perdio,
|
||||||
void * const userdata);
|
void *const userdata);
|
||||||
void deleteTimedHandler(xmpp_timed_handler handler);
|
void deleteTimedHandler(xmpp_timed_handler handler);
|
||||||
void addHandler(xmpp_handler handler,
|
void addHandler(xmpp_handler handler,
|
||||||
const char * const ns,
|
const char *const ns,
|
||||||
const char * const name,
|
const char *const name,
|
||||||
const char * const type,
|
const char *const type,
|
||||||
void * const userdata);
|
void *const userdata);
|
||||||
void deleteHandler(xmpp_handler handler);
|
void deleteHandler(xmpp_handler handler);
|
||||||
void addIdHandler(xmpp_handler handler,
|
void addIdHandler(xmpp_handler handler,
|
||||||
const char * const id,
|
const char *const id,
|
||||||
void * const userdata);
|
void *const userdata);
|
||||||
void deleteIdHandler(xmpp_handler handler);
|
void deleteIdHandler(xmpp_handler handler);
|
||||||
};
|
};
|
||||||
}
|
} // namespace XMPP
|
||||||
|
|
||||||
#endif /* __LIBSTROPHE_STROPHEPP_H__ */
|
#endif /* __LIBSTROPHE_STROPHEPP_H__ */
|
||||||
|
|||||||
@@ -18,14 +18,15 @@
|
|||||||
|
|
||||||
#include "test.h"
|
#include "test.h"
|
||||||
|
|
||||||
#define fail_unless(expr) do { \
|
#define fail_unless(expr) \
|
||||||
int result = (expr); \
|
do { \
|
||||||
if (!result) { \
|
int result = (expr); \
|
||||||
printf("%s:%d: Assertion failed: %s\n", \
|
if (!result) { \
|
||||||
__FILE__, __LINE__, #expr); \
|
printf("%s:%d: Assertion failed: %s\n", __FILE__, __LINE__, \
|
||||||
exit(1); \
|
#expr); \
|
||||||
} \
|
exit(1); \
|
||||||
} while (0)
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
static void create_destroy(void)
|
static void create_destroy(void)
|
||||||
{
|
{
|
||||||
@@ -67,9 +68,7 @@ static void callbacks(void)
|
|||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ctx = xmpp_ctx_new(NULL, NULL);
|
ctx = xmpp_ctx_new(NULL, NULL);
|
||||||
parser = parser_new(ctx,
|
parser = parser_new(ctx, cbtest_handle_start, cbtest_handle_end,
|
||||||
cbtest_handle_start,
|
|
||||||
cbtest_handle_end,
|
|
||||||
cbtest_handle_stanza, NULL);
|
cbtest_handle_stanza, NULL);
|
||||||
|
|
||||||
ret = parser_feed(parser, "<stream>", 8);
|
ret = parser_feed(parser, "<stream>", 8);
|
||||||
|
|||||||
@@ -55,8 +55,8 @@ int main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
domain = argv[1];
|
domain = argv[1];
|
||||||
snprintf(fulldomain, sizeof(fulldomain), "_%s._%s.%s",
|
snprintf(fulldomain, sizeof(fulldomain), "_%s._%s.%s", service, proto,
|
||||||
service, proto, domain);
|
domain);
|
||||||
errno = 0;
|
errno = 0;
|
||||||
len = res_query(fulldomain, C_IN, T_SRV, buf, sizeof(buf));
|
len = res_query(fulldomain, C_IN, T_SRV, buf, sizeof(buf));
|
||||||
|
|
||||||
|
|||||||
@@ -16,9 +16,9 @@
|
|||||||
|
|
||||||
static uint8_t char_to_bin(char c)
|
static uint8_t char_to_bin(char c)
|
||||||
{
|
{
|
||||||
return c <= '9' ? (uint8_t)(c - '0') :
|
return c <= '9'
|
||||||
c <= 'Z' ? (uint8_t)(c - 'A' + 10) :
|
? (uint8_t)(c - '0')
|
||||||
(uint8_t)(c - 'a' + 10);
|
: c <= 'Z' ? (uint8_t)(c - 'A' + 10) : (uint8_t)(c - 'a' + 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_hex_to_bin(const char *hex, uint8_t *bin, size_t *bin_len)
|
void test_hex_to_bin(const char *hex, uint8_t *bin, size_t *bin_len)
|
||||||
|
|||||||
75
tests/test.h
75
tests/test.h
@@ -17,51 +17,48 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "ostypes.h"
|
#include "ostypes.h"
|
||||||
|
|
||||||
#define TEST_MAIN \
|
#define TEST_MAIN \
|
||||||
int main(int argc, char **argv) { \
|
int main(int argc, char **argv) \
|
||||||
int num_failed; \
|
{ \
|
||||||
Suite *s = parser_suite(); \
|
int num_failed; \
|
||||||
SRunner *sr = srunner_create(s); \
|
Suite *s = parser_suite(); \
|
||||||
srunner_run_all(sr, CK_NORMAL); \
|
SRunner *sr = srunner_create(s); \
|
||||||
num_failed = srunner_ntests_failed(sr); \
|
srunner_run_all(sr, CK_NORMAL); \
|
||||||
srunner_free(sr); \
|
num_failed = srunner_ntests_failed(sr); \
|
||||||
return (num_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE; \
|
srunner_free(sr); \
|
||||||
}
|
return (num_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE; \
|
||||||
|
}
|
||||||
|
|
||||||
#ifndef ARRAY_SIZE
|
#ifndef ARRAY_SIZE
|
||||||
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
|
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define COMPARE(v1, v2) \
|
#define COMPARE(v1, v2) \
|
||||||
do { \
|
do { \
|
||||||
const char *__v1 = v1; \
|
const char *__v1 = v1; \
|
||||||
const char *__v2 = v2; \
|
const char *__v2 = v2; \
|
||||||
if (strcmp(__v1, __v2) != 0) { \
|
if (strcmp(__v1, __v2) != 0) { \
|
||||||
printf("%s differs!\n" \
|
printf("%s differs!\n" \
|
||||||
"expected: %s\n" \
|
"expected: %s\n" \
|
||||||
"got: %s\n", \
|
"got: %s\n", \
|
||||||
#v1, __v1, __v2); \
|
#v1, __v1, __v2); \
|
||||||
exit(1); \
|
exit(1); \
|
||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define COMPARE_BUF(v1, len1, v2, len2) \
|
#define COMPARE_BUF(v1, len1, v2, len2) \
|
||||||
do { \
|
do { \
|
||||||
const uint8_t *__v1 = (uint8_t *)(v1); \
|
const uint8_t *__v1 = (uint8_t *)(v1); \
|
||||||
const uint8_t *__v2 = (uint8_t *)(v2); \
|
const uint8_t *__v2 = (uint8_t *)(v2); \
|
||||||
size_t __len1 = len1; \
|
size_t __len1 = len1; \
|
||||||
size_t __len2 = len2; \
|
size_t __len2 = len2; \
|
||||||
if (__len1 != __len2 || \
|
if (__len1 != __len2 || memcmp(__v1, __v2, __len1) != 0) { \
|
||||||
memcmp(__v1, __v2, __len1) != 0) \
|
printf("%s differs!\n", #v1); \
|
||||||
{ \
|
printf("expected: 0x%s\n", test_bin_to_hex(__v1, __len1)); \
|
||||||
printf("%s differs!\n", #v1); \
|
printf("got: 0x%s\n", test_bin_to_hex(__v2, __len2)); \
|
||||||
printf("expected: 0x%s\n", \
|
exit(1); \
|
||||||
test_bin_to_hex(__v1, __len1)); \
|
} \
|
||||||
printf("got: 0x%s\n", \
|
} while (0)
|
||||||
test_bin_to_hex(__v2, __len2)); \
|
|
||||||
exit(1); \
|
|
||||||
} \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
void test_hex_to_bin(const char *hex, uint8_t *bin, size_t *bin_len);
|
void test_hex_to_bin(const char *hex, uint8_t *bin, size_t *bin_len);
|
||||||
const char *test_bin_to_hex(const uint8_t *bin, size_t len);
|
const char *test_bin_to_hex(const uint8_t *bin, size_t len);
|
||||||
|
|||||||
@@ -17,11 +17,11 @@
|
|||||||
|
|
||||||
#include "test.h"
|
#include "test.h"
|
||||||
|
|
||||||
static const unsigned char test_2_raw[] =
|
static const unsigned char test_2_raw[] = {0x14, 0xfb, 0x9c, 0x03,
|
||||||
{0x14, 0xfb, 0x9c, 0x03, 0xd9, 0x7e, 0x00};
|
0xd9, 0x7e, 0x00};
|
||||||
static const unsigned char test_4_raw[] =
|
static const unsigned char test_4_raw[] = {0xd6, 0x2f, 0x27, 0x49, 0x7e, 0xdd,
|
||||||
{0xd6, 0x2f, 0x27, 0x49, 0x7e, 0xdd, 0xf3, 0xd5,
|
0xf3, 0xd5, 0x41, 0xbc, 0x1b, 0xe9,
|
||||||
0x41, 0xbc, 0x1b, 0xe9, 0xdf, 0xe9, 0xb3, 0x08, 0x00};
|
0xdf, 0xe9, 0xb3, 0x08, 0x00};
|
||||||
|
|
||||||
static const struct {
|
static const struct {
|
||||||
char *raw;
|
char *raw;
|
||||||
@@ -36,30 +36,26 @@ static const struct {
|
|||||||
.base64 = "FPucA9l+",
|
.base64 = "FPucA9l+",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.raw =
|
.raw = "From rest and sleep, which but thy pictures be, "
|
||||||
"From rest and sleep, which but thy pictures be, "
|
"Much pleasure; then from thee much more must flow, "
|
||||||
"Much pleasure; then from thee much more must flow, "
|
"And soonest our best men with thee do go, "
|
||||||
"And soonest our best men with thee do go, "
|
"Rest of their bones, and soul's delivery.",
|
||||||
"Rest of their bones, and soul's delivery.",
|
.base64 = "RnJvbSByZXN0IGFuZCBzbGVlcCwgd2hpY2ggYnV0IHRoeSBwaWN0dXJl"
|
||||||
.base64 =
|
"cyBiZSwgTXVjaCBwbGVhc3VyZTsgdGhlbiBmcm9tIHRoZWUgbXVjaCBt"
|
||||||
"RnJvbSByZXN0IGFuZCBzbGVlcCwgd2hpY2ggYnV0IHRoeSBwaWN0dXJl"
|
"b3JlIG11c3QgZmxvdywgQW5kIHNvb25lc3Qgb3VyIGJlc3QgbWVuIHdp"
|
||||||
"cyBiZSwgTXVjaCBwbGVhc3VyZTsgdGhlbiBmcm9tIHRoZWUgbXVjaCBt"
|
"dGggdGhlZSBkbyBnbywgUmVzdCBvZiB0aGVpciBib25lcywgYW5kIHNv"
|
||||||
"b3JlIG11c3QgZmxvdywgQW5kIHNvb25lc3Qgb3VyIGJlc3QgbWVuIHdp"
|
"dWwncyBkZWxpdmVyeS4=",
|
||||||
"dGggdGhlZSBkbyBnbywgUmVzdCBvZiB0aGVpciBib25lcywgYW5kIHNv"
|
|
||||||
"dWwncyBkZWxpdmVyeS4=",
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.raw = (char *)test_4_raw,
|
.raw = (char *)test_4_raw,
|
||||||
.base64 = "1i8nSX7d89VBvBvp3+mzCA==",
|
.base64 = "1i8nSX7d89VBvBvp3+mzCA==",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.raw =
|
.raw = "realm=\"chesspark.com\",nonce=\"b243c0d663257a9149999cef2f83"
|
||||||
"realm=\"chesspark.com\",nonce=\"b243c0d663257a9149999cef2f83"
|
"a22116559e93\",qop=\"auth\",charset=utf-8,algorithm=md5-sess",
|
||||||
"a22116559e93\",qop=\"auth\",charset=utf-8,algorithm=md5-sess",
|
.base64 = "cmVhbG09ImNoZXNzcGFyay5jb20iLG5vbmNlPSJiMjQzYzBkNjYzMjU3"
|
||||||
.base64 =
|
"YTkxNDk5OTljZWYyZjgzYTIyMTE2NTU5ZTkzIixxb3A9ImF1dGgiLGNo"
|
||||||
"cmVhbG09ImNoZXNzcGFyay5jb20iLG5vbmNlPSJiMjQzYzBkNjYzMjU3"
|
"YXJzZXQ9dXRmLTgsYWxnb3JpdGhtPW1kNS1zZXNz",
|
||||||
"YTkxNDk5OTljZWYyZjgzYTIyMTE2NTU5ZTkzIixxb3A9ImF1dGgiLGNo"
|
|
||||||
"YXJzZXQ9dXRmLTgsYWxnb3JpdGhtPW1kNS1zZXNz",
|
|
||||||
},
|
},
|
||||||
|
|
||||||
/* RFC4648 test vectors */
|
/* RFC4648 test vectors */
|
||||||
@@ -94,38 +90,27 @@ static const struct {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static const unsigned char bin_data[] = {
|
static const unsigned char bin_data[] = {
|
||||||
0xda, 0xa8, 0x81, 0x80, 0x00, 0x01, 0x00, 0x05,
|
0xda, 0xa8, 0x81, 0x80, 0x00, 0x01, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x0c, 0x5f, 0x78, 0x6d,
|
0x0c, 0x5f, 0x78, 0x6d, 0x70, 0x70, 0x2d, 0x63, 0x6c, 0x69, 0x65, 0x6e,
|
||||||
0x70, 0x70, 0x2d, 0x63, 0x6c, 0x69, 0x65, 0x6e,
|
0x74, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x67, 0x6d, 0x61, 0x69, 0x6c,
|
||||||
0x74, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x67,
|
0x03, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x21, 0x00, 0x01, 0xc0, 0x0c, 0x00,
|
||||||
0x6d, 0x61, 0x69, 0x6c, 0x03, 0x63, 0x6f, 0x6d,
|
0x21, 0x00, 0x01, 0x00, 0x00, 0x02, 0x43, 0x00, 0x1e, 0x00, 0x14, 0x00,
|
||||||
0x00, 0x00, 0x21, 0x00, 0x01, 0xc0, 0x0c, 0x00,
|
0x00, 0x14, 0x66, 0x04, 0x61, 0x6c, 0x74, 0x31, 0x04, 0x78, 0x6d, 0x70,
|
||||||
0x21, 0x00, 0x01, 0x00, 0x00, 0x02, 0x43, 0x00,
|
0x70, 0x01, 0x6c, 0x06, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x03, 0x63,
|
||||||
0x1e, 0x00, 0x14, 0x00, 0x00, 0x14, 0x66, 0x04,
|
0x6f, 0x6d, 0x00, 0xc0, 0x0c, 0x00, 0x21, 0x00, 0x01, 0x00, 0x00, 0x02,
|
||||||
0x61, 0x6c, 0x74, 0x31, 0x04, 0x78, 0x6d, 0x70,
|
0x43, 0x00, 0x1e, 0x00, 0x14, 0x00, 0x00, 0x14, 0x66, 0x04, 0x61, 0x6c,
|
||||||
0x70, 0x01, 0x6c, 0x06, 0x67, 0x6f, 0x6f, 0x67,
|
0x74, 0x34, 0x04, 0x78, 0x6d, 0x70, 0x70, 0x01, 0x6c, 0x06, 0x67, 0x6f,
|
||||||
0x6c, 0x65, 0x03, 0x63, 0x6f, 0x6d, 0x00, 0xc0,
|
0x6f, 0x67, 0x6c, 0x65, 0x03, 0x63, 0x6f, 0x6d, 0x00, 0xc0, 0x0c, 0x00,
|
||||||
0x0c, 0x00, 0x21, 0x00, 0x01, 0x00, 0x00, 0x02,
|
0x21, 0x00, 0x01, 0x00, 0x00, 0x02, 0x43, 0x00, 0x1e, 0x00, 0x14, 0x00,
|
||||||
0x43, 0x00, 0x1e, 0x00, 0x14, 0x00, 0x00, 0x14,
|
0x00, 0x14, 0x66, 0x04, 0x61, 0x6c, 0x74, 0x32, 0x04, 0x78, 0x6d, 0x70,
|
||||||
0x66, 0x04, 0x61, 0x6c, 0x74, 0x34, 0x04, 0x78,
|
0x70, 0x01, 0x6c, 0x06, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x03, 0x63,
|
||||||
0x6d, 0x70, 0x70, 0x01, 0x6c, 0x06, 0x67, 0x6f,
|
0x6f, 0x6d, 0x00, 0xc0, 0x0c, 0x00, 0x21, 0x00, 0x01, 0x00, 0x00, 0x02,
|
||||||
0x6f, 0x67, 0x6c, 0x65, 0x03, 0x63, 0x6f, 0x6d,
|
0x43, 0x00, 0x19, 0x00, 0x05, 0x00, 0x00, 0x14, 0x66, 0x04, 0x78, 0x6d,
|
||||||
0x00, 0xc0, 0x0c, 0x00, 0x21, 0x00, 0x01, 0x00,
|
0x70, 0x70, 0x01, 0x6c, 0x06, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x03,
|
||||||
0x00, 0x02, 0x43, 0x00, 0x1e, 0x00, 0x14, 0x00,
|
0x63, 0x6f, 0x6d, 0x00, 0xc0, 0x0c, 0x00, 0x21, 0x00, 0x01, 0x00, 0x00,
|
||||||
0x00, 0x14, 0x66, 0x04, 0x61, 0x6c, 0x74, 0x32,
|
0x02, 0x43, 0x00, 0x1e, 0x00, 0x14, 0x00, 0x00, 0x14, 0x66, 0x04, 0x61,
|
||||||
0x04, 0x78, 0x6d, 0x70, 0x70, 0x01, 0x6c, 0x06,
|
0x6c, 0x74, 0x33, 0x04, 0x78, 0x6d, 0x70, 0x70, 0x01, 0x6c, 0x06, 0x67,
|
||||||
0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x03, 0x63,
|
0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x03, 0x63, 0x6f, 0x6d, 0x00,
|
||||||
0x6f, 0x6d, 0x00, 0xc0, 0x0c, 0x00, 0x21, 0x00,
|
|
||||||
0x01, 0x00, 0x00, 0x02, 0x43, 0x00, 0x19, 0x00,
|
|
||||||
0x05, 0x00, 0x00, 0x14, 0x66, 0x04, 0x78, 0x6d,
|
|
||||||
0x70, 0x70, 0x01, 0x6c, 0x06, 0x67, 0x6f, 0x6f,
|
|
||||||
0x67, 0x6c, 0x65, 0x03, 0x63, 0x6f, 0x6d, 0x00,
|
|
||||||
0xc0, 0x0c, 0x00, 0x21, 0x00, 0x01, 0x00, 0x00,
|
|
||||||
0x02, 0x43, 0x00, 0x1e, 0x00, 0x14, 0x00, 0x00,
|
|
||||||
0x14, 0x66, 0x04, 0x61, 0x6c, 0x74, 0x33, 0x04,
|
|
||||||
0x78, 0x6d, 0x70, 0x70, 0x01, 0x6c, 0x06, 0x67,
|
|
||||||
0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x03, 0x63, 0x6f,
|
|
||||||
0x6d, 0x00,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
/* test_ctx.c
|
/* test_ctx.c
|
||||||
** libstrophe XMPP client library -- test routines for the library run-time context
|
** libstrophe XMPP client library -- test routines for the library run-time
|
||||||
|
*context
|
||||||
**
|
**
|
||||||
** Copyright (C) 2005-2009 Collecta, Inc.
|
** Copyright (C) 2005-2009 Collecta, Inc.
|
||||||
**
|
**
|
||||||
@@ -21,30 +22,32 @@ static int mem_alloc_called = 0;
|
|||||||
static int mem_free_called = 0;
|
static int mem_free_called = 0;
|
||||||
static int mem_realloc_called = 0;
|
static int mem_realloc_called = 0;
|
||||||
|
|
||||||
void *my_alloc(const size_t size, void * const userdata)
|
void *my_alloc(const size_t size, void *const userdata)
|
||||||
{
|
{
|
||||||
mem_alloc_called++;
|
mem_alloc_called++;
|
||||||
return malloc(size);
|
return malloc(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void my_free(void *p, void * const userdata)
|
void my_free(void *p, void *const userdata)
|
||||||
{
|
{
|
||||||
mem_free_called++;
|
mem_free_called++;
|
||||||
return free(p);
|
return free(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
void *my_realloc(void *p, const size_t size, void * const userdata)
|
void *my_realloc(void *p, const size_t size, void *const userdata)
|
||||||
{
|
{
|
||||||
mem_realloc_called++;
|
mem_realloc_called++;
|
||||||
return realloc(p, size);
|
return realloc(p, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void my_logger(void * const userdata, const xmpp_log_level_t level,
|
void my_logger(void *const userdata,
|
||||||
const char * const area, const char * const msg)
|
const xmpp_log_level_t level,
|
||||||
|
const char *const area,
|
||||||
|
const char *const msg)
|
||||||
{
|
{
|
||||||
if (strcmp((char *)userdata, "asdf") == 0 && level == XMPP_LEVEL_DEBUG
|
if (strcmp((char *)userdata, "asdf") == 0 && level == XMPP_LEVEL_DEBUG &&
|
||||||
&& strcmp(area, "test") == 0 && strcmp(msg, "hello") == 0)
|
strcmp(area, "test") == 0 && strcmp(msg, "hello") == 0)
|
||||||
log_called++;
|
log_called++;
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
@@ -56,7 +59,8 @@ int main(int argc, char **argv)
|
|||||||
void *testptr1, *testptr2;
|
void *testptr1, *testptr2;
|
||||||
|
|
||||||
ctx = xmpp_ctx_new(NULL, NULL);
|
ctx = xmpp_ctx_new(NULL, NULL);
|
||||||
if (ctx == NULL) return 1;
|
if (ctx == NULL)
|
||||||
|
return 1;
|
||||||
|
|
||||||
/* destroy context */
|
/* destroy context */
|
||||||
xmpp_ctx_free(ctx);
|
xmpp_ctx_free(ctx);
|
||||||
@@ -75,15 +79,15 @@ int main(int argc, char **argv)
|
|||||||
|
|
||||||
testptr1 = xmpp_alloc(ctx, 1024);
|
testptr1 = xmpp_alloc(ctx, 1024);
|
||||||
if (testptr1 == NULL) {
|
if (testptr1 == NULL) {
|
||||||
xmpp_ctx_free(ctx);
|
xmpp_ctx_free(ctx);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
testptr2 = xmpp_realloc(ctx, testptr1, 2048);
|
testptr2 = xmpp_realloc(ctx, testptr1, 2048);
|
||||||
if (testptr2 == NULL) {
|
if (testptr2 == NULL) {
|
||||||
xmpp_free(ctx, testptr1);
|
xmpp_free(ctx, testptr1);
|
||||||
xmpp_ctx_free(ctx);
|
xmpp_ctx_free(ctx);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
xmpp_free(ctx, testptr2);
|
xmpp_free(ctx, testptr2);
|
||||||
@@ -92,8 +96,8 @@ int main(int argc, char **argv)
|
|||||||
|
|
||||||
/* check for test failure */
|
/* check for test failure */
|
||||||
if (!(log_called && mem_alloc_called && mem_realloc_called &&
|
if (!(log_called && mem_alloc_called && mem_realloc_called &&
|
||||||
mem_free_called))
|
mem_free_called))
|
||||||
return 1;
|
return 1;
|
||||||
if (mem_alloc_called != mem_free_called)
|
if (mem_alloc_called != mem_free_called)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
|||||||
@@ -22,12 +22,8 @@
|
|||||||
#define TESTSIZE 500
|
#define TESTSIZE 500
|
||||||
|
|
||||||
/* static test data */
|
/* static test data */
|
||||||
const char *keys[] = {
|
const char *keys[] = {"foo", "bar", "baz", "quux", "xyzzy"};
|
||||||
"foo", "bar", "baz", "quux", "xyzzy"
|
const char *values[] = {"wuzzle", "mug", "canonical", "rosebud", "lottery"};
|
||||||
};
|
|
||||||
const char *values[] = {
|
|
||||||
"wuzzle", "mug", "canonical", "rosebud", "lottery"
|
|
||||||
};
|
|
||||||
const int nkeys = ARRAY_SIZE(keys);
|
const int nkeys = ARRAY_SIZE(keys);
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
@@ -43,10 +39,10 @@ int main(int argc, char **argv)
|
|||||||
|
|
||||||
/* initialize random numbers */
|
/* initialize random numbers */
|
||||||
if (argc > 2) {
|
if (argc > 2) {
|
||||||
/* use a seed from the command line */
|
/* use a seed from the command line */
|
||||||
seed = (unsigned int)atoi(argv[1]);
|
seed = (unsigned int)atoi(argv[1]);
|
||||||
} else {
|
} else {
|
||||||
seed = (unsigned int)clock();
|
seed = (unsigned int)clock();
|
||||||
}
|
}
|
||||||
/* using random seed 'seed' */
|
/* using random seed 'seed' */
|
||||||
srand(seed);
|
srand(seed);
|
||||||
@@ -54,37 +50,42 @@ int main(int argc, char **argv)
|
|||||||
/* allocate a default context */
|
/* allocate a default context */
|
||||||
ctx = xmpp_ctx_new(NULL, NULL);
|
ctx = xmpp_ctx_new(NULL, NULL);
|
||||||
if (ctx == NULL) {
|
if (ctx == NULL) {
|
||||||
/* ctx allocation failed! */
|
/* ctx allocation failed! */
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* allocate a hash table */
|
/* allocate a hash table */
|
||||||
table = hash_new(ctx, TABLESIZE, xmpp_free);
|
table = hash_new(ctx, TABLESIZE, xmpp_free);
|
||||||
if (table == NULL) {
|
if (table == NULL) {
|
||||||
/* table allocation failed! */
|
/* table allocation failed! */
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* test insertion */
|
/* test insertion */
|
||||||
for (i = 0; i < nkeys; i++) {
|
for (i = 0; i < nkeys; i++) {
|
||||||
err = hash_add(table, keys[i], xmpp_strdup(ctx, values[i]));
|
err = hash_add(table, keys[i], xmpp_strdup(ctx, values[i]));
|
||||||
if (err) return err;
|
if (err)
|
||||||
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* test key count */
|
/* test key count */
|
||||||
if (hash_num_keys(table) != nkeys) {
|
if (hash_num_keys(table) != nkeys) {
|
||||||
/* wrong number of keys in table! */
|
/* wrong number of keys in table! */
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* test replacing old values */
|
/* test replacing old values */
|
||||||
for (i = 0; i < nkeys; i++) {
|
for (i = 0; i < nkeys; i++) {
|
||||||
err = hash_add(table, keys[0], xmpp_strdup(ctx, values[i]));
|
err = hash_add(table, keys[0], xmpp_strdup(ctx, values[i]));
|
||||||
if (err) return err;
|
if (err)
|
||||||
if (hash_num_keys(table) != nkeys) return 1;
|
return err;
|
||||||
|
if (hash_num_keys(table) != nkeys)
|
||||||
|
return 1;
|
||||||
result = hash_get(table, keys[0]);
|
result = hash_get(table, keys[0]);
|
||||||
if (result == NULL) return 1;
|
if (result == NULL)
|
||||||
if (strcmp(result, values[i]) != 0) return 1;
|
return 1;
|
||||||
|
if (strcmp(result, values[i]) != 0)
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
/* restore value for the 1st key */
|
/* restore value for the 1st key */
|
||||||
hash_add(table, keys[0], xmpp_strdup(ctx, values[0]));
|
hash_add(table, keys[0], xmpp_strdup(ctx, values[0]));
|
||||||
@@ -94,36 +95,36 @@ int main(int argc, char **argv)
|
|||||||
|
|
||||||
/* test lookup */
|
/* test lookup */
|
||||||
for (i = 0; i < nkeys; i++) {
|
for (i = 0; i < nkeys; i++) {
|
||||||
result = hash_get(clone, keys[i]);
|
result = hash_get(clone, keys[i]);
|
||||||
if (result == NULL) {
|
if (result == NULL) {
|
||||||
/* lookup failed! */
|
/* lookup failed! */
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if (strcmp(values[i], result)) {
|
if (strcmp(values[i], result)) {
|
||||||
/* lookup returned incorrect value! */
|
/* lookup returned incorrect value! */
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* test key iterator */
|
/* test key iterator */
|
||||||
iter = hash_iter_new(clone);
|
iter = hash_iter_new(clone);
|
||||||
if (iter == NULL) {
|
if (iter == NULL) {
|
||||||
/* iterator allocation failed! */
|
/* iterator allocation failed! */
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
for (i = 0; i < nkeys; i++) {
|
for (i = 0; i < nkeys; i++) {
|
||||||
key = hash_iter_next(iter);
|
key = hash_iter_next(iter);
|
||||||
printf("key: '%s'\n", key);
|
printf("key: '%s'\n", key);
|
||||||
}
|
}
|
||||||
key = hash_iter_next(iter);
|
key = hash_iter_next(iter);
|
||||||
if (key != NULL) {
|
if (key != NULL) {
|
||||||
/* extra keys returned! */
|
/* extra keys returned! */
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
key = hash_iter_next(iter);
|
key = hash_iter_next(iter);
|
||||||
if (key != NULL) {
|
if (key != NULL) {
|
||||||
/* extra keys returned! */
|
/* extra keys returned! */
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
hash_iter_release(iter);
|
hash_iter_release(iter);
|
||||||
|
|
||||||
@@ -132,14 +133,19 @@ int main(int argc, char **argv)
|
|||||||
|
|
||||||
/* test drops */
|
/* test drops */
|
||||||
hash_drop(clone, keys[2]);
|
hash_drop(clone, keys[2]);
|
||||||
if (hash_get(clone, keys[2]) != NULL) return 1;
|
if (hash_get(clone, keys[2]) != NULL)
|
||||||
|
return 1;
|
||||||
hash_drop(clone, keys[1]);
|
hash_drop(clone, keys[1]);
|
||||||
hash_drop(clone, keys[4]);
|
hash_drop(clone, keys[4]);
|
||||||
if (hash_get(clone, keys[4]) != NULL) return 1;
|
if (hash_get(clone, keys[4]) != NULL)
|
||||||
if (hash_get(clone, keys[1]) != NULL) return 1;
|
return 1;
|
||||||
|
if (hash_get(clone, keys[1]) != NULL)
|
||||||
|
return 1;
|
||||||
/* keys 0,3 should still be available */
|
/* keys 0,3 should still be available */
|
||||||
if (hash_get(clone, keys[0]) == NULL) return 1;
|
if (hash_get(clone, keys[0]) == NULL)
|
||||||
if (hash_get(clone, keys[3]) == NULL) return 1;
|
return 1;
|
||||||
|
if (hash_get(clone, keys[3]) == NULL)
|
||||||
|
return 1;
|
||||||
|
|
||||||
/* release our clone */
|
/* release our clone */
|
||||||
hash_release(clone);
|
hash_release(clone);
|
||||||
|
|||||||
136
tests/test_jid.c
136
tests/test_jid.c
@@ -36,61 +36,93 @@ int test_jid(xmpp_ctx_t *ctx)
|
|||||||
node = xmpp_jid_node(ctx, jid1);
|
node = xmpp_jid_node(ctx, jid1);
|
||||||
domain = xmpp_jid_domain(ctx, jid1);
|
domain = xmpp_jid_domain(ctx, jid1);
|
||||||
resource = xmpp_jid_resource(ctx, jid1);
|
resource = xmpp_jid_resource(ctx, jid1);
|
||||||
printf("jid '%s' parsed to %s, %s, %s\n",
|
printf("jid '%s' parsed to %s, %s, %s\n", jid1, _s(node), _s(domain),
|
||||||
jid1, _s(node), _s(domain), _s(resource));
|
_s(resource));
|
||||||
if (bare == NULL || strcmp(bare, "foo@bar.com")) return 1;
|
if (bare == NULL || strcmp(bare, "foo@bar.com"))
|
||||||
if (node == NULL || strcmp(node, "foo")) return 1;
|
return 1;
|
||||||
if (domain == NULL || strcmp(domain, "bar.com")) return 1;
|
if (node == NULL || strcmp(node, "foo"))
|
||||||
if (resource != NULL) return 1;
|
return 1;
|
||||||
if (bare) xmpp_free(ctx, bare);
|
if (domain == NULL || strcmp(domain, "bar.com"))
|
||||||
if (node) xmpp_free(ctx, node);
|
return 1;
|
||||||
if (domain) xmpp_free(ctx, domain);
|
if (resource != NULL)
|
||||||
if (resource) xmpp_free(ctx, resource);
|
return 1;
|
||||||
|
if (bare)
|
||||||
|
xmpp_free(ctx, bare);
|
||||||
|
if (node)
|
||||||
|
xmpp_free(ctx, node);
|
||||||
|
if (domain)
|
||||||
|
xmpp_free(ctx, domain);
|
||||||
|
if (resource)
|
||||||
|
xmpp_free(ctx, resource);
|
||||||
|
|
||||||
bare = xmpp_jid_bare(ctx, jid2);
|
bare = xmpp_jid_bare(ctx, jid2);
|
||||||
node = xmpp_jid_node(ctx, jid2);
|
node = xmpp_jid_node(ctx, jid2);
|
||||||
domain = xmpp_jid_domain(ctx, jid2);
|
domain = xmpp_jid_domain(ctx, jid2);
|
||||||
resource = xmpp_jid_resource(ctx, jid2);
|
resource = xmpp_jid_resource(ctx, jid2);
|
||||||
printf("jid '%s' parsed to %s, %s, %s\n",
|
printf("jid '%s' parsed to %s, %s, %s\n", jid2, _s(node), _s(domain),
|
||||||
jid2, _s(node), _s(domain), _s(resource));
|
_s(resource));
|
||||||
if (bare == NULL || strcmp(bare, "anyone@example.com")) return 1;
|
if (bare == NULL || strcmp(bare, "anyone@example.com"))
|
||||||
if (node == NULL || strcmp(node, "anyone")) return 1;
|
return 1;
|
||||||
if (domain == NULL || strcmp(domain, "example.com")) return 1;
|
if (node == NULL || strcmp(node, "anyone"))
|
||||||
if (resource == NULL || strcmp(resource, "hullo")) return 1;
|
return 1;
|
||||||
if (bare) xmpp_free(ctx, bare);
|
if (domain == NULL || strcmp(domain, "example.com"))
|
||||||
if (node) xmpp_free(ctx, node);
|
return 1;
|
||||||
if (domain) xmpp_free(ctx, domain);
|
if (resource == NULL || strcmp(resource, "hullo"))
|
||||||
if (resource) xmpp_free(ctx, resource);
|
return 1;
|
||||||
|
if (bare)
|
||||||
|
xmpp_free(ctx, bare);
|
||||||
|
if (node)
|
||||||
|
xmpp_free(ctx, node);
|
||||||
|
if (domain)
|
||||||
|
xmpp_free(ctx, domain);
|
||||||
|
if (resource)
|
||||||
|
xmpp_free(ctx, resource);
|
||||||
|
|
||||||
bare = xmpp_jid_bare(ctx, jid3);
|
bare = xmpp_jid_bare(ctx, jid3);
|
||||||
node = xmpp_jid_node(ctx, jid3);
|
node = xmpp_jid_node(ctx, jid3);
|
||||||
domain = xmpp_jid_domain(ctx, jid3);
|
domain = xmpp_jid_domain(ctx, jid3);
|
||||||
resource = xmpp_jid_resource(ctx, jid3);
|
resource = xmpp_jid_resource(ctx, jid3);
|
||||||
printf("jid '%s' parsed to %s, %s, %s\n",
|
printf("jid '%s' parsed to %s, %s, %s\n", jid3, _s(node), _s(domain),
|
||||||
jid3, _s(node), _s(domain), _s(resource));
|
_s(resource));
|
||||||
if (bare == NULL || strcmp(bare, "manic.porter@xyz.net")) return 1;
|
if (bare == NULL || strcmp(bare, "manic.porter@xyz.net"))
|
||||||
if (node == NULL || strcmp(node, "manic.porter")) return 1;
|
return 1;
|
||||||
if (domain == NULL || strcmp(domain, "xyz.net")) return 1;
|
if (node == NULL || strcmp(node, "manic.porter"))
|
||||||
if (resource == NULL || strcmp(resource, "frob")) return 1;
|
return 1;
|
||||||
if (bare) xmpp_free(ctx, bare);
|
if (domain == NULL || strcmp(domain, "xyz.net"))
|
||||||
if (node) xmpp_free(ctx, node);
|
return 1;
|
||||||
if (domain) xmpp_free(ctx, domain);
|
if (resource == NULL || strcmp(resource, "frob"))
|
||||||
if (resource) xmpp_free(ctx, resource);
|
return 1;
|
||||||
|
if (bare)
|
||||||
|
xmpp_free(ctx, bare);
|
||||||
|
if (node)
|
||||||
|
xmpp_free(ctx, node);
|
||||||
|
if (domain)
|
||||||
|
xmpp_free(ctx, domain);
|
||||||
|
if (resource)
|
||||||
|
xmpp_free(ctx, resource);
|
||||||
|
|
||||||
bare = xmpp_jid_bare(ctx, jid4);
|
bare = xmpp_jid_bare(ctx, jid4);
|
||||||
node = xmpp_jid_node(ctx, jid4);
|
node = xmpp_jid_node(ctx, jid4);
|
||||||
domain = xmpp_jid_domain(ctx, jid4);
|
domain = xmpp_jid_domain(ctx, jid4);
|
||||||
resource = xmpp_jid_resource(ctx, jid4);
|
resource = xmpp_jid_resource(ctx, jid4);
|
||||||
printf("jid '%s' parsed to %s, %s, %s\n",
|
printf("jid '%s' parsed to %s, %s, %s\n", jid4, _s(node), _s(domain),
|
||||||
jid4, _s(node), _s(domain), _s(resource));
|
_s(resource));
|
||||||
if (bare == NULL || strcmp(bare, "domain.tld")) return 1;
|
if (bare == NULL || strcmp(bare, "domain.tld"))
|
||||||
if (node != NULL) return 1;
|
return 1;
|
||||||
if (domain == NULL || strcmp(domain, "domain.tld")) return 1;
|
if (node != NULL)
|
||||||
if (resource != NULL) return 1;
|
return 1;
|
||||||
if (bare) xmpp_free(ctx, bare);
|
if (domain == NULL || strcmp(domain, "domain.tld"))
|
||||||
if (node) xmpp_free(ctx, node);
|
return 1;
|
||||||
if (domain) xmpp_free(ctx, domain);
|
if (resource != NULL)
|
||||||
if (resource) xmpp_free(ctx, resource);
|
return 1;
|
||||||
|
if (bare)
|
||||||
|
xmpp_free(ctx, bare);
|
||||||
|
if (node)
|
||||||
|
xmpp_free(ctx, node);
|
||||||
|
if (domain)
|
||||||
|
xmpp_free(ctx, domain);
|
||||||
|
if (resource)
|
||||||
|
xmpp_free(ctx, resource);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -101,12 +133,14 @@ int test_jid_new(xmpp_ctx_t *ctx)
|
|||||||
|
|
||||||
jid = xmpp_jid_new(ctx, "node", "domain", "resource");
|
jid = xmpp_jid_new(ctx, "node", "domain", "resource");
|
||||||
printf("new jid: '%s'\n", jid);
|
printf("new jid: '%s'\n", jid);
|
||||||
if (strcmp(jid, "node@domain/resource")) return 1;
|
if (strcmp(jid, "node@domain/resource"))
|
||||||
|
return 1;
|
||||||
xmpp_free(ctx, jid);
|
xmpp_free(ctx, jid);
|
||||||
|
|
||||||
jid = xmpp_jid_new(ctx, "foo", "bar.com", NULL);
|
jid = xmpp_jid_new(ctx, "foo", "bar.com", NULL);
|
||||||
printf("new jid: '%s'\n", jid);
|
printf("new jid: '%s'\n", jid);
|
||||||
if (strcmp(jid, "foo@bar.com")) return 1;
|
if (strcmp(jid, "foo@bar.com"))
|
||||||
|
return 1;
|
||||||
xmpp_free(ctx, jid);
|
xmpp_free(ctx, jid);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -119,20 +153,26 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
printf("allocating context... ");
|
printf("allocating context... ");
|
||||||
ctx = xmpp_ctx_new(NULL, NULL);
|
ctx = xmpp_ctx_new(NULL, NULL);
|
||||||
if (ctx == NULL) printf("failed to create context\n");
|
if (ctx == NULL)
|
||||||
if (ctx == NULL) return -1;
|
printf("failed to create context\n");
|
||||||
|
if (ctx == NULL)
|
||||||
|
return -1;
|
||||||
printf("ok.\n");
|
printf("ok.\n");
|
||||||
|
|
||||||
printf("testing jid routines...\n");
|
printf("testing jid routines...\n");
|
||||||
ret = test_jid(ctx);
|
ret = test_jid(ctx);
|
||||||
if (ret) printf("testing jid routines... failed!\n");
|
if (ret)
|
||||||
if (ret) return ret;
|
printf("testing jid routines... failed!\n");
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
printf("testing jid routines... ok.\n");
|
printf("testing jid routines... ok.\n");
|
||||||
|
|
||||||
printf("testing jid new routines...\n");
|
printf("testing jid new routines...\n");
|
||||||
ret = test_jid_new(ctx);
|
ret = test_jid_new(ctx);
|
||||||
if (ret) printf("testing jid new routines... failed!\n");
|
if (ret)
|
||||||
if (ret) return ret;
|
printf("testing jid new routines... failed!\n");
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
printf("testing jid new routines... ok.\n");
|
printf("testing jid new routines... ok.\n");
|
||||||
|
|
||||||
printf("freeing context... ");
|
printf("freeing context... ");
|
||||||
|
|||||||
@@ -21,14 +21,17 @@
|
|||||||
#include "rand.c"
|
#include "rand.c"
|
||||||
|
|
||||||
/* stubs to build test without whole libstrophe */
|
/* stubs to build test without whole libstrophe */
|
||||||
void *xmpp_alloc(const xmpp_ctx_t * const ctx, const size_t size) {
|
void *xmpp_alloc(const xmpp_ctx_t *const ctx, const size_t size)
|
||||||
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
void xmpp_free(const xmpp_ctx_t * const ctx, void *p) { }
|
void xmpp_free(const xmpp_ctx_t *const ctx, void *p) {}
|
||||||
int xmpp_snprintf (char *str, size_t count, const char *fmt, ...) {
|
int xmpp_snprintf(char *str, size_t count, const char *fmt, ...)
|
||||||
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
uint64_t time_stamp(void) {
|
uint64_t time_stamp(void)
|
||||||
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -121,8 +124,8 @@ int main()
|
|||||||
&entropy_input_len);
|
&entropy_input_len);
|
||||||
test_hex_to_bin(test_vectors[i].nonce, nonce, &nonce_len);
|
test_hex_to_bin(test_vectors[i].nonce, nonce, &nonce_len);
|
||||||
|
|
||||||
Hash_DRBG_Instantiate(&ctx, entropy_input, entropy_input_len,
|
Hash_DRBG_Instantiate(&ctx, entropy_input, entropy_input_len, nonce,
|
||||||
nonce, nonce_len);
|
nonce_len);
|
||||||
COMPARE(test_vectors[i].V1, test_bin_to_hex(ctx.V, sizeof(ctx.V)));
|
COMPARE(test_vectors[i].V1, test_bin_to_hex(ctx.V, sizeof(ctx.V)));
|
||||||
COMPARE(test_vectors[i].C1, test_bin_to_hex(ctx.C, sizeof(ctx.C)));
|
COMPARE(test_vectors[i].C1, test_bin_to_hex(ctx.C, sizeof(ctx.C)));
|
||||||
assert(ctx.reseed_counter == 1);
|
assert(ctx.reseed_counter == 1);
|
||||||
|
|||||||
@@ -19,117 +19,94 @@
|
|||||||
|
|
||||||
/* res_query("_xmpp-client._tcp.jabber.kiev.ua", C_IN, T_SRV, ...) */
|
/* res_query("_xmpp-client._tcp.jabber.kiev.ua", C_IN, T_SRV, ...) */
|
||||||
static const unsigned char data1[] = {
|
static const unsigned char data1[] = {
|
||||||
0x95, 0xf3, 0x81, 0x80, 0x00, 0x01, 0x00, 0x01,
|
0x95, 0xf3, 0x81, 0x80, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x0c, 0x5f, 0x78, 0x6d,
|
0x0c, 0x5f, 0x78, 0x6d, 0x70, 0x70, 0x2d, 0x63, 0x6c, 0x69, 0x65, 0x6e,
|
||||||
0x70, 0x70, 0x2d, 0x63, 0x6c, 0x69, 0x65, 0x6e,
|
0x74, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x06, 0x6a, 0x61, 0x62, 0x62, 0x65,
|
||||||
0x74, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x06, 0x6a,
|
0x72, 0x04, 0x6b, 0x69, 0x65, 0x76, 0x02, 0x75, 0x61, 0x00, 0x00, 0x21,
|
||||||
0x61, 0x62, 0x62, 0x65, 0x72, 0x04, 0x6b, 0x69,
|
0x00, 0x01, 0xc0, 0x0c, 0x00, 0x21, 0x00, 0x01, 0x00, 0x00, 0x00, 0x3b,
|
||||||
0x65, 0x76, 0x02, 0x75, 0x61, 0x00, 0x00, 0x21,
|
0x00, 0x16, 0x00, 0x01, 0x00, 0x00, 0x14, 0x66, 0x06, 0x6a, 0x61, 0x62,
|
||||||
0x00, 0x01, 0xc0, 0x0c, 0x00, 0x21, 0x00, 0x01,
|
0x62, 0x65, 0x72, 0x04, 0x6b, 0x69, 0x65, 0x76, 0x02, 0x75, 0x61, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x3b, 0x00, 0x16, 0x00, 0x01,
|
|
||||||
0x00, 0x00, 0x14, 0x66, 0x06, 0x6a, 0x61, 0x62,
|
|
||||||
0x62, 0x65, 0x72, 0x04, 0x6b, 0x69, 0x65, 0x76,
|
|
||||||
0x02, 0x75, 0x61, 0x00,
|
|
||||||
};
|
};
|
||||||
/* res_query("_xmpp-client._tcp.jabber.org", C_IN, T_SRV, ...) */
|
/* res_query("_xmpp-client._tcp.jabber.org", C_IN, T_SRV, ...) */
|
||||||
static const unsigned char data2[] = {
|
static const unsigned char data2[] = {
|
||||||
0xf2, 0x98, 0x81, 0x80, 0x00, 0x01, 0x00, 0x02,
|
0xf2, 0x98, 0x81, 0x80, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x0c, 0x5f, 0x78, 0x6d,
|
0x0c, 0x5f, 0x78, 0x6d, 0x70, 0x70, 0x2d, 0x63, 0x6c, 0x69, 0x65, 0x6e,
|
||||||
0x70, 0x70, 0x2d, 0x63, 0x6c, 0x69, 0x65, 0x6e,
|
0x74, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x06, 0x6a, 0x61, 0x62, 0x62, 0x65,
|
||||||
0x74, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x06, 0x6a,
|
0x72, 0x03, 0x6f, 0x72, 0x67, 0x00, 0x00, 0x21, 0x00, 0x01, 0xc0, 0x0c,
|
||||||
0x61, 0x62, 0x62, 0x65, 0x72, 0x03, 0x6f, 0x72,
|
0x00, 0x21, 0x00, 0x01, 0x00, 0x00, 0x03, 0x83, 0x00, 0x1a, 0x00, 0x1e,
|
||||||
0x67, 0x00, 0x00, 0x21, 0x00, 0x01, 0xc0, 0x0c,
|
0x00, 0x1e, 0x14, 0x66, 0x07, 0x68, 0x65, 0x72, 0x6d, 0x65, 0x73, 0x32,
|
||||||
0x00, 0x21, 0x00, 0x01, 0x00, 0x00, 0x03, 0x83,
|
0x06, 0x6a, 0x61, 0x62, 0x62, 0x65, 0x72, 0x03, 0x6f, 0x72, 0x67, 0x00,
|
||||||
0x00, 0x1a, 0x00, 0x1e, 0x00, 0x1e, 0x14, 0x66,
|
0xc0, 0x0c, 0x00, 0x21, 0x00, 0x01, 0x00, 0x00, 0x03, 0x83, 0x00, 0x1c,
|
||||||
0x07, 0x68, 0x65, 0x72, 0x6d, 0x65, 0x73, 0x32,
|
0x00, 0x1f, 0x00, 0x1e, 0x14, 0x66, 0x09, 0x68, 0x65, 0x72, 0x6d, 0x65,
|
||||||
0x06, 0x6a, 0x61, 0x62, 0x62, 0x65, 0x72, 0x03,
|
0x73, 0x32, 0x76, 0x36, 0x06, 0x6a, 0x61, 0x62, 0x62, 0x65, 0x72, 0x03,
|
||||||
0x6f, 0x72, 0x67, 0x00, 0xc0, 0x0c, 0x00, 0x21,
|
|
||||||
0x00, 0x01, 0x00, 0x00, 0x03, 0x83, 0x00, 0x1c,
|
|
||||||
0x00, 0x1f, 0x00, 0x1e, 0x14, 0x66, 0x09, 0x68,
|
|
||||||
0x65, 0x72, 0x6d, 0x65, 0x73, 0x32, 0x76, 0x36,
|
|
||||||
0x06, 0x6a, 0x61, 0x62, 0x62, 0x65, 0x72, 0x03,
|
|
||||||
0x6f, 0x72, 0x67, 0x00,
|
0x6f, 0x72, 0x67, 0x00,
|
||||||
};
|
};
|
||||||
/* res_query("_xmpp-client._tcp.gmail.com", C_IN, T_SRV, ...) */
|
/* res_query("_xmpp-client._tcp.gmail.com", C_IN, T_SRV, ...) */
|
||||||
static const unsigned char data3[] = {
|
static const unsigned char data3[] = {
|
||||||
0xda, 0xa8, 0x81, 0x80, 0x00, 0x01, 0x00, 0x05,
|
0xda, 0xa8, 0x81, 0x80, 0x00, 0x01, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x0c, 0x5f, 0x78, 0x6d,
|
0x0c, 0x5f, 0x78, 0x6d, 0x70, 0x70, 0x2d, 0x63, 0x6c, 0x69, 0x65, 0x6e,
|
||||||
0x70, 0x70, 0x2d, 0x63, 0x6c, 0x69, 0x65, 0x6e,
|
0x74, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x67, 0x6d, 0x61, 0x69, 0x6c,
|
||||||
0x74, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x67,
|
0x03, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x21, 0x00, 0x01, 0xc0, 0x0c, 0x00,
|
||||||
0x6d, 0x61, 0x69, 0x6c, 0x03, 0x63, 0x6f, 0x6d,
|
0x21, 0x00, 0x01, 0x00, 0x00, 0x02, 0x43, 0x00, 0x1e, 0x00, 0x14, 0x00,
|
||||||
0x00, 0x00, 0x21, 0x00, 0x01, 0xc0, 0x0c, 0x00,
|
0x00, 0x14, 0x66, 0x04, 0x61, 0x6c, 0x74, 0x31, 0x04, 0x78, 0x6d, 0x70,
|
||||||
0x21, 0x00, 0x01, 0x00, 0x00, 0x02, 0x43, 0x00,
|
0x70, 0x01, 0x6c, 0x06, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x03, 0x63,
|
||||||
0x1e, 0x00, 0x14, 0x00, 0x00, 0x14, 0x66, 0x04,
|
0x6f, 0x6d, 0x00, 0xc0, 0x0c, 0x00, 0x21, 0x00, 0x01, 0x00, 0x00, 0x02,
|
||||||
0x61, 0x6c, 0x74, 0x31, 0x04, 0x78, 0x6d, 0x70,
|
0x43, 0x00, 0x1e, 0x00, 0x14, 0x00, 0x00, 0x14, 0x66, 0x04, 0x61, 0x6c,
|
||||||
0x70, 0x01, 0x6c, 0x06, 0x67, 0x6f, 0x6f, 0x67,
|
0x74, 0x34, 0x04, 0x78, 0x6d, 0x70, 0x70, 0x01, 0x6c, 0x06, 0x67, 0x6f,
|
||||||
0x6c, 0x65, 0x03, 0x63, 0x6f, 0x6d, 0x00, 0xc0,
|
0x6f, 0x67, 0x6c, 0x65, 0x03, 0x63, 0x6f, 0x6d, 0x00, 0xc0, 0x0c, 0x00,
|
||||||
0x0c, 0x00, 0x21, 0x00, 0x01, 0x00, 0x00, 0x02,
|
0x21, 0x00, 0x01, 0x00, 0x00, 0x02, 0x43, 0x00, 0x1e, 0x00, 0x14, 0x00,
|
||||||
0x43, 0x00, 0x1e, 0x00, 0x14, 0x00, 0x00, 0x14,
|
0x00, 0x14, 0x66, 0x04, 0x61, 0x6c, 0x74, 0x32, 0x04, 0x78, 0x6d, 0x70,
|
||||||
0x66, 0x04, 0x61, 0x6c, 0x74, 0x34, 0x04, 0x78,
|
0x70, 0x01, 0x6c, 0x06, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x03, 0x63,
|
||||||
0x6d, 0x70, 0x70, 0x01, 0x6c, 0x06, 0x67, 0x6f,
|
0x6f, 0x6d, 0x00, 0xc0, 0x0c, 0x00, 0x21, 0x00, 0x01, 0x00, 0x00, 0x02,
|
||||||
0x6f, 0x67, 0x6c, 0x65, 0x03, 0x63, 0x6f, 0x6d,
|
0x43, 0x00, 0x19, 0x00, 0x05, 0x00, 0x00, 0x14, 0x66, 0x04, 0x78, 0x6d,
|
||||||
0x00, 0xc0, 0x0c, 0x00, 0x21, 0x00, 0x01, 0x00,
|
0x70, 0x70, 0x01, 0x6c, 0x06, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x03,
|
||||||
0x00, 0x02, 0x43, 0x00, 0x1e, 0x00, 0x14, 0x00,
|
0x63, 0x6f, 0x6d, 0x00, 0xc0, 0x0c, 0x00, 0x21, 0x00, 0x01, 0x00, 0x00,
|
||||||
0x00, 0x14, 0x66, 0x04, 0x61, 0x6c, 0x74, 0x32,
|
0x02, 0x43, 0x00, 0x1e, 0x00, 0x14, 0x00, 0x00, 0x14, 0x66, 0x04, 0x61,
|
||||||
0x04, 0x78, 0x6d, 0x70, 0x70, 0x01, 0x6c, 0x06,
|
0x6c, 0x74, 0x33, 0x04, 0x78, 0x6d, 0x70, 0x70, 0x01, 0x6c, 0x06, 0x67,
|
||||||
0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x03, 0x63,
|
0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x03, 0x63, 0x6f, 0x6d, 0x00,
|
||||||
0x6f, 0x6d, 0x00, 0xc0, 0x0c, 0x00, 0x21, 0x00,
|
|
||||||
0x01, 0x00, 0x00, 0x02, 0x43, 0x00, 0x19, 0x00,
|
|
||||||
0x05, 0x00, 0x00, 0x14, 0x66, 0x04, 0x78, 0x6d,
|
|
||||||
0x70, 0x70, 0x01, 0x6c, 0x06, 0x67, 0x6f, 0x6f,
|
|
||||||
0x67, 0x6c, 0x65, 0x03, 0x63, 0x6f, 0x6d, 0x00,
|
|
||||||
0xc0, 0x0c, 0x00, 0x21, 0x00, 0x01, 0x00, 0x00,
|
|
||||||
0x02, 0x43, 0x00, 0x1e, 0x00, 0x14, 0x00, 0x00,
|
|
||||||
0x14, 0x66, 0x04, 0x61, 0x6c, 0x74, 0x33, 0x04,
|
|
||||||
0x78, 0x6d, 0x70, 0x70, 0x01, 0x6c, 0x06, 0x67,
|
|
||||||
0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x03, 0x63, 0x6f,
|
|
||||||
0x6d, 0x00,
|
|
||||||
};
|
};
|
||||||
/* res_query("_xmpp-client._tcp.jabber.calyxinstitute.org", C_IN, T_SRV, ...) */
|
/* res_query("_xmpp-client._tcp.jabber.calyxinstitute.org", C_IN, T_SRV, ...) */
|
||||||
static const unsigned char data4[] = {
|
static const unsigned char data4[] = {
|
||||||
0x8d, 0x58, 0x81, 0x80, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, // .X........
|
0x8d, 0x58, 0x81, 0x80, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, // .X........
|
||||||
0x00, 0x00, 0x0c, 0x5f, 0x78, 0x6d, 0x70, 0x70, 0x2d, 0x63, // ..._xmpp-c
|
0x00, 0x00, 0x0c, 0x5f, 0x78, 0x6d, 0x70, 0x70, 0x2d, 0x63, // ..._xmpp-c
|
||||||
0x6c, 0x69, 0x65, 0x6e, 0x74, 0x04, 0x5f, 0x74, 0x63, 0x70, // lient._tcp
|
0x6c, 0x69, 0x65, 0x6e, 0x74, 0x04, 0x5f, 0x74, 0x63, 0x70, // lient._tcp
|
||||||
0x06, 0x6a, 0x61, 0x62, 0x62, 0x65, 0x72, 0x0e, 0x63, 0x61, // .jabber.ca
|
0x06, 0x6a, 0x61, 0x62, 0x62, 0x65, 0x72, 0x0e, 0x63, 0x61, // .jabber.ca
|
||||||
0x6c, 0x79, 0x78, 0x69, 0x6e, 0x73, 0x74, 0x69, 0x74, 0x75, // lyxinstitu
|
0x6c, 0x79, 0x78, 0x69, 0x6e, 0x73, 0x74, 0x69, 0x74, 0x75, // lyxinstitu
|
||||||
0x74, 0x65, 0x03, 0x6f, 0x72, 0x67, 0x00, 0x00, 0x21, 0x00, // te.org..!.
|
0x74, 0x65, 0x03, 0x6f, 0x72, 0x67, 0x00, 0x00, 0x21, 0x00, // te.org..!.
|
||||||
0x01, 0xc0, 0x0c, 0x00, 0x21, 0x00, 0x01, 0x00, 0x00, 0x03, // ....!.....
|
0x01, 0xc0, 0x0c, 0x00, 0x21, 0x00, 0x01, 0x00, 0x00, 0x03, // ....!.....
|
||||||
0x83, 0x00, 0x1e, 0x00, 0x04, 0x00, 0x00, 0x14, 0x66, 0x10, // ........f.
|
0x83, 0x00, 0x1e, 0x00, 0x04, 0x00, 0x00, 0x14, 0x66, 0x10, // ........f.
|
||||||
0x69, 0x6a, 0x65, 0x65, 0x79, 0x6e, 0x72, 0x63, 0x36, 0x78, // ijeeynrc6x
|
0x69, 0x6a, 0x65, 0x65, 0x79, 0x6e, 0x72, 0x63, 0x36, 0x78, // ijeeynrc6x
|
||||||
0x32, 0x75, 0x79, 0x35, 0x6f, 0x62, 0x05, 0x6f, 0x6e, 0x69, // 2uy5ob.oni
|
0x32, 0x75, 0x79, 0x35, 0x6f, 0x62, 0x05, 0x6f, 0x6e, 0x69, // 2uy5ob.oni
|
||||||
0x6f, 0x6e, 0x00, 0xc0, 0x0c, 0x00, 0x21, 0x00, 0x01, 0x00, // on....!...
|
0x6f, 0x6e, 0x00, 0xc0, 0x0c, 0x00, 0x21, 0x00, 0x01, 0x00, // on....!...
|
||||||
0x00, 0x03, 0x83, 0x00, 0x21, 0x00, 0x05, 0x00, 0x01, 0x14, // ....!.....
|
0x00, 0x03, 0x83, 0x00, 0x21, 0x00, 0x05, 0x00, 0x01, 0x14, // ....!.....
|
||||||
0x66, 0x06, 0x6a, 0x61, 0x62, 0x62, 0x65, 0x72, 0x0e, 0x63, // f.jabber.c
|
0x66, 0x06, 0x6a, 0x61, 0x62, 0x62, 0x65, 0x72, 0x0e, 0x63, // f.jabber.c
|
||||||
0x61, 0x6c, 0x79, 0x78, 0x69, 0x6e, 0x73, 0x74, 0x69, 0x74, // alyxinstit
|
0x61, 0x6c, 0x79, 0x78, 0x69, 0x6e, 0x73, 0x74, 0x69, 0x74, // alyxinstit
|
||||||
0x75, 0x74, 0x65, 0x03, 0x6f, 0x72, 0x67, 0x00, // ute.org.
|
0x75, 0x74, 0x65, 0x03, 0x6f, 0x72, 0x67, 0x00, // ute.org.
|
||||||
};
|
};
|
||||||
/* res_query("_xmpp-client._tcp.jabber.org", C_IN, T_SRV, ...) with pointers */
|
/* res_query("_xmpp-client._tcp.jabber.org", C_IN, T_SRV, ...) with pointers */
|
||||||
static const unsigned char data5[] = {
|
static const unsigned char data5[] = {
|
||||||
0x00, 0x00, 0x81, 0x80, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, // ..........
|
0x00, 0x00, 0x81, 0x80, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, // ..........
|
||||||
0x00, 0x00, 0x0c, 0x5f, 0x78, 0x6d, 0x70, 0x70, 0x2d, 0x63, // ..._xmpp-c
|
0x00, 0x00, 0x0c, 0x5f, 0x78, 0x6d, 0x70, 0x70, 0x2d, 0x63, // ..._xmpp-c
|
||||||
0x6c, 0x69, 0x65, 0x6e, 0x74, 0x04, 0x5f, 0x74, 0x63, 0x70, // lient._tcp
|
0x6c, 0x69, 0x65, 0x6e, 0x74, 0x04, 0x5f, 0x74, 0x63, 0x70, // lient._tcp
|
||||||
0x06, 0x6a, 0x61, 0x62, 0x62, 0x65, 0x72, 0x03, 0x6f, 0x72, // .jabber.or
|
0x06, 0x6a, 0x61, 0x62, 0x62, 0x65, 0x72, 0x03, 0x6f, 0x72, // .jabber.or
|
||||||
0x67, 0x00, 0x00, 0x21, 0x00, 0x01, 0xc0, 0x0c, 0x00, 0x21, // g..!.....!
|
0x67, 0x00, 0x00, 0x21, 0x00, 0x01, 0xc0, 0x0c, 0x00, 0x21, // g..!.....!
|
||||||
0x00, 0x01, 0x00, 0x00, 0x01, 0x9e, 0x00, 0x12, 0x00, 0x1f, // ..........
|
0x00, 0x01, 0x00, 0x00, 0x01, 0x9e, 0x00, 0x12, 0x00, 0x1f, // ..........
|
||||||
0x00, 0x1e, 0x14, 0x66, 0x09, 0x68, 0x65, 0x72, 0x6d, 0x65, // ...f.herme
|
0x00, 0x1e, 0x14, 0x66, 0x09, 0x68, 0x65, 0x72, 0x6d, 0x65, // ...f.herme
|
||||||
0x73, 0x32, 0x76, 0x36, 0xc0, 0x1e, 0xc0, 0x0c, 0x00, 0x21, // s2v6.....!
|
0x73, 0x32, 0x76, 0x36, 0xc0, 0x1e, 0xc0, 0x0c, 0x00, 0x21, // s2v6.....!
|
||||||
0x00, 0x01, 0x00, 0x00, 0x01, 0x9e, 0x00, 0x10, 0x00, 0x1e, // ..........
|
0x00, 0x01, 0x00, 0x00, 0x01, 0x9e, 0x00, 0x10, 0x00, 0x1e, // ..........
|
||||||
0x00, 0x1e, 0x14, 0x66, 0x07, 0x68, 0x65, 0x72, 0x6d, 0x65, // ...f.herme
|
0x00, 0x1e, 0x14, 0x66, 0x07, 0x68, 0x65, 0x72, 0x6d, 0x65, // ...f.herme
|
||||||
0x73, 0x32, 0xc0, 0x1e, // s2..
|
0x73, 0x32, 0xc0, 0x1e, // s2..
|
||||||
};
|
};
|
||||||
/* hacked data2 with two empty-string targets. */
|
/* hacked data2 with two empty-string targets. */
|
||||||
static const unsigned char data6[] = {
|
static const unsigned char data6[] = {
|
||||||
0xf2, 0x98, 0x81, 0x80, 0x00, 0x01, 0x00, 0x02,
|
0xf2, 0x98, 0x81, 0x80, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x0c, 0x5f, 0x78, 0x6d,
|
0x00, 0x0c, 0x5f, 0x78, 0x6d, 0x70, 0x70, 0x2d, 0x63, 0x6c, 0x69,
|
||||||
0x70, 0x70, 0x2d, 0x63, 0x6c, 0x69, 0x65, 0x6e,
|
0x65, 0x6e, 0x74, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x06, 0x6a, 0x61,
|
||||||
0x74, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x06, 0x6a,
|
0x62, 0x62, 0x65, 0x72, 0x03, 0x6f, 0x72, 0x67, 0x00, 0x00, 0x21,
|
||||||
0x61, 0x62, 0x62, 0x65, 0x72, 0x03, 0x6f, 0x72,
|
0x00, 0x01, 0xc0, 0x0c, 0x00, 0x21, 0x00, 0x01, 0x00, 0x00, 0x03,
|
||||||
0x67, 0x00, 0x00, 0x21, 0x00, 0x01, 0xc0, 0x0c,
|
0x83, 0x00, 0x07, 0x00, 0x1e, 0x00, 0x1e, 0x14, 0x66, 0x00, 0xc0,
|
||||||
0x00, 0x21, 0x00, 0x01, 0x00, 0x00, 0x03, 0x83,
|
0x0c, 0x00, 0x21, 0x00, 0x01, 0x00, 0x00, 0x03, 0x83, 0x00, 0x08,
|
||||||
0x00, 0x07, 0x00, 0x1e, 0x00, 0x1e, 0x14, 0x66,
|
0x00, 0x1f, 0x00, 0x1e, 0x14, 0x66, 0xc0, 0x40,
|
||||||
0x00, 0xc0, 0x0c, 0x00, 0x21, 0x00, 0x01, 0x00,
|
|
||||||
0x00, 0x03, 0x83, 0x00, 0x08, 0x00, 0x1f, 0x00,
|
|
||||||
0x1e, 0x14, 0x66, 0xc0, 0x40,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct {
|
static const struct {
|
||||||
@@ -187,7 +164,8 @@ static int srv_rr_list_len(resolver_srv_rr_t *list)
|
|||||||
{
|
{
|
||||||
int nr;
|
int nr;
|
||||||
|
|
||||||
for (nr = 0; list != NULL; ++nr, list = list->next);
|
for (nr = 0; list != NULL; ++nr, list = list->next)
|
||||||
|
;
|
||||||
|
|
||||||
return nr;
|
return nr;
|
||||||
}
|
}
|
||||||
@@ -223,8 +201,8 @@ int main(int argc, char **argv)
|
|||||||
port = srv_rr_list->port;
|
port = srv_rr_list->port;
|
||||||
COMPARE(tests[i].target, domain);
|
COMPARE(tests[i].target, domain);
|
||||||
if (tests[i].port != port) {
|
if (tests[i].port != port) {
|
||||||
printf("fail! got port=%u, but should be %u\n",
|
printf("fail! got port=%u, but should be %u\n", (unsigned)port,
|
||||||
(unsigned)port, (unsigned)tests[i].port);
|
(unsigned)tests[i].port);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
printf("ok\n");
|
printf("ok\n");
|
||||||
|
|||||||
@@ -21,31 +21,31 @@ static const char password[] = "secret";
|
|||||||
static const char response_plain[] = "AGZvb0BiYXIuY29tAHNlY3JldA==";
|
static const char response_plain[] = "AGZvb0BiYXIuY29tAHNlY3JldA==";
|
||||||
|
|
||||||
static const char challenge_md5[] =
|
static const char challenge_md5[] =
|
||||||
"cmVhbG09InNvbWVyZWFsbSIsbm9uY2U9Ik9BNk1HOXRFUUdtMmhoIixxb3A9ImF1dGgi"
|
"cmVhbG09InNvbWVyZWFsbSIsbm9uY2U9Ik9BNk1HOXRFUUdtMmhoIixxb3A9ImF1dGgi"
|
||||||
"LGNoYXJzZXQ9dXRmLTgsYWxnb3JpdGhtPW1kNS1zZXNzCg==";
|
"LGNoYXJzZXQ9dXRmLTgsYWxnb3JpdGhtPW1kNS1zZXNzCg==";
|
||||||
static const char response_md5[] =
|
static const char response_md5[] =
|
||||||
"dXNlcm5hbWU9InNvbWVub2RlIixyZWFsbT0ic29tZXJlYWxtIixub25jZT0i"
|
"dXNlcm5hbWU9InNvbWVub2RlIixyZWFsbT0ic29tZXJlYWxtIixub25jZT0i"
|
||||||
"T0E2TUc5dEVRR20yaGgiLGNub25jZT0iMDBERUFEQkVFRjAwIixuYz0wMDAw"
|
"T0E2TUc5dEVRR20yaGgiLGNub25jZT0iMDBERUFEQkVFRjAwIixuYz0wMDAw"
|
||||||
"MDAwMSxxb3A9YXV0aCxkaWdlc3QtdXJpPSJ4bXBwL3NvbWVyZWFsbSIscmVz"
|
"MDAwMSxxb3A9YXV0aCxkaWdlc3QtdXJpPSJ4bXBwL3NvbWVyZWFsbSIscmVz"
|
||||||
"cG9uc2U9NGVhNmU4N2JjMDkzMzUwNzQzZGIyOGQ3MDIwOGNhZmIsY2hhcnNl"
|
"cG9uc2U9NGVhNmU4N2JjMDkzMzUwNzQzZGIyOGQ3MDIwOGNhZmIsY2hhcnNl"
|
||||||
"dD11dGYtOA==";
|
"dD11dGYtOA==";
|
||||||
static const char response_md5_rfc[] =
|
static const char response_md5_rfc[] =
|
||||||
"dXNlcm5hbWU9InNvbWVub2RlIixyZWFsbT0ic29tZXJlYWxtIixub25jZT0i"
|
"dXNlcm5hbWU9InNvbWVub2RlIixyZWFsbT0ic29tZXJlYWxtIixub25jZT0i"
|
||||||
"T0E2TUc5dEVRR20yaGgiLGNub25jZT0iT0E2TUhYaDZWcVRyUmsiLG5jPTAw"
|
"T0E2TUc5dEVRR20yaGgiLGNub25jZT0iT0E2TUhYaDZWcVRyUmsiLG5jPTAw"
|
||||||
"MDAwMDAxLHFvcD1hdXRoLGRpZ2VzdC11cmk9InhtcHAvZXhhbXBsZS5jb20i"
|
"MDAwMDAxLHFvcD1hdXRoLGRpZ2VzdC11cmk9InhtcHAvZXhhbXBsZS5jb20i"
|
||||||
"LHJlc3BvbnNlPWQzODhkYWQ5MGQ0YmJkNzYwYTE1MjMyMWYyMTQzYWY3LGNo"
|
"LHJlc3BvbnNlPWQzODhkYWQ5MGQ0YmJkNzYwYTE1MjMyMWYyMTQzYWY3LGNo"
|
||||||
"YXJzZXQ9dXRmLTgK";
|
"YXJzZXQ9dXRmLTgK";
|
||||||
|
|
||||||
static const char challenge_md5_2[] =
|
static const char challenge_md5_2[] =
|
||||||
"cmVhbG09ImVsd29vZC5pbm5vc29mdC5jb20iLG5vbmNlPSJPQTZNRzl0"
|
"cmVhbG09ImVsd29vZC5pbm5vc29mdC5jb20iLG5vbmNlPSJPQTZNRzl0"
|
||||||
"RVFHbTJoaCIscW9wPSJhdXRoIixhbGdvcml0aG09bWQ1LXNlc3MsY2hh"
|
"RVFHbTJoaCIscW9wPSJhdXRoIixhbGdvcml0aG09bWQ1LXNlc3MsY2hh"
|
||||||
"cnNldD11dGYtOA==";
|
"cnNldD11dGYtOA==";
|
||||||
static const char response_md5_2[] =
|
static const char response_md5_2[] =
|
||||||
"Y2hhcnNldD11dGYtOCx1c2VybmFtZT0iY2hyaXMiLHJlYWxtPSJlbHdvb2"
|
"Y2hhcnNldD11dGYtOCx1c2VybmFtZT0iY2hyaXMiLHJlYWxtPSJlbHdvb2"
|
||||||
"QuaW5ub3NvZnQuY29tIixub25jZT0iT0E2TUc5dEVRR20yaGgiLG5jPTAw"
|
"QuaW5ub3NvZnQuY29tIixub25jZT0iT0E2TUc5dEVRR20yaGgiLG5jPTAw"
|
||||||
"MDAwMDAxLGNub25jZT0iT0E2TUhYaDZWcVRyUmsiLGRpZ2VzdC11cmk9Im"
|
"MDAwMDAxLGNub25jZT0iT0E2TUhYaDZWcVRyUmsiLGRpZ2VzdC11cmk9Im"
|
||||||
"ltYXAvZWx3b29kLmlubm9zb2Z0LmNvbSIscmVzcG9uc2U9ZDM4OGRhZDkw"
|
"ltYXAvZWx3b29kLmlubm9zb2Z0LmNvbSIscmVzcG9uc2U9ZDM4OGRhZDkw"
|
||||||
"ZDRiYmQ3NjBhMTUyMzIxZjIxNDNhZjcscW9wPWF1dGg=";
|
"ZDRiYmQ3NjBhMTUyMzIxZjIxNDNhZjcscW9wPWF1dGg=";
|
||||||
|
|
||||||
int test_plain(xmpp_ctx_t *ctx)
|
int test_plain(xmpp_ctx_t *ctx)
|
||||||
{
|
{
|
||||||
@@ -53,12 +53,12 @@ int test_plain(xmpp_ctx_t *ctx)
|
|||||||
|
|
||||||
result = sasl_plain(ctx, jid, password);
|
result = sasl_plain(ctx, jid, password);
|
||||||
if (result == NULL) {
|
if (result == NULL) {
|
||||||
/* SASL PLAIN internal failure! */
|
/* SASL PLAIN internal failure! */
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if (strncmp(response_plain, result, strlen(response_plain))) {
|
if (strncmp(response_plain, result, strlen(response_plain))) {
|
||||||
/* SASL PLAIN returned incorrect string! */
|
/* SASL PLAIN returned incorrect string! */
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
xmpp_free(ctx, result);
|
xmpp_free(ctx, result);
|
||||||
|
|
||||||
@@ -69,12 +69,12 @@ int test_digest_md5(xmpp_ctx_t *ctx)
|
|||||||
{
|
{
|
||||||
char *result;
|
char *result;
|
||||||
|
|
||||||
result = sasl_digest_md5(ctx, challenge_md5,
|
result =
|
||||||
"somenode@somerealm", "secret");
|
sasl_digest_md5(ctx, challenge_md5, "somenode@somerealm", "secret");
|
||||||
printf("response:\n%s\n", result);
|
printf("response:\n%s\n", result);
|
||||||
if (strcmp(response_md5, result)) {
|
if (strcmp(response_md5, result)) {
|
||||||
/* generated incorrect response to challenge */
|
/* generated incorrect response to challenge */
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -87,20 +87,26 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
printf("allocating context... ");
|
printf("allocating context... ");
|
||||||
ctx = xmpp_ctx_new(NULL, NULL);
|
ctx = xmpp_ctx_new(NULL, NULL);
|
||||||
if (ctx == NULL) printf("failed to create context\n");
|
if (ctx == NULL)
|
||||||
if (ctx == NULL) return -1;
|
printf("failed to create context\n");
|
||||||
|
if (ctx == NULL)
|
||||||
|
return -1;
|
||||||
printf("ok.\n");
|
printf("ok.\n");
|
||||||
|
|
||||||
printf("testing SASL PLAIN... ");
|
printf("testing SASL PLAIN... ");
|
||||||
ret = test_plain(ctx);
|
ret = test_plain(ctx);
|
||||||
if (ret) printf("failed!\n");
|
if (ret)
|
||||||
if (ret) return ret;
|
printf("failed!\n");
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
printf("ok.\n");
|
printf("ok.\n");
|
||||||
|
|
||||||
printf("testing SASL DIGEST-MD5... ");
|
printf("testing SASL DIGEST-MD5... ");
|
||||||
ret = test_digest_md5(ctx);
|
ret = test_digest_md5(ctx);
|
||||||
if (ret) printf("failed!\n");
|
if (ret)
|
||||||
if (ret) return ret;
|
printf("failed!\n");
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
printf("ok.\n");
|
printf("ok.\n");
|
||||||
|
|
||||||
printf("freeing context... ");
|
printf("freeing context... ");
|
||||||
|
|||||||
@@ -25,12 +25,12 @@
|
|||||||
* Test vectors for derivation function (RFC6070).
|
* Test vectors for derivation function (RFC6070).
|
||||||
*/
|
*/
|
||||||
static const struct {
|
static const struct {
|
||||||
char *P; /* text */
|
char *P; /* text */
|
||||||
char *S; /* salt */
|
char *S; /* salt */
|
||||||
size_t P_len;
|
size_t P_len;
|
||||||
size_t S_len;
|
size_t S_len;
|
||||||
uint32_t c; /* i */
|
uint32_t c; /* i */
|
||||||
char *DK; /* resulting digest */
|
char *DK; /* resulting digest */
|
||||||
} df_vectors[] = {
|
} df_vectors[] = {
|
||||||
{
|
{
|
||||||
.P = "password",
|
.P = "password",
|
||||||
@@ -115,14 +115,13 @@ static void test_scram(void)
|
|||||||
printf("SCRAM_SHA1_ClientKey and SCRAM_SHA1_ClientSignature tests.\n");
|
printf("SCRAM_SHA1_ClientKey and SCRAM_SHA1_ClientSignature tests.\n");
|
||||||
for (i = 0; i < ARRAY_SIZE(scram_vectors); ++i) {
|
for (i = 0; i < ARRAY_SIZE(scram_vectors); ++i) {
|
||||||
printf("Test #%d: ", (int)i + 1);
|
printf("Test #%d: ", (int)i + 1);
|
||||||
snprintf(auth, sizeof(auth), "%s,%s,%s",
|
snprintf(auth, sizeof(auth), "%s,%s,%s", scram_vectors[i].initial + 3,
|
||||||
scram_vectors[i].initial + 3, scram_vectors[i].challenge,
|
scram_vectors[i].challenge, scram_vectors[i].response);
|
||||||
scram_vectors[i].response);
|
|
||||||
test_hex_to_bin(scram_vectors[i].salt, salt, &salt_len);
|
test_hex_to_bin(scram_vectors[i].salt, salt, &salt_len);
|
||||||
|
|
||||||
SCRAM_SHA1_ClientKey((uint8_t *)scram_vectors[i].password,
|
SCRAM_SHA1_ClientKey((uint8_t *)scram_vectors[i].password,
|
||||||
strlen(scram_vectors[i].password),
|
strlen(scram_vectors[i].password), salt, salt_len,
|
||||||
salt, salt_len, scram_vectors[i].i, key);
|
scram_vectors[i].i, key);
|
||||||
SCRAM_SHA1_ClientSignature(key, (uint8_t *)auth, strlen(auth), sign);
|
SCRAM_SHA1_ClientSignature(key, (uint8_t *)auth, strlen(auth), sign);
|
||||||
for (j = 0; j < SHA1_DIGEST_SIZE; j++) {
|
for (j = 0; j < SHA1_DIGEST_SIZE; j++) {
|
||||||
sign[j] ^= key[j];
|
sign[j] ^= key[j];
|
||||||
|
|||||||
@@ -12,25 +12,23 @@
|
|||||||
|
|
||||||
/* Test Vectors (from FIPS PUB 180-1) */
|
/* Test Vectors (from FIPS PUB 180-1) */
|
||||||
static char *test_data[] = {
|
static char *test_data[] = {
|
||||||
"abc",
|
"abc", "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
|
||||||
"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
|
|
||||||
"A million repetitions of 'a'",
|
"A million repetitions of 'a'",
|
||||||
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
|
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
|
||||||
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"};
|
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"};
|
||||||
static char *test_results[] = {
|
static char *test_results[] = {"A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D",
|
||||||
"A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D",
|
"84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1",
|
||||||
"84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1",
|
"34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F",
|
||||||
"34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F",
|
"AD5B3FDB CB526778 C2839D2F 151EA753 995E26A0"};
|
||||||
"AD5B3FDB CB526778 C2839D2F 151EA753 995E26A0"};
|
|
||||||
|
|
||||||
static void digest_to_hex(const uint8_t *digest, char *output)
|
static void digest_to_hex(const uint8_t *digest, char *output)
|
||||||
{
|
{
|
||||||
int i,j;
|
int i, j;
|
||||||
char *c = output;
|
char *c = output;
|
||||||
|
|
||||||
for (i = 0; i < SHA1_DIGEST_SIZE/4; i++) {
|
for (i = 0; i < SHA1_DIGEST_SIZE / 4; i++) {
|
||||||
for (j = 0; j < 4; j++) {
|
for (j = 0; j < 4; j++) {
|
||||||
sprintf(c,"%02X", digest[i*4+j]);
|
sprintf(c, "%02X", digest[i * 4 + j]);
|
||||||
c += 2;
|
c += 2;
|
||||||
}
|
}
|
||||||
sprintf(c, " ");
|
sprintf(c, " ");
|
||||||
@@ -39,7 +37,7 @@ static void digest_to_hex(const uint8_t *digest, char *output)
|
|||||||
*(c - 1) = '\0';
|
*(c - 1) = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
size_t k;
|
size_t k;
|
||||||
SHA1_CTX context;
|
SHA1_CTX context;
|
||||||
@@ -49,23 +47,23 @@ int main(int argc, char** argv)
|
|||||||
|
|
||||||
fprintf(stdout, "verifying SHA-1 implementation... ");
|
fprintf(stdout, "verifying SHA-1 implementation... ");
|
||||||
|
|
||||||
for (k = 0; k < ARRAY_SIZE(test_data); k++){
|
for (k = 0; k < ARRAY_SIZE(test_data); k++) {
|
||||||
if (k == 2) {
|
if (k == 2) {
|
||||||
/* this case will be checked below */
|
/* this case will be checked below */
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
copy = strdup(test_data[k]);
|
copy = strdup(test_data[k]);
|
||||||
crypto_SHA1_Init(&context);
|
crypto_SHA1_Init(&context);
|
||||||
crypto_SHA1_Update(&context, (uint8_t*)test_data[k],
|
crypto_SHA1_Update(&context, (uint8_t *)test_data[k],
|
||||||
strlen(test_data[k]));
|
strlen(test_data[k]));
|
||||||
crypto_SHA1_Final(&context, digest);
|
crypto_SHA1_Final(&context, digest);
|
||||||
digest_to_hex(digest, output);
|
digest_to_hex(digest, output);
|
||||||
|
|
||||||
if (strcmp(output, test_results[k])) {
|
if (strcmp(output, test_results[k])) {
|
||||||
fprintf(stdout, "FAIL\n");
|
fprintf(stdout, "FAIL\n");
|
||||||
fprintf(stderr,"* hash of \"%s\" incorrect:\n", test_data[k]);
|
fprintf(stderr, "* hash of \"%s\" incorrect:\n", test_data[k]);
|
||||||
fprintf(stderr,"\t%s returned\n", output);
|
fprintf(stderr, "\t%s returned\n", output);
|
||||||
fprintf(stderr,"\t%s is correct\n", test_results[k]);
|
fprintf(stderr, "\t%s is correct\n", test_results[k]);
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
if (strcmp(copy, test_data[k])) {
|
if (strcmp(copy, test_data[k])) {
|
||||||
@@ -78,18 +76,18 @@ int main(int argc, char** argv)
|
|||||||
/* million 'a' vector we feed separately */
|
/* million 'a' vector we feed separately */
|
||||||
crypto_SHA1_Init(&context);
|
crypto_SHA1_Init(&context);
|
||||||
for (k = 0; k < 1000000; k++)
|
for (k = 0; k < 1000000; k++)
|
||||||
crypto_SHA1_Update(&context, (uint8_t*)"a", 1);
|
crypto_SHA1_Update(&context, (uint8_t *)"a", 1);
|
||||||
crypto_SHA1_Final(&context, digest);
|
crypto_SHA1_Final(&context, digest);
|
||||||
digest_to_hex(digest, output);
|
digest_to_hex(digest, output);
|
||||||
if (strcmp(output, test_results[2])) {
|
if (strcmp(output, test_results[2])) {
|
||||||
fprintf(stdout, "FAIL\n");
|
fprintf(stdout, "FAIL\n");
|
||||||
fprintf(stderr,"* hash of \"%s\" incorrect:\n", test_data[2]);
|
fprintf(stderr, "* hash of \"%s\" incorrect:\n", test_data[2]);
|
||||||
fprintf(stderr,"\t%s returned\n", output);
|
fprintf(stderr, "\t%s returned\n", output);
|
||||||
fprintf(stderr,"\t%s is correct\n", test_results[2]);
|
fprintf(stderr, "\t%s is correct\n", test_results[2]);
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* success */
|
/* success */
|
||||||
fprintf(stdout, "ok\n");
|
fprintf(stdout, "ok\n");
|
||||||
return(0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,76 +16,50 @@
|
|||||||
#define LONG_STRING 1024
|
#define LONG_STRING 1024
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int main (void)
|
int main(void)
|
||||||
{
|
{
|
||||||
char buf1[LONG_STRING];
|
char buf1[LONG_STRING];
|
||||||
char buf2[LONG_STRING];
|
char buf2[LONG_STRING];
|
||||||
char *fp_fmt[] = {
|
char *fp_fmt[] = {"%-1.5f", "%1.5f", "%123.9f", "%10.5f", "% 10.5f",
|
||||||
"%-1.5f",
|
"%+22.9f", "%+4.9f", "%01.3f", "%4f", "%3.1f",
|
||||||
"%1.5f",
|
"%3.2f", "%.0f", "%.1f", NULL};
|
||||||
"%123.9f",
|
double fp_nums[] = {-1.5, 134.21, 91340.2, 341.1234, 0203.9, 0.96,
|
||||||
"%10.5f",
|
0.996, 0.9996, 1.996, 4.136, 0};
|
||||||
"% 10.5f",
|
char *int_fmt[] = {"%-1.5d", "%1.5d", "%123.9d", "%5.5d",
|
||||||
"%+22.9f",
|
"%10.5d", "% 10.5d", "%+22.33d", "%01.3d",
|
||||||
"%+4.9f",
|
"%4d", "0x%x", "0x%04x", NULL};
|
||||||
"%01.3f",
|
long int_nums[] = {-1, 134, 91340, 341, 0203, 0x76543210, 0};
|
||||||
"%4f",
|
int x, y;
|
||||||
"%3.1f",
|
int fail = 0;
|
||||||
"%3.2f",
|
int num = 0;
|
||||||
"%.0f",
|
|
||||||
"%.1f",
|
|
||||||
NULL
|
|
||||||
};
|
|
||||||
double fp_nums[] = { -1.5, 134.21, 91340.2, 341.1234, 0203.9, 0.96, 0.996,
|
|
||||||
0.9996, 1.996, 4.136, 0};
|
|
||||||
char *int_fmt[] = {
|
|
||||||
"%-1.5d",
|
|
||||||
"%1.5d",
|
|
||||||
"%123.9d",
|
|
||||||
"%5.5d",
|
|
||||||
"%10.5d",
|
|
||||||
"% 10.5d",
|
|
||||||
"%+22.33d",
|
|
||||||
"%01.3d",
|
|
||||||
"%4d",
|
|
||||||
"0x%x",
|
|
||||||
"0x%04x",
|
|
||||||
NULL
|
|
||||||
};
|
|
||||||
long int_nums[] = { -1, 134, 91340, 341, 0203, 0x76543210, 0};
|
|
||||||
int x, y;
|
|
||||||
int fail = 0;
|
|
||||||
int num = 0;
|
|
||||||
|
|
||||||
printf ("Testing xmpp_snprintf format codes against system sprintf...\n");
|
printf("Testing xmpp_snprintf format codes against system sprintf...\n");
|
||||||
|
|
||||||
for (x = 0; fp_fmt[x] != NULL ; x++)
|
for (x = 0; fp_fmt[x] != NULL; x++)
|
||||||
for (y = 0; fp_nums[y] != 0 ; y++)
|
for (y = 0; fp_nums[y] != 0; y++) {
|
||||||
{
|
xmpp_snprintf(buf1, sizeof(buf1), fp_fmt[x], fp_nums[y]);
|
||||||
xmpp_snprintf (buf1, sizeof (buf1), fp_fmt[x], fp_nums[y]);
|
sprintf(buf2, fp_fmt[x], fp_nums[y]);
|
||||||
sprintf (buf2, fp_fmt[x], fp_nums[y]);
|
if (strcmp(buf1, buf2)) {
|
||||||
if (strcmp (buf1, buf2))
|
printf("xmpp_snprintf doesn't match Format: "
|
||||||
{
|
"%s\n\txmpp_snprintf = %s\n\tsprintf = %s\n",
|
||||||
printf("xmpp_snprintf doesn't match Format: %s\n\txmpp_snprintf = %s\n\tsprintf = %s\n",
|
fp_fmt[x], buf1, buf2);
|
||||||
fp_fmt[x], buf1, buf2);
|
fail++;
|
||||||
fail++;
|
}
|
||||||
}
|
num++;
|
||||||
num++;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
for (x = 0; int_fmt[x] != NULL ; x++)
|
for (x = 0; int_fmt[x] != NULL; x++)
|
||||||
for (y = 0; int_nums[y] != 0 ; y++)
|
for (y = 0; int_nums[y] != 0; y++) {
|
||||||
{
|
xmpp_snprintf(buf1, sizeof(buf1), int_fmt[x], int_nums[y]);
|
||||||
xmpp_snprintf (buf1, sizeof (buf1), int_fmt[x], int_nums[y]);
|
sprintf(buf2, int_fmt[x], int_nums[y]);
|
||||||
sprintf (buf2, int_fmt[x], int_nums[y]);
|
if (strcmp(buf1, buf2)) {
|
||||||
if (strcmp (buf1, buf2))
|
printf("xmpp_snprintf doesn't match Format: "
|
||||||
{
|
"%s\n\txmpp_snprintf = %s\n\tsprintf = %s\n",
|
||||||
printf("xmpp_snprintf doesn't match Format: %s\n\txmpp_snprintf = %s\n\tsprintf = %s\n",
|
int_fmt[x], buf1, buf2);
|
||||||
int_fmt[x], buf1, buf2);
|
fail++;
|
||||||
fail++;
|
}
|
||||||
}
|
num++;
|
||||||
num++;
|
}
|
||||||
}
|
printf("%d tests failed out of %d.\n", fail, num);
|
||||||
printf ("%d tests failed out of %d.\n", fail, num);
|
return fail != 0 ? 1 : 0;
|
||||||
return fail != 0 ? 1 : 0;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,14 +23,19 @@ int wait_for_connect(sock_t sock)
|
|||||||
fd_set wfds, efds;
|
fd_set wfds, efds;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
FD_ZERO(&wfds); FD_SET(sock, &wfds);
|
FD_ZERO(&wfds);
|
||||||
FD_ZERO(&efds); FD_SET(sock, &efds);
|
FD_SET(sock, &wfds);
|
||||||
|
FD_ZERO(&efds);
|
||||||
|
FD_SET(sock, &efds);
|
||||||
|
|
||||||
ret = select(sock + 1, NULL, &wfds, &efds, NULL);
|
ret = select(sock + 1, NULL, &wfds, &efds, NULL);
|
||||||
if (ret <= 0) return -1;
|
if (ret <= 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
if (FD_ISSET(sock, &efds)) return 0;
|
if (FD_ISSET(sock, &efds))
|
||||||
if (FD_ISSET(sock, &wfds)) return 1;
|
return 0;
|
||||||
|
if (FD_ISSET(sock, &wfds))
|
||||||
|
return 1;
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -45,15 +50,15 @@ int main(int argc, char **argv)
|
|||||||
sock = sock_connect("www.google.com", 80);
|
sock = sock_connect("www.google.com", 80);
|
||||||
|
|
||||||
if (sock < 0) {
|
if (sock < 0) {
|
||||||
sock_shutdown();
|
sock_shutdown();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = wait_for_connect(sock);
|
err = wait_for_connect(sock);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
sock_close(sock);
|
sock_close(sock);
|
||||||
sock_shutdown();
|
sock_shutdown();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
sock_close(sock);
|
sock_close(sock);
|
||||||
|
|||||||
@@ -23,11 +23,11 @@
|
|||||||
/* strtok_s() has appeared in visual studio 2005.
|
/* strtok_s() has appeared in visual studio 2005.
|
||||||
Use own implementation for older versions. */
|
Use own implementation for older versions. */
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
# if (_MSC_VER >= 1400)
|
#if (_MSC_VER >= 1400)
|
||||||
# define strtok_r strtok_s
|
#define strtok_r strtok_s
|
||||||
# else
|
#else
|
||||||
# define strtok_r xmpp_strtok_r
|
#define strtok_r xmpp_strtok_r
|
||||||
# endif
|
#endif
|
||||||
#endif /* _MSC_VER */
|
#endif /* _MSC_VER */
|
||||||
|
|
||||||
static int test_strtok_r(void)
|
static int test_strtok_r(void)
|
||||||
@@ -75,8 +75,8 @@ static int test_strdup_one(xmpp_ctx_t *ctx, const char *s)
|
|||||||
|
|
||||||
if (!s1 || !s2 || strcmp(s1, s2) != 0) {
|
if (!s1 || !s2 || strcmp(s1, s2) != 0) {
|
||||||
rc = -1;
|
rc = -1;
|
||||||
printf("strdup: '%s', xmpp_strdup: '%s'\n",
|
printf("strdup: '%s', xmpp_strdup: '%s'\n", s1 ? s1 : "<NULL>",
|
||||||
s1 ? s1 : "<NULL>", s2 ? s2 : "<NULL>");
|
s2 ? s2 : "<NULL>");
|
||||||
}
|
}
|
||||||
|
|
||||||
free(s1);
|
free(s1);
|
||||||
@@ -92,7 +92,7 @@ static int test_strdup(void)
|
|||||||
size_t i;
|
size_t i;
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
|
|
||||||
static const char *tests[] = { "", "\0", "test", "s p a c e", "\n\r" };
|
static const char *tests[] = {"", "\0", "test", "s p a c e", "\n\r"};
|
||||||
|
|
||||||
ctx = xmpp_ctx_new(NULL, NULL);
|
ctx = xmpp_ctx_new(NULL, NULL);
|
||||||
assert(ctx != NULL);
|
assert(ctx != NULL);
|
||||||
|
|||||||
Reference in New Issue
Block a user