source: trunk/libtransmission/handshake.c

Last change on this file was 14718, checked in by mikedld, 5 years ago

Explicitly compare result of str(n)cmp/memcmp to signify that it's not boolean

  • Property svn:keywords set to Date Rev Author Id
File size: 35.0 KB
Line 
1/*
2 * This file Copyright (C) 2007-2014 Mnemosyne LLC
3 *
4 * It may be used under the GNU GPL versions 2 or 3
5 * or any future license endorsed by Mnemosyne LLC.
6 *
7 * $Id: handshake.c 14718 2016-03-13 22:11:01Z mikedld $
8 */
9
10#include <assert.h>
11#include <errno.h>
12#include <string.h> /* strcmp (), strlen () */
13
14#include <event2/buffer.h>
15#include <event2/event.h>
16
17#include "transmission.h"
18#include "clients.h"
19#include "crypto-utils.h"
20#include "handshake.h"
21#include "log.h"
22#include "peer-io.h"
23#include "peer-mgr.h"
24#include "session.h"
25#include "torrent.h"
26#include "tr-dht.h"
27#include "utils.h"
28
29/* enable LibTransmission extension protocol */
30#define ENABLE_LTEP * /
31/* fast extensions */
32#define ENABLE_FAST * /
33/* DHT */
34#define ENABLE_DHT * /
35
36/***
37****
38***/
39
40#define HANDSHAKE_NAME "\023BitTorrent protocol"
41
42enum
43{
44  /* BitTorrent Handshake Constants */
45  HANDSHAKE_NAME_LEN             = 20,
46  HANDSHAKE_FLAGS_LEN            = 8,
47  HANDSHAKE_SIZE                 = 68,
48  INCOMING_HANDSHAKE_LEN         = 48,
49
50  /* Encryption Constants */
51  PadA_MAXLEN                    = 512,
52  PadB_MAXLEN                    = 512,
53  PadC_MAXLEN                    = 512,
54  PadD_MAXLEN                    = 512,
55  VC_LENGTH                      = 8,
56  CRYPTO_PROVIDE_PLAINTEXT       = 1,
57  CRYPTO_PROVIDE_CRYPTO          = 2,
58
59  /* how long to wait before giving up on a handshake */
60  HANDSHAKE_TIMEOUT_SEC          = 30
61};
62
63
64#ifdef ENABLE_LTEP
65 #define HANDSHAKE_HAS_LTEP(bits)(((bits)[5] & 0x10) != 0)
66 #define HANDSHAKE_SET_LTEP(bits)((bits)[5] |= 0x10)
67#else
68 #define HANDSHAKE_HAS_LTEP(bits)(false)
69 #define HANDSHAKE_SET_LTEP(bits)((void)0)
70#endif
71
72#ifdef ENABLE_FAST
73 #define HANDSHAKE_HAS_FASTEXT(bits)(((bits)[7] & 0x04) != 0)
74 #define HANDSHAKE_SET_FASTEXT(bits)((bits)[7] |= 0x04)
75#else
76 #define HANDSHAKE_HAS_FASTEXT(bits)(false)
77 #define HANDSHAKE_SET_FASTEXT(bits)((void)0)
78#endif
79
80#ifdef ENABLE_DHT
81 #define HANDSHAKE_HAS_DHT(bits)(((bits)[7] & 0x01) != 0)
82 #define HANDSHAKE_SET_DHT(bits)((bits)[7] |= 0x01)
83#else
84 #define HANDSHAKE_HAS_DHT(bits)(false)
85 #define HANDSHAKE_SET_DHT(bits)((void)0)
86#endif
87
88/* http://www.azureuswiki.com/index.php/Extension_negotiation_protocol
89   these macros are to be used if both extended messaging and the
90   azureus protocol is supported, they indicate which protocol is preferred */
91#define HANDSHAKE_GET_EXTPREF(reserved)    ((reserved)[5] & 0x03)
92#define HANDSHAKE_SET_EXTPREF(reserved, val)((reserved)[5] |= 0x03 & (val))
93
94/**
95***
96**/
97
98typedef enum
99{
100  /* incoming */
101  AWAITING_HANDSHAKE,
102  AWAITING_PEER_ID,
103  AWAITING_YA,
104  AWAITING_PAD_A,
105  AWAITING_CRYPTO_PROVIDE,
106  AWAITING_PAD_C,
107  AWAITING_IA,
108  AWAITING_PAYLOAD_STREAM,
109
110  /* outgoing */
111  AWAITING_YB,
112  AWAITING_VC,
113  AWAITING_CRYPTO_SELECT,
114  AWAITING_PAD_D,
115
116  N_STATES
117}
118handshake_state_t;
119
120struct tr_handshake
121{
122  bool                  haveReadAnythingFromPeer;
123  bool                  havePeerID;
124  bool                  haveSentBitTorrentHandshake;
125  tr_peerIo *           io;
126  tr_crypto *           crypto;
127  tr_session *          session;
128  handshake_state_t     state;
129  tr_encryption_mode    encryptionMode;
130  uint16_t              pad_c_len;
131  uint16_t              pad_d_len;
132  uint16_t              ia_len;
133  uint32_t              crypto_select;
134  uint32_t              crypto_provide;
135  uint8_t               myReq1[SHA_DIGEST_LENGTH];
136  handshakeDoneCB       doneCB;
137  void *                doneUserData;
138  struct event        * timeout_timer;
139};
140
141/**
142***
143**/
144
145#define dbgmsg(handshake, ...) \
146  do { \
147    if (tr_logGetDeepEnabled ()) \
148      tr_logAddDeep (__FILE__, __LINE__, tr_peerIoGetAddrStr (handshake->io), __VA_ARGS__); \
149  } while (0)
150
151static const char*
152getStateName (const handshake_state_t state)
153{
154  static const char * const state_strings[N_STATES] =
155    {
156      /* AWAITING_HANDSHAKE      */ "awaiting handshake",
157      /* AWAITING_PEER_ID        */ "awaiting peer id",
158      /* AWAITING_YA             */ "awaiting ya",
159      /* AWAITING_PAD_A          */ "awaiting pad a",
160      /* AWAITING_CRYPTO_PROVIDE */ "awaiting crypto_provide",
161      /* AWAITING_PAD_C          */ "awaiting pad c",
162      /* AWAITING_IA             */ "awaiting ia",
163      /* AWAITING_PAYLOAD_STREAM */ "awaiting payload stream",
164      /* AWAITING_YB             */ "awaiting yb",
165      /* AWAITING_VC             */ "awaiting vc",
166      /* AWAITING_CRYPTO_SELECT  */ "awaiting crypto select",
167      /* AWAITING_PAD_D          */ "awaiting pad d"
168  };
169
170  return state<N_STATES ? state_strings[state] : "unknown state";
171}
172
173static void
174setState (tr_handshake * handshake, handshake_state_t state)
175{
176  dbgmsg (handshake, "setting to state [%s]", getStateName (state));
177  handshake->state = state;
178}
179
180static void
181setReadState (tr_handshake * handshake, handshake_state_t state)
182{
183  setState (handshake, state);
184}
185
186static bool
187buildHandshakeMessage (tr_handshake * handshake, uint8_t * buf)
188{
189  const unsigned char * peer_id = NULL;
190  const uint8_t * torrentHash;
191  tr_torrent * tor;
192  bool success;
193
194  if ((torrentHash = tr_cryptoGetTorrentHash (handshake->crypto)))
195    if ((tor = tr_torrentFindFromHash (handshake->session, torrentHash)))
196      peer_id = tr_torrentGetPeerId (tor);
197
198  if (peer_id == NULL)
199    {
200      success = false;
201    }
202  else
203    {
204      uint8_t * walk = buf;
205
206      memcpy (walk, HANDSHAKE_NAME, HANDSHAKE_NAME_LEN);
207      walk += HANDSHAKE_NAME_LEN;
208      memset (walk, 0, HANDSHAKE_FLAGS_LEN);
209      HANDSHAKE_SET_LTEP (walk);
210      HANDSHAKE_SET_FASTEXT (walk);
211
212      /* Note that this doesn't depend on whether the torrent is private.
213       * We don't accept DHT peers for a private torrent,
214       * but we participate in the DHT regardless. */
215      if (tr_dhtEnabled (handshake->session))
216        HANDSHAKE_SET_DHT (walk);
217
218      walk += HANDSHAKE_FLAGS_LEN;
219      memcpy (walk, torrentHash, SHA_DIGEST_LENGTH);
220      walk += SHA_DIGEST_LENGTH;
221      memcpy (walk, peer_id, PEER_ID_LEN);
222      walk += PEER_ID_LEN;
223
224      assert (walk - buf == HANDSHAKE_SIZE);
225      success = true;
226    }
227
228  return success;
229}
230
231static ReadState tr_handshakeDone (tr_handshake * handshake,
232                                   bool           isConnected);
233
234typedef enum
235{
236  HANDSHAKE_OK,
237  HANDSHAKE_ENCRYPTION_WRONG,
238  HANDSHAKE_BAD_TORRENT,
239  HANDSHAKE_PEER_IS_SELF,
240}
241handshake_parse_err_t;
242
243static handshake_parse_err_t
244parseHandshake (tr_handshake *    handshake,
245                struct evbuffer * inbuf)
246{
247  uint8_t name[HANDSHAKE_NAME_LEN];
248  uint8_t reserved[HANDSHAKE_FLAGS_LEN];
249  uint8_t hash[SHA_DIGEST_LENGTH];
250  tr_torrent * tor;
251  uint8_t peer_id[PEER_ID_LEN];
252
253  dbgmsg (handshake, "payload: need %d, got %zu",
254          HANDSHAKE_SIZE, evbuffer_get_length (inbuf));
255
256  if (evbuffer_get_length (inbuf) < HANDSHAKE_SIZE)
257    return HANDSHAKE_ENCRYPTION_WRONG;
258
259  /* confirm the protocol */
260  tr_peerIoReadBytes (handshake->io, inbuf, name, HANDSHAKE_NAME_LEN);
261  if (memcmp (name, HANDSHAKE_NAME, HANDSHAKE_NAME_LEN) != 0)
262    return HANDSHAKE_ENCRYPTION_WRONG;
263
264  /* read the reserved bytes */
265  tr_peerIoReadBytes (handshake->io, inbuf, reserved, HANDSHAKE_FLAGS_LEN);
266
267  /* torrent hash */
268  tr_peerIoReadBytes (handshake->io, inbuf, hash, sizeof (hash));
269  assert (tr_peerIoHasTorrentHash (handshake->io));
270  if (!tr_torrentExists (handshake->session, hash)
271      || memcmp (hash, tr_peerIoGetTorrentHash (handshake->io), SHA_DIGEST_LENGTH) != 0)
272    {
273      dbgmsg (handshake, "peer returned the wrong hash. wtf?");
274      return HANDSHAKE_BAD_TORRENT;
275    }
276
277  /* peer_id */
278  tr_peerIoReadBytes (handshake->io, inbuf, peer_id, sizeof (peer_id));
279  tr_peerIoSetPeersId (handshake->io, peer_id);
280
281  /* peer id */
282  handshake->havePeerID = true;
283  dbgmsg (handshake, "peer-id is [%*.*s]", PEER_ID_LEN, PEER_ID_LEN, peer_id);
284
285  tor = tr_torrentFindFromHash (handshake->session, hash);
286  if (memcmp (peer_id, tr_torrentGetPeerId(tor), PEER_ID_LEN) == 0)
287    {
288      dbgmsg (handshake, "streuth!  we've connected to ourselves.");
289      return HANDSHAKE_PEER_IS_SELF;
290    }
291
292  /**
293  *** Extensions
294  **/
295
296  tr_peerIoEnableDHT  (handshake->io, HANDSHAKE_HAS_DHT    (reserved));
297  tr_peerIoEnableLTEP (handshake->io, HANDSHAKE_HAS_LTEP    (reserved));
298  tr_peerIoEnableFEXT (handshake->io, HANDSHAKE_HAS_FASTEXT (reserved));
299
300  return HANDSHAKE_OK;
301}
302
303/***
304****
305****  OUTGOING CONNECTIONS
306****
307***/
308
309/* 1 A->B: Diffie Hellman Ya, PadA */
310static void
311sendYa (tr_handshake * handshake)
312{
313  int len;
314  const uint8_t * public_key;
315  char outbuf[ KEY_LEN + PadA_MAXLEN ];
316  char *walk = outbuf;
317
318  /* add our public key (Ya) */
319  public_key = tr_cryptoGetMyPublicKey (handshake->crypto, &len);
320  assert (len == KEY_LEN);
321  assert (public_key);
322  memcpy (walk, public_key, len);
323  walk += len;
324
325  /* add some bullshit padding */
326  len = tr_rand_int (PadA_MAXLEN);
327  tr_rand_buffer (walk, len);
328  walk += len;
329
330  /* send it */
331  setReadState (handshake, AWAITING_YB);
332  tr_peerIoWriteBytes (handshake->io, outbuf, walk - outbuf, false);
333}
334
335static uint32_t
336getCryptoProvide (const tr_handshake * handshake)
337{
338  uint32_t provide = 0;
339
340  switch (handshake->encryptionMode)
341    {
342      case TR_ENCRYPTION_REQUIRED:
343      case TR_ENCRYPTION_PREFERRED:
344        provide |= CRYPTO_PROVIDE_CRYPTO;
345        break;
346
347      case TR_CLEAR_PREFERRED:
348        provide |= CRYPTO_PROVIDE_CRYPTO | CRYPTO_PROVIDE_PLAINTEXT;
349        break;
350    }
351
352  return provide;
353}
354
355static uint32_t
356getCryptoSelect (const tr_handshake * handshake,
357                 uint32_t             crypto_provide)
358{
359  uint32_t choices[2];
360  int i;
361  int nChoices = 0;
362
363  switch (handshake->encryptionMode)
364    {
365      case TR_ENCRYPTION_REQUIRED:
366        choices[nChoices++] = CRYPTO_PROVIDE_CRYPTO;
367        break;
368
369      case TR_ENCRYPTION_PREFERRED:
370        choices[nChoices++] = CRYPTO_PROVIDE_CRYPTO;
371        choices[nChoices++] = CRYPTO_PROVIDE_PLAINTEXT;
372        break;
373
374      case TR_CLEAR_PREFERRED:
375        choices[nChoices++] = CRYPTO_PROVIDE_PLAINTEXT;
376        choices[nChoices++] = CRYPTO_PROVIDE_CRYPTO;
377        break;
378    }
379
380  for (i=0; i<nChoices; ++i)
381    if (crypto_provide & choices[i])
382      return choices[i];
383
384  return 0;
385}
386
387static void
388computeRequestHash (const tr_handshake * handshake,
389                    const char         * name,
390                    uint8_t            * hash)
391{
392  tr_cryptoSecretKeySha1 (handshake->crypto, name, 4, NULL, 0, hash);
393}
394
395static ReadState
396readYb (tr_handshake * handshake, struct evbuffer * inbuf)
397{
398  bool isEncrypted;
399  uint8_t yb[KEY_LEN];
400  struct evbuffer * outbuf;
401  size_t needlen = HANDSHAKE_NAME_LEN;
402
403  if (evbuffer_get_length (inbuf) < needlen)
404    return READ_LATER;
405
406  isEncrypted = memcmp (evbuffer_pullup (inbuf, HANDSHAKE_NAME_LEN), HANDSHAKE_NAME, HANDSHAKE_NAME_LEN) != 0;
407  if (isEncrypted)
408    {
409      needlen = KEY_LEN;
410
411      if (evbuffer_get_length (inbuf) < needlen)
412        return READ_LATER;
413    }
414
415  dbgmsg (handshake, "got an %s handshake", (isEncrypted ? "encrypted" : "plain"));
416
417  tr_peerIoSetEncryption (handshake->io, isEncrypted ? PEER_ENCRYPTION_RC4
418                                                     : PEER_ENCRYPTION_NONE);
419  if (!isEncrypted)
420    {
421      setState (handshake, AWAITING_HANDSHAKE);
422      return READ_NOW;
423    }
424
425  handshake->haveReadAnythingFromPeer = true;
426
427  /* compute the secret */
428  evbuffer_remove (inbuf, yb, KEY_LEN);
429  tr_cryptoComputeSecret (handshake->crypto, yb);
430
431  /* now send these: HASH ('req1', S), HASH ('req2', SKEY) xor HASH ('req3', S),
432   * ENCRYPT (VC, crypto_provide, len (PadC), PadC, len (IA)), ENCRYPT (IA) */
433  outbuf = evbuffer_new ();
434
435  /* HASH ('req1', S) */
436  {
437    uint8_t req1[SHA_DIGEST_LENGTH];
438    computeRequestHash (handshake, "req1", req1);
439    evbuffer_add (outbuf, req1, SHA_DIGEST_LENGTH);
440  }
441
442  /* HASH ('req2', SKEY) xor HASH ('req3', S) */
443  {
444    int i;
445    uint8_t req2[SHA_DIGEST_LENGTH];
446    uint8_t req3[SHA_DIGEST_LENGTH];
447    uint8_t buf[SHA_DIGEST_LENGTH];
448
449    tr_sha1 (req2, "req2", 4, tr_cryptoGetTorrentHash (handshake->crypto), SHA_DIGEST_LENGTH, NULL);
450    computeRequestHash (handshake, "req3", req3);
451
452    for (i=0; i<SHA_DIGEST_LENGTH; ++i)
453      buf[i] = req2[i] ^ req3[i];
454
455    evbuffer_add (outbuf, buf, SHA_DIGEST_LENGTH);
456  }
457
458  /* ENCRYPT (VC, crypto_provide, len (PadC), PadC
459   * PadC is reserved for future extensions to the handshake...
460   * standard practice at this time is for it to be zero-length */
461  {
462    uint8_t vc[VC_LENGTH] = { 0, 0, 0, 0, 0, 0, 0, 0 };
463
464    tr_peerIoWriteBuf (handshake->io, outbuf, false);
465    tr_cryptoEncryptInit (handshake->crypto);
466    tr_peerIoSetEncryption (handshake->io, PEER_ENCRYPTION_RC4);
467
468    evbuffer_add        (outbuf, vc, VC_LENGTH);
469    evbuffer_add_uint32 (outbuf, getCryptoProvide (handshake));
470    evbuffer_add_uint16 (outbuf, 0);
471  }
472
473  /* ENCRYPT len (IA)), ENCRYPT (IA) */
474  {
475    uint8_t msg[HANDSHAKE_SIZE];
476    if (!buildHandshakeMessage (handshake, msg))
477      return tr_handshakeDone (handshake, false);
478
479    evbuffer_add_uint16 (outbuf, sizeof (msg));
480    evbuffer_add        (outbuf, msg, sizeof (msg));
481
482    handshake->haveSentBitTorrentHandshake = true;
483  }
484
485  /* send it */
486  tr_cryptoDecryptInit (handshake->crypto);
487  setReadState (handshake, AWAITING_VC);
488  tr_peerIoWriteBuf (handshake->io, outbuf, false);
489
490  /* cleanup */
491  evbuffer_free (outbuf);
492  return READ_LATER;
493}
494
495static ReadState
496readVC (tr_handshake    * handshake,
497        struct evbuffer * inbuf)
498{
499  uint8_t tmp[VC_LENGTH];
500  const int key_len = VC_LENGTH;
501  const uint8_t key[VC_LENGTH] = { 0, 0, 0, 0, 0, 0, 0, 0 };
502
503  /* note: this works w/o having to `unwind' the buffer if
504   * we read too much, but it is pretty brute-force.
505   * it would be nice to make this cleaner. */
506  for (;;)
507    {
508      if (evbuffer_get_length (inbuf) < VC_LENGTH)
509        {
510          dbgmsg (handshake, "not enough bytes... returning read_more");
511          return READ_LATER;
512        }
513
514      memcpy (tmp, evbuffer_pullup (inbuf, key_len), key_len);
515      tr_cryptoDecryptInit (handshake->crypto);
516      tr_cryptoDecrypt (handshake->crypto, key_len, tmp, tmp);
517      if (memcmp (tmp, key, key_len) == 0)
518        break;
519
520      evbuffer_drain (inbuf, 1);
521    }
522
523  dbgmsg (handshake, "got it!");
524  evbuffer_drain (inbuf, key_len);
525  setState (handshake, AWAITING_CRYPTO_SELECT);
526  return READ_NOW;
527}
528
529static ReadState
530readCryptoSelect (tr_handshake    * handshake,
531                  struct evbuffer * inbuf)
532{
533  uint16_t pad_d_len;
534  uint32_t crypto_select;
535  static const size_t needlen = sizeof (uint32_t) + sizeof (uint16_t);
536
537  if (evbuffer_get_length (inbuf) < needlen)
538    return READ_LATER;
539
540  tr_peerIoReadUint32 (handshake->io, inbuf, &crypto_select);
541  handshake->crypto_select = crypto_select;
542  dbgmsg (handshake, "crypto select is %d", (int)crypto_select);
543  if (!(crypto_select & getCryptoProvide (handshake)))
544    {
545      dbgmsg (handshake, "peer selected an encryption option we didn't offer");
546      return tr_handshakeDone (handshake, false);
547    }
548
549  tr_peerIoReadUint16 (handshake->io, inbuf, &pad_d_len);
550  dbgmsg (handshake, "pad_d_len is %d", (int)pad_d_len);
551
552  if (pad_d_len > 512)
553    {
554      dbgmsg (handshake, "encryption handshake: pad_d_len is too long");
555      return tr_handshakeDone (handshake, false);
556    }
557
558  handshake->pad_d_len = pad_d_len;
559
560  setState (handshake, AWAITING_PAD_D);
561  return READ_NOW;
562}
563
564static ReadState
565readPadD (tr_handshake    * handshake,
566          struct evbuffer * inbuf)
567{
568  const size_t needlen = handshake->pad_d_len;
569
570  dbgmsg (handshake, "pad d: need %zu, got %zu",
571          needlen, evbuffer_get_length (inbuf));
572  if (evbuffer_get_length (inbuf) < needlen)
573    return READ_LATER;
574
575  tr_peerIoDrain (handshake->io, inbuf, needlen);
576
577  tr_peerIoSetEncryption (handshake->io, handshake->crypto_select);
578
579  setState (handshake, AWAITING_HANDSHAKE);
580  return READ_NOW;
581}
582
583/***
584****
585****  INCOMING CONNECTIONS
586****
587***/
588
589static ReadState
590readHandshake (tr_handshake    * handshake,
591               struct evbuffer * inbuf)
592{
593  uint8_t pstrlen;
594  uint8_t pstr[20];
595  uint8_t reserved[HANDSHAKE_FLAGS_LEN];
596  uint8_t hash[SHA_DIGEST_LENGTH];
597
598  dbgmsg (handshake, "payload: need %d, got %zu",
599          INCOMING_HANDSHAKE_LEN, evbuffer_get_length (inbuf));
600
601  if (evbuffer_get_length (inbuf) < INCOMING_HANDSHAKE_LEN)
602    return READ_LATER;
603
604  handshake->haveReadAnythingFromPeer = true;
605
606  pstrlen = evbuffer_pullup (inbuf, 1)[0]; /* peek, don't read. We may be
607                                              handing inbuf to AWAITING_YA */
608
609  if (pstrlen == 19) /* unencrypted */
610    {
611      tr_peerIoSetEncryption (handshake->io, PEER_ENCRYPTION_NONE);
612
613      if (handshake->encryptionMode == TR_ENCRYPTION_REQUIRED)
614        {
615          dbgmsg (handshake, "peer is unencrypted, and we're disallowing that");
616          return tr_handshakeDone (handshake, false);
617        }
618    }
619  else /* encrypted or corrupt */
620    {
621      tr_peerIoSetEncryption (handshake->io, PEER_ENCRYPTION_RC4);
622
623      if (tr_peerIoIsIncoming (handshake->io))
624        {
625          dbgmsg (handshake, "I think peer is sending us an encrypted handshake...");
626          setState (handshake, AWAITING_YA);
627          return READ_NOW;
628        }
629
630      tr_cryptoDecrypt (handshake->crypto, 1, &pstrlen, &pstrlen);
631
632      if (pstrlen != 19)
633        {
634          dbgmsg (handshake, "I think peer has sent us a corrupt handshake...");
635          return tr_handshakeDone (handshake, false);
636        }
637    }
638
639  evbuffer_drain (inbuf, 1);
640
641  /* pstr (BitTorrent) */
642  assert (pstrlen == 19);
643  tr_peerIoReadBytes (handshake->io, inbuf, pstr, pstrlen);
644  pstr[pstrlen] = '\0';
645  if (memcmp (pstr, "BitTorrent protocol", 19) != 0)
646    return tr_handshakeDone (handshake, false);
647
648  /* reserved bytes */
649  tr_peerIoReadBytes (handshake->io, inbuf, reserved, sizeof (reserved));
650
651  /**
652  *** Extensions
653  **/
654
655  tr_peerIoEnableDHT  (handshake->io, HANDSHAKE_HAS_DHT     (reserved));
656  tr_peerIoEnableLTEP (handshake->io, HANDSHAKE_HAS_LTEP    (reserved));
657  tr_peerIoEnableFEXT (handshake->io, HANDSHAKE_HAS_FASTEXT (reserved));
658
659  /* torrent hash */
660  tr_peerIoReadBytes (handshake->io, inbuf, hash, sizeof (hash));
661  if (tr_peerIoIsIncoming (handshake->io))
662    {
663      if (!tr_torrentExists (handshake->session, hash))
664        {
665          dbgmsg (handshake, "peer is trying to connect to us for a torrent we don't have.");
666          return tr_handshakeDone (handshake, false);
667        }
668      else
669        {
670          assert (!tr_peerIoHasTorrentHash (handshake->io));
671          tr_peerIoSetTorrentHash (handshake->io, hash);
672        }
673    }
674  else /* outgoing */
675    {
676      assert (tr_peerIoHasTorrentHash (handshake->io));
677
678      if (memcmp (hash, tr_peerIoGetTorrentHash (handshake->io), SHA_DIGEST_LENGTH) != 0)
679        {
680          dbgmsg (handshake, "peer returned the wrong hash. wtf?");
681          return tr_handshakeDone (handshake, false);
682        }
683    }
684
685  /**
686  ***  If it's an incoming message, we need to send a response handshake
687  **/
688
689  if (!handshake->haveSentBitTorrentHandshake)
690    {
691      uint8_t msg[HANDSHAKE_SIZE];
692      if (!buildHandshakeMessage (handshake, msg))
693        return tr_handshakeDone (handshake, false);
694      tr_peerIoWriteBytes (handshake->io, msg, sizeof (msg), false);
695      handshake->haveSentBitTorrentHandshake = true;
696    }
697
698  setReadState (handshake, AWAITING_PEER_ID);
699  return READ_NOW;
700}
701
702static ReadState
703readPeerId (tr_handshake    * handshake,
704            struct evbuffer * inbuf)
705{
706  bool connected_to_self;
707  char client[128];
708  uint8_t peer_id[PEER_ID_LEN];
709  tr_torrent * tor;
710
711  if (evbuffer_get_length (inbuf) < PEER_ID_LEN)
712    return READ_LATER;
713
714  /* peer id */
715  tr_peerIoReadBytes (handshake->io, inbuf, peer_id, PEER_ID_LEN);
716  tr_peerIoSetPeersId (handshake->io, peer_id);
717  handshake->havePeerID = true;
718  tr_clientForId (client, sizeof (client), peer_id);
719  dbgmsg (handshake, "peer-id is [%s] ... isIncoming is %d", client,
720          tr_peerIoIsIncoming (handshake->io));
721
722  /* if we've somehow connected to ourselves, don't keep the connection */
723  tor = tr_torrentFindFromHash (handshake->session, tr_peerIoGetTorrentHash (handshake->io));
724  connected_to_self = (tor != NULL) && memcmp (peer_id, tr_torrentGetPeerId(tor), PEER_ID_LEN) == 0;
725
726  return tr_handshakeDone (handshake, !connected_to_self);
727}
728
729static ReadState
730readYa (tr_handshake    * handshake,
731        struct evbuffer * inbuf)
732{
733  uint8_t ya[KEY_LEN];
734  uint8_t * walk, outbuf[KEY_LEN + PadB_MAXLEN];
735  const uint8_t * myKey;
736  int len;
737
738  dbgmsg (handshake, "in readYa... need %d, have %zu",
739          KEY_LEN, evbuffer_get_length (inbuf));
740  if (evbuffer_get_length (inbuf) < KEY_LEN)
741    return READ_LATER;
742
743  /* read the incoming peer's public key */
744  evbuffer_remove (inbuf, ya, KEY_LEN);
745  tr_cryptoComputeSecret (handshake->crypto, ya);
746  computeRequestHash (handshake, "req1", handshake->myReq1);
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_rand_int (PadB_MAXLEN);
755  tr_rand_buffer (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 ReadState
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 ReadState
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  computeRequestHash (handshake, "req3", req3);
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 ReadState
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 ReadState
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 = true;
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 ReadState
958readPayloadStream (tr_handshake    * handshake,
959                   struct evbuffer * inbuf)
960{
961  handshake_parse_err_t 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 ReadState
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 = true;
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 = true;
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 (evutil_socket_t 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 = true;
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.