mirror of
https://github.com/dashpay/dash.git
synced 2024-12-28 05:23:01 +01:00
058c9f729f
7a046cdc1423963bdcbcf9bb98560af61fa90b37 tests: Avoid using C-style NUL-terminated strings as arguments (practicalswift) fefb9165f23fe9d10ad092ec31715f906e0d2ee7 tests: Add tests to make sure lookup methods fail on std::string parameters with embedded NUL characters (practicalswift) 9574de86ad703ad942cdd0eca79f48c0d42b102b net: Avoid using C-style NUL-terminated strings as arguments in the netbase interface (practicalswift) Pull request description: Don't allow resolving of `std::string`:s with embedded `NUL` characters. Avoid using C-style `NUL`-terminated strings as arguments in the `netbase` interface Add tests. The only place in where C-style `NUL`-terminated strings are actually needed is here: ```diff + if (!ValidAsCString(name)) { + return false; + } ... - int nErr = getaddrinfo(pszName, nullptr, &aiHint, &aiRes); + int nErr = getaddrinfo(name.c_str(), nullptr, &aiHint, &aiRes); if (nErr) return false; ``` Interface changes: ```diff -bool LookupHost(const char *pszName, std::vector<CNetAddr>& vIP, unsigned int nMaxSolutions, bool fAllowLookup); +bool LookupHost(const std::string& name, std::vector<CNetAddr>& vIP, unsigned int nMaxSolutions, bool fAllowLookup); -bool LookupHost(const char *pszName, CNetAddr& addr, bool fAllowLookup); +bool LookupHost(const std::string& name, CNetAddr& addr, bool fAllowLookup); -bool Lookup(const char *pszName, CService& addr, int portDefault, bool fAllowLookup); +bool Lookup(const std::string& name, CService& addr, int portDefault, bool fAllowLookup); -bool Lookup(const char *pszName, std::vector<CService>& vAddr, int portDefault, bool fAllowLookup, unsigned int nMaxSolutions); +bool Lookup(const std::string& name, std::vector<CService>& vAddr, int portDefault, bool fAllowLookup, unsigned int nMaxSolutions); -bool LookupSubNet(const char *pszName, CSubNet& subnet); +bool LookupSubNet(const std::string& strSubnet, CSubNet& subnet); -CService LookupNumeric(const char *pszName, int portDefault = 0); +CService LookupNumeric(const std::string& name, int portDefault = 0); -bool ConnectThroughProxy(const proxyType &proxy, const std::string& strDest, int port, const SOCKET& hSocketRet, int nTimeout, bool *outProxyConnectionFailed); +bool ConnectThroughProxy(const proxyType &proxy, const std::string& strDest, int port, const SOCKET& hSocketRet, int nTimeout, bool& outProxyConnectionFailed); ``` It should be noted that the `ConnectThroughProxy` change (from `bool *outProxyConnectionFailed` to `bool& outProxyConnectionFailed`) has nothing to do with `NUL` handling but I thought it was worth doing when touching this file :) ACKs for top commit: EthanHeilman: ACK 7a046cdc1423963bdcbcf9bb98560af61fa90b37 laanwj: ACK 7a046cdc1423963bdcbcf9bb98560af61fa90b37 Tree-SHA512: 66556e290db996917b54091acd591df221f72230f6b9f6b167b9195ee870ebef6e26f4cda2f6f54d00e1c362e1743bf56785d0de7cae854e6bf7d26f6caccaba
112 lines
4.2 KiB
C++
112 lines
4.2 KiB
C++
// Copyright (c) 2009-2018 The Bitcoin Core developers
|
|
// Distributed under the MIT software license, see the accompanying
|
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
|
|
|
#include <net_permissions.h>
|
|
#include <netbase.h>
|
|
#include <util/error.h>
|
|
#include <util/system.h>
|
|
#include <util/translation.h>
|
|
|
|
namespace {
|
|
|
|
// Parse the following format: "perm1,perm2@xxxxxx"
|
|
bool TryParsePermissionFlags(const std::string& str, NetPermissionFlags& output, size_t& readen, bilingual_str& error)
|
|
{
|
|
NetPermissionFlags flags = PF_NONE;
|
|
const auto atSeparator = str.find('@');
|
|
|
|
// if '@' is not found (ie, "xxxxx"), the caller should apply implicit permissions
|
|
if (atSeparator == std::string::npos) {
|
|
NetPermissions::AddFlag(flags, PF_ISIMPLICIT);
|
|
readen = 0;
|
|
}
|
|
// else (ie, "perm1,perm2@xxxxx"), let's enumerate the permissions by splitting by ',' and calculate the flags
|
|
else {
|
|
readen = 0;
|
|
// permissions == perm1,perm2
|
|
const auto permissions = str.substr(0, atSeparator);
|
|
while (readen < permissions.length()) {
|
|
const auto commaSeparator = permissions.find(',', readen);
|
|
const auto len = commaSeparator == std::string::npos ? permissions.length() - readen : commaSeparator - readen;
|
|
// permission == perm1
|
|
const auto permission = permissions.substr(readen, len);
|
|
readen += len; // We read "perm1"
|
|
if (commaSeparator != std::string::npos) readen++; // We read ","
|
|
|
|
if (permission == "bloomfilter" || permission == "bloom") NetPermissions::AddFlag(flags, PF_BLOOMFILTER);
|
|
else if (permission == "noban") NetPermissions::AddFlag(flags, PF_NOBAN);
|
|
else if (permission == "forcerelay") NetPermissions::AddFlag(flags, PF_FORCERELAY);
|
|
else if (permission == "mempool") NetPermissions::AddFlag(flags, PF_MEMPOOL);
|
|
else if (permission == "all") NetPermissions::AddFlag(flags, PF_ALL);
|
|
else if (permission == "relay") NetPermissions::AddFlag(flags, PF_RELAY);
|
|
else if (permission.length() == 0); // Allow empty entries
|
|
else {
|
|
error = strprintf(_("Invalid P2P permission: '%s'"), permission);
|
|
return false;
|
|
}
|
|
}
|
|
readen++;
|
|
}
|
|
|
|
output = flags;
|
|
error = Untranslated("");
|
|
return true;
|
|
}
|
|
|
|
}
|
|
|
|
std::vector<std::string> NetPermissions::ToStrings(NetPermissionFlags flags)
|
|
{
|
|
std::vector<std::string> strings;
|
|
if (NetPermissions::HasFlag(flags, PF_BLOOMFILTER)) strings.push_back("bloomfilter");
|
|
if (NetPermissions::HasFlag(flags, PF_NOBAN)) strings.push_back("noban");
|
|
if (NetPermissions::HasFlag(flags, PF_FORCERELAY)) strings.push_back("forcerelay");
|
|
if (NetPermissions::HasFlag(flags, PF_RELAY)) strings.push_back("relay");
|
|
if (NetPermissions::HasFlag(flags, PF_MEMPOOL)) strings.push_back("mempool");
|
|
return strings;
|
|
}
|
|
|
|
bool NetWhitebindPermissions::TryParse(const std::string& str, NetWhitebindPermissions& output, bilingual_str& error)
|
|
{
|
|
NetPermissionFlags flags;
|
|
size_t offset;
|
|
if (!TryParsePermissionFlags(str, flags, offset, error)) return false;
|
|
|
|
const std::string strBind = str.substr(offset);
|
|
CService addrBind;
|
|
if (!Lookup(strBind, addrBind, 0, false)) {
|
|
error = ResolveErrMsg("whitebind", strBind);
|
|
return false;
|
|
}
|
|
if (addrBind.GetPort() == 0) {
|
|
error = strprintf(_("Need to specify a port with -whitebind: '%s'"), strBind);
|
|
return false;
|
|
}
|
|
|
|
output.m_flags = flags;
|
|
output.m_service = addrBind;
|
|
error = Untranslated("");
|
|
return true;
|
|
}
|
|
|
|
bool NetWhitelistPermissions::TryParse(const std::string& str, NetWhitelistPermissions& output, bilingual_str& error)
|
|
{
|
|
NetPermissionFlags flags;
|
|
size_t offset;
|
|
if (!TryParsePermissionFlags(str, flags, offset, error)) return false;
|
|
|
|
const std::string net = str.substr(offset);
|
|
CSubNet subnet;
|
|
LookupSubNet(net, subnet);
|
|
if (!subnet.IsValid()) {
|
|
error = strprintf(_("Invalid netmask specified in -whitelist: '%s'"), net);
|
|
return false;
|
|
}
|
|
|
|
output.m_flags = flags;
|
|
output.m_subnet = subnet;
|
|
error = Untranslated("");
|
|
return true;
|
|
}
|