|
|
|
@ -71,7 +71,7 @@ static void *aji_recv_loop(void *data);
|
|
|
|
|
static int aji_component_initialize(struct aji_client *client);
|
|
|
|
|
static int aji_client_initialize(struct aji_client *client);
|
|
|
|
|
static int aji_client_connect(void *data, ikspak *pak);
|
|
|
|
|
static void aji_set_presence(struct aji_client *client, char *user, int level, char *desc);
|
|
|
|
|
static void aji_set_presence(struct aji_client *client, char *to, char *from, int level, char *desc);
|
|
|
|
|
static int aji_do_debug(int fd, int argc, char *argv[]);
|
|
|
|
|
static int aji_do_reload(int fd, int argc, char *argv[]);
|
|
|
|
|
static int aji_no_debug(int fd, int argc, char *argv[]);
|
|
|
|
@ -469,7 +469,7 @@ static int aji_act_hook(void *data, int type, iks *node)
|
|
|
|
|
|
|
|
|
|
pak = iks_packet(node);
|
|
|
|
|
|
|
|
|
|
if (client->component == AJI_CLIENT) {
|
|
|
|
|
if (!client->component) { /*client */
|
|
|
|
|
switch (type) {
|
|
|
|
|
case IKS_NODE_START:
|
|
|
|
|
if (client->usetls && !iks_is_secure(client->p)) {
|
|
|
|
@ -577,7 +577,7 @@ static int aji_act_hook(void *data, int type, iks *node)
|
|
|
|
|
return IKS_HOOK;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
} else if (client->state != AJI_CONNECTED && client->component == AJI_COMPONENT) {
|
|
|
|
|
} else if (client->state != AJI_CONNECTED && client->component) {
|
|
|
|
|
switch (type) {
|
|
|
|
|
case IKS_NODE_START:
|
|
|
|
|
if (client->state == AJI_DISCONNECTED) {
|
|
|
|
@ -596,7 +596,7 @@ static int aji_act_hook(void *data, int type, iks *node)
|
|
|
|
|
if(iks_recv(client->p,1) == 2) /*XXX proper result for iksemel library on iks_recv of <handshake/> XXX*/
|
|
|
|
|
client->state = AJI_CONNECTED;
|
|
|
|
|
else
|
|
|
|
|
ast_log(LOG_WARNING,"Jabber didn't seem to handshake\n");
|
|
|
|
|
ast_log(LOG_WARNING,"Jabber didn't seem to handshake, failed to authenicate.\n");
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
@ -659,42 +659,43 @@ static int aji_act_hook(void *data, int type, iks *node)
|
|
|
|
|
static int aji_register_approve_handler(void *data, ikspak *pak)
|
|
|
|
|
{
|
|
|
|
|
struct aji_client *client = ASTOBJ_REF((struct aji_client *) data);
|
|
|
|
|
iks *iq = NULL, *query = NULL, *item = NULL;
|
|
|
|
|
iks *iq = NULL, *presence = NULL, *query = NULL, *x = NULL;
|
|
|
|
|
|
|
|
|
|
iq = iks_new("iq");
|
|
|
|
|
presence = iks_new("presence");
|
|
|
|
|
query = iks_new("query");
|
|
|
|
|
item = iks_new("item");
|
|
|
|
|
|
|
|
|
|
if (client && iq && query && item) {
|
|
|
|
|
x = iks_new("x");
|
|
|
|
|
if (client && iq && presence && query && x) {
|
|
|
|
|
if (!iks_find(pak->query, "remove")) {
|
|
|
|
|
iks_insert_attrib(iq, "from", client->jid->full);
|
|
|
|
|
iks_insert_attrib(iq, "to", pak->from->full);
|
|
|
|
|
iks_insert_attrib(iq, "id", pak->id);
|
|
|
|
|
iks_insert_attrib(iq, "type", "result");
|
|
|
|
|
iks_insert_attrib(query, "xmlns", "jabber:iq:register");
|
|
|
|
|
|
|
|
|
|
iks_insert_node(iq, query);
|
|
|
|
|
iks_send(client->p, iq);
|
|
|
|
|
iks_insert_attrib(iq, "from", pak->from->full);
|
|
|
|
|
iks_insert_attrib(iq, "to", pak->from->full);
|
|
|
|
|
iks_insert_attrib(iq, "id", client->mid);
|
|
|
|
|
|
|
|
|
|
iks_insert_attrib(presence, "from", client->jid->full);
|
|
|
|
|
iks_insert_attrib(presence, "to", pak->from->partial);
|
|
|
|
|
iks_insert_attrib(presence, "id", client->mid);
|
|
|
|
|
ast_aji_increment_mid(client->mid);
|
|
|
|
|
iks_insert_attrib(iq, "type", "set");
|
|
|
|
|
iks_insert_attrib(query, "xmlns", "jabber:iq:roster");
|
|
|
|
|
iks_insert_attrib(item, "subscription", "none");
|
|
|
|
|
iks_insert_attrib(item, "jid", client->jid->full);
|
|
|
|
|
iks_insert_node(query, item);
|
|
|
|
|
iks_send(client->p, iq);
|
|
|
|
|
iks_insert_attrib(presence, "type", "subscribe");
|
|
|
|
|
iks_insert_attrib(x, "xmlns", "vcard-temp:x:update");
|
|
|
|
|
iks_insert_node(presence, x);
|
|
|
|
|
iks_send(client->p, presence);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
ast_log(LOG_ERROR, "Out of memory.\n");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (iq)
|
|
|
|
|
iks_delete(iq);
|
|
|
|
|
if(presence)
|
|
|
|
|
iks_delete(presence);
|
|
|
|
|
if (query)
|
|
|
|
|
iks_delete(query);
|
|
|
|
|
if (item)
|
|
|
|
|
iks_delete(item);
|
|
|
|
|
if (x)
|
|
|
|
|
iks_delete(x);
|
|
|
|
|
ASTOBJ_UNREF(client, aji_client_destroy);
|
|
|
|
|
return IKS_FILTER_EAT;
|
|
|
|
|
}
|
|
|
|
@ -1092,6 +1093,10 @@ static void aji_handle_presence(struct aji_client *client, ikspak *pak)
|
|
|
|
|
ast_log(LOG_NOTICE, "Got presence packet from %s, someone not in our roster!!!!\n", pak->from->partial);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if(client->component && !strcasecmp(iks_find_attrib(pak->x, "type"), "probe")) {
|
|
|
|
|
aji_set_presence(client, pak->from->full, iks_find_attrib(pak->x, "to"), 1, client->statusmessage);
|
|
|
|
|
ast_verbose("what i was looking for \n");
|
|
|
|
|
}
|
|
|
|
|
ASTOBJ_WRLOCK(buddy);
|
|
|
|
|
status = (pak->show) ? pak->show : 6;
|
|
|
|
|
priority = atoi((iks_find_cdata(pak->x, "priority")) ? iks_find_cdata(pak->x, "priority") : "0");
|
|
|
|
@ -1268,8 +1273,28 @@ static void aji_handle_presence(struct aji_client *client, ikspak *pak)
|
|
|
|
|
*/
|
|
|
|
|
static void aji_handle_subscribe(struct aji_client *client, ikspak *pak)
|
|
|
|
|
{
|
|
|
|
|
if(pak->subtype == IKS_TYPE_SUBSCRIBE)
|
|
|
|
|
iks_send(client->p, iks_make_s10n(IKS_TYPE_SUBSCRIBED, iks_find_attrib(pak->x, "from"), "Asterisk has approved subscription"));
|
|
|
|
|
if(pak->subtype == IKS_TYPE_SUBSCRIBE) {
|
|
|
|
|
iks *presence = NULL, *status = NULL;
|
|
|
|
|
presence = iks_new("presence");
|
|
|
|
|
status = iks_new("status");
|
|
|
|
|
if(presence && status) {
|
|
|
|
|
iks_insert_attrib(presence, "type", "subscribed");
|
|
|
|
|
iks_insert_attrib(presence, "to", pak->from->full);
|
|
|
|
|
iks_insert_attrib(presence, "from", iks_find_attrib(pak->x, "to"));
|
|
|
|
|
if(pak->id)
|
|
|
|
|
iks_insert_attrib(presence, "id", pak->id);
|
|
|
|
|
iks_insert_cdata(status, "Asterisk has approved subscription", 0);
|
|
|
|
|
iks_insert_node(presence, status);
|
|
|
|
|
iks_send(client->p, presence);
|
|
|
|
|
} else
|
|
|
|
|
ast_log(LOG_ERROR, "Unable to allocate nodes\n");
|
|
|
|
|
if(presence)
|
|
|
|
|
iks_delete(presence);
|
|
|
|
|
if(status)
|
|
|
|
|
iks_delete(status);
|
|
|
|
|
if(client->component)
|
|
|
|
|
aji_set_presence(client, pak->from->full, iks_find_attrib(pak->x, "to"), 1, client->statusmessage);
|
|
|
|
|
}
|
|
|
|
|
if (option_verbose > 4) {
|
|
|
|
|
switch (pak->subtype) {
|
|
|
|
|
case IKS_TYPE_SUBSCRIBE:
|
|
|
|
@ -1381,7 +1406,7 @@ int ast_aji_invite_chat(struct aji_client *client, char *user, char *room, char
|
|
|
|
|
iks_insert_attrib(invite, "to", user);
|
|
|
|
|
iks_insert_attrib(invite, "id", client->mid);
|
|
|
|
|
ast_aji_increment_mid(client->mid);
|
|
|
|
|
iks_insert_cdata(body, message, strlen(message));
|
|
|
|
|
iks_insert_cdata(body, message, 0);
|
|
|
|
|
iks_insert_attrib(namespace, "xmlns", "jabber:x:conference");
|
|
|
|
|
iks_insert_attrib(namespace, "jid", room);
|
|
|
|
|
iks_insert_node(invite, body);
|
|
|
|
@ -1522,8 +1547,8 @@ static int aji_register_transport2(void *data, ikspak *pak)
|
|
|
|
|
ast_aji_increment_mid(client->mid);
|
|
|
|
|
iks_insert_attrib(regiq, "from", client->user);
|
|
|
|
|
iks_insert_attrib(regquery, "xmlns", "jabber:iq:register");
|
|
|
|
|
iks_insert_cdata(reguser, buddy->user, strlen(buddy->user));
|
|
|
|
|
iks_insert_cdata(regpass, buddy->pass, strlen(buddy->pass));
|
|
|
|
|
iks_insert_cdata(reguser, buddy->user, 0);
|
|
|
|
|
iks_insert_cdata(regpass, buddy->pass, 0);
|
|
|
|
|
iks_insert_node(regiq, regquery);
|
|
|
|
|
iks_insert_node(regquery, reguser);
|
|
|
|
|
iks_insert_node(regquery, regpass);
|
|
|
|
@ -1705,14 +1730,11 @@ static int aji_reconnect(struct aji_client *client)
|
|
|
|
|
if (client->authorized)
|
|
|
|
|
client->authorized = 0;
|
|
|
|
|
|
|
|
|
|
switch (client->component) {
|
|
|
|
|
case AJI_COMPONENT:
|
|
|
|
|
if(client->component)
|
|
|
|
|
res = aji_component_initialize(client);
|
|
|
|
|
break;
|
|
|
|
|
case AJI_CLIENT:
|
|
|
|
|
else
|
|
|
|
|
res = aji_client_initialize(client);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return res;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -1722,7 +1744,7 @@ static int aji_get_roster(struct aji_client *client)
|
|
|
|
|
roster = iks_make_iq(IKS_TYPE_GET, IKS_NS_ROSTER);
|
|
|
|
|
if(roster) {
|
|
|
|
|
iks_insert_attrib(roster, "id", "roster");
|
|
|
|
|
aji_set_presence(client, client->jid->full, 1, client->statusmessage);
|
|
|
|
|
aji_set_presence(client, NULL, client->jid->full, 1, client->statusmessage);
|
|
|
|
|
iks_send(client->p, roster);
|
|
|
|
|
}
|
|
|
|
|
if (roster)
|
|
|
|
@ -1746,7 +1768,7 @@ static int aji_client_connect(void *data, ikspak *pak)
|
|
|
|
|
client->state = AJI_CONNECTING;
|
|
|
|
|
client->jid = (iks_find_cdata(pak->query, "jid")) ? iks_id_new(client->stack, iks_find_cdata(pak->query, "jid")) : client->jid;
|
|
|
|
|
iks_filter_remove_hook(client->f, aji_client_connect);
|
|
|
|
|
if(client->component == AJI_CLIENT)
|
|
|
|
|
if(!client->component) /*client*/
|
|
|
|
|
aji_get_roster(client);
|
|
|
|
|
}
|
|
|
|
|
} else
|
|
|
|
@ -1818,10 +1840,10 @@ int ast_aji_disconnect(struct aji_client *client)
|
|
|
|
|
|
|
|
|
|
/*!
|
|
|
|
|
* \brief set presence of client.
|
|
|
|
|
* \param aji_client struct, user to send it to, level, description.
|
|
|
|
|
* \param aji_client struct, user to send it to, and from, level, description.
|
|
|
|
|
* \return void.
|
|
|
|
|
*/
|
|
|
|
|
static void aji_set_presence(struct aji_client *client, char *user, int level, char *desc)
|
|
|
|
|
static void aji_set_presence(struct aji_client *client, char *to, char *from, int level, char *desc)
|
|
|
|
|
{
|
|
|
|
|
int res = 0;
|
|
|
|
|
iks *presence = iks_make_pres(level, desc);
|
|
|
|
@ -1830,6 +1852,10 @@ static void aji_set_presence(struct aji_client *client, char *user, int level, c
|
|
|
|
|
|
|
|
|
|
iks_insert_cdata(priority, "0", 1);
|
|
|
|
|
if (presence && cnode && client) {
|
|
|
|
|
if(to)
|
|
|
|
|
iks_insert_attrib(presence, "to", to);
|
|
|
|
|
if(from)
|
|
|
|
|
iks_insert_attrib(presence, "from", from);
|
|
|
|
|
iks_insert_attrib(cnode, "node", "http://www.asterisk.org/xmpp/client/caps");
|
|
|
|
|
iks_insert_attrib(cnode, "ver", "asterisk-xmpp");
|
|
|
|
|
iks_insert_attrib(cnode, "ext", "voice-v1");
|
|
|
|
@ -2014,7 +2040,7 @@ static int aji_create_client(char *label, struct ast_variable *var, int debug)
|
|
|
|
|
client->timeout = 50;
|
|
|
|
|
client->message_timeout = 100;
|
|
|
|
|
AST_LIST_HEAD_INIT(&client->messages);
|
|
|
|
|
client->component = AJI_CLIENT;
|
|
|
|
|
client->component = 0;
|
|
|
|
|
ast_copy_string(client->statusmessage, "Online and Available", sizeof(client->statusmessage));
|
|
|
|
|
|
|
|
|
|
if (flag) {
|
|
|
|
@ -2038,7 +2064,7 @@ static int aji_create_client(char *label, struct ast_variable *var, int debug)
|
|
|
|
|
client->debug = (ast_false(var->value)) ? 0 : 1;
|
|
|
|
|
else if (!strcasecmp(var->name, "type")) {
|
|
|
|
|
if (!strcasecmp(var->value, "component"))
|
|
|
|
|
client->component = AJI_COMPONENT;
|
|
|
|
|
client->component = 1;
|
|
|
|
|
} else if (!strcasecmp(var->name, "usetls")) {
|
|
|
|
|
client->usetls = (ast_false(var->value)) ? 0 : 1;
|
|
|
|
|
} else if (!strcasecmp(var->name, "usesasl")) {
|
|
|
|
@ -2062,7 +2088,7 @@ static int aji_create_client(char *label, struct ast_variable *var, int debug)
|
|
|
|
|
ASTOBJ_UNREF(client, aji_client_destroy);
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
client->p = iks_stream_new(((client->component == AJI_CLIENT) ? "jabber:client" : "jabber:component:accept"), client, aji_act_hook);
|
|
|
|
|
client->p = iks_stream_new(((client->component) ? "jabber:component:accept" : "jabber:client"), client, aji_act_hook);
|
|
|
|
|
if (!client->p) {
|
|
|
|
|
ast_log(LOG_ERROR, "Failed to create stream for client '%s'!\n", client->name);
|
|
|
|
|
return 0;
|
|
|
|
@ -2077,7 +2103,7 @@ static int aji_create_client(char *label, struct ast_variable *var, int debug)
|
|
|
|
|
ast_log(LOG_ERROR, "Failed to create filter for client '%s'\n", client->name);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
if (!strchr(client->user, '/') && client->component == AJI_CLIENT) {
|
|
|
|
|
if (!strchr(client->user, '/') && !client->component) { /*client */
|
|
|
|
|
resource = NULL;
|
|
|
|
|
asprintf(&resource, "%s/asterisk", client->user);
|
|
|
|
|
if (resource) {
|
|
|
|
@ -2086,7 +2112,7 @@ static int aji_create_client(char *label, struct ast_variable *var, int debug)
|
|
|
|
|
}
|
|
|
|
|
} else
|
|
|
|
|
client->jid = iks_id_new(client->stack, client->user);
|
|
|
|
|
if (client->component == AJI_COMPONENT) {
|
|
|
|
|
if (client->component) {
|
|
|
|
|
iks_filter_add_rule(client->f, aji_dinfo_handler, client, IKS_RULE_NS, "http://jabber.org/protocol/disco#info", IKS_RULE_DONE);
|
|
|
|
|
iks_filter_add_rule(client->f, aji_ditems_handler, client, IKS_RULE_NS, "http://jabber.org/protocol/disco#items", IKS_RULE_DONE);
|
|
|
|
|
iks_filter_add_rule(client->f, aji_register_query_handler, client, IKS_RULE_SUBTYPE, IKS_TYPE_GET, IKS_RULE_NS, "jabber:iq:register", IKS_RULE_DONE);
|
|
|
|
@ -2094,7 +2120,7 @@ static int aji_create_client(char *label, struct ast_variable *var, int debug)
|
|
|
|
|
} else {
|
|
|
|
|
iks_filter_add_rule(client->f, aji_client_info_handler, client, IKS_RULE_NS, "http://jabber.org/protocol/disco#info", IKS_RULE_DONE);
|
|
|
|
|
}
|
|
|
|
|
if (!strchr(client->user, '/') && client->component == AJI_CLIENT) {
|
|
|
|
|
if (!strchr(client->user, '/') && !client->component) { /*client */
|
|
|
|
|
resource = NULL;
|
|
|
|
|
asprintf(&resource, "%s/asterisk", client->user);
|
|
|
|
|
if (resource) {
|
|
|
|
|