Ver Fonte

Add --bt-force-encryption option

This option requires BitTorrent message payload encryption with
arc4. This is a shorthand of --bt-requre-crypto
--bt-min-crypto-level=arc4.  If true is given, deny legacy BitTorrent
handshake and only use Obfuscation handshake and always encrypt
message payload. This option defaults to false.
Tatsuhiro Tsujikawa há 10 anos atrás
pai
commit
c653c72dc8

+ 10 - 0
doc/manual-src/en/aria2c.rst

@@ -625,6 +625,15 @@ BitTorrent Specific Options
   tracker. Although this function is named ``external``, it can accept
   any kind of IP addresses. IPADDRESS must be a numeric IP address.
 
+.. option:: --bt-force-encryption[=true|false]
+
+  Requires BitTorrent message payload encryption with arc4.  This is a
+  shorthand of :option:`--bt-requre-crypto`
+  :option:`--bt-min-crypto-level`\=arc4.  This option does not change
+  the option value of those options.  If ``true`` is given, deny
+  legacy BitTorrent handshake and only use Obfuscation handshake and
+  always encrypt message payload.  Default: ``false``
+
 .. option:: --bt-hash-check-seed[=true|false]
 
  If ``true`` is given, after hash check using :option:`--check-integrity <-V>` option and
@@ -1894,6 +1903,7 @@ of URIs. These optional lines must start with white space(s).
   * :option:`bt-enable-lpd <--bt-enable-lpd>`
   * :option:`bt-exclude-tracker <--bt-exclude-tracker>`
   * :option:`bt-external-ip <--bt-external-ip>`
+  * :option:`bt-force-encryption <--bt-force-encryption>`
   * :option:`bt-hash-check-seed <--bt-hash-check-seed>`
   * :option:`bt-max-peers <--bt-max-peers>`
   * :option:`bt-metadata-only <--bt-metadata-only>`

+ 2 - 1
src/DefaultBtAnnounce.cc

@@ -189,7 +189,8 @@ std::string DefaultBtAnnounce::getAnnounceUrl() {
     uri += "&trackerid=";
     uri += util::torrentPercentEncode(trackerId_);
   }
