00001 #include "notice.h"
00002 #include "exec.h"
00003 #include "mux.h"
00004 #include "main.h"
00005
00006 void process_presence(jabconn conn, jabpacket packet);
00007 void process_iq_get(jabconn conn, jabpacket packet);
00008 void process_iq_set(jabconn conn, jabpacket packet);
00009 void process_iq_result(jabconn conn, jabpacket packet);
00010 void process_iq_error(jabconn conn, jabpacket packet);
00011
00012 void
00013 jab_on_packet_handler(conn, packet)
00014 jabconn conn;
00015 jabpacket packet;
00016 {
00017 dprintf(dExecution, "Jabber packet handler called...\n");
00018 if (conn->dumpfd != -1) {
00019 char *id = xode_get_attrib(packet->x, "id");
00020 if (conn->dumpid == NULL ||
00021 (id != NULL && !strcmp(conn->dumpid, id))) {
00022 char *tmpstr;
00023
00024 dprintf(dExecution, "Dumping to client...\n");
00025 tmpstr = xode_to_str(packet->x);
00026 if (tmpstr) {
00027 write(conn->dumpfd, tmpstr, strlen(tmpstr) + 1);
00028 }
00029 return;
00030 }
00031 }
00032
00033 jabpacket_reset(packet);
00034 dprintf(dExecution, "Packet: %s\n",
00035 packet->x->name ? packet->x->name : "n/a");
00036 switch (packet->type) {
00037 case JABPACKET_MESSAGE: {
00038 xode x;
00039 char *cbody, *body, *ns, *convbody;
00040 int body_sz;
00041
00042 body = NULL;
00043
00044 dprintf(dExecution, "Received MESSAGE\n");
00045
00046 #ifdef USE_GPGME
00047 x = xode_get_tag(packet->x, "x");
00048 if (x) {
00049 ns = xode_get_attrib(x, "xmlns");
00050 if (ns && !strcmp(ns, NS_ENCRYPTED)) {
00051 cbody = xode_get_data(x);
00052 if (cbody) {
00053 body = JDecrypt(cbody);
00054 if (body) {
00055 trim_message(body);
00056 }
00057 }
00058 }
00059 }
00060 #endif
00061 if (!body) {
00062 x = xode_get_tag(packet->x, "body");
00063 if (x) {
00064 cbody = xode_get_data(x);
00065 if (cbody) {
00066 body = strdup(cbody);
00067 trim_message(body);
00068 }
00069 }
00070 }
00071
00072 if (!unicode_to_str(body, &convbody)) {
00073 convbody = strdup("");
00074 }
00075 body_sz = strlen(convbody);
00076
00077 decode_notice(packet);
00078 dprintf(dExecution, "Rendering message...\n");
00079 exec_process_packet(program, packet, convbody, body_sz);
00080 free(body);
00081 } break;
00082
00083 case JABPACKET_PRESENCE: {
00084 dprintf(dExecution, "Received PRESENCE\n");
00085 dprintf(dExecution, "Contact status change\n");
00086 process_presence(conn, packet);
00087 } break;
00088
00089 case JABPACKET_IQ: {
00090 dprintf(dExecution, "IQ received: %d\n",
00091 packet->subtype);
00092 switch (packet->subtype) {
00093 case JABPACKET__GET: {
00094 dprintf(dExecution,
00095 "Process IQ Get...\n");
00096 process_iq_get(conn, packet);
00097 } break;
00098
00099 case JABPACKET__SET: {
00100 dprintf(dExecution,
00101 "Process IQ Set...\n");
00102 process_iq_set(conn, packet);
00103 } break;
00104
00105 case JABPACKET__RESULT: {
00106 dprintf(dExecution,
00107 "Process IQ Result...\n");
00108 process_iq_result(conn, packet);
00109 } break;
00110
00111 case JABPACKET__ERROR: {
00112 dprintf(dExecution,
00113 "Process IQ Error...\n");
00114 process_iq_error(conn, packet);
00115 } break;
00116
00117 default: {
00118 dprintf(dExecution,
00119 "Unknown subtype.\n");
00120 } break;
00121 }
00122 } break;
00123
00124 default: {
00125 dprintf(dExecution,
00126 "unrecognized packet: %i recieved\n", packet->type);
00127 } break;
00128 }
00129 }
00130
00131 void
00132 jab_on_state_handler(conn, state)
00133 jabconn conn;
00134 int state;
00135 {
00136 static int previous_state = JABCONN_STATE_OFF;
00137
00138 dprintf(dExecution,
00139 "Entering: new state: %i previous_state: %i\n", state, previous_state);
00140 switch (state) {
00141 case JABCONN_STATE_OFF: {
00142 if (previous_state != JABCONN_STATE_OFF) {
00143 dprintf(dExecution,
00144 "The Jabber server has disconnected you: %i\n",
00145 previous_state);
00146 mux_delete_input_source(jab_getfd(jab_c));
00147 jab_reauth = 1;
00148 }
00149 } break;
00150
00151 case JABCONN_STATE_CONNECTED: {
00152 dprintf(dExecution, "JABCONN_STATE_CONNECTED\n");
00153 } break;
00154
00155 case JABCONN_STATE_AUTH: {
00156 dprintf(dExecution, "JABCONN_STATE_AUTH\n");
00157 } break;
00158
00159 case JABCONN_STATE_ON: {
00160 xode x, out;
00161
00162 dprintf(dExecution, "JABCONN_STATE_ON\n");
00163
00164 dprintf(dExecution, "requesting agent list\n");
00165 x = jabutil_iqnew(JABPACKET__GET, NS_AGENTS);
00166 jab_send(conn, x);
00167 xode_free(x);
00168
00169 dprintf(dExecution, "requesting roster\n");
00170 x = jabutil_iqnew(JABPACKET__GET, NS_ROSTER);
00171 jab_send(conn, x);
00172 xode_free(x);
00173
00174 dprintf(dExecution, "requesting agent info\n");
00175 x = jabutil_iqnew(JABPACKET__GET, NS_AGENT);
00176 jab_send(conn, x);
00177 xode_free(x);
00178
00179 if (strcmp((char *)jVars_get(jVarPresence),
00180 "available")) {
00181 xode y;
00182
00183 out = jabutil_presnew(JABPACKET__AVAILABLE,
00184 NULL,
00185 (char *)jVars_get(jVarPresence),
00186 *(int *)jVars_get(jVarPriority));
00187 x = xode_insert_tag(out, "show");
00188 y = xode_insert_cdata(x,
00189 (char *)jVars_get(jVarPresence),
00190 strlen((char *)jVars_get(jVarPresence)));
00191 }
00192 else {
00193 out = jabutil_presnew(JABPACKET__AVAILABLE,
00194 NULL,
00195 NULL,
00196 *(int *)jVars_get(jVarPriority));
00197 }
00198 jab_send(conn, out);
00199 xode_free(out);
00200 } break;
00201
00202 default: {
00203 dprintf(dExecution, "UNKNOWN state: %i\n", state);
00204 } break;
00205 }
00206 previous_state = state;
00207 }
00208
00209 void
00210 process_presence(conn, packet)
00211 jabconn conn;
00212 jabpacket packet;
00213 {
00214 char *from = packet->from->full;
00215 if (!from) {
00216 dprintf(dExecution, "Presence processing with no from.\n");
00217 return;
00218 }
00219
00220 switch (packet->subtype) {
00221 case JABPACKET__SUBSCRIBE: {
00222 xode x;
00223
00224 x = jabutil_presnew(JABPACKET__SUBSCRIBED,
00225 from, NULL, -1);
00226 jab_send(conn, x);
00227 decode_notice(packet);
00228 dprintf(dExecution,
00229 "Rendering subscribe message...\n");
00230 exec_process_packet(program, packet, "", 0);
00231 xode_free(x);
00232 } break;
00233
00234 case JABPACKET__UNSUBSCRIBE: {
00235 xode x;
00236
00237 x = jabutil_presnew(JABPACKET__UNSUBSCRIBED,
00238 from, NULL, -1);
00239 jab_send(conn, x);
00240 decode_notice(packet);
00241 dprintf(dExecution,
00242 "Rendering unsubscribe message...\n");
00243 exec_process_packet(program, packet, "", 0);
00244 xode_free(x);
00245 } break;
00246
00247 case JABPACKET__SUBSCRIBED: {
00248 dprintf(dExecution,
00249 "Rendering subscribed message...\n");
00250 exec_process_packet(program, packet, "", 0);
00251 } break;
00252
00253 case JABPACKET__UNSUBSCRIBED: {
00254 dprintf(dExecution,
00255 "Rendering unsubscribed message...\n");
00256 exec_process_packet(program, packet, "", 0);
00257 } break;
00258
00259 case JABPACKET__INVISIBLE:
00260 case JABPACKET__UNAVAILABLE:
00261 case JABPACKET__AVAILABLE: {
00262 xode x;
00263 char *jid, *pos, *ns;
00264 int ret;
00265
00266 ret = contact_status_change(packet);
00267 if (ret) {
00268 if (time(0) > (jab_connect_time + 30)) {
00269 dprintf(dExecution, "Decoding notice...\n");
00270 decode_notice(packet);
00271 dprintf(dExecution, "Rendering presence message\n");
00272 exec_process_packet(
00273 program,
00274 packet,
00275 "",
00276 0);
00277 }
00278 }
00279
00280 jid = xode_get_attrib(packet->x, "from");
00281 if (!jid) {
00282 break;
00283 }
00284
00285 pos = (char *) strchr(jid, '/');
00286 if (pos) {
00287 *pos = '\0';
00288 }
00289
00290 x = xode_get_tag(packet->x, "x");
00291 if (!x) {
00292 break;
00293 }
00294
00295 ns = xode_get_attrib(x, "xmlns");
00296 if (!ns) {
00297 break;
00298 }
00299
00300
00301 dprintf(dExecution, "presence ns: %s\n", ns);
00302 #ifdef USE_GPGME
00303 if (!strcmp(ns, NS_SIGNED)) {
00304 char *signature, *status;
00305
00306 dprintf(dExecution,
00307 "Processing gpg signature...\n");
00308
00309 signature = xode_get_data(x);
00310 status = xode_get_tagdata(packet->x, "status");
00311 if (signature && status) {
00312 dprintf(dExecution,
00313 "Signature[%d] is:\n%s\n",
00314 jid, signature);
00315 JUpdateKeyList(jid, status, signature);
00316 }
00317 }
00318 #endif
00319 } break;
00320
00321 case JABPACKET__ERROR: {
00322 char *errormsg;
00323
00324 errormsg = xode_get_tagdata(packet->x, "error");
00325 dprintf(dExecution,
00326 "Error from %s: %s\n",
00327 from ? from : "n/a",
00328 errormsg ? errormsg : "n/a");
00329 } break;
00330
00331 default: {
00332 dprintf(dExecution,
00333 "Unknown or ignored subtype from %s.\n",
00334 from ? from : "n/a");
00335 } break;
00336 }
00337 }
00338
00339 void
00340 process_iq_result(conn, packet)
00341 jabconn conn;
00342 jabpacket packet;
00343 {
00344 char *id, *ns;
00345 xode x, out;
00346
00347 id = xode_get_attrib(packet->x, "id");
00348 if (!id) {
00349 dprintf(dExecution, "No ID!\n");
00350 }
00351
00352 x = xode_get_tag(packet->x, "query");
00353 if (!x) {
00354 dprintf(dExecution, "No query\n");
00355 return;
00356 }
00357
00358 ns = xode_get_attrib(x, "xmlns");
00359 if (!ns) {
00360 dprintf(dExecution, "No NS!\n");
00361 return;
00362 }
00363
00364 dprintf(dExecution, "ns: %s\n", ns);
00365 if (strcmp(ns, NS_ROSTER) == 0) {
00366 xode y;
00367
00368 y = xode_get_tag(x, "item");
00369 while (y) {
00370 char *jid, *sub, *name, *group;
00371 char *resource = NULL;
00372 char *pos;
00373 xode z;
00374
00375 jid = xode_get_attrib(y, "jid");
00376 if (!jid)
00377 break;
00378 sub = xode_get_attrib(y, "subscription");
00379 name = xode_get_attrib(y, "name");
00380 z = xode_get_tag(y, "group");
00381 group = xode_get_data(z);
00382
00383 pos = (char *) strchr(jid, '/');
00384 if (pos) {
00385 *pos = '\0';
00386 resource = pos + 1;
00387 }
00388
00389 dprintf(dExecution, "Buddy: %s/%s(%s) %s %s\n",
00390 jid ? jid : "n/a",
00391 resource ? resource : "n/a",
00392 group ? group : "n/a",
00393 sub ? sub : "n/a",
00394 name ? name : "n/a");
00395 update_contact_status(jid, NULL, resource);
00396 if (name) {
00397 update_nickname(jid, name);
00398 }
00399 if (group) {
00400 update_group(jid, group);
00401 }
00402 y = xode_get_nextsibling(y);
00403 }
00404 }
00405 else if (strcmp(ns, NS_AGENTS) == 0) {
00406 xode y;
00407
00408 y = xode_get_tag(x, "agent");
00409 while (y) {
00410 char *jid, *name, *service;
00411 int flags = AGENT_NONE;
00412
00413 jid = xode_get_attrib(y, "jid");
00414 if (!jid)
00415 break;
00416 name = xode_get_tagdata(y, "name");
00417 service = xode_get_tagdata(y, "service");
00418 if (xode_get_tag(y, "transport")) {
00419 flags |= AGENT_TRANSPORT;
00420 }
00421 if (xode_get_tag(y, "register")) {
00422 flags |= AGENT_REGISTER;
00423 }
00424 if (xode_get_tag(y, "groupchat")) {
00425 flags |= AGENT_GROUPCHAT;
00426 }
00427 if (xode_get_tag(y, "search")) {
00428 flags |= AGENT_SEARCH;
00429 }
00430 insert_into_agent_list(jid, name, service, flags);
00431 dprintf(dExecution, "Agent[%s]: %s [%s]\n",
00432 name ? name : "n/a",
00433 jid ? jid : "n/a",
00434 service ? service : "n/a");
00435 y = xode_get_nextsibling(y);
00436 }
00437 }
00438 else if (strcmp(ns, NS_AGENT) == 0) {
00439 char *name, *url, *reg;
00440
00441 name = xode_get_tagdata(x, "name");
00442 url = xode_get_tagdata(x, "url");
00443 reg = xode_get_tagdata(x, "register");
00444 dprintf(dExecution, "agent: %s - %s\n",
00445 name ? name : "n/a",
00446 url ? url : "n/a");
00447 }
00448 else if (strcmp(ns, NS_VERSION) == 0) {
00449 char *name, *ver, *os;
00450
00451 name = xode_get_tagdata(x, "name");
00452 ver = xode_get_tagdata(x, "version");
00453 os = xode_get_tagdata(x, "os");
00454 dprintf(dExecution, "version: %s - %s - %s\n",
00455 name ? name : "n/a",
00456 ver ? ver : "n/a",
00457 os ? os : "n/a");
00458 }
00459 else if (strcmp(ns, NS_AUTH) == 0) {
00460 char *seq, *tok;
00461 xode password, digest;
00462
00463 password = xode_get_tag(x, "password");
00464 if (password)
00465 conn->auth_password = 1;
00466 else
00467 conn->auth_password = 0;
00468
00469 digest = xode_get_tag(x, "digest");
00470 if (digest)
00471 conn->auth_digest = 1;
00472 else
00473 conn->auth_digest = 0;
00474
00475 seq = xode_get_tagdata(x, "sequence");
00476 if (seq)
00477 conn->sequence = atoi(seq);
00478 else
00479 conn->sequence = 0;
00480
00481 tok = xode_get_tagdata(x, "token");
00482 if (tok)
00483 conn->token = tok;
00484 else
00485 conn->token = NULL;
00486
00487 if (seq && tok)
00488 conn->auth_0k = 1;
00489 else
00490 conn->auth_0k = 0;
00491
00492
00493
00494
00495 dprintf(dExecution,
00496 "auth support:\npassword=%s\ndigest=%s\n0k=%s %s %s\n",
00497 password ? "supported" : "not supported",
00498 digest ? "supported" : "not supported",
00499 (seq && tok) ? "supported" : "not supported",
00500 (seq && tok) ? seq : "",
00501 (seq && tok) ? tok : "");
00502 }
00503
00504 return;
00505 }
00506
00507 void
00508 process_iq_set(conn, packet)
00509 jabconn conn;
00510 jabpacket packet;
00511 {
00512 xode x;
00513 char *ns;
00514
00515 x = xode_get_tag(packet->x, "query");
00516 ns = xode_get_attrib(x, "xmlns");
00517 if (strcmp(ns, NS_ROSTER) == 0) {
00518 xode y;
00519 char *jid, *sub, *name, *ask;
00520
00521 y = xode_get_tag(x, "item");
00522 jid = xode_get_attrib(y, "jid");
00523 sub = xode_get_attrib(y, "subscription");
00524 name = xode_get_attrib(y, "name");
00525 ask = xode_get_attrib(y, "ask");
00526 dprintf(dExecution, "iq set request: %s %s %s %s\n",
00527 jid ? jid : "n/a",
00528 sub ? sub : "n/a",
00529 name ? name : "n/a",
00530 ask ? ask : "n/a");
00531
00532 if (sub) {
00533 if (!strcmp(sub, "remove") || !strcmp(sub, "none")) {
00534 if (!jid) {
00535 dprintf(dExecution,
00536 "No jid specified!\n");
00537 return;
00538 }
00539 remove_from_contact_list(jid);
00540 dprintf(dExecution, "Contact %s removed\n", jid);
00541 return;
00542 }
00543 }
00544 }
00545 }
00546
00547 void
00548 process_iq_get(conn, packet)
00549 jabconn conn;
00550 jabpacket packet;
00551 {
00552 }
00553
00554 void
00555 process_iq_error(conn, packet)
00556 jabconn conn;
00557 jabpacket packet;
00558 {
00559 xode x;
00560 char *code, *desc;
00561
00562 x = xode_get_tag(packet->x, "error");
00563 code = xode_get_attrib(x, "code");
00564 desc = xode_get_tagdata(packet->x, "error");
00565 dprintf(dExecution, "Received error: %s\n",
00566 desc ? desc : "n/a");
00567 fprintf(stderr, "Error %s: %s\n",
00568 code ? code : "n/a",
00569 desc ? desc : "n/a");
00570 switch (atoi(code)) {
00571 case 302:
00572 break;
00573 case 400:
00574
00575 break;
00576 case 401:
00577
00578 break;
00579 case 402:
00580
00581 break;
00582 case 403:
00583
00584 break;
00585 case 404:
00586
00587 break;
00588 case 405:
00589
00590 break;
00591 case 406:
00592
00593 break;
00594 case 407:
00595
00596 break;
00597 case 408:
00598
00599 break;
00600 case 409:
00601
00602 break;
00603 case 500:
00604 break;
00605 case 501:
00606 break;
00607 case 502:
00608 break;
00609 case 503:
00610 break;
00611 case 504:
00612 break;
00613 default:
00614 break;
00615 }
00616 }