static int auth_handler(int x, void *user) { struct xmpp *xmpp = (struct xmpp *)user; xmpp_printf(xmpp, "<presence><show/></presence>"); xmpp_printf(xmpp, x_roster); return 0; }
static void do_contact_input_string(struct xmpp *xmpp, struct contact *u, char *s) { struct command *cmd; if (s[0] == 0) return; if (s[0] != '/') { if (u->jid[0]) send_message(xmpp, u->type, u->jid, s); else xmpp_printf(xmpp, "%S", s); if (strcmp(u->type, "groupchat")) print_msg(0, u->jid, "<%s> %s\n", me, s); return; } for (cmd = commands; cmd->c; ++cmd) if (cmd->c == s[1] && cmd->fn != 0) { cmd->fn(xmpp, u, s); break; } if (!cmd->c) { send_message(xmpp, u->type, u->jid, s); if (strcmp(u->type, "groupchat")) print_msg(0, u->jid, "<%s> %s\n", me, s); } }
static void join_room(struct xmpp *xmpp, const char *to) { static const char *muc_ns = "http://jabber.org/protocol/muc"; static const char *p = "<presence to='%s'><x xmlns='%s'/></presence>"; xmpp_printf(xmpp, p, to, muc_ns); }
static void send_message(struct xmpp *x, const char *type, const char *to, const char *msg) { const char *m = "<message to='%s' type='%s'><body>%s</body></message>"; xmpp_printf(x, m, to, type, msg); }
int main(int argc, char **argv) { struct xmpp xmpp = { 0 }; int i, port = XMPP_PORT, fd, ret = 1; char *jid = 0, *pwdfile = 0, *srv = 0; for (i = 1; i < argc - 1 && argv[i][0] == '-'; i++) switch (argv[i][1]) { case 'j': jid = argv[++i]; break; case 'k': pwdfile = argv[++i]; break; case 's': srv = argv[++i]; break; case 'l': show_log = atoi(argv[++i]); break; case 'p': port = atoi(argv[++i]); break; default: die_usage(); } if (!jid) die_usage(); xmpp.io_context = &fd; xmpp.send = io_send; xmpp.tls_fn = use_tls ? start_tls : 0; xmpp.stream_fn = stream_handler; xmpp.node_fn = node_handler; xmpp.auth_fn = auth_handler; xmpp.use_sasl = use_sasl; xmpp.jid = jid; read_pw(pwdfile, &xmpp); if (xmpp_init(&xmpp, 4096)) return 1; if (!srv) srv = xmpp.server; fd = tcp_connect(srv, port); if (fd < 0) return 1; if (!(xmpp_start(&xmpp) || process_connection(fd, &xmpp))) ret = 0; xmpp_printf(&xmpp, "</stream:stream>"); xmpp_clean(&xmpp); close(fd); shutdown(fd, 2); return ret; }
static void roster_handler(int x, struct xmpp *xmpp) { struct xml_data *d; char *jid, *name, *sub; for (d = xml_node_data(xml_node_find(x, "query", &xmpp->xml.mem), &xmpp->xml.mem); d; d = xml_data_next(d, &xmpp->xml.mem)) { if (d->type != XML_NODE) continue; jid = xml_node_find_attr(d->value, "jid", &xmpp->xml.mem); name = xml_node_find_attr(d->value, "name", &xmpp->xml.mem); sub = xml_node_find_attr(d->value, "subscription", &xmpp->xml.mem); print_msg("* %s - %s - [%s]\n", name ? name : "", jid, sub); } print_msg("End of roster\n"); for (d = xml_node_data(xml_node_find(x, "query", &xmpp->xml.mem), &xmpp->xml.mem); d; d = xml_data_next(d, &xmpp->xml.mem)) { if (d->type != XML_NODE) continue; jid = xml_node_find_attr(d->value, "jid", &xmpp->xml.mem); if (jid) xmpp_printf(xmpp, "<presence type='probe' to='%s'/>", jid); } }
void xmpp_ball_start_rolling(struct xmpp_server *xs) { /* F**k it */ xmpp_printf(xs,"<stream:stream xmlns:stream=\"http://etherx.jabber.org/streams\" xmlns=\"jabber:client\" to=\"%s\" version=\"1.0\">\n", xs->label); #ifdef CLOWNS xmlDocPtr doc = NULL;/* document pointer */ xmlNodePtr root_node = NULL; xmlNodePtr node = NULL; xmlNodePtr node1 = NULL;/* node pointers */ xmlNsPtr ns_stream = NULL; xmlNsPtr ns_jabber = NULL; /* Well commented because libxml2 is a mindfuck */ /* Starts the document with xml 1.0 */ doc = xmlNewDoc(BAD_CAST "1.0"); /* Create the root node */ root_node = xmlNewNode(NULL, BAD_CAST "stream"); /* Create the stream namespace */ ns_stream = xmlNewNs(root_node, /* Hardcode OK */ BAD_CAST "http://etherx.jabber.org/streams", /* Hardcode OK */ BAD_CAST "stream"); /* Create the jabber namespace */ ns_jabber = xmlNewNs(root_node, /* Hardcode OK */ BAD_CAST "jabber:client", NULL); /* Make the node I just created the first node in the document */ xmlDocSetRootElement(doc, root_node); /* Name of the server, should probably go off sslserver or server tag in conf */ xmlNewProp(root_node, BAD_CAST "to", BAD_CAST xs->label); /* I need to meet the requirements of RFC 3920 for this */ xmlNewProp(root_node, BAD_CAST "version", BAD_CAST "1.0"); /* Sends XML Packet */ xmpp_xml_send(xs, doc); /* We don't need it anymore */ xmlFreeDoc(doc); return; #endif /* CLOWNS */ }
static int auth_handler(int x, void *user) { struct xmpp *xmpp = (struct xmpp *)user; int n; char *name; send_status(xmpp, stats[me_status].show, stats[me_status].msg); xmpp_printf(xmpp, x_roster); name = jid_name(xmpp->jid, &n); if (name) snprintf(me, sizeof(me), "%.*s", n, name); is_ready = 1; return 0; }
static void cmd_leave(struct xmpp *xmpp, struct contact *u, char *s) { char *part; int len; if (s[2] && s[3]) { part = jid_partial(s + 3, &len); if (!part) return; find_contact(u, len, part); } if (!u->jid[0]) return; if (!strcmp(u->type, "groupchat")) xmpp_printf(xmpp, "<presence to='%s' type='unavailable'/>", u->jid); rm_contact(u); }
static void cmd_roster(struct xmpp *xmpp, struct contact *u, char *s) { xmpp_printf(xmpp, x_roster); }
static void request_presence(struct xmpp *xmpp, const char *to) { xmpp_printf(xmpp, "<presence type='probe' to='%s'/>", to); }
static void send_status(struct xmpp *x, const char *status, const char *msg) { const char *p = "<presence><show>%s</show><status>%s</status></presence>"; xmpp_printf(x, p, status, msg); }
static int process_input(int fd, struct xmpp *xmpp) { char buf[BUF_BYTES]; char *s; char *pres = "<presence><show>%s</show><status>%s</status></presence>"; char *epres = "<presence to='%s' type='%s'/>"; char *jpres = "<presence to='%s'>" "<x xmlns='http://jabber.org/protocol/muc'/></presence>"; char *msg = "<message to='%s' type='%s'><body>%s</body></message>"; static const char *show[2] = { "online", "away" }; if (read_line(fd, sizeof(buf), buf)) return -1; if (buf[0] != ':') xmpp_printf(xmpp, msg, jid_to, msg_type, buf); else { switch (buf[1]) { case 'a': status = !status; if (buf[2]) snprintf(status_msg[status], sizeof(status_msg[status]), "%s", buf + 3); xmpp_printf(xmpp, pres, show[status], status_msg[status]); break; case 'g': msg_type = "groupchat"; case 'm': if (buf[1] != 'g') msg_type = "chat"; s = strchr(buf + 3, ' '); if (!s) break; *s++ = 0; snprintf(jid_to, sizeof(jid_to), "%s", buf + 3); xmpp_printf(xmpp, msg, jid_to, msg_type, s); break; case 'r': memcpy(jid_to, jid_from, sizeof(jid_to)); if (!buf[2]) break; xmpp_printf(xmpp, msg, jid_to, buf + 3); break; case 'j': xmpp_printf(xmpp, jpres, buf + 3); break; case 'l': xmpp_printf(xmpp, epres, buf + 3, "unavailable"); break; case 'w': xmpp_printf(xmpp, x_roster); break; case '<': xmpp_printf(xmpp, "%S", buf + 3); break; default: if (jid_to[0]) xmpp_printf(xmpp, msg, jid_to, msg_type, buf); } } return 0; }
/* This function gets an unparsed line from XMPP, and makes it into the xmpp_data struct */ void parse_xmpp_line(struct xmpp_server *xs, const char *buffer) { struct xmpp_data *data = NULL; struct auth_type *at = NULL; xmlNodePtr node = NULL; xmlNodePtr node2 = NULL; xmlNodePtr splnker = NULL; data = xmpp_data_new(); printf("Incoming Packet: %s\n",buffer); data->txt_packet = tstrdup(buffer); data->xml_packet = xmlReadMemory(buffer, strlen(buffer), "noname.xml", NULL, 0); if (data->xml_packet == NULL) { log_entry_printf(NULL,NULL,"X","Failed to parse XML packet from XMPP"); return; } /* Parse out the packet a bit for the one time shit */ node = xmlDocGetRootElement(data->xml_packet); /* Go to the child node pointer */ if ((node = node->xmlChildrenNode) == NULL) { log_entry_printf(NULL,NULL,"X","Root element of packet had no children"); xmpp_data_free(data); return; } /* For all the ugly one time stuff that I'm not going to create a bind type for */ if (!xmlStrcmp(node->name, (const xmlChar *)"features")) { /* features * starttls/ * mechanisms * mechanism - DIGEST-MD5 * mechanism - PLAIN * /mechanisms * /features */ if ((node2 = node->xmlChildrenNode) == NULL) { log_entry_printf(NULL,NULL,"X","features node of XMPP packet had NULL children"); xmpp_data_free(data); return; } while (node2 != NULL) { if (!xmlStrcmp(node2->name, (const xmlChar *)"starttls")) { log_entry_printf(NULL,NULL,"X","Server claims: TLS Supported"); } else if (!xmlStrcmp(node2->name, (const xmlChar *)"register")) { log_entry_printf(NULL,NULL,"X","Server is requiring us to register"); } else if (!xmlStrcmp(node2->name,(const xmlChar *)"mechanisms")) { if ((splnker = node2->xmlChildrenNode) == NULL) { log_entry_printf(NULL,NULL,"X","mechanisms of XMPP packet had NULL children"); xmpp_data_free(data); return; } while (splnker != NULL) { if (!xmlStrcmp(splnker->name,(const xmlChar *)"mechanism")) { at = new_auth_type(); at->name = xmlNodeListGetString(data->xml_packet, splnker->xmlChildrenNode, 1); log_entry_printf(NULL,NULL,"X","Server accepts algorithm type: %s",at->name); /* Add it to the server's list */ xs->auth_types_remote = auth_type_add(xs->auth_types_remote, at); /* Try to get the local algorithm name */ at->algo_name = auth_type_get_algo_info(at->name); } splnker = splnker->next; } log_entry_printf(NULL,NULL,"X","Server Mechanisms complete"); } node2 = node2->next; } xmpp_printf(xs, "<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>"); } xmpp_trigger_match(xs, data); xmpp_data_free(data); }