-  if(option_->getAsBool(PREF_BT_REQUIRE_CRYPTO)) {
+  if(option_->getAsBool(PREF_BT_FORCE_ENCRYPTION) ||
+     option_->getAsBool(PREF_BT_REQUIRE_CRYPTO)) {
     uri += "&requirecrypto=1";
   } else {
     uri += "&supportcrypto=1";

+ 3 - 1
src/InitiatorMSEHandshakeCommand.cc

@@ -216,7 +216,8 @@ bool InitiatorMSEHandshakeCommand::prepareForNextPeer(time_t wait)
     // established.
     tryNewPeer();
     return true;
-  } else if(getOption()->getAsBool(PREF_BT_REQUIRE_CRYPTO)) {
+  } else if(getOption()->getAsBool(PREF_BT_FORCE_ENCRYPTION) ||
+            getOption()->getAsBool(PREF_BT_REQUIRE_CRYPTO)) {
     A2_LOG_INFO(fmt("CUID#%" PRId64 " - Establishing connection using legacy"
                     " BitTorrent handshake is disabled by preference.",
                     getCuid()));
@@ -239,6 +240,7 @@ bool InitiatorMSEHandshakeCommand::prepareForNextPeer(time_t wait)
 void InitiatorMSEHandshakeCommand::onAbort()
 {
   if(sequence_ == INITIATOR_SEND_KEY ||
+     getOption()->getAsBool(PREF_BT_FORCE_ENCRYPTION) ||
      getOption()->getAsBool(PREF_BT_REQUIRE_CRYPTO)) {
     peerStorage_->returnPeer(getPeer());
   }

+ 6 - 3
src/MSEHandshake.cc

@@ -284,7 +284,8 @@ void MSEHandshake::sendInitiatorStep2()
   ptr += sizeof(VC);
   // crypto_provide
   memset(ptr, 0, CRYPTO_BITFIELD_LENGTH);
-  if(option_->get(PREF_BT_MIN_CRYPTO_LEVEL) == V_PLAIN) {
+  if(!option_->getAsBool(PREF_BT_FORCE_ENCRYPTION) &&
+     option_->get(PREF_BT_MIN_CRYPTO_LEVEL) == V_PLAIN) {
     ptr[3] = CRYPTO_PLAIN_TEXT;
   }
   ptr[3] |= CRYPTO_ARC4;
@@ -347,7 +348,8 @@ bool MSEHandshake::receiveInitiatorCryptoSelectAndPadDLength()
   //verifyCryptoSelect
   unsigned char* rbufptr = rbuf_;
   decryptor_->encrypt(CRYPTO_BITFIELD_LENGTH, rbufptr, rbufptr);
-  if(rbufptr[3]&CRYPTO_PLAIN_TEXT &&
+  if((rbufptr[3]&CRYPTO_PLAIN_TEXT) &&
+     !option_->getAsBool(PREF_BT_FORCE_ENCRYPTION) &&
      option_->get(PREF_BT_MIN_CRYPTO_LEVEL) == V_PLAIN) {
     A2_LOG_DEBUG(fmt("CUID#%" PRId64 " - peer prefers plaintext.",
                      cuid_));
@@ -447,7 +449,8 @@ bool MSEHandshake::receiveReceiverHashAndPadCLength
   decryptor_->encrypt(CRYPTO_BITFIELD_LENGTH, rbufptr, rbufptr);
   // TODO choose the crypto type based on the preference.
   // For now, choose ARC4.
-  if(rbufptr[3]&CRYPTO_PLAIN_TEXT &&
+  if((rbufptr[3]&CRYPTO_PLAIN_TEXT) &&
+     !option_->getAsBool(PREF_BT_FORCE_ENCRYPTION) &&
      option_->get(PREF_BT_MIN_CRYPTO_LEVEL) == V_PLAIN) {
     A2_LOG_DEBUG(fmt("CUID#%" PRId64 " - peer provides plaintext.",
                      cuid_));

+ 12 - 0
src/OptionHandlerFactory.cc

@@ -1757,6 +1757,18 @@ std::vector<OptionHandler*> OptionHandlerFactory::createOptionHandlers()
     op->setChangeOptionForReserved(true);
     handlers.push_back(op);
   }
+  {
+    OptionHandler* op(new BooleanOptionHandler
+                      (PREF_BT_FORCE_ENCRYPTION,
+                       TEXT_BT_FORCE_ENCRYPTION,
+                       A2_V_FALSE,
+                       OptionHandler::OPT_ARG));
+    op->addTag(TAG_BITTORRENT);
+    op->setInitialOption(true);
+    op->setChangeGlobalOption(true);
+    op->setChangeOptionForReserved(true);
+    handlers.push_back(op);
+  }
   {
     OptionHandler* op(new NumberOptionHandler
                       (PREF_BT_KEEP_ALIVE_INTERVAL,

+ 3 - 1
src/ReceiverMSEHandshakeCommand.cc

@@ -96,7 +96,9 @@ bool ReceiverMSEHandshakeCommand::executeInternal()
         sequence_ = RECEIVER_WAIT_KEY;
         break;
       case MSEHandshake::HANDSHAKE_LEGACY: {
-        if(getDownloadEngine()->getOption()->getAsBool(PREF_BT_REQUIRE_CRYPTO)){
+        const auto option = getDownloadEngine()->getOption();
+        if(option->getAsBool(PREF_BT_FORCE_ENCRYPTION) ||
+           option->getAsBool(PREF_BT_REQUIRE_CRYPTO)){
           throw DL_ABORT_EX
             ("The legacy BitTorrent handshake is not acceptable by the"
              " preference.");

+ 1 - 0
src/prefs.cc

@@ -549,6 +549,7 @@ PrefPtr PREF_BT_EXCLUDE_TRACKER = makePref("bt-exclude-tracker");
 PrefPtr PREF_BT_REMOVE_UNSELECTED_FILE =
   makePref("bt-remove-unselected-file");
 PrefPtr PREF_BT_DETACH_SEED_ONLY = makePref("bt-detach-seed-only");
+PrefPtr PREF_BT_FORCE_ENCRYPTION = makePref("bt-force-encryption");
 
 /**
  * Metalink related preferences

+ 2 - 0
src/prefs.h

@@ -486,6 +486,8 @@ extern PrefPtr PREF_BT_EXCLUDE_TRACKER;
 extern PrefPtr PREF_BT_REMOVE_UNSELECTED_FILE;
 // values: true |false
 extern PrefPtr PREF_BT_DETACH_SEED_ONLY;
+// values: true | false
+extern PrefPtr PREF_BT_FORCE_ENCRYPTION;
 
 /**
  * Metalink related preferences

+ 8 - 0
src/usage_text.h

@@ -1013,3 +1013,11 @@
   "                              recognized as active download in RPC method.")
 #define TEXT_MIN_TLS_VERSION                                            \
   _(" --min-tls-version=VERSION  Specify minimum SSL/TLS version to enable.")
+#define TEXT_BT_FORCE_ENCRYPTION                                        \
+  _(" --bt-force-encryption[=true|false]\n"                             \
+    "                              Requires BitTorrent message payload encryption\n" \
+    "                              with arc4. This is a shorthand of\n" \
+    "                              --bt-requre-crypto --bt-min-crypto-level=arc4.\n" \
+    "                              If true is given, deny legacy BitTorrent\n" \
+    "                              handshake and only use Obfuscation handshake and\n" \
+    "                              always encrypt message payload.")