426#define CLIENT_BUCKETS 53
429#define BUDDY_BUCKETS 53
432#define RESOURCE_BUCKETS 53
435#define XMPP_TLS_NS "urn:ietf:params:xml:ns:xmpp-tls"
438#define STATUS_DISAPPEAR 6
562 iks_filter_delete(client->
filter);
566 iks_stack_delete(client->
stack);
581 const char *
id = obj;
590 const char *
id = arg;
641 if (!(client->
stack = iks_stack_new(8192, 8192))) {
668 if (!cfg || !cfg->clients || !(clientcfg =
xmpp_config_find(cfg->clients, category))) {
672 ao2_ref(clientcfg->client, +1);
673 return clientcfg->client;
765 ast_log(
LOG_ERROR,
"No oauth_clientid or oauth_secret specified, so client '%s' can't be used\n", clientcfg->
name);
770 if (!cfg || !cfg->clients || !(oldclientcfg =
xmpp_config_find(cfg->clients, clientcfg->
name))) {
776 if (strcmp(clientcfg->
user, oldclientcfg->user) ||
777 strcmp(clientcfg->
password, oldclientcfg->password) ||
778 strcmp(clientcfg->
refresh_token, oldclientcfg->refresh_token) ||
779 strcmp(clientcfg->
oauth_clientid, oldclientcfg->oauth_clientid) ||
780 strcmp(clientcfg->
oauth_secret, oldclientcfg->oauth_secret) ||
781 strcmp(clientcfg->
server, oldclientcfg->server) ||
782 (clientcfg->
port != oldclientcfg->port) ||
784 (clientcfg->
priority != oldclientcfg->priority)) {
805 .category =
"general",
814 .category =
"general",
818 .item_offset = offsetof(
struct xmpp_config, clients),
825 .alias =
"jabber.conf",
875 return client->stream_flags & SECURE;
890 ao2_ref(clientcfg->client, +1);
891 return clientcfg->client;
919 !(message_packet = iks_make_msg(
group ? IKS_TYPE_GROUPCHAT : IKS_TYPE_CHAT,
address,
message))) {
924 snprintf(from,
sizeof(from),
"%s@%s/%s", nick, client->
jid->full, nick);
926 snprintf(from,
sizeof(from),
"%s", client->
jid->full);
929 iks_insert_attrib(message_packet,
"from", from);
933 iks_delete(message_packet);
946 iks *invite, *body =
NULL, *
namespace =
NULL;
948 if (!(invite = iks_new(
"message")) || !(body = iks_new(
"body")) || !(
namespace = iks_new(
"x"))) {
953 iks_insert_attrib(invite,
"to",
user);
955 iks_insert_attrib(invite,
"id", client->
mid);
958 iks_insert_cdata(body,
message, 0);
959 iks_insert_node(invite, body);
960 iks_insert_attrib(
namespace,
"xmlns",
"jabber:x:conference");
961 iks_insert_attrib(
namespace,
"jid", room);
962 iks_insert_node(invite,
namespace);
967 iks_delete(
namespace);
983 !(presence = iks_make_pres(level,
NULL)) || !(x = iks_new(
"x"))) {
989 snprintf(from,
sizeof(from),
"%s@%s/%s", nick, client->
jid->full, nick);
990 snprintf(roomid,
sizeof(roomid),
"%s/%s", room, nick);
992 snprintf(from,
sizeof(from),
"%s", client->
jid->full);
993 snprintf(roomid,
sizeof(roomid),
"%s/%s", room,
S_OR(nick, client->
jid->user));
996 iks_insert_attrib(presence,
"to", roomid);
997 iks_insert_attrib(presence,
"from", from);
998 iks_insert_attrib(x,
"xmlns",
"http://jabber.org/protocol/muc");
999 iks_insert_node(presence, x);
1005 iks_delete(presence);
1029 for (i = strlen(mid) - 1; i >= 0; i--) {
1030 if (mid[i] !=
'z') {
1031 mid[i] = mid[i] + 1;
1057 iks_insert_attrib(
request,
"to", clientcfg->pubsubnode);
1060 iks_insert_attrib(
request,
"from", client->
jid->full);
1064 iks_insert_attrib(
request,
"id", client->
mid);
1078 const char *event_type,
unsigned int cachable)
1087 pubsub = iks_insert(
request,
"pubsub");
1088 iks_insert_attrib(pubsub,
"xmlns",
"http://jabber.org/protocol/pubsub");
1089 publish = iks_insert(pubsub,
"publish");
1092 iks_insert_attrib(
item,
"id",
node);
1095 iks *
options, *x, *field_form_type, *field_persist;
1097 options = iks_insert(pubsub,
"publish-options");
1099 iks_insert_attrib(x,
"xmlns",
"jabber:x:data");
1100 iks_insert_attrib(x,
"type",
"submit");
1101 field_form_type = iks_insert(x,
"field");
1102 iks_insert_attrib(field_form_type,
"var",
"FORM_TYPE");
1103 iks_insert_attrib(field_form_type,
"type",
"hidden");
1104 iks_insert_cdata(iks_insert(field_form_type,
"value"),
"http://jabber.org/protocol/pubsub#publish-options", 0);
1105 field_persist = iks_insert(x,
"field");
1106 iks_insert_attrib(field_persist,
"var",
"pubsub#persist_items");
1107 iks_insert_cdata(iks_insert(field_persist,
"value"),
"0", 1);
1116 iks *configure, *x, *field_owner, *field_node_type, *field_node_config,
1117 *field_deliver_payload, *field_persist_items, *field_access_model,
1118 *field_pubsub_collection;
1119 configure = iks_insert(pubsub,
"configure");
1120 x = iks_insert(configure,
"x");
1121 iks_insert_attrib(x,
"xmlns",
"jabber:x:data");
1122 iks_insert_attrib(x,
"type",
"submit");
1123 field_owner = iks_insert(x,
"field");
1124 iks_insert_attrib(field_owner,
"var",
"FORM_TYPE");
1125 iks_insert_attrib(field_owner,
"type",
"hidden");
1126 iks_insert_cdata(iks_insert(field_owner,
"value"),
1127 "http://jabber.org/protocol/pubsub#owner", 39);
1129 field_node_type = iks_insert(x,
"field");
1130 iks_insert_attrib(field_node_type,
"var",
"pubsub#node_type");
1131 iks_insert_cdata(iks_insert(field_node_type,
"value"),
node_type, strlen(
node_type));
1133 field_node_config = iks_insert(x,
"field");
1134 iks_insert_attrib(field_node_config,
"var",
"FORM_TYPE");
1135 iks_insert_attrib(field_node_config,
"type",
"hidden");
1136 iks_insert_cdata(iks_insert(field_node_config,
"value"),
1137 "http://jabber.org/protocol/pubsub#node_config", 45);
1138 field_deliver_payload = iks_insert(x,
"field");
1139 iks_insert_attrib(field_deliver_payload,
"var",
"pubsub#deliver_payloads");
1140 iks_insert_cdata(iks_insert(field_deliver_payload,
"value"),
"1", 1);
1141 field_persist_items = iks_insert(x,
"field");
1142 iks_insert_attrib(field_persist_items,
"var",
"pubsub#persist_items");
1143 iks_insert_cdata(iks_insert(field_persist_items,
"value"),
"1", 1);
1144 field_access_model = iks_insert(x,
"field");
1145 iks_insert_attrib(field_access_model,
"var",
"pubsub#access_model");
1146 iks_insert_cdata(iks_insert(field_access_model,
"value"),
"whitelist", 9);
1148 field_pubsub_collection = iks_insert(x,
"field");
1149 iks_insert_attrib(field_pubsub_collection,
"var",
"pubsub#collection");
1150 iks_insert_cdata(iks_insert(field_pubsub_collection,
"value"), collection_name,
1151 strlen(collection_name));
1164 iks *pubsub, *affiliations, *affiliate;
1168 if (!modify_affiliates) {
1169 ast_log(
LOG_ERROR,
"Could not create IQ for creating affiliations on client '%s'\n", client->
name);
1173 pubsub = iks_insert(modify_affiliates,
"pubsub");
1174 iks_insert_attrib(pubsub,
"xmlns",
"http://jabber.org/protocol/pubsub#owner");
1175 affiliations = iks_insert(pubsub,
"affiliations");
1176 iks_insert_attrib(affiliations,
"node",
node);
1180 affiliate = iks_insert(affiliations,
"affiliation");
1181 iks_insert_attrib(affiliate,
"jid", buddy->
id);
1182 iks_insert_attrib(affiliate,
"affiliation",
"owner");
1188 iks_delete(modify_affiliates);
1199 char *
name,
const char *collection_name)
1201 iks *
node, *pubsub, *create;
1207 pubsub = iks_insert(
node,
"pubsub");
1208 iks_insert_attrib(pubsub,
"xmlns",
"http://jabber.org/protocol/pubsub");
1209 create = iks_insert(pubsub,
"create");
1210 iks_insert_attrib(create,
"node",
name);
1224 iks *
request, *pubsub, *
delete;
1230 pubsub = iks_insert(
request,
"pubsub");
1231 iks_insert_attrib(pubsub,
"xmlns",
"http://jabber.org/protocol/pubsub#owner");
1232 delete = iks_insert(pubsub,
"delete");
1233 iks_insert_attrib(
delete,
"node", node_name);
1257 const char *leaf_name)
1270 const char *oldmsgs,
const char *newmsgs)
1282 mailbox_node = iks_insert(
request,
"mailbox");
1283 iks_insert_attrib(mailbox_node,
"xmlns",
"http://asterisk.org");
1284 iks_insert_attrib(mailbox_node,
"eid", eid_str);
1285 iks_insert_cdata(iks_insert(mailbox_node,
"NEWMSGS"), newmsgs, strlen(newmsgs));
1286 iks_insert_cdata(iks_insert(mailbox_node,
"OLDMSGS"), oldmsgs, strlen(oldmsgs));
1301 const char *device_state,
unsigned int cachable)
1305 char eid_str[20], cachable_str[2];
1321 iks_insert_attrib(
state,
"xmlns",
"http://asterisk.org");
1322 iks_insert_attrib(
state,
"eid", eid_str);
1323 snprintf(cachable_str,
sizeof(cachable_str),
"%u", cachable);
1324 iks_insert_attrib(
state,
"cachable", cachable_str);
1325 iks_insert_cdata(
state, device_state, strlen(device_state));
1338 char oldmsgs[10], newmsgs[10];
1352 snprintf(oldmsgs,
sizeof(oldmsgs),
"%d", mwi_state->
old_msgs);
1353 snprintf(newmsgs,
sizeof(newmsgs),
"%d", mwi_state->
new_msgs);
1391 ast_log(
LOG_ERROR,
"Could not create IQ when creating pubsub unsubscription on client '%s'\n", client->
name);
1395 pubsub = iks_insert(
request,
"pubsub");
1396 iks_insert_attrib(pubsub,
"xmlns",
"http://jabber.org/protocol/pubsub");
1416 if (!cfg || !cfg->global || !
request) {
1417 ast_log(
LOG_ERROR,
"Could not create IQ when creating pubsub subscription on client '%s'\n", client->
name);
1421 pubsub = iks_insert(
request,
"pubsub");
1422 iks_insert_attrib(pubsub,
"xmlns",
"http://jabber.org/protocol/pubsub");
1423 subscribe = iks_insert(pubsub,
"subscribe");
1424 iks_insert_attrib(
subscribe,
"jid", client->
jid->partial);
1427 iks *
options, *x, *sub_options, *sub_type, *sub_depth, *sub_expire;
1428 options = iks_insert(pubsub,
"options");
1430 iks_insert_attrib(x,
"xmlns",
"jabber:x:data");
1431 iks_insert_attrib(x,
"type",
"submit");
1432 sub_options = iks_insert(x,
"field");
1433 iks_insert_attrib(sub_options,
"var",
"FORM_TYPE");
1434 iks_insert_attrib(sub_options,
"type",
"hidden");
1435 iks_insert_cdata(iks_insert(sub_options,
"value"),
1436 "http://jabber.org/protocol/pubsub#subscribe_options", 51);
1437 sub_type = iks_insert(x,
"field");
1438 iks_insert_attrib(sub_type,
"var",
"pubsub#subscription_type");
1439 iks_insert_cdata(iks_insert(sub_type,
"value"),
"items", 5);
1440 sub_depth = iks_insert(x,
"field");
1441 iks_insert_attrib(sub_depth,
"var",
"pubsub#subscription_depth");
1442 iks_insert_cdata(iks_insert(sub_depth,
"value"),
"all", 3);
1443 sub_expire = iks_insert(x,
"field");
1444 iks_insert_attrib(sub_expire,
"var",
"pubsub#expire");
1445 iks_insert_cdata(iks_insert(sub_expire,
"value"),
"presence", 8);
1459 char *item_id, *device_state, *
mailbox, *cachable_str;
1460 int oldmsgs, newmsgs;
1461 iks *
item, *item_content;
1464 item = iks_find(iks_find(iks_find(pak->x,
"event"),
"items"),
"item");
1467 return IKS_FILTER_EAT;
1469 item_id = iks_find_attrib(
item,
"id");
1470 item_content = iks_child(
item);
1471 ast_str_to_eid(&pubsub_eid, iks_find_attrib(item_content,
"eid"));
1473 ast_debug(1,
"Returning here, eid of incoming event matches ours!\n");
1474 return IKS_FILTER_EAT;
1476 if (!strcasecmp(iks_name(item_content),
"state")) {
1477 if ((cachable_str = iks_find_attrib(item_content,
"cachable"))) {
1478 sscanf(cachable_str,
"%30u", &cachable);
1480 device_state = iks_find_cdata(
item,
"state");
1485 return IKS_FILTER_EAT;
1486 }
else if (!strcasecmp(iks_name(item_content),
"mailbox")) {
1488 sscanf(iks_find_cdata(item_content,
"OLDMSGS"),
"%10d", &oldmsgs);
1489 sscanf(iks_find_cdata(item_content,
"NEWMSGS"),
"%10d", &newmsgs);
1493 return IKS_FILTER_EAT;
1495 ast_debug(1,
"Don't know how to handle PubSub event of type %s\n",
1496 iks_name(item_content));
1497 return IKS_FILTER_EAT;
1500 return IKS_FILTER_EAT;
1506 char *node_name, *
error;
1508 iks *orig_request, *orig_pubsub = iks_find(pak->x,
"pubsub");
1511 if (!cfg || !cfg->global) {
1513 return IKS_FILTER_EAT;
1517 ast_debug(1,
"Error isn't a PubSub error, why are we here?\n");
1518 return IKS_FILTER_EAT;
1521 orig_request = iks_child(orig_pubsub);
1522 error = iks_find_attrib(iks_find(pak->x,
"error"),
"code");
1523 node_name = iks_find_attrib(orig_request,
"node");
1525 if (!sscanf(
error,
"%30d", &error_num)) {
1526 return IKS_FILTER_EAT;
1529 if (error_num > 399 && error_num < 500 && error_num != 404) {
1531 "Error performing operation on PubSub node %s, %s.\n", node_name,
error);
1532 return IKS_FILTER_EAT;
1533 }
else if (error_num > 499 && error_num < 600) {
1535 return IKS_FILTER_EAT;
1538 if (!strcasecmp(iks_name(orig_request),
"publish")) {
1542 if (iks_find(iks_find(orig_request,
"item"),
"state")) {
1544 }
else if (iks_find(iks_find(orig_request,
"item"),
"mailbox")) {
1552 iks_insert_node(
request, orig_pubsub);
1559 return IKS_FILTER_EAT;
1560 }
else if (!strcasecmp(iks_name(orig_request),
"subscribe")) {
1568 return IKS_FILTER_EAT;
1615 IKS_PAK_MESSAGE, IKS_RULE_FROM, clientcfg->pubsubnode, IKS_RULE_DONE);
1617 IKS_PAK_IQ, IKS_RULE_SUBTYPE, IKS_TYPE_ERROR, IKS_RULE_DONE);
1627#define BUDDY_OFFLINE 6
1628#define BUDDY_NOT_IN_ROSTER 7
1685 if (
args.argc != 2) {
1686 ast_log(
LOG_ERROR,
"JABBER_STATUS requires 2 arguments: sender and jid.\n");
1691 if (jid.argc < 1 || jid.argc > 2) {
1707 .
name =
"JABBER_STATUS",
1736 if (
args.argc < 2 ||
args.argc > 3) {
1741 if (strchr(
args.jid,
'/')) {
1753 snprintf(nick,
sizeof(nick),
"asterisk");
1755 snprintf(nick,
sizeof(nick),
"%s", clientcfg->client->jid->user);
1758 snprintf(nick,
sizeof(nick),
"%s",
args.nick);
1795 if (
args.argc < 2 ||
args.argc > 3) {
1800 if (strchr(
args.jid,
'/')) {
1817 snprintf(nick,
sizeof(nick),
"asterisk");
1819 snprintf(nick,
sizeof(nick),
"%s", clientcfg->client->jid->user);
1822 snprintf(nick,
sizeof(nick),
"%s",
args.nick);
1910 snprintf(nick,
sizeof(nick),
"asterisk");
1912 snprintf(nick,
sizeof(nick),
"%s", clientcfg->client->jid->user);
1915 snprintf(nick,
sizeof(nick),
"%s",
args.nick);
1938 int timeout, jidlen, resourcelen, found = 0;
1939 struct timeval start;
1960 if (
args.argc < 2 ||
args.argc > 3) {
1975 sscanf(
args.timeout,
"%d", &timeout);
1982 jidlen = strlen(jid.screenname);
1983 resourcelen =
ast_strlen_zero(jid.resource) ? 0 : strlen(jid.resource);
1990 ast_debug(3,
"Waiting for an XMPP message from %s\n",
args.jid);
2001 while (diff < timeout) {
2002 struct timespec ts = { 0, };
2003 struct timeval wait;
2007 ts.tv_sec = wait.tv_sec;
2008 ts.tv_nsec = wait.tv_usec * 1000;
2016 if (res == ETIMEDOUT) {
2017 ast_debug(3,
"No message received from %s in %d seconds\n",
args.jid, timeout);
2023 if (jid.argc == 1) {
2025 if (strncasecmp(jid.screenname,
message->from, jidlen)) {
2030 char *resource = strchr(
message->from,
'/');
2031 if (!resource || strlen(resource) == 0) {
2033 if (strncasecmp(jid.screenname,
message->from, jidlen)) {
2038 if (strncasecmp(jid.screenname,
message->from, jidlen) || strncmp(jid.resource, resource, resourcelen)) {
2080 .
name =
"JABBER_RECEIVE",
2096 int deleted = 0, isold = 0;
2130 char *sender, *dest;
2143 if (!cfg || !cfg->clients || !(clientcfg =
xmpp_config_find(cfg->clients, sender))) {
2148 ast_debug(1,
"Sending message to '%s' from '%s'\n", dest, clientcfg->name);
2154 return res == IKS_OK ? 0 : -1;
2194 "Goodbye. Your status is no longer required.\n"))) {
2198 if (!(iq = iks_new(
"iq")) || !(query = iks_new(
"query")) || !(
item = iks_new(
"item"))) {
2199 ast_log(
LOG_WARNING,
"Could not allocate memory for roster removal of '%s' from client '%s'\n",
2204 iks_insert_attrib(iq,
"from", client->
jid->full);
2205 iks_insert_attrib(iq,
"type",
"set");
2206 iks_insert_attrib(query,
"xmlns",
"jabber:iq:roster");
2207 iks_insert_node(iq, query);
2208 iks_insert_attrib(
item,
"jid",
user);
2209 iks_insert_attrib(
item,
"subscription",
"remove");
2210 iks_insert_node(query,
item);
2213 ast_log(
LOG_WARNING,
"Could not send roster removal request of '%s' from client '%s'\n",
2236 "Greetings! I am the Asterisk Open Source PBX and I want to subscribe to your presence\n"))) {
2238 buddy->
id, client->
name);
2255 return IKS_FILTER_EAT;
2261 if (iks_strcmp(iks_name(
item),
"item")) {
2271 iks_find_attrib(
item,
"jid"), client->
name);
2277 ast_log(
LOG_ERROR,
"Could not allocate buddy '%s' on client '%s'\n", iks_find_attrib(
item,
"jid"),
2284 if (!iks_strcmp(iks_find_attrib(
item,
"subscription"),
"none") ||
2285 !iks_strcmp(iks_find_attrib(
item,
"subscription"),
"from")) {
2301 return IKS_FILTER_EAT;
2313 !(presence = iks_make_pres(level,
desc)) || !(cnode = iks_new(
"c")) || !(
priority = iks_new(
"priority"))) {
2314 ast_log(
LOG_ERROR,
"Unable to allocate stanzas for setting presence status for client '%s'\n", client->
name);
2319 iks_insert_attrib(presence,
"to", to);
2323 iks_insert_attrib(presence,
"from", from);
2326 snprintf(priorityS,
sizeof(priorityS),
"%d", clientcfg->priority);
2327 iks_insert_cdata(
priority, priorityS, strlen(priorityS));
2328 iks_insert_node(presence,
priority);
2329 iks_insert_attrib(cnode,
"node",
"http://www.asterisk.org/xmpp/client/caps");
2330 iks_insert_attrib(cnode,
"ver",
"asterisk-xmpp");
2331 iks_insert_attrib(cnode,
"ext",
"voice-v1 video-v1 camera-v1");
2332 iks_insert_attrib(cnode,
"xmlns",
"http://jabber.org/protocol/caps");
2333 iks_insert_node(presence, cnode);
2338 iks_delete(presence);
2348 if (!(iq = iks_new(
"iq")) || !(query = iks_new(
"query")) || !(ident = iks_new(
"identity")) || !(disco = iks_new(
"feature")) ||
2349 !(google = iks_new(
"feature")) || !(jingle = iks_new(
"feature")) || !(ice = iks_new(
"feature")) || !(rtp = iks_new(
"feature")) ||
2350 !(audio = iks_new(
"feature")) || !(video = iks_new(
"feature"))) {
2351 ast_log(
LOG_ERROR,
"Could not allocate memory for responding to service discovery request from '%s' on client '%s'\n",
2352 pak->from->full, client->
name);
2356 iks_insert_attrib(iq,
"from", client->
jid->full);
2359 iks_insert_attrib(iq,
"to", pak->from->full);
2362 iks_insert_attrib(iq,
"type",
"result");
2363 iks_insert_attrib(iq,
"id", pak->id);
2364 iks_insert_attrib(query,
"xmlns",
"http://jabber.org/protocol/disco#info");
2365 iks_insert_attrib(ident,
"category",
"client");
2366 iks_insert_attrib(ident,
"type",
"pc");
2367 iks_insert_attrib(ident,
"name",
"asterisk");
2368 iks_insert_attrib(disco,
"var",
"http://jabber.org/protocol/disco#info");
2370 iks_insert_attrib(google,
"var",
"http://www.google.com/xmpp/protocol/voice/v1");
2371 iks_insert_attrib(jingle,
"var",
"urn:xmpp:jingle:1");
2372 iks_insert_attrib(ice,
"var",
"urn:xmpp:jingle:transports:ice-udp:1");
2373 iks_insert_attrib(rtp,
"var",
"urn:xmpp:jingle:apps:rtp:1");
2374 iks_insert_attrib(audio,
"var",
"urn:xmpp:jingle:apps:rtp:audio");
2375 iks_insert_attrib(video,
"var",
"urn:xmpp:jingle:apps:rtp:video");
2376 iks_insert_node(iq, query);
2377 iks_insert_node(query, ident);
2378 iks_insert_node(query, google);
2379 iks_insert_node(query, disco);
2380 iks_insert_node(query, jingle);
2381 iks_insert_node(query, ice);
2382 iks_insert_node(query, rtp);
2383 iks_insert_node(query, audio);
2384 iks_insert_node(query, video);
2399 return IKS_FILTER_EAT;
2410 return IKS_FILTER_EAT;
2415 return IKS_FILTER_EAT;
2420 if (iks_find_with_attrib(pak->query,
"feature",
"var",
"urn:xmpp:jingle:1")) {
2429 return IKS_FILTER_EAT;
2444 client->
jid = (iks_find_cdata(pak->query,
"jid")) ? iks_id_new(client->
stack, iks_find_cdata(pak->query,
"jid")) : client->
jid;
2450 if (!(roster = iks_make_iq(IKS_TYPE_GET, IKS_NS_ROSTER))) {
2451 ast_log(
LOG_ERROR,
"Unable to allocate memory for roster request for client '%s'\n", client->
name);
2458 iks_insert_attrib(roster,
"id",
"roster");
2462 iks_filter_add_rule(client->
filter,
xmpp_roster_hook, client, IKS_RULE_TYPE, IKS_PAK_IQ, IKS_RULE_SUBTYPE, IKS_TYPE_RESULT, IKS_RULE_ID,
"roster", IKS_RULE_DONE);
2467 return IKS_FILTER_EAT;
2471static void xmpp_log_hook(
void *data,
const char *xmpp,
size_t size,
int incoming)
2482 ast_verbose(
"\n<--- XMPP sent to '%s' --->\n%s\n<------------->\n", client->
name, xmpp);
2484 ast_verbose(
"\n<--- XMPP received from '%s' --->\n%s\n<------------->\n", client->
name, xmpp);
2495 return IKS_NET_NOCONN;
2502 ret = SSL_write(client->ssl_session,
message,
len);
2514 if (ret != IKS_OK) {
2525 char msg[91 + strlen(
namespace) + 6 + strlen(to) + 16 + 1];
2527 snprintf(msg,
sizeof(msg),
"<?xml version='1.0'?>"
2528 "<stream:stream xmlns:stream='http://etherx.jabber.org/streams' xmlns='"
2529 "%s' to='%s' version='1.0'>",
namespace, to);
2549 ast_log(
LOG_ERROR,
"TLS connection for client '%s' cannot be established. OpenSSL is not available.\n", client->
name);
2552 if (iks_send_raw(client->
parser,
"<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>") == IKS_NET_TLSFAIL) {
2557 client->stream_flags |= TRY_SECURE;
2566static char *openssl_error_string(
void)
2570 BIO *bio = BIO_new(BIO_s_mem());
2572 ERR_print_errors(bio);
2573 len = BIO_get_mem_data(bio, &
buf);
2592 if (!strcmp(iks_name(
node),
"success")) {
2596 }
else if (!strcmp(iks_name(
node),
"failure")) {
2599 }
else if (strcmp(iks_name(
node),
"proceed")) {
2605 ast_log(
LOG_ERROR,
"Somehow we managed to try to start TLS negotiation on client '%s' without OpenSSL support, disconnecting\n", client->
name);
2608 client->ssl_method = SSLv23_method();
2609 if (!(client->ssl_context = SSL_CTX_new((SSL_METHOD *) client->ssl_method))) {
2613 ssl_opts = SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3;
2614 SSL_CTX_set_options(client->ssl_context, ssl_opts);
2616 if (!(client->ssl_session = SSL_new(client->ssl_context))) {
2620 sock = iks_fd(client->
parser);
2621 if (!SSL_set_fd(client->ssl_session, sock)) {
2625 if (SSL_connect(client->ssl_session) <= 0) {
2629 client->stream_flags &= (~TRY_SECURE);
2630 client->stream_flags |= SECURE;
2633 ast_log(
LOG_ERROR,
"TLS connection for client '%s' could not be established, failed to send stream header after negotiation\n",
2638 ast_debug(1,
"TLS connection for client '%s' started with server\n", client->
name);
2645 err = openssl_error_string();
2646 ast_log(
LOG_ERROR,
"TLS connection for client '%s' cannot be established. "
2647 "OpenSSL initialization failed: %s\n", client->
name, err);
2657 char buf[41], sidpass[100];
2659 if (!(iq = iks_new(
"iq")) || !(query = iks_insert(iq,
"query"))) {
2660 ast_log(
LOG_ERROR,
"Stanzas could not be allocated for authentication on client '%s'\n", client->
name);
2665 iks_insert_attrib(iq,
"type",
"set");
2666 iks_insert_cdata(iks_insert(query,
"username"), client->
jid->user, 0);
2667 iks_insert_cdata(iks_insert(query,
"resource"), client->
jid->resource, 0);
2669 iks_insert_attrib(query,
"xmlns",
"jabber:iq:auth");
2670 snprintf(sidpass,
sizeof(sidpass),
"%s%s", iks_find_attrib(
node,
"id"), cfg->
password);
2672 iks_insert_cdata(iks_insert(query,
"digest"),
buf, 0);
2675 iks_filter_add_rule(client->
filter,
xmpp_connect_hook, client, IKS_RULE_TYPE, IKS_PAK_IQ, IKS_RULE_SUBTYPE, IKS_TYPE_RESULT, IKS_RULE_ID, client->
mid, IKS_RULE_DONE);
2676 iks_insert_attrib(iq,
"id", client->
mid);
2680 iks_insert_attrib(iq,
"to", client->
jid->server);
2694 int features,
len = strlen(client->
jid->user) + strlen(cfg->
password) + 3;
2699 if (strcmp(iks_name(
node),
"stream:features")) {
2704 features = iks_stream_features(
node);
2706 if ((features & IKS_STREAM_SASL_MD5) && !
xmpp_is_secure(client)) {
2707 if (iks_start_sasl(client->
parser, IKS_SASL_DIGEST_MD5, (
char*)client->
jid->user, (
char*)cfg->
password) != IKS_OK) {
2708 ast_log(
LOG_ERROR,
"Tried to authenticate client '%s' using SASL DIGEST-MD5 but could not\n", client->
name);
2717 if (!(features & IKS_STREAM_SASL_PLAIN)) {
2718 ast_log(
LOG_ERROR,
"Tried to authenticate client '%s' using SASL PLAIN but server does not support it\n", client->
name);
2722 if (!(auth = iks_new(
"auth"))) {
2723 ast_log(
LOG_ERROR,
"Could not allocate memory for SASL PLAIN authentication for client '%s'\n", client->
name);
2727 iks_insert_attrib(auth,
"xmlns", IKS_NS_XMPP_SASL);
2729 iks_insert_attrib(auth,
"mechanism",
"X-OAUTH2");
2730 iks_insert_attrib(auth,
"auth:service",
"oauth2");
2731 iks_insert_attrib(auth,
"xmlns:auth",
"http://www.google.com/talk/protocol/auth");
2733 iks_insert_attrib(auth,
"mechanism",
"PLAIN");
2736 if (strchr(client->
jid->user,
'/')) {
2739 snprintf(combined,
sizeof(combined),
"%c%s%c%s", 0,
strsep(&
user,
"/"), 0, cfg->
password);
2741 snprintf(combined,
sizeof(combined),
"%c%s%c%s", 0, client->
jid->user, 0, cfg->
password);
2745 iks_insert_cdata(auth,
base64, 0);
2767 if (!strcmp(iks_name(
node),
"success")) {
2772 }
else if (!strcmp(iks_name(
node),
"failure")) {
2775 }
else if (strcmp(iks_name(
node),
"stream:features")) {
2780 features = iks_stream_features(
node);
2782 if (features & IKS_STREAM_BIND) {
2785 if (!(auth = iks_make_resource_bind(client->
jid))) {
2786 ast_log(
LOG_ERROR,
"Failed to allocate memory for stream bind on client '%s'\n", client->
name);
2791 iks_insert_attrib(auth,
"id", client->
mid);
2798 iks_filter_add_rule(client->
filter,
xmpp_connect_hook, client, IKS_RULE_TYPE, IKS_PAK_IQ, IKS_RULE_SUBTYPE, IKS_TYPE_RESULT, IKS_RULE_DONE);
2801 if (features & IKS_STREAM_SESSION) {
2804 if (!(auth = iks_make_session())) {
2805 ast_log(
LOG_ERROR,
"Failed to allocate memory for stream session on client '%s'\n", client->
name);
2809 iks_insert_attrib(auth,
"id",
"auth");
2817 iks_filter_add_rule(client->
filter,
xmpp_connect_hook, client, IKS_RULE_TYPE, IKS_PAK_IQ, IKS_RULE_SUBTYPE, IKS_TYPE_RESULT, IKS_RULE_ID,
"auth", IKS_RULE_DONE);
2826 char secret[160], shasum[320],
message[344];
2827 ikspak *pak = iks_packet(
node);
2829 snprintf(secret,
sizeof(secret),
"%s%s", pak->id, cfg->
password);
2831 snprintf(
message,
sizeof(
message),
"<handshake>%s</handshake>", shasum);
2854 !(iq = iks_new(
"iq")) || !(query = iks_new(
"query")) || !(identity = iks_new(
"identity")) || !(disco = iks_new(
"feature")) ||
2855 !(reg = iks_new(
"feature")) || !(
commands = iks_new(
"feature")) || !(gateway = iks_new(
"feature")) || !(
version = iks_new(
"feature")) ||
2856 !(vcard = iks_new(
"feature")) || !(search = iks_new(
"search")) || !(
item = iks_new(
"item"))) {
2857 ast_log(
LOG_ERROR,
"Failed to allocate stanzas for service discovery get response to '%s' on component '%s'\n",
2858 pak->from->partial, client->
name);
2862 iks_insert_attrib(iq,
"from", clientcfg->user);
2863 iks_insert_attrib(iq,
"to", pak->from->full);
2864 iks_insert_attrib(iq,
"id", pak->id);
2865 iks_insert_attrib(iq,
"type",
"result");
2867 if (!(
node = iks_find_attrib(pak->query,
"node"))) {
2868 iks_insert_attrib(query,
"xmlns",
"http://jabber.org/protocol/disco#info");
2869 iks_insert_attrib(identity,
"category",
"gateway");
2870 iks_insert_attrib(identity,
"type",
"pstn");
2871 iks_insert_attrib(identity,
"name",
"Asterisk The Open Source PBX");
2872 iks_insert_attrib(disco,
"var",
"http://jabber.org/protocol/disco");
2873 iks_insert_attrib(reg,
"var",
"jabber:iq:register");
2874 iks_insert_attrib(
commands,
"var",
"http://jabber.org/protocol/commands");
2875 iks_insert_attrib(gateway,
"var",
"jabber:iq:gateway");
2876 iks_insert_attrib(
version,
"var",
"jabber:iq:version");
2877 iks_insert_attrib(vcard,
"var",
"vcard-temp");
2878 iks_insert_attrib(search,
"var",
"jabber:iq:search");
2880 iks_insert_node(iq, query);
2881 iks_insert_node(query, identity);
2882 iks_insert_node(query, disco);
2883 iks_insert_node(query, reg);
2885 iks_insert_node(query, gateway);
2886 iks_insert_node(query,
version);
2887 iks_insert_node(query, vcard);
2888 iks_insert_node(query, search);
2889 }
else if (!strcasecmp(
node,
"http://jabber.org/protocol/commands")) {
2890 iks_insert_attrib(query,
"xmlns",
"http://jabber.org/protocol/disco#items");
2891 iks_insert_attrib(query,
"node",
"http://jabber.org/protocol/commands");
2892 iks_insert_attrib(
item,
"node",
"confirmaccount");
2893 iks_insert_attrib(
item,
"name",
"Confirm account");
2894 iks_insert_attrib(
item,
"jid", clientcfg->user);
2896 iks_insert_node(iq, query);
2897 iks_insert_node(query,
item);
2898 }
else if (!strcasecmp(
node,
"confirmaccount")) {
2899 iks_insert_attrib(query,
"xmlns",
"http://jabber.org/protocol/disco#info");
2900 iks_insert_attrib(
commands,
"var",
"http://jabber.org/protocol/commands");
2902 iks_insert_node(iq, query);
2905 ast_debug(3,
"Unsupported service discovery info request received with node '%s' on component '%s'\n",
2911 ast_log(
LOG_WARNING,
"Could not send response to service discovery request on component '%s'\n",
2919 iks_delete(gateway);
2923 iks_delete(identity);
2927 return IKS_FILTER_EAT;
2941 !(iq = iks_new(
"iq")) || !(query = iks_new(
"query")) || !(
error = iks_new(
"error")) || !(notacceptable = iks_new(
"not-acceptable")) ||
2942 !(instructions = iks_new(
"instructions"))) {
2943 ast_log(
LOG_ERROR,
"Failed to allocate stanzas for register get response to '%s' on component '%s'\n",
2944 pak->from->partial, client->
name);
2948 iks_insert_attrib(iq,
"from", clientcfg->user);
2949 iks_insert_attrib(iq,
"to", pak->from->full);
2950 iks_insert_attrib(iq,
"id", pak->id);
2951 iks_insert_attrib(iq,
"type",
"result");
2952 iks_insert_attrib(query,
"xmlns",
"jabber:iq:register");
2953 iks_insert_node(iq, query);
2956 iks_insert_attrib(
error,
"code",
"406");
2957 iks_insert_attrib(
error,
"type",
"modify");
2958 iks_insert_attrib(notacceptable,
"xmlns",
"urn:ietf:params:xml:ns:xmpp-stanzas");
2960 iks_insert_node(iq,
error);
2961 iks_insert_node(
error, notacceptable);
2963 ast_log(
LOG_ERROR,
"Received register attempt from '%s' but buddy is not configured on component '%s'\n",
2964 pak->from->partial, client->
name);
2965 }
else if (!(
node = iks_find_attrib(pak->query,
"node"))) {
2966 iks_insert_cdata(instructions,
"Welcome to Asterisk - the Open Source PBX.\n", 0);
2967 iks_insert_node(query, instructions);
2970 ast_log(
LOG_WARNING,
"Received register get to component '%s' using unsupported node '%s' from '%s'\n",
2971 client->
name,
node, pak->from->partial);
2977 ast_log(
LOG_WARNING,
"Could not send response to '%s' for received register get on component '%s'\n",
2978 pak->from->partial, client->
name);
2982 iks_delete(instructions);
2983 iks_delete(notacceptable);
2988 return IKS_FILTER_EAT;
2995 iks *iq, *presence =
NULL, *x =
NULL;
2997 if (!(iq = iks_new(
"iq")) || !(presence = iks_new(
"presence")) || !(x = iks_new(
"x"))) {
2998 ast_log(
LOG_ERROR,
"Failed to allocate stanzas for register set response to '%s' on component '%s'\n",
2999 pak->from->partial, client->
name);
3003 iks_insert_attrib(iq,
"from", client->
jid->full);
3004 iks_insert_attrib(iq,
"to", pak->from->full);
3005 iks_insert_attrib(iq,
"id", pak->id);
3006 iks_insert_attrib(iq,
"type",
"result");
3009 ast_log(
LOG_WARNING,
"Could not send response to '%s' for received register set on component '%s'\n",
3010 pak->from->partial, client->
name);
3014 iks_insert_attrib(presence,
"from", client->
jid->full);
3015 iks_insert_attrib(presence,
"to", pak->from->partial);
3017 iks_insert_attrib(presence,
"id", client->
mid);
3020 iks_insert_attrib(presence,
"type",
"subscribe");
3021 iks_insert_attrib(x,
"xmlns",
"vcard-temp:x:update");
3023 iks_insert_node(presence, x);
3027 pak->from->partial, client->
name);
3032 iks_delete(presence);
3035 return IKS_FILTER_EAT;
3048 !(iq = iks_new(
"iq")) || !(query = iks_new(
"query")) || !(
item = iks_new(
"item")) || !(feature = iks_new(
"feature"))) {
3049 ast_log(
LOG_ERROR,
"Failed to allocate stanzas for service discovery items response to '%s' on component '%s'\n",
3050 pak->from->partial, client->
name);
3054 iks_insert_attrib(iq,
"from", clientcfg->user);
3055 iks_insert_attrib(iq,
"to", pak->from->full);
3056 iks_insert_attrib(iq,
"id", pak->id);
3057 iks_insert_attrib(iq,
"type",
"result");
3058 iks_insert_attrib(query,
"xmlns",
"http://jabber.org/protocol/disco#items");
3059 iks_insert_node(iq, query);
3061 if (!(
node = iks_find_attrib(pak->query,
"node"))) {
3062 iks_insert_attrib(
item,
"node",
"http://jabber.org/protocol/commands");
3063 iks_insert_attrib(
item,
"name",
"Asterisk Commands");
3064 iks_insert_attrib(
item,
"jid", clientcfg->user);
3066 iks_insert_node(query,
item);
3067 }
else if (!strcasecmp(
node,
"http://jabber.org/protocol/commands")) {
3068 iks_insert_attrib(query,
"node",
"http://jabber.org/protocol/commands");
3070 ast_log(
LOG_WARNING,
"Received service discovery items request to component '%s' using unsupported node '%s' from '%s'\n",
3071 client->
name,
node, pak->from->partial);
3076 ast_log(
LOG_WARNING,
"Could not send response to service discovery items request from '%s' on component '%s'\n",
3077 pak->from->partial, client->
name);
3081 iks_delete(feature);
3086 return IKS_FILTER_EAT;
3092 if (!strcmp(iks_name(
node),
"stream:features")) {
3096 if (strcmp(iks_name(
node),
"handshake")) {
3123 ast_debug(3,
"XMPP client '%s' received a message\n", client->
name);
3125 if (!(body = iks_find_cdata(pak->x,
"body"))) {
3178 ast_debug(3,
"Deleted %d messages for client %s from JID %s\n", deleted, client->
name, pak->from->partial);
3197 if (!(iq = iks_new(
"iq")) || !(query = iks_new(
"query"))) {
3202 iks_insert_attrib(iq,
"type",
"get");
3203 iks_insert_attrib(iq,
"to", to);
3204 iks_insert_attrib(iq,
"from", from);
3206 iks_insert_attrib(iq,
"id", client->
mid);
3209 iks_insert_attrib(query,
"xmlns",
"http://jabber.org/protocol/disco#info");
3210 iks_insert_node(iq, query);
3234 ast_debug(2,
"JABBER: Sending Keep-Alive Ping for client '%s'\n", client->
name);
3236 if (!(iq = iks_new(
"iq")) || !(ping = iks_new(
"ping"))) {
3241 iks_insert_attrib(iq,
"type",
"get");
3242 iks_insert_attrib(iq,
"to", to);
3243 iks_insert_attrib(iq,
"from", from);
3246 iks_insert_attrib(iq,
"id", client->
mid);
3250 iks_insert_attrib(ping,
"xmlns",
"urn:xmpp:ping");
3251 iks_insert_node(iq, ping);
3267 char *
type = iks_find_attrib(pak->x,
"type");
3277 if (!pak->from->resource) {
3283 if (strcmp(client->
jid->partial, pak->from->partial)) {
3284 ast_log(
LOG_WARNING,
"Received presence information about '%s' despite not having them in roster on client '%s'\n",
3285 pak->from->partial, client->
name);
3296 ast_log(
LOG_ERROR,
"Could not allocate resource object for resource '%s' of buddy '%s' on client '%s'\n",
3297 pak->from->resource, buddy->
id, client->
name);
3315 if (!(
node = iks_find_attrib(iks_find(pak->x,
"c"),
"node"))) {
3316 node = iks_find_attrib(iks_find(pak->x,
"caps:c"),
"node");
3319 if (!(ver = iks_find_attrib(iks_find(pak->x,
"c"),
"ver"))) {
3320 ver = iks_find_attrib(iks_find(pak->x,
"caps:c"),
"ver");
3337 if (iks_find_with_attrib(pak->x,
"c",
"node",
"http://www.google.com/xmpp/client/caps") ||
3338 iks_find_with_attrib(pak->x,
"caps:c",
"node",
"http://www.google.com/xmpp/client/caps") ||
3339 iks_find_with_attrib(pak->x,
"c",
"node",
"http://www.android.com/gtalk/client/caps") ||
3340 iks_find_with_attrib(pak->x,
"caps:c",
"node",
"http://www.android.com/gtalk/client/caps") ||
3341 iks_find_with_attrib(pak->x,
"c",
"node",
"http://mail.google.com/xmpp/client/caps") ||
3342 iks_find_with_attrib(pak->x,
"caps:c",
"node",
"http://mail.google.com/xmpp/client/caps")) {
3348 ast_log(
LOG_WARNING,
"Could not send discovery information request to resource '%s' of buddy '%s' on client '%s', capabilities may be incomplete\n",
resource->resource, buddy->
id, client->
name);
3354 resource->priority = atoi((iks_find_cdata(pak->x,
"priority")) ? iks_find_cdata(pak->x,
"priority") :
"0");
3359 "Account: %s\r\nJID: %s\r\nResource: %s\r\nStatus: %d\r\nPriority: %d"
3360 "\r\nDescription: %s\r\n",
3372 "Account: %s\r\nJID: %s\r\nStatus: %u\r\n",
3373 client->
name, pak->from->partial, pak->show ? pak->show : IKS_SHOW_UNAVAILABLE);
3396 switch (pak->subtype) {
3397 case IKS_TYPE_SUBSCRIBE:
3401 if ((presence = iks_new(
"presence")) && (
status = iks_new(
"status"))) {
3402 iks_insert_attrib(presence,
"type",
"subscribed");
3403 iks_insert_attrib(presence,
"to", pak->from->full);
3404 iks_insert_attrib(presence,
"from", client->
jid->full);
3407 iks_insert_attrib(presence,
"id", pak->id);
3410 iks_insert_cdata(
status,
"Asterisk has approved your subscription", 0);
3411 iks_insert_node(presence,
status);
3414 ast_log(
LOG_ERROR,
"Could not send subscription acceptance to '%s' from client '%s'\n",
3415 pak->from->partial, client->
name);
3418 ast_log(
LOG_ERROR,
"Could not allocate presence stanzas for accepting subscription from '%s' to client '%s'\n",
3419 pak->from->partial, client->
name);
3423 iks_delete(presence);
3430 case IKS_TYPE_SUBSCRIBED:
3439 pak->from->partial, client->
name);
3477 pak = iks_packet(
node);
3482 if (iks_has_children(
node) && strchr(iks_name(iks_child(
node)),
':')) {
3483 char *node_ns =
NULL;
3485 char *node_name = iks_name(iks_child(
node));
3486 char *aux = strchr(node_name,
':') + 1;
3487 snprintf(attr, strlen(
"xmlns:") + (strlen(node_name) - strlen(aux)),
"xmlns:%s", node_name);
3488 node_ns = iks_find_attrib(iks_child(
node), attr);
3491 pak->query = iks_child(
node);
3518 iks_filter_packet(client->
filter, pak);
3529 pthread_cancel(client->
thread);
3545 if (client->stream_flags & SECURE) {
3546 SSL_shutdown(client->ssl_session);
3547 SSL_CTX_free(client->ssl_context);
3548 SSL_free(client->ssl_session);
3551 client->stream_flags = 0;
3555 iks_disconnect(client->
parser);
3566 struct timeval tv = { .tv_sec = 5, .tv_usec = 0 };
3569 int res = IKS_NET_NOCONN;
3578 iks_parser_reset(client->
parser);
3580 if (!client->
filter && !(client->
filter = iks_filter_new())) {
3586 ast_debug(2,
"Obtaining OAuth access token for client '%s'\n", client->
name);
3593 res = iks_connect_via(client->
parser,
S_OR(clientcfg->server, client->
jid->server), clientcfg->port,
3597 setsockopt(iks_fd(client->
parser), SOL_SOCKET, SO_RCVTIMEO, (
char *)&tv,
sizeof(
struct timeval));
3599 if (res == IKS_NET_NOCONN) {
3600 ast_log(
LOG_ERROR,
"No XMPP connection available when trying to connect client '%s'\n", client->
name);
3602 }
else if (res == IKS_NET_NODNS) {
3603 ast_log(
LOG_ERROR,
"No DNS available for XMPP connection when trying to connect client '%s'\n", client->
name);
3616 struct pollfd pfd = { .events = POLLIN };
3621 pfd.fd = SSL_get_fd(client->ssl_session);
3627 pfd.fd = iks_fd(client->
parser);
3629 res =
ast_poll(&pfd, 1, timeout > 0 ? timeout * 1000 : -1);
3633 len = SSL_read(client->ssl_session, buffer, buf_len);
3636 len = recv(pfd.fd, buffer, buf_len, 0);
3640 }
else if (
len <= 0) {
3650 int len, ret, pos = 0, newbufpos = 0;
3657 if (
len < 0)
return IKS_NET_RWERR;
3669 while (isspace(
buf[pos+1])) {
3685 ast_debug(1,
"JABBER: Detected Google Keep Alive. "
3686 "Sending out Ping request for client '%s'\n", client->
name);
3708 if (ret != IKS_OK) {
3711 ast_debug(3,
"XML parsing successful\n");
3719 pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,
NULL);
3722 *sleep_time =
MIN(60, *sleep_time * 2);
3724 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE,
NULL);
3731 int res = IKS_NET_RWERR;
3732 unsigned int sleep_time = 1;
3735 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE,
NULL);
3743 if (res == IKS_NET_RWERR || client->
timeout == 0) {
3747 res = IKS_NET_RWERR;
3760 if (res == IKS_HOOK) {
3762 }
else if (res == IKS_NET_TLSFAIL) {
3768 if (cfg && cfg->clients) {
3778 if (res == IKS_OK) {
3783 }
else if (res == IKS_NET_RWERR) {
3787 }
else if (res == IKS_NET_NOSOCK) {
3789 }
else if (res == IKS_NET_NOCONN) {
3791 }
else if (res == IKS_NET_NODNS) {
3793 }
else if (res == IKS_NET_NOTSUPP) {
3795 }
else if (res == IKS_NET_DROPPED) {
3797 }
else if (res == IKS_NET_UNKNOWN) {
3799 }
else if (res == IKS_OK) {
3827 char cBuf[1024] =
"";
3828 const char *
url =
"https://www.googleapis.com/oauth2/v3/token";
3833 "CURL(%s,client_id=%s&client_secret=%s&refresh_token=%s&grant_type=refresh_token)",
3838 ast_debug(2,
"Performing OAuth 2.0 authentication for client '%s' using command: %s\n",
3842 ast_log(
LOG_ERROR,
"CURL is unavailable. This is required for OAuth 2.0 authentication of XMPP client '%s'. Please ensure it is loaded.\n",
3847 ast_debug(2,
"OAuth 2.0 authentication for client '%s' returned: %s\n", cfg->
name, cBuf);
3858 ast_log(
LOG_ERROR,
"An error occurred while performing OAuth 2.0 authentication for client '%s': %s\n", cfg->
name, cBuf);
3880 ast_log(
LOG_ERROR,
"Iksemel stream could not be created for client '%s' - client not active\n", cfg->
name);
3888 char resource[strlen(cfg->
user) + strlen(
"/asterisk-xmpp") + 1];
3890 snprintf(resource,
sizeof(resource),
"%s/asterisk-xmpp", cfg->
user);
3897 ast_log(
LOG_ERROR,
"Jabber identity '%s' could not be created for client '%s' - client not active\n", cfg->
user, cfg->
name);
3948 if (!cfg || !cfg->clients || !(clientcfg =
xmpp_config_find(cfg->clients, jabber))) {
3982 query = iks_insert(
request,
"query");
3983 iks_insert_attrib(query,
"xmlns",
"http://jabber.org/protocol/disco#items");
3986 iks_insert_attrib(query,
"node", collection);
4003 if (iks_has_children(pak->query)) {
4004 item = iks_first_tag(pak->query);
4005 ast_verbose(
"Connection %s: %s\nNode name: %s\n", client->
name, client->
jid->partial,
4006 iks_find_attrib(
item,
"node"));
4007 while ((
item = iks_next_tag(
item))) {
4017 return IKS_FILTER_EAT;
4030 ast_log(
LOG_ERROR,
"Could not request pubsub nodes on client '%s' - IQ could not be created\n", client->
name);
4035 IKS_PAK_IQ, IKS_RULE_SUBTYPE, IKS_TYPE_RESULT, IKS_RULE_ID, client->
mid,
4058 e->
command =
"xmpp list nodes";
4060 "Usage: xmpp list nodes <connection> [collection]\n"
4061 " Lists the user's nodes on the respective connection\n"
4062 " ([connection] as configured in xmpp.conf.)\n";
4068 if (
a->argc > 5 ||
a->argc < 4) {
4070 }
else if (
a->argc == 4 ||
a->argc == 5) {
4075 collection =
a->argv[4];
4083 ast_cli(
a->fd,
"Listing pubsub nodes.\n");
4101 if (iks_has_children(pak->query)) {
4102 item = iks_first_tag(pak->query);
4104 iks_find_attrib(
item,
"node"));
4105 while ((
item = iks_next_tag(
item))) {
4114 return IKS_FILTER_EAT;
4122 IKS_PAK_IQ, IKS_RULE_SUBTYPE, IKS_TYPE_RESULT, IKS_RULE_ID, client->
mid,
4144 e->
command =
"xmpp purge nodes";
4146 "Usage: xmpp purge nodes <connection> <node>\n"
4147 " Purges nodes on PubSub server\n"
4148 " as configured in xmpp.conf.\n";
4189 e->
command =
"xmpp delete node";
4191 "Usage: xmpp delete node <connection> <node>\n"
4192 " Deletes a node on PubSub server\n"
4193 " as configured in xmpp.conf.\n";
4222 const char *
name, *collection_name;
4226 e->
command =
"xmpp create collection";
4228 "Usage: xmpp create collection <connection> <collection>\n"
4229 " Creates a PubSub collection node using the account\n"
4230 " as configured in xmpp.conf.\n";
4240 collection_name =
a->argv[4];
4247 ast_cli(
a->fd,
"Creating test PubSub node collection.\n");
4262 const char *
name, *collection_name, *leaf_name;
4266 e->
command =
"xmpp create leaf";
4268 "Usage: xmpp create leaf <connection> <collection> <leaf>\n"
4269 " Creates a PubSub leaf node using the account\n"
4270 " as configured in xmpp.conf.\n";
4280 collection_name =
a->argv[4];
4281 leaf_name =
a->argv[5];
4288 ast_cli(
a->fd,
"Creating test PubSub node collection.\n");
4304 e->
command =
"xmpp set debug {on|off}";
4306 "Usage: xmpp set debug {on|off}\n"
4307 " Enables/disables dumping of XMPP/Jabber packets for debugging purposes.\n";
4313 if (
a->argc != e->
args) {
4317 if (!strncasecmp(
a->argv[e->
args - 1],
"on", 2)) {
4319 ast_cli(
a->fd,
"XMPP Debugging Enabled.\n");
4321 }
else if (!strncasecmp(
a->argv[e->
args - 1],
"off", 3)) {
4323 ast_cli(
a->fd,
"XMPP Debugging Disabled.\n");
4342 e->
command =
"xmpp show connections";
4344 "Usage: xmpp show connections\n"
4345 " Shows state of client and component connections\n";
4351 if (!cfg || !cfg->clients) {
4355 ast_cli(
a->fd,
"Jabber Users and their status:\n");
4363 state =
"Disconnecting";
4366 state =
"Disconnected";
4369 state =
"Connecting";
4372 state =
"Waiting to request TLS";
4375 state =
"Requested TLS";
4378 state =
"Waiting to authenticate";
4381 state =
"Authenticating";
4384 state =
"Retrieving roster";
4387 state =
"Connected";
4418 e->
command =
"xmpp show buddies";
4420 "Usage: xmpp show buddies\n"
4421 " Shows buddy lists of our clients\n";
4427 if (!cfg || !cfg->clients) {
4431 ast_cli(
a->fd,
"XMPP buddy lists\n");
4452 ast_cli(
a->fd,
"\t\t\tGoogle Talk capable: %s\n",
resource->caps.google ?
"yes" :
"no");
4453 ast_cli(
a->fd,
"\t\t\tJingle capable: %s\n",
resource->caps.jingle ?
"yes" :
"no");