source: trunk/libtransmission/handshake.c @ 14155

Last change on this file since 14155 was 14155, checked in by jordan, 9 years ago

(trunk, libT) #5451: 'crash in tr_torrentGetPeerId() during incoming encrypted handshake' -- fixed.

  • Property svn:keywords set to Date Rev Author Id
File size: 34.9 KB
Line 
1/*
2 * This file Copyright (C) Mnemosyne LLC
3 *
4 * This file is licensed by the GPL version 2. Works owned by the
5 * Transmission project are granted a special exemption to clause 2 (b)
6 * so that the bulk of its code can remain under the MIT license.
7 * This exemption does not extend to derived works not owned by
8 * the Transmission project.
9 *
10 * $Id: handshake.c 14155 2013-08-05 04:39:43Z jordan $
11 */
12
13#include <assert.h>
14#include <errno.h>
15#include <string.h> /* strcmp (), strlen () */
16
17#include <event2/buffer.h>
18#include <event2/event.h>
19
20#include "transmission.h"
21#include "clients.h"
22#include "crypto.h"
23#include "handshake.h"
24#include "log.h"
25#include "peer-io.h"
26#include "peer-mgr.h"
27#include "session.h"
28#include "torrent.h"
29#include "tr-dht.h"
30#include "utils.h"
31
32/* enable LibTransmission extension protocol */
33#define ENABLE_LTEP * /
34/* fast extensions */
35#define ENABLE_FAST * /
36/* DHT */
37#define ENABLE_DHT * /
38
39/***
40****
41***/
42
43#define HANDSHAKE_NAME "\023BitTorrent protocol"
44
45enum
46{
47  /* BitTorrent Handshake Constants */
48  HANDSHAKE_NAME_LEN             = 20,
49  HANDSHAKE_FLAGS_LEN            = 8,
50  HANDSHAKE_SIZE                 = 68,
51  INCOMING_HANDSHAKE_LEN         = 48,
52
53  /* Encryption Constants */
54  PadA_MAXLEN                    = 512,
55  PadB_MAXLEN                    = 512,
56  PadC_MAXLEN                    = 512,
57  PadD_MAXLEN                    = 512,
58  VC_LENGTH                      = 8,
59  CRYPTO_PROVIDE_PLAINTEXT       = 1,
60  CRYPTO_PROVIDE_CRYPTO          = 2,
61
62  /* how long to wait before giving up on a handshake */
63  HANDSHAKE_TIMEOUT_SEC          = 30
64};
65
66
67#ifdef ENABLE_LTEP
68 #define HANDSHAKE_HAS_LTEP(bits)(((bits)[5] & 0x10) ? 1 : 0)
69 #define HANDSHAKE_SET_LTEP(bits)((bits)[5] |= 0x10)
70#else
71 #define HANDSHAKE_HAS_LTEP(bits)(0)
72 #define HANDSHAKE_SET_LTEP(bits)((void)0)
73#endif
74
75#ifdef ENABLE_FAST
76 #define HANDSHAKE_HAS_FASTEXT(bits)(((bits)[7] & 0x04) ? 1 : 0)
77 #define HANDSHAKE_SET_FASTEXT(bits)((bits)[7] |= 0x04)
78#else
79 #define HANDSHAKE_HAS_FASTEXT(bits)(0)
80 #define HANDSHAKE_SET_FASTEXT(bits)((void)0)
81#endif
82
83#ifdef ENABLE_DHT
84 #define HANDSHAKE_HAS_DHT(bits)(((bits)[7] & 0x01) ? 1 : 0)
85 #define HANDSHAKE_SET_DHT(bits)((bits)[7] |= 0x01)
86#else
87 #define HANDSHAKE_HAS_DHT(bits)(0)
88 #define HANDSHAKE_SET_DHT(bits)((void)0)
89#endif
90
91/* http://www.azureuswiki.com/index.php/Extension_negotiation_protocol
92   these macros are to be used if both extended messaging and the
93   azureus protocol is supported, they indicate which protocol is preferred */
94#define HANDSHAKE_GET_EXTPREF(reserved)    ((reserved)[5] & 0x03)
95#define HANDSHAKE_SET_EXTPREF(reserved, val)((reserved)[5] |= 0x03 & (val))
96
97typedef uint8_t handshake_state_t;
98
99struct tr_handshake
100{
101  bool                  haveReadAnythingFromPeer;
102  bool                  havePeerID;
103  bool                  haveSentBitTorrentHandshake;
104  tr_peerIo *           io;
105  tr_crypto *           crypto;
106  tr_session *          session;
107  uint8_t               mySecret[KEY_LEN];
108  handshake_state_t     state;
109  tr_encryption_mode    encryptionMode;
110  uint16_t              pad_c_len;
111  uint16_t              pad_d_len;
112  uint16_t              ia_len;
113  uint32_t              crypto_select;
114  uint32_t              crypto_provide;
115  uint8_t               myReq1[SHA_DIGEST_LENGTH];
116  handshakeDoneCB       doneCB;
117  void *                doneUserData;
118  struct event        * timeout_timer;
119};
120
121/**
122***
123**/
124
125enum
126{
127  /* incoming */
128  AWAITING_HANDSHAKE,
129  AWAITING_PEER_ID,
130  AWAITING_YA,
131  AWAITING_PAD_A,
132  AWAITING_CRYPTO_PROVIDE,
133  AWAITING_PAD_C,
134  AWAITING_IA,
135  AWAITING_PAYLOAD_STREAM,
136
137  /* outgoing */
138  AWAITING_YB,
139  AWAITING_VC,
140  AWAITING_CRYPTO_SELECT,
141  AWAITING_PAD_D,
142
143  N_STATES
144};
145
146/**
147***
148**/
149
150#define dbgmsg(handshake, ...) \
151  do { \
152    if (tr_logGetDeepEnabled ()) \
153      tr_logAddDeep (__FILE__, __LINE__, tr_peerIoGetAddrStr (handshake->io), __VA_ARGS__); \
154  } while (0)
155
156static const char*
157getStateName (const handshake_state_t state)
158{
159  static const char * const state_strings[N_STATES] =
160    {
161      /* AWAITING_HANDSHAKE      */ "awaiting handshake",
162      /* AWAITING_PEER_ID        */ "awaiting peer id",
163      /* AWAITING_YA             */ "awaiting ya",
164      /* AWAITING_PAD_A          */ "awaiting pad a",
165      /* AWAITING_CRYPTO_PROVIDE */ "awaiting crypto_provide",
166      /* AWAITING_PAD_C          */ "awaiting pad c",
167      /* AWAITING_IA             */ "awaiting ia",
168      /* AWAITING_PAYLOAD_STREAM */ "awaiting payload stream",
169      /* AWAITING_YB             */ "awaiting yb",
170      /* AWAITING_VC             */ "awaiting vc",
171      /* AWAITING_CRYPTO_SELECT  */ "awaiting crypto select",
172      /* AWAITING_PAD_D          */ "awaiting pad d"
173  };
174
175  return state<N_STATES ? state_strings[state] : "unknown state";
176}
177
178static void
179setState (tr_handshake * handshake, handshake_state_t state)
180{
181  dbgmsg (handshake, "setting to state [%s]", getStateName (state));
182  handshake->state = state;
183}
184
185static void
186setReadState (tr_handshake * handshake, handshake_state_t state)
187{
188  setState (handshake, state);
189}
190
191static bool
192buildHandshakeMessage (tr_handshake * handshake, uint8_t * buf)
193{
194  const unsigned char * peer_id = NULL;
195  const uint8_t * torrentHash;
196  tr_torrent * tor;
197  bool success;
198
199  if ((torrentHash = tr_cryptoGetTorrentHash (handshake->crypto)))
200    if ((tor = tr_torrentFindFromHash (handshake->session, torrentHash)))
201      peer_id = tr_torrentGetPeerId (tor);
202
203  if (peer_id == NULL)
204    {
205      success = false;
206    }
207  else
208    {
209      uint8_t * walk = buf;
210
211      memcpy (walk, HANDSHAKE_NAME, HANDSHAKE_NAME_LEN);
212      walk += HANDSHAKE_NAME_LEN;
213      memset (walk, 0, HANDSHAKE_FLAGS_LEN);
214      HANDSHAKE_SET_LTEP (walk);
215      HANDSHAKE_SET_FASTEXT (walk);
216
217      /* Note that this doesn't depend on whether the torrent is private.
218       * We don't accept DHT peers for a private torrent,
219       * but we participate in the DHT regardless. */
220      if (tr_dhtEnabled (handshake->session))
221        HANDSHAKE_SET_DHT (walk);
222
223      walk += HANDSHAKE_FLAGS_LEN;
224      memcpy (walk, torrentHash, SHA_DIGEST_LENGTH);
225      walk += SHA_DIGEST_LENGTH;
226      memcpy (walk, peer_id, PEER_ID_LEN);
227      walk += PEER_ID_LEN;
228
229      assert (walk - buf == HANDSHAKE_SIZE);
230      success = true;
231    }
232
233  return success;
234}
235
236static int tr_handshakeDone (tr_handshake * handshake,
237                             bool           isConnected);
238
239enum
240{
241  HANDSHAKE_OK,
242  HANDSHAKE_ENCRYPTION_WRONG,
243  HANDSHAKE_BAD_TORRENT,
244  HANDSHAKE_PEER_IS_SELF,
245};
246
247static int
248parseHandshake (tr_handshake *    handshake,
249                struct evbuffer * inbuf)
250{
251  uint8_t name[HANDSHAKE_NAME_LEN];
252  uint8_t reserved[HANDSHAKE_FLAGS_LEN];
253  uint8_t hash[SHA_DIGEST_LENGTH];
254  tr_torrent * tor;
255  uint8_t peer_id[PEER_ID_LEN];
256
257  dbgmsg (handshake, "payload: need %d, got %zu",
258          HANDSHAKE_SIZE, evbuffer_get_length (inbuf));
259
260  if (evbuffer_get_length (inbuf) < HANDSHAKE_SIZE)
261    return READ_LATER;
262
263  /* confirm the protocol */
264  tr_peerIoReadBytes (handshake->io, inbuf, name, HANDSHAKE_NAME_LEN);
265  if (memcmp (name, HANDSHAKE_NAME, HANDSHAKE_NAME_LEN))
266    return HANDSHAKE_ENCRYPTION_WRONG;
267
268  /* read the reserved bytes */
269  tr_peerIoReadBytes (handshake->io, inbuf, reserved, HANDSHAKE_FLAGS_LEN);
270
271  /* torrent hash */
272  tr_peerIoReadBytes (handshake->io, inbuf, hash, sizeof (hash));
273  assert (tr_peerIoHasTorrentHash (handshake->io));
274  if (!tr_torrentExists (handshake->session, hash)
275      || memcmp (hash, tr_peerIoGetTorrentHash (handshake->io), SHA_DIGEST_LENGTH))
276    {
277      dbgmsg (handshake, "peer returned the wrong hash. wtf?");
278      return HANDSHAKE_BAD_TORRENT;
279    }
280
281  /* peer_id */
282  tr_peerIoReadBytes (handshake->io, inbuf, peer_id, sizeof (peer_id));
283  tr_peerIoSetPeersId (handshake->io, peer_id);
284
285  /* peer id */
286  handshake->havePeerID = true;
287  dbgmsg (handshake, "peer-id is [%*.*s]", PEER_ID_LEN, PEER_ID_LEN, peer_id);
288
289  tor = tr_torrentFindFromHash (handshake->session, hash);
290  if (!memcmp (peer_id, tr_torrentGetPeerId(tor), PEER_ID_LEN))
291    {
292      dbgmsg (handshake, "streuth!  we've connected to ourselves.");
293      return HANDSHAKE_PEER_IS_SELF;
294    }
295
296  /**
297  *** Extensions
298  **/
299
300  tr_peerIoEnableDHT  (handshake->io, HANDSHAKE_HAS_DHT    (reserved));
301  tr_peerIoEnableLTEP (handshake->io, HANDSHAKE_HAS_LTEP    (reserved));
302  tr_peerIoEnableFEXT (handshake->io, HANDSHAKE_HAS_FASTEXT (reserved));
303
304  return HANDSHAKE_OK;
305}
306
307/***
308****
309****  OUTGOING CONNECTIONS
310****
311***/
312
313/* 1 A->B: Diffie Hellman Ya, PadA */
314static void
315sendYa (tr_handshake * handshake)
316{
317  int len;
318  const uint8_t * public_key;
319  char outbuf[ KEY_LEN + PadA_MAXLEN ];
320  char *walk = outbuf;
321
322  /* add our public key (Ya) */
323  public_key = tr_cryptoGetMyPublicKey (handshake->crypto, &len);
324  assert (len == KEY_LEN);
325  assert (public_key);
326  memcpy (walk, public_key, len);
327  walk += len;
328
329  /* add some bullshit padding */
330  len = tr_cryptoRandInt (PadA_MAXLEN);
331  tr_cryptoRandBuf (walk, len);
332  walk += len;
333
334  /* send it */
335  setReadState (handshake, AWAITING_YB);
336  tr_peerIoWriteBytes (handshake->io, outbuf, walk - outbuf, false);
337}
338
339static uint32_t
340getCryptoProvide (const tr_handshake * handshake)
341{
342  uint32_t provide = 0;
343
344  switch (handshake->encryptionMode)
345    {
346      case TR_ENCRYPTION_REQUIRED:
347      case TR_ENCRYPTION_PREFERRED:
348        provide |= CRYPTO_PROVIDE_CRYPTO;
349        break;
350
351      case TR_CLEAR_PREFERRED:
352        provide |= CRYPTO_PROVIDE_CRYPTO | CRYPTO_PROVIDE_PLAINTEXT;
353        break;
354    }
355
356  return provide;
357}
358
359static uint32_t
360getCryptoSelect (const tr_handshake * handshake,
361                 uint32_t             crypto_provide)
362{
363  uint32_t choices[2];
364  int i;
365  int nChoices = 0;
366
367  switch (handshake->encryptionMode)
368    {
369      case TR_ENCRYPTION_REQUIRED:
370        choices[nChoices++] = CRYPTO_PROVIDE_CRYPTO;
371        break;
372
373      case TR_ENCRYPTION_PREFERRED:
374        choices[nChoices++] = CRYPTO_PROVIDE_CRYPTO;
375        choices[nChoices++] = CRYPTO_PROVIDE_PLAINTEXT;
376        break;
377
378      case TR_CLEAR_PREFERRED:
379        choices[nChoices++] = CRYPTO_PROVIDE_PLAINTEXT;
380        choices[nChoices++] = CRYPTO_PROVIDE_CRYPTO;
381        break;
382    }
383
384  for (i=0; i<nChoices; ++i)
385    if (crypto_provide & choices[i])
386      return choices[i];
387
388  return 0;
389}
390
391static int
392readYb (tr_handshake * handshake, struct evbuffer * inbuf)
393{
394  int isEncrypted;
395  const uint8_t * secret;
396  uint8_t yb[KEY_LEN];
397  struct evbuffer * outbuf;
398  size_t needlen = HANDSHAKE_NAME_LEN;
399
400  if (evbuffer_get_length (inbuf) < needlen)
401    return READ_LATER;
402
403  isEncrypted = memcmp (evbuffer_pullup (inbuf, HANDSHAKE_NAME_LEN), HANDSHAKE_NAME, HANDSHAKE_NAME_LEN);
404  if (isEncrypted)
405    {
406      needlen = KEY_LEN;
407
408      if (evbuffer_get_length (inbuf) < needlen)
409        return READ_LATER;
410    }
411
412  dbgmsg (handshake, "got an %s handshake", (isEncrypted ? "encrypted" : "plain"));
413
414  tr_peerIoSetEncryption (handshake->io, isEncrypted ? PEER_ENCRYPTION_RC4
415                                                     : PEER_ENCRYPTION_NONE);
416  if (!isEncrypted)
417    {
418      setState (handshake, AWAITING_HANDSHAKE);
419      return READ_NOW;
420    }
421
422  handshake->haveReadAnythingFromPeer = true;
423
424  /* compute the secret */
425  evbuffer_remove (inbuf, yb, KEY_LEN);
426  secret = tr_cryptoComputeSecret (handshake->crypto, yb);
427  memcpy (handshake->mySecret, secret, KEY_LEN);
428
429  /* now send these: HASH ('req1', S), HASH ('req2', SKEY) xor HASH ('req3', S),
430   * ENCRYPT (VC, crypto_provide, len (PadC), PadC, len (IA)), ENCRYPT (IA) */
431  outbuf = evbuffer_new ();
432
433  /* HASH ('req1', S) */
434  {
435    uint8_t req1[SHA_DIGEST_LENGTH];
436    tr_sha1 (req1, "req1", 4, secret, KEY_LEN, NULL);
437    evbuffer_add (outbuf, req1, SHA_DIGEST_LENGTH);
438  }
439
440  /* HASH ('req2', SKEY) xor HASH ('req3', S) */
441  {
442    int i;
443    uint8_t req2[SHA_DIGEST_LENGTH];
444    uint8_t req3[SHA_DIGEST_LENGTH];
445    uint8_t buf[SHA_DIGEST_LENGTH];
446
447    tr_sha1 (req2, "req2", 4, tr_cryptoGetTorrentHash (handshake->crypto), SHA_DIGEST_LENGTH, NULL);
448    tr_sha1 (req3, "req3", 4, secret, KEY_LEN, NULL);
449
450    for (i=0; i<SHA_DIGEST_LENGTH; ++i)
451      buf[i] = req2[i] ^ req3[i];
452
453    evbuffer_add (outbuf, buf, SHA_DIGEST_LENGTH);
454  }
455
456  /* ENCRYPT (VC, crypto_provide, len (PadC), PadC
457   * PadC is reserved for future extensions to the handshake...
458   * standard practice at this time is for it to be zero-length */
459  {
460    uint8_t vc[VC_LENGTH] = { 0, 0, 0, 0, 0, 0, 0, 0 };
461
462    tr_peerIoWriteBuf (handshake->io, outbuf, false);
463    tr_cryptoEncryptInit (handshake->crypto);
464    tr_peerIoSetEncryption (handshake->io, PEER_ENCRYPTION_RC4);
465
466    evbuffer_add        (outbuf, vc, VC_LENGTH);
467    evbuffer_add_uint32 (outbuf, getCryptoProvide (handshake));
468    evbuffer_add_uint16 (outbuf, 0);
469  }
470
471  /* ENCRYPT len (IA)), ENCRYPT (IA) */
472  {
473    uint8_t msg[HANDSHAKE_SIZE];
474    if (!buildHandshakeMessage (handshake, msg))
475      return tr_handshakeDone (handshake, false);
476
477    evbuffer_add_uint16 (outbuf, sizeof (msg));
478    evbuffer_add        (outbuf, msg, sizeof (msg));
479
480    handshake->haveSentBitTorrentHandshake = 1;
481  }
482
483  /* send it */
484  tr_cryptoDecryptInit (handshake->crypto);
485  setReadState (handshake, AWAITING_VC);
486  tr_peerIoWriteBuf (handshake->io, outbuf, false);
487
488  /* cleanup */
489  evbuffer_free (outbuf);
490  return READ_LATER;
491}
492
493static int
494readVC (tr_handshake    * handshake,
495        struct evbuffer * inbuf)
496{
497  uint8_t tmp[VC_LENGTH];
498  const int key_len = VC_LENGTH;
499  const uint8_t key[VC_LENGTH] = { 0, 0, 0, 0, 0, 0, 0, 0 };
500
501  /* note: this works w/o having to `unwind' the buffer if
502   * we read too much, but it is pretty brute-force.
503   * it would be nice to make this cleaner. */
504  for (;;)
505    {
506      if (evbuffer_get_length (inbuf) < VC_LENGTH)
507        {
508          dbgmsg (handshake, "not enough bytes... returning read_more");
509          return READ_LATER;
510        }
511
512      memcpy (tmp, evbuffer_pullup (inbuf, key_len), key_len);
513      tr_cryptoDecryptInit (handshake->crypto);
514      tr_cryptoDecrypt (handshake->crypto, key_len, tmp, tmp);
515      if (!memcmp (tmp, key, key_len))
516        break;
517
518      evbuffer_drain (inbuf, 1);
519    }
520
521  dbgmsg (handshake, "got it!");
522  evbuffer_drain (inbuf, key_len);
523  setState (handshake, AWAITING_CRYPTO_SELECT);
524  return READ_NOW;
525}
526
527static int
528readCryptoSelect (tr_handshake    * handshake,
529                  struct evbuffer * inbuf)
530{
531  uint16_t pad_d_len;
532  uint32_t crypto_select;
533  static const size_t needlen = sizeof (uint32_t) + sizeof (uint16_t);
534
535  if (evbuffer_get_length (inbuf) < needlen)
536    return READ_LATER;
537
538  tr_peerIoReadUint32 (handshake->io, inbuf, &crypto_select);
539  handshake->crypto_select = crypto_select;
540  dbgmsg (handshake, "crypto select is %d", (int)crypto_select);
541  if (!(crypto_select & getCryptoProvide (handshake)))
542    {
543      dbgmsg (handshake, "peer selected an encryption option we didn't offer");
544      return tr_handshakeDone (handshake, false);
545    }
546
547  tr_peerIoReadUint16 (handshake->io, inbuf, &pad_d_len);
548  dbgmsg (handshake, "pad_d_len is %d", (int)pad_d_len);
549
550  if (pad_d_len > 512)
551    {
552      dbgmsg (handshake, "encryption handshake: pad_d_len is too long");
553      return tr_handshakeDone (handshake, false);
554    }
555
556  handshake->pad_d_len = pad_d_len;
557
558  setState (handshake, AWAITING_PAD_D);
559  return READ_NOW;
560}
561
562static int
563readPadD (tr_handshake    * handshake,
564          struct evbuffer * inbuf)
565{
566  const size_t needlen = handshake->pad_d_len;
567
568  dbgmsg (handshake, "pad d: need %zu, got %zu",
569          needlen, evbuffer_get_length (inbuf));
570  if (evbuffer_get_length (inbuf) < needlen)
571    return READ_LATER;
572
573  tr_peerIoDrain (handshake->io, inbuf, needlen);
574
575  tr_peerIoSetEncryption (handshake->io, handshake->crypto_select);
576
577  setState (handshake, AWAITING_HANDSHAKE);
578  return READ_NOW;
579}
580
581/***
582****
583****  INCOMING CONNECTIONS
584****
585***/
586
587static int
588readHandshake (tr_handshake    * handshake,
589               struct evbuffer * inbuf)
590{
591  uint8_t pstrlen;
592  uint8_t pstr[20];
593  uint8_t reserved[HANDSHAKE_FLAGS_LEN];
594  uint8_t hash[SHA_DIGEST_LENGTH];
595
596  dbgmsg (handshake, "payload: need %d, got %zu",
597          INCOMING_HANDSHAKE_LEN, evbuffer_get_length (inbuf));
598
599  if (evbuffer_get_length (inbuf) < INCOMING_HANDSHAKE_LEN)
600    return READ_LATER;
601
602  handshake->haveReadAnythingFromPeer = true;
603
604  pstrlen = evbuffer_pullup (inbuf, 1)[0]; /* peek, don't read. We may be
605                                              handing inbuf to AWAITING_YA */
606
607  if (pstrlen == 19) /* unencrypted */
608    {
609      tr_peerIoSetEncryption (handshake->io, PEER_ENCRYPTION_NONE);
610
611      if (handshake->encryptionMode == TR_ENCRYPTION_REQUIRED)
612        {
613          dbgmsg (handshake, "peer is unencrypted, and we're disallowing that");
614          return tr_handshakeDone (handshake, false);
615        }
616    }
617  else /* encrypted or corrupt */
618    {
619      tr_peerIoSetEncryption (handshake->io, PEER_ENCRYPTION_RC4);
620
621      if (tr_peerIoIsIncoming (handshake->io))
622        {
623          dbgmsg (handshake, "I think peer is sending us an encrypted handshake...");
624          setState (handshake, AWAITING_YA);
625          return READ_NOW;
626        }
627
628      tr_cryptoDecrypt (handshake->crypto, 1, &pstrlen, &pstrlen);
629
630      if (pstrlen != 19)
631        {
632          dbgmsg (handshake, "I think peer has sent us a corrupt handshake...");
633          return tr_handshakeDone (handshake, false);
634        }
635    }
636
637  evbuffer_drain (inbuf, 1);
638
639  /* pstr (BitTorrent) */
640  assert (pstrlen == 19);
641  tr_peerIoReadBytes (handshake->io, inbuf, pstr, pstrlen);
642  pstr[pstrlen] = '\0';
643  if (memcmp (pstr, "BitTorrent protocol", 19))
644    return tr_handshakeDone (handshake, false);
645
646  /* reserved bytes */
647  tr_peerIoReadBytes (handshake->io, inbuf, reserved, sizeof (reserved));
648
649  /**
650  *** Extensions
651  **/
652
653  tr_peerIoEnableDHT  (handshake->io, HANDSHAKE_HAS_DHT     (reserved));
654  tr_peerIoEnableLTEP (handshake->io, HANDSHAKE_HAS_LTEP    (reserved));
655  tr_peerIoEnableFEXT (handshake->io, HANDSHAKE_HAS_FASTEXT (reserved));
656
657  /* torrent hash */
658  tr_peerIoReadBytes (handshake->io, inbuf, hash, sizeof (hash));
659  if (tr_peerIoIsIncoming (handshake->io))
660    {
661      if (!tr_torrentExists (handshake->session, hash))
662        {
663          dbgmsg (handshake, "peer is trying to connect to us for a torrent we don't have.");
664          return tr_handshakeDone (handshake, false);
665        }
666      else
667        {
668          assert (!tr_peerIoHasTorrentHash (handshake->io));
669          tr_peerIoSetTorrentHash (handshake->io, hash);
670        }
671    }
672  else /* outgoing */
673    {
674      assert (tr_peerIoHasTorrentHash (handshake->io));
675
676      if (memcmp (hash, tr_peerIoGetTorrentHash (handshake->io), SHA_DIGEST_LENGTH))
677        {
678          dbgmsg (handshake, "peer returned the wrong hash. wtf?");
679          return tr_handshakeDone (handshake, false);
680        }
681    }
682
683  /**
684  ***  If it's an incoming message, we need to send a response handshake
685  **/
686
687  if (!handshake->haveSentBitTorrentHandshake)
688    {
689      uint8_t msg[HANDSHAKE_SIZE];
690      if (!buildHandshakeMessage (handshake, msg))
691        return tr_handshakeDone (handshake, false);
692      tr_peerIoWriteBytes (handshake->io, msg, sizeof (msg), false);
693      handshake->haveSentBitTorrentHandshake = 1;
694    }
695
696  setReadState (handshake, AWAITING_PEER_ID);
697  return READ_NOW;
698}
699
700static int
701readPeerId (tr_handshake    * handshake,
702            struct evbuffer * inbuf)
703{
704  bool connected_to_self;
705  char client[128];
706  uint8_t peer_id[PEER_ID_LEN];
707  tr_torrent * tor;
708
709  if (evbuffer_get_length (inbuf) < PEER_ID_LEN)
710    return READ_LATER;
711
712  /* peer id */
713  tr_peerIoReadBytes (handshake->io, inbuf, peer_id, PEER_ID_LEN);
714  tr_peerIoSetPeersId (handshake->io, peer_id);
715  handshake->havePeerID = true;
716  tr_clientForId (client, sizeof (client), peer_id);
717  dbgmsg (handshake, "peer-id is [%s] ... isIncoming is %d", client,
718          tr_peerIoIsIncoming (handshake->io));
719
720  /* if we've somehow connected to ourselves, don't keep the connection */
721  tor = tr_torrentFindFromHash (handshake->session, tr_peerIoGetTorrentHash (handshake->io));
722  connected_to_self = (tor != NULL) && !memcmp (peer_id, tr_torrentGetPeerId(tor), PEER_ID_LEN);
723
724  return tr_handshakeDone (handshake, !connected_to_self);
725}
726
727static int
728readYa (tr_handshake    * handshake,
729        struct evbuffer * inbuf)
730{
731  uint8_t ya[KEY_LEN];
732  uint8_t * walk, outbuf[KEY_LEN + PadB_MAXLEN];
733  const uint8_t * myKey;
734  const uint8_t * secret;
735  int len;
736
737  dbgmsg (handshake, "in readYa... need %d, have %zu",
738          KEY_LEN, evbuffer_get_length (inbuf));
739  if (evbuffer_get_length (inbuf) < KEY_LEN)
740    return READ_LATER;
741
742  /* read the incoming peer's public key */
743  evbuffer_remove (inbuf, ya, KEY_LEN);
744  secret = tr_cryptoComputeSecret (handshake->crypto, ya);
745  memcpy (handshake->mySecret, secret, KEY_LEN);
746  tr_sha1 (handshake->myReq1, "req1", 4, secret, KEY_LEN, NULL);
747
748  /* send our public key to the peer */
749  dbgmsg (handshake, "sending B->A: Diffie Hellman Yb, PadB");
750  walk = outbuf;
751  myKey = tr_cryptoGetMyPublicKey (handshake->crypto, &len);
752  memcpy (walk, myKey, len);
753  walk += len;
754  len = tr_cryptoRandInt (PadB_MAXLEN);
755  tr_cryptoRandBuf (walk, len);
756  walk += len;
757
758  setReadState (handshake, AWAITING_PAD_A);
759  tr_peerIoWriteBytes (handshake->io, outbuf, walk - outbuf, false);
760  return READ_NOW;
761}
762
763static int
764readPadA (tr_handshake * handshake, struct evbuffer * inbuf)
765{
766  /* resynchronizing on HASH ('req1',S) */
767  struct evbuffer_ptr ptr = evbuffer_search (inbuf, (const char*)handshake->myReq1, SHA_DIGEST_LENGTH, NULL);
768
769  if (ptr.pos != -1) /* match */
770    {
771      evbuffer_drain (inbuf, ptr.pos);
772      dbgmsg (handshake, "found it... looking setting to awaiting_crypto_provide");
773      setState (handshake, AWAITING_CRYPTO_PROVIDE);
774      return READ_NOW;
775    }
776  else
777    {
778      const size_t len = evbuffer_get_length (inbuf);
779      if (len > SHA_DIGEST_LENGTH)
780        evbuffer_drain (inbuf, len - SHA_DIGEST_LENGTH);
781      return READ_LATER;
782    }
783}
784
785static int
786readCryptoProvide (tr_handshake    * handshake,
787                   struct evbuffer * inbuf)
788{
789  /* HASH ('req2', SKEY) xor HASH ('req3', S), ENCRYPT (VC, crypto_provide, len (PadC)) */
790
791  int i;
792  uint8_t vc_in[VC_LENGTH];
793  uint8_t req2[SHA_DIGEST_LENGTH];
794  uint8_t req3[SHA_DIGEST_LENGTH];
795  uint8_t obfuscatedTorrentHash[SHA_DIGEST_LENGTH];
796  uint16_t padc_len = 0;
797  uint32_t crypto_provide = 0;
798  tr_torrent * tor;
799  const size_t needlen = SHA_DIGEST_LENGTH /* HASH ('req1',s) */
800                       + SHA_DIGEST_LENGTH /* HASH ('req2', SKEY) xor HASH ('req3', S) */
801                       + VC_LENGTH
802                       + sizeof (crypto_provide)
803                       + sizeof (padc_len);
804
805  if (evbuffer_get_length (inbuf) < needlen)
806    return READ_LATER;
807
808  /* TODO: confirm they sent HASH ('req1',S) here? */
809  evbuffer_drain (inbuf, SHA_DIGEST_LENGTH);
810
811  /* This next piece is HASH ('req2', SKEY) xor HASH ('req3', S) ...
812   * we can get the first half of that (the obufscatedTorrentHash)
813   * by building the latter and xor'ing it with what the peer sent us */
814  dbgmsg (handshake, "reading obfuscated torrent hash...");
815  evbuffer_remove (inbuf, req2, SHA_DIGEST_LENGTH);
816  tr_sha1 (req3, "req3", 4, handshake->mySecret, KEY_LEN, NULL);
817  for (i=0; i<SHA_DIGEST_LENGTH; ++i)
818    obfuscatedTorrentHash[i] = req2[i] ^ req3[i];
819  if ((tor = tr_torrentFindFromObfuscatedHash (handshake->session, obfuscatedTorrentHash)))
820    {
821      const bool clientIsSeed = tr_torrentIsSeed (tor);
822      const bool peerIsSeed = tr_peerMgrPeerIsSeed (tor, tr_peerIoGetAddress (handshake->io, NULL));
823      dbgmsg (handshake, "got INCOMING connection's encrypted handshake for torrent [%s]", tr_torrentName (tor));
824      tr_peerIoSetTorrentHash (handshake->io, tor->info.hash);
825
826      if (clientIsSeed && peerIsSeed)
827        {
828          dbgmsg (handshake, "another seed tried to reconnect to us!");
829          return tr_handshakeDone (handshake, false);
830        }
831    }
832  else
833    {
834      dbgmsg (handshake, "can't find that torrent...");
835      return tr_handshakeDone (handshake, false);
836    }
837
838  /* next part: ENCRYPT (VC, crypto_provide, len (PadC), */
839
840  tr_cryptoDecryptInit (handshake->crypto);
841
842  tr_peerIoReadBytes (handshake->io, inbuf, vc_in, VC_LENGTH);
843
844  tr_peerIoReadUint32 (handshake->io, inbuf, &crypto_provide);
845  handshake->crypto_provide = crypto_provide;
846  dbgmsg (handshake, "crypto_provide is %d", (int)crypto_provide);
847
848  tr_peerIoReadUint16 (handshake->io, inbuf, &padc_len);
849  dbgmsg (handshake, "padc is %d", (int)padc_len);
850  handshake->pad_c_len = padc_len;
851  setState (handshake, AWAITING_PAD_C);
852  return READ_NOW;
853}
854
855static int
856readPadC (tr_handshake    * handshake,
857          struct evbuffer * inbuf)
858{
859  char * padc;
860  uint16_t ia_len;
861  const size_t needlen = handshake->pad_c_len + sizeof (uint16_t);
862
863  if (evbuffer_get_length (inbuf) < needlen)
864    return READ_LATER;
865
866  /* read the throwaway padc */
867  padc = tr_new (char, handshake->pad_c_len);
868  tr_peerIoReadBytes (handshake->io, inbuf, padc, handshake->pad_c_len);
869  tr_free (padc);
870
871  /* read ia_len */
872  tr_peerIoReadUint16 (handshake->io, inbuf, &ia_len);
873  dbgmsg (handshake, "ia_len is %d", (int)ia_len);
874  handshake->ia_len = ia_len;
875  setState (handshake, AWAITING_IA);
876  return READ_NOW;
877}
878
879static int
880readIA (tr_handshake    * handshake,
881        struct evbuffer * inbuf)
882{
883  const size_t needlen = handshake->ia_len;
884  struct evbuffer * outbuf;
885  uint32_t crypto_select;
886
887  dbgmsg (handshake, "reading IA... have %zu, need %zu",
888          evbuffer_get_length (inbuf), needlen);
889  if (evbuffer_get_length (inbuf) < needlen)
890    return READ_LATER;
891
892  /**
893  ***  B->A: ENCRYPT (VC, crypto_select, len (padD), padD), ENCRYPT2 (Payload Stream)
894  **/
895
896  tr_cryptoEncryptInit (handshake->crypto);
897  outbuf = evbuffer_new ();
898
899  {
900    /* send VC */
901    uint8_t vc[VC_LENGTH];
902    memset (vc, 0, VC_LENGTH);
903    evbuffer_add (outbuf, vc, VC_LENGTH);
904    dbgmsg (handshake, "sending vc");
905  }
906
907  /* send crypto_select */
908  crypto_select = getCryptoSelect (handshake, handshake->crypto_provide);
909  if (crypto_select)
910    {
911      dbgmsg (handshake, "selecting crypto mode '%d'", (int)crypto_select);
912      evbuffer_add_uint32 (outbuf, crypto_select);
913    }
914  else
915    {
916      dbgmsg (handshake, "peer didn't offer an encryption mode we like.");
917      evbuffer_free (outbuf);
918      return tr_handshakeDone (handshake, false);
919    }
920
921  dbgmsg (handshake, "sending pad d");
922  /* ENCRYPT (VC, crypto_provide, len (PadD), PadD
923   * PadD is reserved for future extensions to the handshake...
924   * standard practice at this time is for it to be zero-length */
925  {
926    const uint16_t len = 0;
927    evbuffer_add_uint16 (outbuf, len);
928  }
929
930  /* maybe de-encrypt our connection */
931  if (crypto_select == CRYPTO_PROVIDE_PLAINTEXT)
932    {
933      tr_peerIoWriteBuf (handshake->io, outbuf, false);
934      tr_peerIoSetEncryption (handshake->io, PEER_ENCRYPTION_NONE);
935    }
936
937  dbgmsg (handshake, "sending handshake");
938  /* send our handshake */
939  {
940    uint8_t msg[HANDSHAKE_SIZE];
941    if (!buildHandshakeMessage (handshake, msg))
942      return tr_handshakeDone (handshake, false);
943
944    evbuffer_add (outbuf, msg, sizeof (msg));
945    handshake->haveSentBitTorrentHandshake = 1;
946  }
947
948  /* send it out */
949  tr_peerIoWriteBuf (handshake->io, outbuf, false);
950  evbuffer_free (outbuf);
951
952  /* now await the handshake */
953  setState (handshake, AWAITING_PAYLOAD_STREAM);
954  return READ_NOW;
955}
956
957static int
958readPayloadStream (tr_handshake    * handshake,
959                   struct evbuffer * inbuf)
960{
961  int i;
962  const size_t needlen = HANDSHAKE_SIZE;
963
964  dbgmsg (handshake, "reading payload stream... have %zu, need %zu",
965          evbuffer_get_length (inbuf), needlen);
966  if (evbuffer_get_length (inbuf) < needlen)
967    return READ_LATER;
968
969  /* parse the handshake ... */
970  i = parseHandshake (handshake, inbuf);
971  dbgmsg (handshake, "parseHandshake returned %d", i);
972  if (i != HANDSHAKE_OK)
973    return tr_handshakeDone (handshake, false);
974
975  /* we've completed the BT handshake... pass the work on to peer-msgs */
976  return tr_handshakeDone (handshake, true);
977}
978
979/***
980****
981****
982****
983***/
984
985static ReadState
986canRead (struct tr_peerIo * io, void * arg, size_t * piece)
987{
988  ReadState ret;
989  tr_handshake * handshake = arg;
990  struct evbuffer * inbuf = tr_peerIoGetReadBuffer (io);
991  bool readyForMore = true;
992
993  assert (tr_isPeerIo (io));
994
995  /* no piece data in handshake */
996  *piece = 0;
997
998  dbgmsg (handshake, "handling canRead; state is [%s]",
999          getStateName (handshake->state));
1000
1001  while (readyForMore)
1002    {
1003      switch (handshake->state)
1004        {
1005          case AWAITING_HANDSHAKE:
1006            ret = readHandshake (handshake, inbuf);
1007            break;
1008
1009          case AWAITING_PEER_ID:
1010            ret = readPeerId (handshake, inbuf);
1011            break;
1012
1013          case AWAITING_YA:
1014            ret = readYa (handshake, inbuf);
1015            break;
1016
1017          case AWAITING_PAD_A:
1018            ret = readPadA (handshake, inbuf);
1019            break;
1020
1021          case AWAITING_CRYPTO_PROVIDE:
1022            ret = readCryptoProvide (handshake, inbuf);
1023            break;
1024
1025          case AWAITING_PAD_C:
1026            ret = readPadC (handshake, inbuf);
1027            break;
1028
1029          case AWAITING_IA:
1030            ret = readIA (handshake, inbuf);
1031            break;
1032
1033          case AWAITING_PAYLOAD_STREAM:
1034            ret = readPayloadStream (handshake, inbuf);
1035            break;
1036
1037          case AWAITING_YB:
1038            ret = readYb (handshake, inbuf);
1039            break;
1040
1041          case AWAITING_VC:
1042            ret = readVC (handshake, inbuf);
1043            break;
1044
1045          case AWAITING_CRYPTO_SELECT:
1046            ret = readCryptoSelect (handshake, inbuf);
1047            break;
1048
1049          case AWAITING_PAD_D:
1050            ret = readPadD (handshake, inbuf);
1051            break;
1052
1053          default:
1054            assert (0);
1055        }
1056
1057      if (ret != READ_NOW)
1058        readyForMore = false;
1059      else if (handshake->state == AWAITING_PAD_C)
1060        readyForMore = evbuffer_get_length (inbuf) >= handshake->pad_c_len;
1061      else if (handshake->state == AWAITING_PAD_D)
1062        readyForMore = evbuffer_get_length (inbuf) >= handshake->pad_d_len;
1063      else if (handshake->state == AWAITING_IA)
1064        readyForMore = evbuffer_get_length (inbuf) >= handshake->ia_len;
1065    }
1066
1067  return ret;
1068}
1069
1070static bool
1071fireDoneFunc (tr_handshake * handshake, bool isConnected)
1072{
1073  const uint8_t * peer_id = isConnected && handshake->havePeerID
1074                          ? tr_peerIoGetPeersId (handshake->io)
1075                          : NULL;
1076  const bool success = (*handshake->doneCB)(handshake,
1077                                            handshake->io,
1078                                            handshake->haveReadAnythingFromPeer,
1079                                            isConnected,
1080                                            peer_id,
1081                                            handshake->doneUserData);
1082
1083  return success;
1084}
1085
1086static void
1087tr_handshakeFree (tr_handshake * handshake)
1088{
1089  if (handshake->io)
1090    tr_peerIoUnref (handshake->io); /* balanced by the ref in tr_handshakeNew */
1091
1092  event_free (handshake->timeout_timer);
1093  tr_free (handshake);
1094}
1095
1096static int
1097tr_handshakeDone (tr_handshake * handshake, bool isOK)
1098{
1099  bool success;
1100
1101  dbgmsg (handshake, "handshakeDone: %s", isOK ? "connected" : "aborting");
1102  tr_peerIoSetIOFuncs (handshake->io, NULL, NULL, NULL, NULL);
1103
1104  success = fireDoneFunc (handshake, isOK);
1105
1106  tr_handshakeFree (handshake);
1107
1108  return success ? READ_LATER : READ_ERR;
1109}
1110
1111void
1112tr_handshakeAbort (tr_handshake * handshake)
1113{
1114  if (handshake != NULL)
1115    tr_handshakeDone (handshake, false);
1116}
1117
1118static void
1119gotError (tr_peerIo  * io,
1120          short        what,
1121          void       * vhandshake)
1122{
1123  int errcode = errno;
1124  tr_handshake * handshake = vhandshake;
1125
1126  if (io->utp_socket && !io->isIncoming && handshake->state == AWAITING_YB)
1127    {
1128      /* This peer probably doesn't speak uTP. */
1129
1130      tr_torrent *tor;
1131
1132      if (tr_peerIoHasTorrentHash (io))
1133        tor = tr_torrentFindFromHash (handshake->session, tr_peerIoGetTorrentHash (io));
1134      else
1135        tor = NULL;
1136
1137      /* Don't mark a peer as non-uTP unless it's really a connect failure. */
1138      if ((errcode == ETIMEDOUT || errcode == ECONNREFUSED) && tr_isTorrent(tor))
1139        tr_peerMgrSetUtpFailed (tor, tr_peerIoGetAddress (io, NULL), true);
1140
1141      if (!tr_peerIoReconnect (handshake->io))
1142        {
1143          uint8_t msg[HANDSHAKE_SIZE];
1144          buildHandshakeMessage (handshake, msg);
1145          handshake->haveSentBitTorrentHandshake = 1;
1146          setReadState (handshake, AWAITING_HANDSHAKE);
1147          tr_peerIoWriteBytes (handshake->io, msg, sizeof (msg), false);
1148        }
1149    }
1150
1151  /* if the error happened while we were sending a public key, we might
1152   * have encountered a peer that doesn't do encryption... reconnect and
1153   * try a plaintext handshake */
1154  if (((handshake->state == AWAITING_YB) || (handshake->state == AWAITING_VC))
1155      && (handshake->encryptionMode != TR_ENCRYPTION_REQUIRED)
1156      && (!tr_peerIoReconnect (handshake->io)))
1157    {
1158      uint8_t msg[HANDSHAKE_SIZE];
1159
1160      dbgmsg (handshake, "handshake failed, trying plaintext...");
1161      buildHandshakeMessage (handshake, msg);
1162      handshake->haveSentBitTorrentHandshake = 1;
1163      setReadState (handshake, AWAITING_HANDSHAKE);
1164      tr_peerIoWriteBytes (handshake->io, msg, sizeof (msg), false);
1165    }
1166  else
1167    {
1168      dbgmsg (handshake, "libevent got an error what==%d, errno=%d (%s)",
1169                         (int)what, errno, tr_strerror (errno));
1170      tr_handshakeDone (handshake, false);
1171    }
1172}
1173
1174/**
1175***
1176**/
1177
1178static void
1179handshakeTimeout (int foo UNUSED, short bar UNUSED, void * handshake)
1180{
1181  tr_handshakeAbort (handshake);
1182}
1183
1184tr_handshake*
1185tr_handshakeNew (tr_peerIo           * io,
1186                 tr_encryption_mode    encryptionMode,
1187                 handshakeDoneCB       doneCB,
1188                 void                * doneUserData)
1189{
1190  tr_handshake * handshake;
1191  tr_session * session = tr_peerIoGetSession (io);
1192
1193  handshake = tr_new0 (tr_handshake, 1);
1194  handshake->io = io;
1195  handshake->crypto = tr_peerIoGetCrypto (io);
1196  handshake->encryptionMode = encryptionMode;
1197  handshake->doneCB = doneCB;
1198  handshake->doneUserData = doneUserData;
1199  handshake->session = session;
1200  handshake->timeout_timer = evtimer_new (session->event_base, handshakeTimeout, handshake);
1201  tr_timerAdd (handshake->timeout_timer, HANDSHAKE_TIMEOUT_SEC, 0);
1202
1203  tr_peerIoRef (io); /* balanced by the unref in tr_handshakeFree */
1204  tr_peerIoSetIOFuncs (handshake->io, canRead, NULL, gotError, handshake);
1205  tr_peerIoSetEncryption (io, PEER_ENCRYPTION_NONE);
1206
1207  if (tr_peerIoIsIncoming (handshake->io))
1208    {
1209      setReadState (handshake, AWAITING_HANDSHAKE);
1210    }
1211  else if (encryptionMode != TR_CLEAR_PREFERRED)
1212    {
1213      sendYa (handshake);
1214    }
1215  else
1216    {
1217      uint8_t msg[HANDSHAKE_SIZE];
1218      buildHandshakeMessage (handshake, msg);
1219
1220      handshake->haveSentBitTorrentHandshake = 1;
1221      setReadState (handshake, AWAITING_HANDSHAKE);
1222      tr_peerIoWriteBytes (handshake->io, msg, sizeof (msg), false);
1223    }
1224
1225  return handshake;
1226}
1227
1228struct tr_peerIo*
1229tr_handshakeGetIO (tr_handshake * handshake)
1230{
1231  assert (handshake != NULL);
1232  assert (handshake->io != NULL);
1233
1234  return handshake->io;
1235}
1236
1237struct tr_peerIo*
1238tr_handshakeStealIO (tr_handshake * handshake)
1239{
1240  struct tr_peerIo * io;
1241
1242  assert (handshake != NULL);
1243  assert (handshake->io != NULL);
1244
1245  io = handshake->io;
1246  handshake->io = NULL;
1247  return io;
1248}
1249
1250const tr_address *
1251tr_handshakeGetAddr (const struct tr_handshake * handshake,
1252                     tr_port                   * port)
1253{
1254  assert (handshake != NULL);
1255  assert (handshake->io != NULL);
1256
1257  return tr_peerIoGetAddress (handshake->io, port);
1258}
1259
Note: See TracBrowser for help on using the repository browser.