1 /*
2 * Handles incoming and creates outgoing SNAC packets
3 * for the family 4 (icbm) commands.
4 *
5 * climm Copyright (C) © 2001-2007 Rüdiger Kuhlmann
6 *
7 * climm is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; version 2 dated June, 1991.
10 *
11 * climm is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
14 * License for more details.
15 *
16 * In addition, as a special exception permission is granted to link the
17 * code of this release of climm with the OpenSSL project's "OpenSSL"
18 * library, and distribute the linked executables. You must obey the GNU
19 * General Public License in all respects for all of the code used other
20 * than "OpenSSL". If you modify this file, you may extend this exception
21 * to your version of the file, but you are not obligated to do so. If you
22 * do not wish to do so, delete this exception statement from your version
23 * of this file.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this package; if not, write to the Free Software
27 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
28 * 02111-1307, USA.
29 *
30 * $Id: oscar_icbm.c 2788 2009-04-11 22:05:30Z kuhlmann $
31 */
32
33 #include "climm.h"
34 #include <assert.h>
35 #include "oscar_base.h"
36 #include "oscar_tlv.h"
37 #include "oscar_snac.h"
38 #include "oscar_icbm.h"
39 #include "oscar_oldicq.h"
40 #include "packet.h"
41 #include "contact.h"
42 #include "connection.h"
43 #include "conv.h"
44 #include "im_request.h"
45 #include "im_response.h"
46 #include "buildmark.h"
47 #include "oscar_dc.h"
48 #include "oscar_dc_file.h"
49 #include "util_ui.h"
50 #include "preferences.h"
51
52 static void SnacCallbackType2Ack (Event *event);
53 static void SnacCallbackType2 (Event *event);
54 static void SnacCallbackType2Cancel (Event *event);
55 static void SnacCallbackIgnore (Event *event);
56
57 #define PEEK_REFID 0x3d1db11f
58
59 /*
60 * SRV_ICBMERR - SNAC(4,1)
61 */
JUMP_SNAC_F(SnacSrvIcbmerr)62 JUMP_SNAC_F(SnacSrvIcbmerr)
63 {
64 Connection *serv = event->conn;
65 UWORD err = PacketReadB2 (event->pak);
66
67 if ((event->pak->ref == PEEK_REFID) && (err == 0xe || err == 4 || err == 9))
68 {
69 if (err == 0xe || err == 9)
70 rl_print (i18n (2017, "The user is online, but possibly invisible.\n"));
71 else
72 rl_print (i18n (2564, "The user couldn't be detected to be online.\n"));
73 return;
74 }
75
76 event = QueueDequeue (serv, QUEUE_TYPE2_RESEND_ACK, event->pak->ref);
77 if (event && event->callback)
78 event->callback (event);
79 else if (err == 4)
80 rl_print (i18n (2022, "The user is offline.\n"));
81 else if (err != 0xd)
82 rl_printf (i18n (2191, "Instant message error: %d.\n"), err);
83 }
84
85 /*
86 * CLI_SETICBM - SNAC(4,2)
87 */
SnacCliSeticbm(Server * serv)88 void SnacCliSeticbm (Server *serv)
89 {
90 Packet *pak;
91
92 pak = SnacC (serv, 4, 2, 0, 0);
93 PacketWriteB2 (pak, 0);
94 PacketWriteB2 (pak, 0);
95 PacketWriteB2 (pak, 3);
96 PacketWriteB2 (pak, 8000);
97 PacketWriteB2 (pak, 999);
98 PacketWriteB2 (pak, 999);
99 PacketWriteB2 (pak, 0);
100 PacketWriteB2 (pak, 0);
101 SnacSend (serv, pak);
102 }
103
104 /*
105 * CLI_REQICBM - SNAC(4,4)
106 */
107
108 /* implemented as macro */
109
110 /*
111 * SRV_REPLYICBM - SNAC(4,5)
112 */
JUMP_SNAC_F(SnacSrvReplyicbm)113 JUMP_SNAC_F(SnacSrvReplyicbm)
114 {
115 SnacCliSeticbm (event->conn->serv);
116 }
117
JUMP_SNAC_F(SnacSrvAckmsg)118 JUMP_SNAC_F(SnacSrvAckmsg)
119 {
120 Server *serv = event->conn->serv;
121 /* UDWORD midtime, midrand; */
122 UWORD msgtype, seq_dc;
123 Contact *cont;
124 Packet *pak;
125 strc_t ctext;
126 char *text;
127
128 pak = event->pak;
129 /*midtime*/PacketReadB4 (pak);
130 /*midrand*/PacketReadB4 (pak);
131 PacketReadB2 (pak);
132 cont = PacketReadCont (pak, serv);
133 PacketReadB2 (pak);
134 PacketReadData (pak, NULL, PacketRead2 (pak));
135 PacketRead2 (pak);
136 seq_dc = PacketRead2 (pak);
137 PacketRead4 (pak);
138 PacketRead4 (pak);
139 PacketRead4 (pak);
140 msgtype = PacketRead2 (pak);
141 PacketRead2 (pak);
142 PacketRead2 (pak);
143 ctext = PacketReadL2Str (pak, NULL);
144
145 if (!cont)
146 return;
147
148 text = strdup (c_in_to_split (ctext, cont));
149 if (msgtype == MSG_NORM)
150 {
151 strc_t cctmp;
152 PacketRead4 (pak);
153 PacketRead4 (pak);
154 cctmp = PacketReadL2Str (pak, NULL);
155 if (!strcmp (cctmp->txt, CAP_GID_UTF8))
156 {
157 free (text);
158 text = strdup (ctext->txt);
159 }
160 }
161
162 event = QueueDequeue (serv->conn, QUEUE_TYPE2_RESEND, seq_dc);
163 if (!event)
164 event = QueueDequeue2 (serv->conn, QUEUE_TYPE2_RESEND, 0, cont);
165
166 if ((msgtype & 0x300) == 0x300)
167 IMSrvMsg (cont, NOW, CV_ORIGIN_v8, msgtype, text);
168 if (event)
169 {
170 Message *msg = event->data;
171 assert (msg);
172 assert (msg->cont == cont);
173 if ((msg->plain_message || msg->send_message) && !msg->otrinjected && (msgtype & 0x300) != 0x300)
174 {
175 msg->type = INT_MSGACK_TYPE2;
176 IMIntMsgMsg (msg, NOW, ims_offline);
177 if ((~cont->oldflags & CONT_SEENAUTO) && strlen (text) && msg->send_message && strcmp (text, msg->send_message))
178 {
179 IMSrvMsg (cont, NOW, CV_ORIGIN_v8, MSG_AUTO, text);
180 cont->oldflags |= CONT_SEENAUTO;
181 }
182 }
183 MsgD (msg);
184 event->data = NULL;
185 EventD (event);
186 }
187 free (text);
188 }
189
SnacCallbackIgnore(Event * event)190 void SnacCallbackIgnore (Event *event)
191 {
192 EventD (event);
193 }
194
195 /*
196 * CLI_SENDMSG - SNAC(4,6)
197 */
SnacCliSendmsg1(Server * serv,Message * msg)198 static UBYTE SnacCliSendmsg1 (Server *serv, Message *msg)
199 {
200 Packet *pak;
201 Event *event;
202 Contact *cont;
203 UDWORD mtime = rand() % 0xffff, mid = rand() % 0xffff;
204 int remenc;
205 strc_t str;
206 int enc = ENC_LATIN1, icqenc = 0, icqcol;
207
208 assert (serv);
209 assert (msg);
210 cont = msg->cont;
211 assert (cont);
212
213 remenc = ContactPrefVal (cont, CO_ENCODING);
214
215 if (cont->status != ims_offline &&
216 HAS_CAP (cont->caps, CAP_UTF8) &&
217 !ConvFits (msg->send_message, ENC_ASCII) &&
218 !(cont->dc && cont->dc->id1 == (time_t)0xffffff42 &&
219 (cont->dc->id2 & 0x7fffffff) < (time_t)0x00040c00)) /* exclude old mICQ */
220 {
221 enc = ENC_UCS2BE;
222 icqenc = 2;
223 }
224 else
225 {
226 /* too bad, there's nothing we can do */
227 enc = remenc;
228 icqenc = 3;
229 }
230 if (msg->type != 1)
231 {
232 icqenc = msg->type;
233 enc = ENC_LATIN9;
234 }
235
236 icqcol = atoi (msg->send_message); /* FIXME FIXME WIXME */
237 str = ConvTo (msg->send_message, enc);
238 if (str->len > 700)
239 {
240 msg->maxsize = 700; /* FIXME: not 450? What is the real max? */
241 msg->maxenc = enc;
242 return RET_DEFER;
243 }
244
245 pak = SnacC (serv, 4, 6, 0, 0);
246 PacketWriteB4 (pak, mtime);
247 PacketWriteB4 (pak, mid);
248 PacketWriteB2 (pak, 1 /* format */);
249 PacketWriteCont (pak, cont);
250
251 PacketWriteTLV (pak, 2);
252 PacketWriteTLV (pak, 1281);
253 if (icqenc == 2)
254 PacketWriteB2 (pak, 0x0106);
255 else
256 PacketWrite1 (pak, 0x01);
257 PacketWriteTLVDone (pak);
258 PacketWriteTLV (pak, 257);
259 PacketWriteB2 (pak, icqenc);
260 PacketWriteB2 (pak, icqcol);
261 PacketWriteData (pak, str->txt, str->len);
262 PacketWriteTLVDone (pak);
263 PacketWriteTLVDone (pak);
264 PacketWriteB2 (pak, 3);
265 PacketWriteB2 (pak, 0);
266 PacketWriteB2 (pak, 6);
267 PacketWriteB2 (pak, 0);
268
269 event = QueueEnqueueData2 (serv->conn, QUEUE_TYPE1_RESEND_ACK, pak->ref, 120, msg, &SnacCallbackIgnore, NULL);
270 event->cont = cont;
271
272 SnacSend (serv, pak);
273
274 return RET_OK;
275 }
276
SnacCliSendmsg4(Server * serv,Message * msg)277 static UBYTE SnacCliSendmsg4 (Server *serv, Message *msg)
278 {
279 Packet *pak;
280 Event *event;
281 const char *text;
282 Contact *cont;
283 UDWORD mtime = rand() % 0xffff, mid = rand() % 0xffff;
284
285 assert (serv);
286 assert (msg);
287 cont = msg->cont;
288 assert (cont);
289
290 text = c_out_to_split (msg->send_message, cont);
291 if (strlen (text) > 3 * 1024)
292 {
293 msg->maxsize = 3 * 1024;
294 msg->maxenc = ContactPrefVal (cont, CO_ENCODING);
295 return RET_DEFER;
296 }
297
298 pak = SnacC (serv, 4, 6, 0, 0);
299 PacketWriteB4 (pak, mtime);
300 PacketWriteB4 (pak, mid);
301 PacketWriteB2 (pak, 4 /* format */);
302 PacketWriteCont (pak, cont);
303
304 PacketWriteTLV (pak, 5);
305 PacketWrite4 (pak, serv->oscar_uin);
306 PacketWrite1 (pak, msg->type % 256);
307 PacketWrite1 (pak, msg->type / 256);
308 PacketWriteLNTS (pak, text);
309 PacketWriteTLVDone (pak);
310 PacketWriteB2 (pak, 6);
311 PacketWriteB2 (pak, 0);
312
313 event = QueueEnqueueData2 (serv->conn, QUEUE_TYPE4_RESEND_ACK, pak->ref, 120, msg, &SnacCallbackIgnore, NULL);
314 event->cont = cont;
315
316 SnacSend (serv, pak);
317
318 return RET_OK;
319 }
320
SnacCallbackType2Cancel2(Event * event)321 static void SnacCallbackType2Cancel2 (Event *event)
322 {
323 assert (event);
324 assert (event->conn);
325 assert (!event->data);
326 EventD (event);
327 }
328
SnacCallbackType2Ack(Event * event)329 static void SnacCallbackType2Ack (Event *event)
330 {
331 Connection *conn = event->conn;
332 Contact *cont = event->cont;
333 Event *aevent;
334 UDWORD opt_ref;
335 Message *msg;
336
337 if (!OptGetVal (event->opt, CO_REF, &opt_ref))
338 {
339 EventD (event);
340 return;
341 }
342 aevent = QueueDequeue (conn, QUEUE_TYPE2_RESEND, opt_ref);
343 assert (aevent);
344 assert (cont);
345 ASSERT_SERVER_CONN (conn);
346
347 msg = aevent->data;
348 assert (msg);
349 assert (msg->cont == cont);
350 aevent->data = NULL;
351 EventD (aevent);
352 EventD (event);
353 IMCliReMsg (cont, msg);
354 }
355
SnacCallbackType2Cancel(Event * event)356 static void SnacCallbackType2Cancel (Event *event)
357 {
358 Message *msg = event->data;
359 if (msg->send_message && !msg->otrinjected)
360 rl_printf (i18n (2234, "Message %s discarded - lost session.\n"),
361 msg->plain_message ? msg->plain_message : msg->send_message);
362 MsgD (event->data);
363 event->data = NULL;
364 EventD (event);
365 }
366
SnacCallbackType2(Event * event)367 static void SnacCallbackType2 (Event *event)
368 {
369 Server *serv = event->conn->serv;
370 Contact *cont = event->cont;
371 Packet *pak = event->pak;
372 Message *msg = event->data;
373 Event *event2;
374
375 ASSERT_SERVER (serv);
376 assert (pak);
377 assert (event->cont);
378 assert (event->data);
379 assert (!event->opt);
380
381 if (event->attempts < MAX_RETRY_TYPE2_ATTEMPTS && serv->conn->connect & CONNECT_MASK)
382 {
383 if (serv->conn->connect & CONNECT_OK)
384 {
385 if (event->attempts > 1)
386 IMIntMsg (cont, NOW, ims_offline, INT_MSGTRY_TYPE2, msg->plain_message ? msg->plain_message : msg->send_message);
387 SnacSend (serv, PacketClone (pak));
388 event->attempts++;
389 /* allow more time for the peer's ack than the server's ack */
390 event->due = time (NULL) + RETRY_DELAY_TYPE2 + 5;
391
392 event2 = QueueEnqueueData2 (serv->conn, QUEUE_TYPE2_RESEND_ACK, pak->ref, RETRY_DELAY_TYPE2, NULL, &SnacCallbackType2Ack, &SnacCallbackType2Cancel2);
393 event2->cont = cont;
394 event2->opt = OptSetVals (NULL, CO_REF, event->seq, 0);
395 }
396 else
397 event->due = time (NULL) + 1;
398 QueueEnqueue (event);
399 return;
400 }
401
402 event->data = NULL;
403 IMCliReMsg (cont, msg);
404 EventD (event);
405 }
406
SnacCliSendIP(Server * serv,Contact * cont)407 void SnacCliSendIP (Server *serv, Contact *cont)
408 {
409 Packet *pak;
410 UDWORD mtime = rand() % 0xffff, mid = rand() % 0xffff;
411
412 assert (serv);
413 assert (cont);
414
415 serv->oscar_type2_seq--;
416
417 pak = SnacC (serv, 4, 6, 0, 0);
418 PacketWriteB4 (pak, mtime);
419 PacketWriteB4 (pak, mid);
420 PacketWriteB2 (pak, 2);
421 PacketWriteCont (pak, cont);
422 PacketWriteTLV (pak, 5);
423 PacketWrite2 (pak, 0);
424 PacketWriteB4 (pak, mtime);
425 PacketWriteB4 (pak, mid);
426 PacketWriteCapID (pak, CAP_REVCONNREQ);
427 PacketWriteTLV2 (pak, 10, 1);
428 PacketWriteB4 (pak, 0x000f0000); /* empty TLV(15) */
429 PacketWriteTLV (pak, 10001);
430 PacketWrite4 (pak, serv->conn->cont->uin);
431 PacketWriteB4 (pak, serv->conn->our_local_ip);
432 PacketWrite4 (pak, serv->oscar_dc->port);
433 PacketWrite1 (pak, 4);
434 PacketWrite4 (pak, serv->conn->our_outside_ip);
435 PacketWrite4 (pak, serv->oscar_dc->port);
436 PacketWrite2 (pak, serv->oscar_dc->version);
437 PacketWrite4 (pak, 0x0000002f);
438 PacketWriteTLVDone (pak);
439 PacketWriteTLVDone (pak);
440 PacketWriteTLV (pak, 19);
441 PacketWrite1 (pak, 1);
442 PacketWriteTLVDone (pak);
443 SnacSend (serv, pak);
444 }
445
SnacCliSendmsg2(Server * serv,Message * msg)446 static UBYTE SnacCliSendmsg2 (Server *serv, Message *msg)
447 {
448 Packet *pak;
449 UDWORD mtime = rand() % 0xffff, mid = rand() % 0xffff;
450 BOOL peek = 0;
451 Contact *cont;
452 const char *text;
453
454 assert (serv);
455 assert (msg);
456 cont = msg->cont;
457 assert (cont);
458
459 if (msg->type == MSG_GET_PEEK)
460 {
461 peek = 1;
462 msg->type = MSG_GET_AWAY | MSGF_GETAUTO;
463 }
464
465 text = c_out_for (msg->send_message, cont, msg->type);
466 if (strlen (text) > 3 * 1024)
467 {
468 msg->maxsize = 3 * 1024;
469 msg->maxenc = CONT_UTF8 (cont, msg->type) ? ENC_UTF8 : ContactPrefVal (cont, CO_ENCODING);
470 return RET_DEFER;
471 }
472
473 serv->oscar_type2_seq--;
474 msg->trans &= ~CV_MSGTRANS_TYPE2;
475
476 pak = SnacC (serv, 4, 6, 0, peek ? PEEK_REFID : 0);
477 PacketWriteB4 (pak, mtime);
478 PacketWriteB4 (pak, mid);
479 PacketWriteB2 (pak, 2);
480 PacketWriteCont (pak, cont);
481
482 PacketWriteTLV (pak, 5);
483 PacketWrite2 (pak, 0);
484 PacketWriteB4 (pak, mtime);
485 PacketWriteB4 (pak, mid);
486
487 PacketWriteCapID (pak, peek ? CAP_NONE : CAP_SRVRELAY);
488 PacketWriteTLV2 (pak, 10, 1);
489 PacketWriteB4 (pak, 0x000f0000); /* empty TLV(15) */
490 if (!peek) {
491 PacketWriteTLV (pak, 10001);
492 PacketWriteLen (pak);
493 PacketWrite2 (pak, serv->oscar_dc && serv->oscar_dc->connect & CONNECT_OK
494 ? serv->oscar_dc->version : 8);
495 PacketWriteCapID (pak, CAP_NONE);
496 PacketWrite2 (pak, 0);
497 PacketWrite4 (pak, 3);
498 PacketWrite1 (pak, 0);
499 PacketWrite2 (pak, peek ? 0 : serv->oscar_type2_seq);
500 PacketWriteLenDone (pak);
501 if (peek)
502 {
503 PacketWriteLen (pak);
504 PacketWrite2 (pak, serv->oscar_type2_seq); /* sequence number */
505 PacketWrite4 (pak, 0);
506 PacketWrite4 (pak, 0);
507 PacketWrite4 (pak, 0);
508 PacketWriteLenDone (pak);
509 PacketWrite2 (pak, MSG_GET_DND | MSGF_GETAUTO); /* message type */
510 PacketWrite2 (pak, 0); /* status */
511 PacketWrite2 (pak, 0); /* flags */
512 PacketWrite2 (pak, 0x7fff);
513 PacketWrite1 (pak, 0);
514 }
515 else
516 {
517 SrvMsgAdvanced (pak, serv->oscar_type2_seq, msg->type, serv->status, cont->status, -1, text);
518 PacketWrite4 (pak, TCP_COL_FG);
519 PacketWrite4 (pak, TCP_COL_BG);
520 if (CONT_UTF8 (cont, msg->type))
521 PacketWriteDLStr (pak, CAP_GID_UTF8);
522 }
523 PacketWriteTLVDone (pak);
524 }
525 PacketWriteTLVDone (pak);
526
527 if (peek)
528 {
529 PacketWriteB4 (pak, 0x00060000);
530 SnacSend (serv, pak);
531 MsgD (msg);
532 }
533 else
534 {
535 Event *event;
536
537 PacketWriteB4 (pak, 0x00030000); /* empty TLV(3) */
538 event = QueueEnqueueData2 (serv->conn, QUEUE_TYPE2_RESEND, serv->oscar_type2_seq, 0, msg, &SnacCallbackType2, &SnacCallbackType2Cancel);
539 event->cont = cont;
540 event->pak = pak;
541 }
542 return RET_INPR;
543 }
544
545
546 /*
547 * CLI_SENDMSG - SNAC(4,6) - all
548 */
SnacCliSendmsg(Server * serv,Contact * cont,UBYTE format,Message * msg)549 UBYTE SnacCliSendmsg (Server *serv, Contact *cont, UBYTE format, Message *msg)
550 {
551 assert (serv);
552 assert (cont);
553 assert (msg);
554 assert (msg->cont == cont);
555
556 if (format == 2 && !msg->force)
557 {
558 switch (msg->type & 0xff)
559 {
560 case MSG_AUTO:
561 case MSG_AUTH_REQ:
562 case MSG_AUTH_GRANT:
563 case MSG_AUTH_DENY:
564 case MSG_AUTH_ADDED:
565 return RET_DEFER;
566 case MSG_GET_PEEK:
567 case MSG_GET_VER:
568 break;
569 default:
570 if (!HAS_CAP (cont->caps, CAP_SRVRELAY) || !HAS_CAP (cont->caps, CAP_REVCONNREQ))
571 return RET_DEFER;
572 }
573 }
574 else if (format == 1 && !msg->force)
575 {
576 if ((msg->type & 0xff) != MSG_NORM)
577 return RET_DEFER;
578 }
579 else if (format == 4 && !msg->force)
580 {
581 switch (msg->type & 0xff)
582 {
583 case MSG_AUTO:
584 case MSG_URL:
585 case MSG_AUTH_REQ:
586 case MSG_AUTH_GRANT:
587 case MSG_AUTH_DENY:
588 case MSG_AUTH_ADDED:
589 if (!cont->uin)
590 return RET_DEFER;
591 break;
592 case MSG_NORM:
593 default:
594 case MSG_GET_AWAY:
595 case MSG_GET_DND:
596 case MSG_GET_OCC:
597 case MSG_GET_FFC:
598 case MSG_GET_NA:
599 case MSG_GET_VER:
600 case MSG_GET_PEEK:
601 return RET_DEFER;
602 }
603 }
604 else if (!format || format == 0xff)
605 {
606 switch (msg->type & 0xff)
607 {
608 case MSG_AUTO:
609 case MSG_URL:
610 case MSG_AUTH_REQ:
611 case MSG_AUTH_GRANT:
612 case MSG_AUTH_DENY:
613 case MSG_AUTH_ADDED:
614 if (!cont->uin)
615 return RET_DEFER;
616 format = 4;
617 break;
618 case MSG_NORM:
619 format = 1;
620 break;
621 default:
622 case MSG_GET_AWAY:
623 case MSG_GET_DND:
624 case MSG_GET_OCC:
625 case MSG_GET_FFC:
626 case MSG_GET_NA:
627 case MSG_GET_VER:
628 case MSG_GET_PEEK:
629 format = 2;
630 }
631 }
632
633 if (format == 1)
634 return SnacCliSendmsg1 (serv, msg);
635 else if (format == 4)
636 return SnacCliSendmsg4 (serv, msg);
637 else if (format == 2)
638 return SnacCliSendmsg2 (serv, msg);
639 return RET_DEFER;
640 }
641
SnacSrvCallbackSendack(Event * event)642 static void SnacSrvCallbackSendack (Event *event)
643 {
644 if (!event || !event->conn)
645 {
646 EventD (event);
647 return;
648 }
649 ASSERT_SERVER_CONN (event->conn);
650 if (event->pak)
651 {
652 SnacSend (event->conn->serv, event->pak);
653 event->pak = NULL;
654 }
655 EventD (event);
656 }
657
658 /*
659 * SRV_RECVMSG - SNAC(4,7)
660 */
JUMP_SNAC_F(SnacSrvRecvmsg)661 JUMP_SNAC_F(SnacSrvRecvmsg)
662 {
663 Server *serv = event->conn->serv;
664 Contact *cont;
665 Event *newevent;
666 Cap *cap1, *cap2;
667 Packet *p = NULL, *pp = NULL, *pak;
668 TLV *tlv, *tlvs;
669 Opt *opt;
670 UDWORD midtim, midrnd, midtime, midrand, unk, tmp, type1enc, tlvc;
671 UWORD seq1, tcpver, len, i, msgtyp, type;
672 const char *txt = NULL;
673 strc_t ctext;
674 str_s str = { NULL, 0, 0 };
675
676 pak = event->pak;
677
678 midtime = PacketReadB4 (pak);
679 midrand = PacketReadB4 (pak);
680 type = PacketReadB2 (pak);
681 cont = PacketReadCont (pak, serv);
682 PacketReadB2 (pak); /* WARNING */
683 tlvc = PacketReadB2 (pak); /* COUNT */
684
685 if (!cont)
686 return;
687
688 tlv = TLVRead (pak, PacketReadLeft (pak), tlvc);
689
690 #ifdef WIP
691 if (tlv[6].str.len && tlv[6].nr != cont->nativestatus)
692 rl_printf ("FIXMEWIP: status for %s embedded in message 0x%08lx different from server status 0x%08lx.\n", cont->screen, UD2UL (tlv[6].nr), UD2UL (cont->nativestatus));
693 #endif
694
695 if (tlv[6].str.len)
696 event->opt = OptSetVals (event->opt, CO_STATUS, tlv[6].nr, 0);
697
698 TLVD (tlv);
699 tlv = TLVRead (pak, PacketReadLeft (pak), -1);
700
701 if (type == 1 && tlv[2].str.len)
702 tlvs = &tlv[2];
703 else if (type == 2 && tlv[5].str.len)
704 tlvs = &tlv[5];
705 else if (type == 4 && tlv[5].str.len)
706 tlvs = &tlv[5];
707 else
708 {
709 SnacSrvUnknown (event);
710 TLVD (tlv);
711 return;
712 }
713 p = PacketCreate (&tlvs->str);
714 TLVD (tlv);
715
716 switch (type)
717 {
718 case 1:
719 PacketReadB2 (p);
720 PacketReadData (p, NULL, PacketReadB2 (p));
721 PacketReadB2 (p);
722 len = PacketReadB2 (p);
723
724 type1enc = PacketReadB4 (p);
725 if (len < 4)
726 {
727 SnacSrvUnknown (event);
728 PacketD (p);
729 return;
730 }
731 PacketReadData (p, &str, len - 4);
732 PacketD (p);
733 /* TLV 1, 2(!), 3, 4, f ignored */
734 switch (type1enc & 0xf0000)
735 {
736 case 0x00020000:
737 txt = ConvFrom (&str, ENC_UCS2BE)->txt;
738 break;
739 case 0x00030000:
740 txt = ConvFromCont (&str, cont);
741 break;
742 case 0x00000000:
743 if (ConvIsUTF8 (str.txt) && len == strlen (str.txt) + 4)
744 txt = ConvFrom (&str, ENC_UTF8)->txt;
745 else
746 txt = ConvFromCont (&str, cont);
747 break;
748 default:
749 SnacSrvUnknown (event);
750 txt = ConvFromCont (&str, cont);
751 break;
752 }
753 opt = OptSetVals (event->opt, CO_ORIGIN, CV_ORIGIN_v5, CO_MSGTYPE, MSG_NORM, CO_MSGTEXT, txt, 0);
754 event->opt = NULL;
755 IMSrvMsgFat (cont, NOW, opt);
756 Auto_Reply (serv, cont);
757 s_done (&str);
758 break;
759 case 2:
760 type = PacketReadB2 (p);
761 midtim = PacketReadB4 (p);
762 midrnd = PacketReadB4 (p);
763 cap1 = PacketReadCap (p);
764
765 ContactSetCap (cont, cap1);
766 if (midtim != midtime || midrnd != midrand)
767 {
768 SnacSrvUnknown (event);
769 PacketD (p);
770 return;
771 }
772
773 tlv = TLVRead (p, PacketReadLeft (p), -1);
774 PacketD (p);
775
776 if ((i = TLVGet (tlv, 0x2711)) == (UWORD)-1)
777 {
778 if (TLVGet (tlv, 11) == (UWORD)-1)
779 SnacSrvUnknown (event);
780 #ifdef WIP
781 else
782 {
783 rl_log_for (cont->nick, COLCONTACT);
784 rl_printf ("FIXMEWIP: tlv(b)-only packet.\n");
785 }
786 #endif
787 TLVD (tlv);
788 return;
789 }
790
791 switch (cap1->id)
792 {
793 case CAP_REVCONNREQ:
794 if (tlv[i].str.len != 0x1b)
795 {
796 SnacSrvUnknown (event);
797 TLVD (tlv);
798 return;
799 }
800 pp = PacketCreate (&tlv[i].str);
801 {
802 UDWORD suin = PacketRead4 (pp);
803 UDWORD sip = PacketReadB4 (pp);
804 UDWORD sp1 = PacketRead4 (pp);
805 UBYTE scon = PacketRead1 (pp);
806 UDWORD sop = PacketRead4 (pp);
807 UDWORD sp2 = PacketRead4 (pp);
808 UWORD sver = PacketRead2 (pp);
809 UDWORD sunk = PacketRead4 (pp);
810 if (suin != cont->uin)
811 {
812 SnacSrvUnknown (event);
813 TLVD (tlv);
814 return;
815 }
816
817 if (prG->verbose)
818 {
819 char *ip = strdup (s_ip (sip));
820 rl_log_for (cont->nick, COLCONTACT);
821 rl_printf (i18n (2742, "Incoming reverse connection request to %s.\n"),
822 s_sprintf ("%s:%ld|%ld|%ld v%d %d seq %ld",
823 ip, UD2UL (sp1), UD2UL (sp2), UD2UL (sop), sver, scon, UD2UL (sunk)));
824 free (ip);
825 }
826 CONTACT_DC (cont)->ip_rem = sip;
827 cont->dc->port = sp1;
828 cont->dc->type = scon;
829 cont->dc->version = sver;
830 }
831 PacketD (pp);
832 TLVD (tlv);
833 TCPDirectOpen (serv->oscar_dc, cont);
834 return;
835
836 case CAP_SRVRELAY:
837 if (tlv[i].str.txt[0] != 0x1b)
838 {
839 SnacSrvUnknown (event);
840 TLVD (tlv);
841 return;
842 }
843 pp = PacketCreate (&tlv[i].str);
844
845 p = SnacC (serv, 4, 11, 0, 0);
846 PacketWriteB4 (p, midtim);
847 PacketWriteB4 (p, midrnd);
848 PacketWriteB2 (p, 2);
849 PacketWriteCont (p, cont);
850 PacketWriteB2 (p, 3);
851
852 len = PacketRead2 (pp); PacketWrite2 (p, len);
853 tcpver = PacketRead2 (pp); PacketWrite2 (p, tcpver);
854 cap2 = PacketReadCap (pp); PacketWriteCap (p, cap2);
855 tmp = PacketRead2 (pp); PacketWrite2 (p, tmp);
856 tmp = PacketRead4 (pp); PacketWrite4 (p, tmp);
857 tmp = PacketRead1 (pp); PacketWrite1 (p, tmp);
858 seq1 = PacketRead2 (pp); PacketWrite2 (p, seq1);
859
860 ContactSetCap (cont, cap2);
861 ContactSetVersion (cont);
862
863 if (cap2->id != CAP_STR_2001 && cap2->id != CAP_STR_2002)
864 {
865 event->opt = OptSetVals (event->opt, CO_ORIGIN, CV_ORIGIN_v8, 0);
866 event->cont = cont;
867 newevent = QueueEnqueueData (serv->conn, QUEUE_ACKNOWLEDGE, seq1,
868 (time_t)-1, p, cont, NULL, &SnacSrvCallbackSendack);
869 SrvReceiveAdvanced (serv, event, pp, newevent);
870 }
871 else
872 PacketD (p);
873 PacketD (pp);
874 TLVD (tlv);
875 return;
876
877 default:
878 SnacSrvUnknown (event);
879 TLVD (tlv);
880 return;
881 }
882 /* TLV 1, 2(!), 3, 4, f ignored */
883 break;
884 case 4:
885 unk = PacketRead4 (p);
886 msgtyp = PacketRead2 (p);
887 if (unk != cont->uin)
888 {
889 PacketD (p);
890 SnacSrvUnknown (event);
891 return;
892 }
893 ctext = PacketReadL2Str (p, NULL);
894 PacketD (p);
895 /* FOREGROUND / BACKGROUND ignored */
896 /* TLV 1, 2(!), 3, 4, f ignored */
897
898 opt = OptSetVals (event->opt, CO_ORIGIN, CV_ORIGIN_v5, CO_MSGTYPE, msgtyp,
899 CO_MSGTEXT, msgtyp == MSG_NORM ? ConvFromCont (ctext, cont) : c_in_to_split (ctext, cont), 0);
900 event->opt = NULL;
901 IMSrvMsgFat (cont, NOW, opt);
902 Auto_Reply (serv, cont);
903 break;
904 }
905 }
906
907 /*
908 * SRV_ACKMSG - SNAC(4,C)
909 */
JUMP_SNAC_F(SnacSrvSrvackmsg)910 JUMP_SNAC_F(SnacSrvSrvackmsg)
911 {
912 Server *serv = event->conn->serv;
913 Event *event2 = NULL;
914 Packet *pak;
915 Message *msg;
916 Contact *cont;
917 /* UDWORD mid1, mid2; */
918 UWORD format;
919
920 pak = event->pak;
921
922 /*mid1=*/PacketReadB4 (pak);
923 /*mid2=*/PacketReadB4 (pak);
924 format = PacketReadB2 (pak);
925
926 cont = PacketReadCont (pak, serv);
927
928 if (!cont)
929 return;
930
931
932 switch (format)
933 {
934 case 1:
935 event2 = QueueDequeue (serv->conn, QUEUE_TYPE1_RESEND_ACK, pak->ref);
936 if (!event2 || !(msg = event2->data))
937 break;
938 msg->type = INT_MSGACK_V8;
939 if ((msg->send_message || msg->plain_message) && !msg->otrinjected)
940 IMIntMsgMsg (msg, NOW, ims_offline);
941 break;
942 case 4:
943 event2 = QueueDequeue (serv->conn, QUEUE_TYPE4_RESEND_ACK, pak->ref);
944 if (!event2 || !(msg = event2->data))
945 break;
946 msg->type = INT_MSGACK_V8;
947 if ((msg->send_message || msg->plain_message) && !msg->otrinjected)
948 IMIntMsgMsg (msg, NOW, ims_offline);
949 break;
950 case 2: /* msg was received by server */
951 event2 = QueueDequeue (serv->conn, QUEUE_TYPE2_RESEND_ACK, pak->ref);
952 if (!event2 || !(msg = event2->data))
953 break;
954 if (pak->ref == PEEK_REFID)
955 rl_print (i18n (2573, "The user is probably offline.\n"));
956 break;
957 }
958 if (event2)
959 {
960 MsgD (event2->data);
961 event2->data = NULL;
962 EventD (event2);
963 }
964 }
965
SrvMsgAdvanced(Packet * pak,UDWORD seq,UWORD msgtype,status_t status,status_t deststatus,UWORD flags,const char * msg)966 void SrvMsgAdvanced (Packet *pak, UDWORD seq, UWORD msgtype, status_t status,
967 status_t deststatus, UWORD flags, const char *msg)
968 {
969 if (msgtype == MSG_SSL_OPEN)
970 status = ims_online;
971
972 if (flags == (UWORD)-1)
973 {
974 switch (ContactClearInv (deststatus))
975 {
976 case imr_offline: /* keep */ break;
977 case imr_dnd:
978 case imr_occ: flags = TCP_MSGF_CLIST; break;
979 case imr_na:
980 case imr_away: flags = TCP_MSGF_1; break;
981 case imr_ffc:
982 case imr_online: flags = TCP_MSGF_LIST | TCP_MSGF_1; break;
983 }
984 }
985
986 PacketWriteLen (pak);
987 PacketWrite2 (pak, seq); /* sequence number */
988 PacketWrite4 (pak, 0);
989 PacketWrite4 (pak, 0);
990 PacketWrite4 (pak, 0);
991 PacketWriteLenDone (pak);
992 PacketWrite2 (pak, msgtype); /* message type */
993 PacketWrite2 (pak, IcqFromStatus (status));
994 /* status */
995 PacketWrite2 (pak, flags); /* flags */
996 PacketWriteLNTS (pak, msg); /* the message */
997 }
998
999 /*
1000 * Append the "geeting" part to an advanced message packet.
1001 */
SrvMsgGreet(Packet * pak,UWORD cmd,const char * reason,UWORD port,UDWORD len,const char * msg)1002 void SrvMsgGreet (Packet *pak, UWORD cmd, const char *reason, UWORD port, UDWORD len, const char *msg)
1003 {
1004 PacketWrite2 (pak, cmd);
1005 switch (cmd)
1006 {
1007 case 0x2d:
1008 default:
1009 PacketWriteB4 (pak, 0xbff720b2);
1010 PacketWriteB4 (pak, 0x378ed411);
1011 PacketWriteB4 (pak, 0xbd280004);
1012 PacketWriteB4 (pak, 0xac96d905);
1013 break;
1014 case 0x29:
1015 case 0x32:
1016 PacketWriteB4 (pak, 0xf02d12d9);
1017 PacketWriteB4 (pak, 0x3091d311);
1018 PacketWriteB4 (pak, 0x8dd70010);
1019 PacketWriteB4 (pak, 0x4b06462e);
1020 }
1021 PacketWrite2 (pak, 0);
1022 switch (cmd)
1023 {
1024 case 0x29: PacketWriteDLStr (pak, "File"); break;
1025 case 0x2d: PacketWriteDLStr (pak, "ICQ Chat"); break;
1026 case 0x32: PacketWriteDLStr (pak, "File Transfer"); break;
1027 default: PacketWriteDLStr (pak, "");
1028 }
1029 PacketWrite2 (pak, 0);
1030 PacketWrite1 (pak, 1);
1031 switch (cmd)
1032 {
1033 case 0x29:
1034 case 0x2d: PacketWriteB4 (pak, 0x00000100); break;
1035 case 0x32: PacketWriteB4 (pak, 0x01000000); break;
1036 default: PacketWriteB4 (pak, 0);
1037 }
1038 PacketWriteB4 (pak, 0);
1039 PacketWriteB4 (pak, 0);
1040 PacketWriteLen4 (pak);
1041 PacketWriteDLStr (pak, c_out (reason));
1042 PacketWriteB2 (pak, port);
1043 PacketWriteB2 (pak, 0);
1044 PacketWriteLNTS (pak, c_out (msg));
1045 PacketWrite4 (pak, len);
1046 if (cmd != 0x2d)
1047 PacketWrite4 (pak, port);
1048 PacketWriteLen4Done (pak);
1049 }
1050
1051 /*
1052 * Process an advanced message.
1053 *
1054 * Note: swallows only acknowledge event/packet;
1055 * the caller destructs inc_event after return.
1056 */
SrvReceiveAdvanced(Server * serv,Event * inc_event,Packet * inc_pak,Event * ack_event)1057 void SrvReceiveAdvanced (Server *serv, Event *inc_event, Packet *inc_pak, Event *ack_event)
1058 {
1059 #ifdef ENABLE_PEER2PEER
1060 Connection *flist;
1061 Event *e1;
1062 UDWORD opt_acc;
1063 #endif
1064 Contact *cont = inc_event->cont;
1065 Opt *opt = inc_event->opt, *opt2;
1066 Packet *ack_pak = ack_event->pak;
1067 const char *txt, *ack_msg = "", *tauto;
1068 strc_t text, cname, ctext, reason, cctmp;
1069 char *name;
1070 UDWORD tmp, cmd, flen;
1071 UWORD unk, seq, msgtype, unk2, pri;
1072 UWORD ack_flags, ack_status, accept;
1073
1074 unk = PacketRead2 (inc_pak); PacketWrite2 (ack_pak, unk);
1075 seq = PacketRead2 (inc_pak); PacketWrite2 (ack_pak, seq);
1076 tmp = PacketRead4 (inc_pak); PacketWrite4 (ack_pak, tmp);
1077 tmp = PacketRead4 (inc_pak); PacketWrite4 (ack_pak, tmp);
1078 tmp = PacketRead4 (inc_pak); PacketWrite4 (ack_pak, tmp);
1079 msgtype = PacketRead2 (inc_pak); PacketWrite2 (ack_pak, msgtype);
1080
1081 unk2 = PacketRead2 (inc_pak);
1082 pri = PacketRead2 (inc_pak);
1083 text = PacketReadL2Str (inc_pak, NULL);
1084
1085 #ifdef WIP
1086 if (prG->verbose)
1087 rl_printf ("FIXMEWIP: Starting advanced message: events %p, %p; type %d, seq %x.\n",
1088 inc_event, ack_event, msgtype, seq);
1089 #endif
1090
1091 OptSetVal (opt, CO_MSGTYPE, msgtype);
1092 OptSetStr (opt, CO_MSGTEXT, msgtype == MSG_NORM ? ConvFromCont (text, cont) : c_in_to_split (text, cont));
1093
1094 accept = FALSE;
1095
1096 /*
1097 * Don't refuse until we have sensible preferences for that
1098 */
1099 switch (ContactClearInv (serv->status))
1100 {
1101 case imr_dnd: ack_msg = (tauto = ContactPrefStr (cont, CO_TAUTODND)) && *tauto ?
1102 tauto : ContactPrefStr (cont, CO_AUTODND); ack_status = TCP_ACK_ONLINE; break;
1103 case imr_occ: ack_msg = (tauto = ContactPrefStr (cont, CO_TAUTOOCC)) && *tauto ?
1104 tauto : ContactPrefStr (cont, CO_AUTOOCC); ack_status = TCP_ACK_ONLINE; break;
1105 case imr_na: ack_msg = (tauto = ContactPrefStr (cont, CO_TAUTONA)) && *tauto ?
1106 tauto : ContactPrefStr (cont, CO_AUTONA); ack_status = TCP_ACK_NA; break;
1107 case imr_away: ack_msg = (tauto = ContactPrefStr (cont, CO_TAUTOAWAY)) && *tauto ?
1108 tauto : ContactPrefStr (cont, CO_AUTOAWAY); ack_status = TCP_ACK_AWAY; break;
1109 default: ack_status = TCP_ACK_ONLINE;
1110 }
1111
1112 ack_flags = 0;
1113 if (ContactIsInv (serv->status)) ack_flags |= TCP_MSGF_INV;
1114
1115 switch (msgtype & ~MSGF_MASS)
1116 {
1117 /* Requests for auto-response message */
1118 do {
1119 val_t val;
1120
1121 case MSGF_GETAUTO | MSG_GET_AWAY:
1122 ack_msg = (tauto = ContactPrefStr (cont, CO_TAUTOAWAY)) && *tauto ? tauto : ContactPrefStr (cont, CO_AUTOAWAY);
1123 break;
1124 case MSGF_GETAUTO | MSG_GET_OCC:
1125 ack_msg = (tauto = ContactPrefStr (cont, CO_TAUTOOCC)) && *tauto ? tauto : ContactPrefStr (cont, CO_AUTOOCC);
1126 break;
1127 case MSGF_GETAUTO | MSG_GET_NA:
1128 ack_msg = (tauto = ContactPrefStr (cont, CO_TAUTONA)) && *tauto ? tauto : ContactPrefStr (cont, CO_AUTONA);
1129 break;
1130 case MSGF_GETAUTO | MSG_GET_DND:
1131 ack_msg = (tauto = ContactPrefStr (cont, CO_TAUTODND)) && *tauto ? tauto : ContactPrefStr (cont, CO_AUTODND);
1132 break;
1133 case MSGF_GETAUTO | MSG_GET_FFC: ack_msg = ContactPrefStr (cont, CO_AUTOFFC); break;
1134 case MSGF_GETAUTO | MSG_GET_VER:
1135 if (!OptGetVal (&prG->copts, CO_ENCODING, &val))
1136 val = -1;
1137 ack_msg = s_sprintf ("%s\nLocale: %s %s %s %s %d %s", BuildVersionText,
1138 prG->locale, prG->locale_orig, prG->locale_full,
1139 ConvEncName (prG->enc_loc), prG->locale_broken, ConvEncName (val));
1140 } while (0);
1141
1142 #ifdef WIP
1143 if (1)
1144 #else
1145 if (msgtype != 1012)
1146 #endif
1147 {
1148 if (((ack_flags & TCP_MSGF_INV) && !ContactPrefVal (cont, CO_INTIMATE)) || ContactPrefVal (cont, CO_HIDEFROM))
1149 {
1150 if (ContactPrefVal (cont, CO_SHOWCHANGE))
1151 {
1152 rl_log_for (cont->nick, COLCONTACT);
1153 rl_printf (i18n (2568, "Ignored request for auto-response from %s%s%s.\n"),
1154 COLCONTACT, cont->nick, COLNONE);
1155 }
1156 ack_event->due = 0;
1157 ack_event->callback = NULL;
1158 QueueDequeueEvent (ack_event);
1159 EventD (ack_event);
1160 return;
1161 }
1162 if (ContactPrefVal (cont, CO_SHOWCHANGE))
1163 {
1164 rl_log_for (cont->nick, COLCONTACT);
1165 rl_printf (i18n (1814, "Sent auto-response message to %s%s%s.\n"),
1166 COLCONTACT, cont->nick, COLNONE);
1167 }
1168 }
1169
1170 accept = TRUE;
1171 ack_flags = pri;
1172 ack_status = 0;
1173 break;
1174
1175 case MSG_FILE:
1176 #ifdef ENABLE_PEER2PEER
1177 cmd = PacketRead4 (inc_pak);
1178 cname = PacketReadL2Str (inc_pak, NULL);
1179 flen = PacketRead4 (inc_pak);
1180 msgtype = PacketRead4 (inc_pak);
1181
1182 name = strdup (ConvFromCont (cname, cont));
1183
1184 flist = PeerFileCreate (serv);
1185 OptSetVal (opt, CO_FILEACCEPT, 0);
1186 OptSetVal (opt, CO_BYTES, flen);
1187 OptSetStr (opt, CO_MSGTEXT, name);
1188 OptSetVal (opt, CO_REF, ack_event->seq);
1189 if (!OptGetVal (opt, CO_FILEACCEPT, &opt_acc) && flen)
1190 {
1191 opt2 = OptC ();
1192 OptSetVal (opt2, CO_BYTES, flen);
1193 OptSetStr (opt2, CO_MSGTEXT, name);
1194 OptSetVal (opt2, CO_REF, ack_event->seq);
1195 OptSetVal (opt2, CO_MSGTYPE, msgtype);
1196 IMSrvMsgFat (cont, NOW, opt2);
1197 opt2 = OptC ();
1198 OptSetVal (opt2, CO_FILEACCEPT, 0);
1199 OptSetStr (opt2, CO_REFUSE, i18n (2514, "refused (ignored)"));
1200 e1 = QueueEnqueueData (serv->conn, QUEUE_USERFILEACK, ack_event->seq, time (NULL) + 120,
1201 NULL, inc_event->cont, opt2, &PeerFileTO);
1202 QueueEnqueueDep (inc_event->conn, inc_event->type, ack_event->seq, e1,
1203 inc_event->pak, inc_event->cont, opt, inc_event->callback);
1204 inc_event->pak->rpos = inc_event->pak->tpos;
1205 inc_event->opt = NULL;
1206 inc_event->pak = NULL;
1207 ack_event->due = 0;
1208 ack_event->callback = NULL;
1209 QueueDequeueEvent (ack_event);
1210 EventD (ack_event);
1211 free (name);
1212 #ifdef WIP
1213 rl_printf ("FIXMEWIP: Delaying advanced message: events %p, %p.\n", inc_event, ack_event);
1214 #endif
1215 return;
1216 }
1217 free (name);
1218 if (serv->oscar_dc && PeerFileIncAccept (serv->oscar_dc, inc_event))
1219 {
1220 PacketWrite2 (ack_pak, ack_status);
1221 PacketWrite2 (ack_pak, ack_flags);
1222 PacketWriteLNTS (ack_pak, c_out (ack_msg));
1223 PacketWriteB2 (ack_pak, flist->port);
1224 PacketWrite2 (ack_pak, 0);
1225 PacketWriteStr (ack_pak, "");
1226 PacketWrite4 (ack_pak, 0);
1227 if (serv->oscar_dc->version > 6)
1228 PacketWrite4 (ack_pak, 0x20726f66);
1229 PacketWrite4 (ack_pak, flist->port);
1230 }
1231 else
1232 #endif
1233 {
1234 if (!OptGetStr (inc_event->wait->opt, CO_REFUSE, &txt))
1235 txt = "";
1236 PacketWrite2 (ack_pak, TCP_ACK_REFUSE);
1237 PacketWrite2 (ack_pak, ack_flags);
1238 PacketWriteLNTS (ack_pak, c_out (ack_msg));
1239 PacketWriteB2 (ack_pak, 0);
1240 PacketWrite2 (ack_pak, 0);
1241 PacketWriteStr (ack_pak, txt);
1242 PacketWrite4 (ack_pak, 0);
1243 if (serv->oscar_dc->version > 6)
1244 PacketWrite4 (ack_pak, 0x20726f66);
1245 PacketWrite4 (ack_pak, 0);
1246 }
1247 EventD (QueueDequeueEvent (inc_event->wait));
1248 inc_event->wait = NULL;
1249 accept = -1;
1250 break;
1251 case MSG_EXTENDED:
1252 {
1253 /* UWORD port, port2, pad; */
1254 char *gtext;
1255 char id[20];
1256 cmd = PacketRead2 (inc_pak);
1257 {
1258 str_s t = { 0, 0, 0 };
1259 s_init (&t, "", 20);
1260 PacketReadData (inc_pak, &t, 16);
1261 memcpy (id, t.txt, 16);
1262 id[17] = 0;
1263 s_done (&t);
1264 }
1265 PacketRead2 (inc_pak);
1266 ctext = PacketReadL4Str (inc_pak, NULL);
1267 PacketReadData (inc_pak, NULL, 15);
1268 PacketRead4 (inc_pak);
1269 reason = PacketReadL4Str (inc_pak, NULL);
1270 /*port=*/PacketReadB2 (inc_pak);
1271 /*pad=*/ PacketRead2 (inc_pak);
1272 cname = PacketReadL2Str (inc_pak, NULL);
1273 flen = PacketRead4 (inc_pak);
1274 /*port2*/PacketRead4 (inc_pak);
1275
1276 gtext = strdup (ConvFromCont (ctext, cont));
1277 name = strdup (ConvFromCont (cname, cont));
1278
1279 switch (cmd)
1280 {
1281 case 0x0029:
1282 #ifdef ENABLE_PEER2PEER
1283 flist = PeerFileCreate (serv);
1284 OptSetVal (opt, CO_FILEACCEPT, 0);
1285 OptSetVal (opt, CO_BYTES, flen);
1286 OptSetStr (opt, CO_MSGTEXT, name);
1287 OptSetVal (opt, CO_REF, ack_event->seq);
1288 if (!inc_event->wait)
1289 {
1290 opt2 = OptC ();
1291 OptSetVal (opt2, CO_BYTES, flen);
1292 OptSetStr (opt2, CO_MSGTEXT, name);
1293 OptSetVal (opt2, CO_REF, ack_event->seq);
1294 OptSetVal (opt2, CO_MSGTYPE, MSG_FILE);
1295 IMSrvMsgFat (cont, NOW, opt2);
1296 opt2 = OptC ();
1297 OptSetVal (opt2, CO_FILEACCEPT, 0);
1298 OptSetStr (opt2, CO_REFUSE, i18n (2514, "refused (ignored)"));
1299 e1 = QueueEnqueueData (serv->conn, QUEUE_USERFILEACK, ack_event->seq, time (NULL) + 120,
1300 NULL, inc_event->cont, opt2, &PeerFileTO);
1301 QueueEnqueueDep (inc_event->conn, inc_event->type, ack_event->seq, e1,
1302 inc_event->pak, inc_event->cont, opt, inc_event->callback);
1303 inc_event->pak->rpos = inc_event->pak->tpos;
1304 inc_event->opt = NULL;
1305 inc_event->pak = NULL;
1306 ack_event->callback = NULL;
1307 ack_event->due = 0;
1308 QueueDequeueEvent (ack_event);
1309 EventD (ack_event);
1310 free (name);
1311 free (gtext);
1312 #ifdef WIP
1313 rl_printf ("FIXMEWIP: Delaying advanced message: events %p, %p.\n", inc_event, ack_event);
1314 #endif
1315 return;
1316 }
1317 if (serv->oscar_dc && PeerFileIncAccept (serv->oscar_dc, inc_event))
1318 {
1319 PacketWrite2 (ack_pak, ack_status);
1320 PacketWrite2 (ack_pak, ack_flags);
1321 PacketWriteLNTS (ack_pak, "");
1322 SrvMsgGreet (ack_pak, cmd, "", flist->port, 0, "");
1323 }
1324 else
1325 #endif
1326 {
1327 if (!OptGetStr (inc_event->wait->opt, CO_REFUSE, &txt))
1328 txt = "";
1329 PacketWrite2 (ack_pak, TCP_ACK_REFUSE);
1330 PacketWrite2 (ack_pak, ack_flags);
1331 PacketWriteLNTS (ack_pak, txt);
1332 SrvMsgGreet (ack_pak, cmd, "", 0, 0, "");
1333 }
1334 EventD (QueueDequeueEvent (inc_event->wait));
1335 inc_event->wait = NULL;
1336 break;
1337
1338 case 0x002d:
1339 if (id[0] == (char)0xbf)
1340 {
1341 IMSrvMsg (cont, NOW, 0, msgtype, c_in_to_split (text, cont));
1342 IMSrvMsg (cont, NOW, 0, MSG_CHAT, name);
1343 opt2 = OptC ();
1344 OptSetVal (opt2, CO_MSGTYPE, MSG_CHAT);
1345 OptSetStr (opt2, CO_MSGTEXT, reason->txt);
1346 PacketWrite2 (ack_pak, TCP_ACK_REFUSE);
1347 PacketWrite2 (ack_pak, ack_flags);
1348 PacketWriteLNTS (ack_pak, "");
1349 SrvMsgGreet (ack_pak, cmd, "", 0, 0, "");
1350 break;
1351 }
1352 else if (id[0] == (char)0x2a)
1353 {
1354 IMSrvMsg (cont, NOW, 0, MSG_CONTACT, c_in_to_split (reason, cont));
1355 PacketWrite2 (ack_pak, ack_status);
1356 PacketWrite2 (ack_pak, ack_flags);
1357 PacketWriteLNTS (ack_pak, "");
1358 SrvMsgGreet (ack_pak, cmd, "", 0, 0, "");
1359 break;
1360 }
1361
1362 case 0x0032:
1363 default:
1364 if (prG->verbose & DEB_PROTOCOL)
1365 rl_printf (i18n (2065, "Unknown TCP_MSG_GREET_ command %04x.\n"), msgtype);
1366 PacketWrite2 (ack_pak, TCP_ACK_REFUSE);
1367 PacketWrite2 (ack_pak, ack_flags);
1368 PacketWriteLNTS (ack_pak, "");
1369 SrvMsgGreet (ack_pak, cmd, "", 0, 0, "");
1370 break;
1371
1372 }
1373 free (name);
1374 free (gtext);
1375 accept = -1;
1376 }
1377 break;
1378 #ifdef ENABLE_SSL
1379 case MSG_SSL_OPEN: /* Licq compatible SSL handshake */
1380 if (!unk2)
1381 {
1382 PacketWrite2 (ack_pak, ack_status);
1383 PacketWrite2 (ack_pak, ack_flags);
1384 PacketWriteLNTS (ack_pak, c_out ("1"));
1385 accept = -1;
1386 ack_event->conn->ssl_status = SSL_STATUS_INIT;
1387 }
1388 break;
1389 case MSG_SSL_CLOSE:
1390 if (!unk2)
1391 {
1392 PacketWrite2 (ack_pak, ack_status);
1393 PacketWrite2 (ack_pak, ack_flags);
1394 PacketWriteLNTS (ack_pak, c_out (""));
1395 accept = -1;
1396 ack_event->conn->ssl_status = SSL_STATUS_CLOSE;
1397 }
1398 break;
1399 #endif
1400 default:
1401 if (prG->verbose & DEB_PROTOCOL)
1402 rl_printf (i18n (2066, "Unknown TCP_MSG_ command %04x.\n"), msgtype);
1403 /* fall-through */
1404 case MSG_CHAT:
1405 /* chat ist not implemented, so reject chat requests */
1406 accept = FALSE;
1407 break;
1408
1409 /* Regular messages */
1410 case MSG_AUTO:
1411 case MSG_NORM:
1412 case MSG_URL:
1413 case MSG_AUTH_REQ:
1414 case MSG_AUTH_DENY:
1415 case MSG_AUTH_GRANT:
1416 case MSG_AUTH_ADDED:
1417 case MSG_WEB:
1418 case MSG_EMAIL:
1419 case MSG_CONTACT:
1420 /**/ PacketRead4 (inc_pak);
1421 /**/ PacketRead4 (inc_pak);
1422 cctmp = PacketReadL4Str (inc_pak, NULL);
1423 if (!strcmp (cctmp->txt, CAP_GID_UTF8))
1424 OptSetStr (opt, CO_MSGTEXT, text->txt);
1425 if (*text->txt)
1426 IMSrvMsgFat (cont, NOW, opt);
1427 inc_event->opt = NULL;
1428 PacketWrite2 (ack_pak, ack_status);
1429 PacketWrite2 (ack_pak, ack_flags);
1430 PacketWriteLNTS (ack_pak, c_out_for (ack_msg, cont, msgtype));
1431 if (msgtype == MSG_NORM)
1432 {
1433 PacketWrite4 (ack_pak, TCP_COL_FG);
1434 PacketWrite4 (ack_pak, TCP_COL_BG);
1435 }
1436 if (CONT_UTF8 (cont, msgtype))
1437 PacketWriteDLStr (ack_pak, CAP_GID_UTF8);
1438 accept = -1;
1439 break;
1440 }
1441 switch (accept)
1442 {
1443 case FALSE:
1444 PacketWrite2 (ack_pak, TCP_ACK_REFUSE);
1445 PacketWrite2 (ack_pak, ack_flags);
1446 PacketWriteLNTS (ack_pak, c_out_to (ack_msg, cont));
1447 break;
1448
1449 case TRUE:
1450 PacketWrite2 (ack_pak, ack_status);
1451 PacketWrite2 (ack_pak, ack_flags);
1452 PacketWriteLNTS (ack_pak, c_out_to (ack_msg, cont));
1453 }
1454 #ifdef WIP
1455 if (prG->verbose)
1456 rl_printf ("FIXMEWIP: Finishing advanced message: events %p, %p.\n", inc_event, ack_event);
1457 #endif
1458 QueueDequeueEvent (ack_event);
1459 ack_event->callback (ack_event);
1460 }
1461
1462