Mercurial > pidgin
comparison libpurple/protocols/msn/directconn.c @ 31088:b55b3d34846c
A direct connection really has no need of the whole P2P packet header,
and there's no need to shoehorn the nonce negotiation into one either.
author | Elliott Sales de Andrade <qulogic@pidgin.im> |
---|---|
date | Tue, 04 Jan 2011 09:12:59 +0000 |
parents | a8cc50c2279f |
children | 089a9825076c |
comparison
equal
deleted
inserted
replaced
31087:a46a737efbe3 | 31088:b55b3d34846c |
---|---|
25 #include "internal.h" | 25 #include "internal.h" |
26 #include "cipher.h" | 26 #include "cipher.h" |
27 #include "debug.h" | 27 #include "debug.h" |
28 | 28 |
29 #include "msn.h" | 29 #include "msn.h" |
30 #include "msnutils.h" | |
30 #include "directconn.h" | 31 #include "directconn.h" |
31 | 32 |
32 #include "slp.h" | 33 #include "slp.h" |
33 #include "slpmsg.h" | 34 #include "slpmsg.h" |
34 #include "p2p.h" | 35 #include "p2p.h" |
440 memcpy(p->data, "foo\0", 4); | 441 memcpy(p->data, "foo\0", 4); |
441 | 442 |
442 msn_dc_enqueue_packet(dc, p); | 443 msn_dc_enqueue_packet(dc, p); |
443 } | 444 } |
444 | 445 |
445 static void | 446 #if 0 /* We don't actually need this */ |
446 msn_dc_send_handshake_with_nonce(MsnDirectConn *dc, MsnDirectConnPacket *p) | 447 typedef struct { |
447 { | 448 guint32 null; |
448 const gchar *h; | 449 guint32 id; |
449 | 450 guint32 null[5]; |
450 h = msn_p2p_header_to_wire(&dc->header); | 451 guint32 flags; |
451 | 452 guint8 nonce[16]; |
452 memcpy(p->data, h, P2P_PACKET_HEADER_SIZE); | 453 } MsnDirectConnNoncePacket; |
453 | 454 #endif |
454 memcpy(p->data + P2P_HEADER_ACK_ID_OFFSET, dc->nonce, 16); | 455 #define DC_NONCE_PACKET_SIZE (8 * 4 + 16) |
456 #define DC_NONCE_PACKET_NONCE (8 * 4) | |
457 | |
458 static void | |
459 msn_dc_send_handshake(MsnDirectConn *dc) | |
460 { | |
461 MsnDirectConnPacket *p; | |
462 gchar *h; | |
463 | |
464 p = msn_dc_new_packet(DC_NONCE_PACKET_SIZE); | |
465 h = (gchar *)p->data; | |
466 | |
467 msn_push32le(h, 0); /* NUL */ | |
468 | |
469 msn_push32le(h, dc->slpcall->slplink->slp_seq_id++); | |
470 | |
471 /* More NUL stuff */ | |
472 msn_push64le(h, 0); | |
473 msn_push64le(h, 0); | |
474 msn_push32le(h, 0); | |
475 | |
476 /* Flags */ | |
477 msn_push32le(h, P2P_DC_HANDSHAKE); | |
478 | |
479 /* The real Nonce, yay! */ | |
480 memcpy(h, dc->nonce, 16); | |
455 | 481 |
456 msn_dc_enqueue_packet(dc, p); | 482 msn_dc_enqueue_packet(dc, p); |
457 } | |
458 | |
459 static void | |
460 msn_dc_send_handshake(MsnDirectConn *dc) | |
461 { | |
462 MsnDirectConnPacket *p; | |
463 | |
464 p = msn_dc_new_packet(P2P_PACKET_HEADER_SIZE); | |
465 | |
466 dc->header.session_id = 0; | |
467 dc->header.id = dc->slpcall->slplink->slp_seq_id++; | |
468 dc->header.offset = 0; | |
469 dc->header.total_size = 0; | |
470 dc->header.length = 0; | |
471 dc->header.flags = 0x100; | |
472 | |
473 msn_dc_send_handshake_with_nonce(dc, p); | |
474 } | |
475 | |
476 static void | |
477 msn_dc_send_handshake_reply(MsnDirectConn *dc) | |
478 { | |
479 MsnDirectConnPacket *p; | |
480 | |
481 p = msn_dc_new_packet(P2P_PACKET_HEADER_SIZE); | |
482 | |
483 dc->header.id = dc->slpcall->slplink->slp_seq_id++; | |
484 dc->header.length = 0; | |
485 | |
486 msn_dc_send_handshake_with_nonce(dc, p); | |
487 } | 483 } |
488 | 484 |
489 static gboolean | 485 static gboolean |
490 msn_dc_verify_handshake(MsnDirectConn *dc, guint32 packet_length) | 486 msn_dc_verify_handshake(MsnDirectConn *dc, guint32 packet_length) |
491 { | 487 { |
492 guchar nonce[16]; | 488 guchar nonce[16]; |
493 gchar nonce_hash[37]; | 489 gchar nonce_hash[37]; |
494 | 490 |
495 if (packet_length != P2P_PACKET_HEADER_SIZE) | 491 if (packet_length != DC_NONCE_PACKET_SIZE) |
496 return FALSE; | 492 return FALSE; |
497 | 493 |
498 memcpy(nonce, dc->in_buffer + 4 + P2P_HEADER_ACK_ID_OFFSET, 16); | 494 memcpy(nonce, dc->in_buffer + 4 + DC_NONCE_PACKET_NONCE, 16); |
499 | 495 |
500 if (dc->nonce_type == DC_NONCE_PLAIN) { | 496 if (dc->nonce_type == DC_NONCE_PLAIN) { |
501 if (memcmp(dc->nonce, nonce, 16) == 0) { | 497 if (memcmp(dc->nonce, nonce, 16) == 0) { |
502 purple_debug_info("msn", | 498 purple_debug_info("msn", |
503 "Nonce from buddy request and nonce from DC attempt match, " | 499 "Nonce from buddy request and nonce from DC attempt match, " |
578 | 574 |
579 case DC_STATE_HANDSHAKE: | 575 case DC_STATE_HANDSHAKE: |
580 if (!msn_dc_verify_handshake(dc, packet_length)) | 576 if (!msn_dc_verify_handshake(dc, packet_length)) |
581 return DC_PROCESS_FALLBACK; | 577 return DC_PROCESS_FALLBACK; |
582 | 578 |
583 msn_dc_send_handshake_reply(dc); | 579 msn_dc_send_handshake(dc); |
584 dc->state = DC_STATE_ESTABLISHED; | 580 dc->state = DC_STATE_ESTABLISHED; |
585 | 581 |
586 msn_slpcall_session_init(dc->slpcall); | 582 msn_slpcall_session_init(dc->slpcall); |
587 dc->slpcall = NULL; | 583 dc->slpcall = NULL; |
588 break; | 584 break; |
593 | 589 |
594 dc->state = DC_STATE_ESTABLISHED; | 590 dc->state = DC_STATE_ESTABLISHED; |
595 | 591 |
596 msn_slpcall_session_init(dc->slpcall); | 592 msn_slpcall_session_init(dc->slpcall); |
597 dc->slpcall = NULL; | 593 dc->slpcall = NULL; |
594 msn_dc_send_foo(dc); | |
598 break; | 595 break; |
599 | 596 |
600 case DC_STATE_ESTABLISHED: | 597 case DC_STATE_ESTABLISHED: |
601 | 598 if (packet_length) { |
602 if (dc->header.length) { | 599 part = msn_slpmsgpart_new_from_data(dc->in_buffer + 4, packet_length); |
603 part = msn_slpmsgpart_new_from_data(dc->in_buffer + 4, dc->header.length); | |
604 if (part) { | 600 if (part) { |
605 msn_slplink_process_msg(dc->slplink, part); | 601 msn_slplink_process_msg(dc->slplink, part); |
606 msn_slpmsgpart_unref(part); | 602 msn_slpmsgpart_unref(part); |
607 } | 603 } |
608 } | 604 } |
673 } | 669 } |
674 | 670 |
675 /* Wait for the whole packet to arrive */ | 671 /* Wait for the whole packet to arrive */ |
676 if (dc->in_pos < 4 + packet_length) | 672 if (dc->in_pos < 4 + packet_length) |
677 return; | 673 return; |
678 | |
679 if (dc->state != DC_STATE_FOO && packet_length >= P2P_PACKET_HEADER_SIZE) { | |
680 MsnP2PHeader *context; | |
681 | |
682 /* Skip packet size */ | |
683 context = msn_p2p_header_from_wire(dc->in_buffer + 4); | |
684 memcpy(&dc->header, context, P2P_PACKET_HEADER_SIZE); | |
685 g_free(context); | |
686 } | |
687 | 674 |
688 switch (msn_dc_process_packet(dc, packet_length)) { | 675 switch (msn_dc_process_packet(dc, packet_length)) { |
689 case DC_PROCESS_CLOSE: | 676 case DC_PROCESS_CLOSE: |
690 return; | 677 return; |
691 | 678 |