LCOV - code coverage report
Current view: top level - src - net_permissions.cpp (source / functions) Hit Total Coverage
Test: fuzz_coverage.info Lines: 80 80 100.0 %
Date: 2023-10-05 15:40:34 Functions: 6 6 100.0 %
Branches: 122 203 60.1 %

           Branch data     Line data    Source code
       1                 :            : // Copyright (c) 2009-2021 The Bitcoin Core developers
       2                 :            : // Distributed under the MIT software license, see the accompanying
       3                 :            : // file COPYING or http://www.opensource.org/licenses/mit-license.php.
       4                 :            : 
       5                 :            : #include <common/system.h>
       6                 :            : #include <net_permissions.h>
       7                 :            : #include <netbase.h>
       8                 :            : #include <util/error.h>
       9                 :            : #include <util/translation.h>
      10                 :            : 
      11   [ +  -  #  # ]:        173 : const std::vector<std::string> NET_PERMISSIONS_DOC{
      12         [ +  - ]:        173 :     "bloomfilter (allow requesting BIP37 filtered blocks and transactions)",
      13         [ +  - ]:        173 :     "noban (do not ban for misbehavior; implies download)",
      14         [ +  - ]:        173 :     "forcerelay (relay transactions that are already in the mempool; implies relay)",
      15         [ +  - ]:        173 :     "relay (relay even in -blocksonly mode, and unlimited transaction announcements)",
      16         [ +  - ]:        173 :     "mempool (allow requesting BIP35 mempool contents)",
      17         [ +  - ]:        173 :     "download (allow getheaders during IBD, no disconnect after maxuploadtarget limit)",
      18         [ +  - ]:        173 :     "addr (responses to GETADDR avoid hitting the cache and contain random records with the most up-to-date info)"
      19                 :            : };
      20                 :            : 
      21                 :            : namespace {
      22                 :            : 
      23                 :            : // Parse the following format: "perm1,perm2@xxxxxx"
      24                 :        172 : bool TryParsePermissionFlags(const std::string& str, NetPermissionFlags& output, size_t& readen, bilingual_str& error)
      25                 :            : {
      26                 :        172 :     NetPermissionFlags flags = NetPermissionFlags::None;
      27                 :        172 :     const auto atSeparator = str.find('@');
      28                 :            : 
      29                 :            :     // if '@' is not found (ie, "xxxxx"), the caller should apply implicit permissions
      30         [ +  + ]:        172 :     if (atSeparator == std::string::npos) {
      31                 :        146 :         NetPermissions::AddFlag(flags, NetPermissionFlags::Implicit);
      32                 :        146 :         readen = 0;
      33                 :        146 :     }
      34                 :            :     // else (ie, "perm1,perm2@xxxxx"), let's enumerate the permissions by splitting by ',' and calculate the flags
      35                 :            :     else {
      36                 :         26 :         readen = 0;
      37                 :            :         // permissions == perm1,perm2
      38                 :         26 :         const auto permissions = str.substr(0, atSeparator);
      39         [ +  + ]:         66 :         while (readen < permissions.length()) {
      40                 :         44 :             const auto commaSeparator = permissions.find(',', readen);
      41         [ +  + ]:         44 :             const auto len = commaSeparator == std::string::npos ? permissions.length() - readen : commaSeparator - readen;
      42                 :            :             // permission == perm1
      43         [ +  - ]:         44 :             const auto permission = permissions.substr(readen, len);
      44                 :         44 :             readen += len; // We read "perm1"
      45         [ +  + ]:         44 :             if (commaSeparator != std::string::npos) readen++; // We read ","
      46                 :            : 
      47   [ +  -  +  -  :         44 :             if (permission == "bloomfilter" || permission == "bloom") NetPermissions::AddFlag(flags, NetPermissionFlags::BloomFilter);
          +  -  +  -  #  
                      # ]
      48   [ +  -  +  +  :         44 :             else if (permission == "noban") NetPermissions::AddFlag(flags, NetPermissionFlags::NoBan);
                   +  - ]
      49   [ +  -  +  +  :         28 :             else if (permission == "forcerelay") NetPermissions::AddFlag(flags, NetPermissionFlags::ForceRelay);
                   +  - ]
      50   [ +  -  +  +  :         26 :             else if (permission == "mempool") NetPermissions::AddFlag(flags, NetPermissionFlags::Mempool);
                   +  - ]
      51   [ +  -  -  +  :         20 :             else if (permission == "download") NetPermissions::AddFlag(flags, NetPermissionFlags::Download);
                   #  # ]
      52   [ +  -  +  +  :         20 :             else if (permission == "all") NetPermissions::AddFlag(flags, NetPermissionFlags::All);
                   +  - ]
      53   [ +  -  +  +  :         18 :             else if (permission == "relay") NetPermissions::AddFlag(flags, NetPermissionFlags::Relay);
                   +  - ]
      54   [ +  -  +  +  :         14 :             else if (permission == "addr") NetPermissions::AddFlag(flags, NetPermissionFlags::Addr);
                   +  - ]
      55         [ +  - ]:          4 :             else if (permission.length() == 0); // Allow empty entries
      56                 :            :             else {
      57   [ +  -  +  - ]:          4 :                 error = strprintf(_("Invalid P2P permission: '%s'"), permission);
      58                 :          4 :                 return false;
      59                 :            :             }
      60         [ +  + ]:         44 :         }
      61                 :         22 :         readen++;
      62      [ -  +  + ]:         26 :     }
      63                 :            : 
      64                 :        168 :     output = flags;
      65   [ +  -  +  - ]:        168 :     error = Untranslated("");
      66                 :        168 :     return true;
      67                 :        172 : }
      68                 :            : 
      69                 :            : }
      70                 :            : 
      71                 :         46 : std::vector<std::string> NetPermissions::ToStrings(NetPermissionFlags flags)
      72                 :            : {
      73                 :         46 :     std::vector<std::string> strings;
      74   [ +  -  +  +  :        219 :     if (NetPermissions::HasFlag(flags, NetPermissionFlags::BloomFilter)) strings.push_back("bloomfilter");
             +  -  +  - ]
      75   [ +  -  +  +  :         46 :     if (NetPermissions::HasFlag(flags, NetPermissionFlags::NoBan)) strings.push_back("noban");
             +  -  +  - ]
      76   [ +  -  +  +  :         46 :     if (NetPermissions::HasFlag(flags, NetPermissionFlags::ForceRelay)) strings.push_back("forcerelay");
             +  -  +  - ]
      77   [ +  -  +  +  :         46 :     if (NetPermissions::HasFlag(flags, NetPermissionFlags::Relay)) strings.push_back("relay");
             +  -  +  - ]
      78   [ +  -  +  +  :         46 :     if (NetPermissions::HasFlag(flags, NetPermissionFlags::Mempool)) strings.push_back("mempool");
             +  -  +  - ]
      79   [ +  -  +  +  :         46 :     if (NetPermissions::HasFlag(flags, NetPermissionFlags::Download)) strings.push_back("download");
             +  -  +  - ]
      80   [ +  -  +  +  :         46 :     if (NetPermissions::HasFlag(flags, NetPermissionFlags::Addr)) strings.push_back("addr");
             +  -  -  + ]
      81                 :         46 :     return strings;
      82         [ +  - ]:         46 : }
      83                 :            : 
      84                 :         86 : bool NetWhitebindPermissions::TryParse(const std::string& str, NetWhitebindPermissions& output, bilingual_str& error)
      85                 :            : {
      86                 :            :     NetPermissionFlags flags;
      87                 :            :     size_t offset;
      88         [ +  + ]:         86 :     if (!TryParsePermissionFlags(str, flags, offset, error)) return false;
      89                 :            : 
      90                 :         84 :     const std::string strBind = str.substr(offset);
      91   [ +  -  +  - ]:         84 :     const std::optional<CService> addrBind{Lookup(strBind, 0, false)};
      92         [ +  + ]:         84 :     if (!addrBind.has_value()) {
      93   [ +  -  +  - ]:         68 :         error = ResolveErrMsg("whitebind", strBind);
      94                 :         68 :         return false;
      95                 :            :     }
      96   [ +  -  +  -  :         16 :     if (addrBind.value().GetPort() == 0) {
                   +  + ]
      97   [ +  -  -  + ]:         11 :         error = strprintf(_("Need to specify a port with -whitebind: '%s'"), strBind);
      98                 :         11 :         return false;
      99                 :            :     }
     100                 :            : 
     101                 :          5 :     output.m_flags = flags;
     102   [ +  -  +  - ]:          5 :     output.m_service = addrBind.value();
     103   [ +  -  +  - ]:          5 :     error = Untranslated("");
     104                 :          5 :     return true;
     105                 :         86 : }
     106                 :            : 
     107                 :         86 : bool NetWhitelistPermissions::TryParse(const std::string& str, NetWhitelistPermissions& output, bilingual_str& error)
     108                 :            : {
     109                 :            :     NetPermissionFlags flags;
     110                 :            :     size_t offset;
     111         [ +  + ]:         86 :     if (!TryParsePermissionFlags(str, flags, offset, error)) return false;
     112                 :            : 
     113                 :         84 :     const std::string net = str.substr(offset);
     114         [ +  - ]:         84 :     CSubNet subnet;
     115         [ +  - ]:         84 :     LookupSubNet(net, subnet);
     116   [ +  -  +  + ]:         84 :     if (!subnet.IsValid()) {
     117   [ +  -  +  - ]:         66 :         error = strprintf(_("Invalid netmask specified in -whitelist: '%s'"), net);
     118                 :         66 :         return false;
     119                 :            :     }
     120                 :            : 
     121                 :         18 :     output.m_flags = flags;
     122         [ +  - ]:         18 :     output.m_subnet = subnet;
     123   [ +  -  -  + ]:         18 :     error = Untranslated("");
     124                 :         18 :     return true;
     125                 :         86 : }

Generated by: LCOV version 1.14