diff --git a/src/init.cpp b/src/init.cpp index ab52f44a272d6..ef3fbaa24faa6 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -1390,7 +1390,7 @@ bool AppInitMain() for (const auto& net : gArgs.GetArgs("-whitelist")) { CSubNet subnet; - LookupSubNet(net.c_str(), subnet); + LookupSubNet(net, subnet); if (!subnet.IsValid()) return UIError(strprintf(_("Invalid netmask specified in %s: '%s'"), "-whitelist", net)); connman.AddWhitelistedRange(subnet); @@ -1406,7 +1406,7 @@ bool AppInitMain() SetLimited(NET_ONION); if (!proxyArg.empty() && proxyArg != "0") { CService proxyAddr; - if (!Lookup(proxyArg.c_str(), proxyAddr, 9050, fNameLookup)) { + if (!Lookup(proxyArg, proxyAddr, 9050, fNameLookup)) { return UIError(strprintf(_("%s Invalid %s address or hostname: '%s'"), "Lookup():", "-proxy", proxyArg)); } @@ -1430,7 +1430,7 @@ bool AppInitMain() SetLimited(NET_ONION); // set onions as unreachable } else { CService onionProxy; - if (!Lookup(onionArg.c_str(), onionProxy, 9050, fNameLookup)) { + if (!Lookup(onionArg, onionProxy, 9050, fNameLookup)) { return UIError(strprintf(_("%s Invalid %s address or hostname: '%s'"), "Lookup():", "-onion", onionArg)); } proxyType addrOnion = proxyType(onionProxy, proxyRandomize); @@ -1449,13 +1449,13 @@ bool AppInitMain() if (fListen) { for (const std::string& strBind : gArgs.GetArgs("-bind")) { CService addrBind; - if (!Lookup(strBind.c_str(), addrBind, GetListenPort(), false)) + if (!Lookup(strBind, addrBind, GetListenPort(), false)) return UIError(ResolveErrMsg("bind", strBind)); fBound |= Bind(connman, addrBind, (BF_EXPLICIT | BF_REPORT_ERROR)); } for (const std::string& strBind : gArgs.GetArgs("-whitebind")) { CService addrBind; - if (!Lookup(strBind.c_str(), addrBind, 0, false)) + if (!Lookup(strBind, addrBind, 0, false)) return UIError(ResolveErrMsg("whitebind", strBind)); if (addrBind.GetPort() == 0) return UIError(strprintf(_("Need to specify a port with %s: '%s'"), "-whitebind", strBind)); @@ -1473,7 +1473,7 @@ bool AppInitMain() for (const std::string& strAddr : gArgs.GetArgs("-externalip")) { CService addrLocal; - if (Lookup(strAddr.c_str(), addrLocal, GetListenPort(), fNameLookup) && addrLocal.IsValid()) + if (Lookup(strAddr, addrLocal, GetListenPort(), fNameLookup) && addrLocal.IsValid()) AddLocal(addrLocal, LOCAL_MANUAL); else return UIError(ResolveErrMsg("externalip", strAddr)); diff --git a/src/net.cpp b/src/net.cpp index 285adc795990b..e81e134d8c8db 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -1400,7 +1400,7 @@ void CConnman::ThreadDNSAddressSeed() if (!resolveSource.SetInternal(host)) { continue; } - if (LookupHost(host.c_str(), vIPs, 0, true)) { + if (LookupHost(host, vIPs, 0, true)) { for (CNetAddr& ip : vIPs) { int nOneDay = 24*3600; CAddress addr = CAddress(CService(ip, Params().GetDefaultPort()), requiredServiceBits); @@ -1641,7 +1641,7 @@ std::vector CConnman::GetAddedNodeInfo() } for (std::string& strAddNode : lAddresses) { - CService service(LookupNumeric(strAddNode.c_str(), Params().GetDefaultPort())); + CService service(LookupNumeric(strAddNode, Params().GetDefaultPort())); if (service.IsValid()) { // strAddNode is an IP:port auto it = mapConnected.find(service); @@ -1678,7 +1678,7 @@ void CConnman::ThreadOpenAddedConnections() CSemaphoreGrant grant(*semOutbound); // If strAddedNode is an IP/port, decode it immediately, so // OpenNetworkConnection can detect existing connections to that IP/port. - CService service(LookupNumeric(info.strAddedNode.c_str(), Params().GetDefaultPort())); + CService service(LookupNumeric(info.strAddedNode, Params().GetDefaultPort())); OpenNetworkConnection(CAddress(service, NODE_NONE), false, &grant, info.strAddedNode.c_str(), false); if (!interruptNet.sleep_for(std::chrono::milliseconds(500))) return; @@ -2461,7 +2461,7 @@ CNode* CConnman::ConnectNode(CAddress addrConnect) bool validateMasternodeIP(const std::string& addrStr) { CNetAddr resolved; - if (LookupHost(addrStr.c_str(), resolved, false)) { + if (LookupHost(addrStr, resolved, false)) { return ((IsReachable(resolved) && resolved.IsRoutable()) || (Params().IsRegTestNet() && resolved.IsValid())); } diff --git a/src/netbase.cpp b/src/netbase.cpp index 0e2ec97cc5dfc..274272c367d45 100644 --- a/src/netbase.cpp +++ b/src/netbase.cpp @@ -1,15 +1,14 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2015 The Bitcoin developers // Copyright (c) 2017-2020 The PIVX developers -// Distributed under the MIT/X11 software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. +// Distributed under the MIT software license, see the accompanying +// file COPYING or https://www.opensource.org/licenses/mit-license.php. #include "netbase.h" -#include "hash.h" #include "sync.h" -#include "uint256.h" #include "random.h" +#include "util/string.h" #include "util/system.h" #include "utilstrencodings.h" @@ -81,13 +80,17 @@ void SplitHostPort(std::string in, int& portOut, std::string& hostOut) hostOut = in; } -bool static LookupIntern(const char* pszName, std::vector& vIP, unsigned int nMaxSolutions, bool fAllowLookup) +bool static LookupIntern(const std::string& name, std::vector& vIP, unsigned int nMaxSolutions, bool fAllowLookup) { vIP.clear(); + if (!ValidAsCString(name)) { + return false; + } + { CNetAddr addr; - if (addr.SetSpecial(std::string(pszName))) { + if (addr.SetSpecial(name)) { vIP.push_back(addr); return true; } @@ -105,7 +108,7 @@ bool static LookupIntern(const char* pszName, std::vector& vIP, unsign aiHint.ai_flags = fAllowLookup ? AI_ADDRCONFIG : AI_NUMERICHOST; #endif struct addrinfo* aiRes = NULL; - int nErr = getaddrinfo(pszName, NULL, &aiHint, &aiRes); + int nErr = getaddrinfo(name.c_str(), NULL, &aiHint, &aiRes); if (nErr) return false; @@ -135,38 +138,45 @@ bool static LookupIntern(const char* pszName, std::vector& vIP, unsign return (vIP.size() > 0); } -bool LookupHost(const char* pszName, std::vector& vIP, unsigned int nMaxSolutions, bool fAllowLookup) +bool LookupHost(const std::string& name, std::vector& vIP, unsigned int nMaxSolutions, bool fAllowLookup) { - std::string strHost(pszName); + if (!ValidAsCString(name)) { + return false; + } + std::string strHost = name; if (strHost.empty()) return false; if (strHost.front() == '[' && strHost.back() == ']') { strHost = strHost.substr(1, strHost.size() - 2); } - return LookupIntern(strHost.c_str(), vIP, nMaxSolutions, fAllowLookup); + return LookupIntern(strHost, vIP, nMaxSolutions, fAllowLookup); } -bool LookupHost(const char* pszName, CNetAddr& addr, bool fAllowLookup) +bool LookupHost(const std::string& name, CNetAddr& addr, bool fAllowLookup) { + if (!ValidAsCString(name)) { + return false; + } std::vector vIP; - LookupHost(pszName, vIP, 1, fAllowLookup); + LookupHost(name, vIP, 1, fAllowLookup); if (vIP.empty()) return false; addr = vIP.front(); return true; } -bool Lookup(const char* pszName, std::vector& vAddr, int portDefault, bool fAllowLookup, unsigned int nMaxSolutions) +bool Lookup(const std::string& name, std::vector& vAddr, int portDefault, bool fAllowLookup, unsigned int nMaxSolutions) { - if (pszName[0] == 0) + if (name.empty() || !ValidAsCString(name)) { return false; + } int port = portDefault; - std::string hostname = ""; - SplitHostPort(std::string(pszName), port, hostname); + std::string hostname; + SplitHostPort(name, port, hostname); std::vector vIP; - bool fRet = LookupIntern(hostname.c_str(), vIP, nMaxSolutions, fAllowLookup); + bool fRet = LookupIntern(hostname, vIP, nMaxSolutions, fAllowLookup); if (!fRet) return false; vAddr.resize(vIP.size()); @@ -175,22 +185,28 @@ bool Lookup(const char* pszName, std::vector& vAddr, int portDefault, return true; } -bool Lookup(const char* pszName, CService& addr, int portDefault, bool fAllowLookup) +bool Lookup(const std::string& name, CService& addr, int portDefault, bool fAllowLookup) { + if (!ValidAsCString(name)) { + return false; + } std::vector vService; - bool fRet = Lookup(pszName, vService, portDefault, fAllowLookup, 1); + bool fRet = Lookup(name, vService, portDefault, fAllowLookup, 1); if (!fRet) return false; addr = vService[0]; return true; } -CService LookupNumeric(const char* pszName, int portDefault) +CService LookupNumeric(const std::string& name, int portDefault) { + if (!ValidAsCString(name)) { + return {}; + } CService addr; // "1.2:345" will fail to resolve the ip, but will still set the port. // If the ip fails to resolve, re-init the result. - if (!Lookup(pszName, addr, portDefault, false)) + if (!Lookup(name, addr, portDefault, false)) addr = CService(); return addr; } @@ -669,14 +685,16 @@ bool ConnectSocketByName(CService& addr, SOCKET& hSocketRet, const char* pszDest return ConnectThroughProxy(proxy, strDest, port, hSocketRet, nTimeout, outProxyConnectionFailed); } -bool LookupSubNet(const char* pszName, CSubNet& ret) +bool LookupSubNet(const std::string& strSubnet, CSubNet& ret) { - std::string strSubnet(pszName); + if (!ValidAsCString(strSubnet)) { + return false; + } size_t slash = strSubnet.find_last_of('/'); std::vector vIP; std::string strAddress = strSubnet.substr(0, slash); - if (LookupHost(strAddress.c_str(), vIP, 1, false)) + if (LookupHost(strAddress, vIP, 1, false)) { CNetAddr network = vIP[0]; if (slash != strSubnet.npos) { @@ -689,7 +707,7 @@ bool LookupSubNet(const char* pszName, CSubNet& ret) } else // If not a valid number, try full netmask syntax { // Never allow lookup for netmask - if (LookupHost(strNetmask.c_str(), vIP, 1, false)) { + if (LookupHost(strNetmask, vIP, 1, false)) { ret = CSubNet(network, vIP[0]); return ret.IsValid(); } diff --git a/src/netbase.h b/src/netbase.h index 06bad8f300e06..8d124c1e82422 100644 --- a/src/netbase.h +++ b/src/netbase.h @@ -46,12 +46,12 @@ bool GetProxy(enum Network net, proxyType& proxyInfoOut); bool IsProxy(const CNetAddr& addr); bool SetNameProxy(const proxyType &addrProxy); bool HaveNameProxy(); -bool LookupHost(const char* pszName, std::vector& vIP, unsigned int nMaxSolutions, bool fAllowLookup); -bool LookupHost(const char* pszName, CNetAddr& addr, bool fAllowLookup); -bool Lookup(const char* pszName, CService& addr, int portDefault, bool fAllowLookup); -bool Lookup(const char* pszName, std::vector& vAddr, int portDefault, bool fAllowLookup, unsigned int nMaxSolutions); -CService LookupNumeric(const char* pszName, int portDefault = 0); -bool LookupSubNet(const char* pszName, CSubNet& subnet); +bool LookupHost(const std::string& name, std::vector& vIP, unsigned int nMaxSolutions, bool fAllowLookup); +bool LookupHost(const std::string& name, CNetAddr& addr, bool fAllowLookup); +bool Lookup(const std::string& name, CService& addr, int portDefault, bool fAllowLookup); +bool Lookup(const std::string& name, std::vector& vAddr, int portDefault, bool fAllowLookup, unsigned int nMaxSolutions); +CService LookupNumeric(const std::string& name, int portDefault = 0); +bool LookupSubNet(const std::string& name, CSubNet& subnet); bool ConnectSocket(const CService& addr, SOCKET& hSocketRet, int nTimeout, bool* outProxyConnectionFailed = 0); bool ConnectSocketByName(CService& addr, SOCKET& hSocketRet, const char* pszDest, int portDefault, int nTimeout, bool* outProxyConnectionFailed = 0); /** Return readable error string for a network error code */ diff --git a/src/qt/clientmodel.cpp b/src/qt/clientmodel.cpp index fff6ae476f39f..785983ffaa5b3 100644 --- a/src/qt/clientmodel.cpp +++ b/src/qt/clientmodel.cpp @@ -364,7 +364,7 @@ bool ClientModel::getTorInfo(std::string& ip_port) const LOCK(cs_mapLocalHost); for (const std::pair& item : mapLocalHost) { if (item.first.IsTor()) { - CService addrOnion(LookupNumeric(item.first.ToString().c_str(), item.second.nPort)); + CService addrOnion(LookupNumeric(item.first.ToString(), item.second.nPort)); ip_port = addrOnion.ToStringIPPort(); return true; } diff --git a/src/rpc/net.cpp b/src/rpc/net.cpp index 8b4ebd7926ebe..a375d1da5a502 100644 --- a/src/rpc/net.cpp +++ b/src/rpc/net.cpp @@ -466,10 +466,10 @@ UniValue setban(const JSONRPCRequest& request) if (!isSubnet) { CNetAddr resolved; - LookupHost(request.params[0].get_str().c_str(), resolved, false); + LookupHost(request.params[0].get_str(), resolved, false); netAddr = resolved; } else - LookupSubNet(request.params[0].get_str().c_str(), subNet); + LookupSubNet(request.params[0].get_str(), subNet); if (! (isSubnet ? subNet.IsValid() : netAddr.IsValid()) ) throw JSONRPCError(RPC_CLIENT_NODE_ALREADY_ADDED, "Error: Invalid IP/Subnet"); diff --git a/src/rpc/rpcevo.cpp b/src/rpc/rpcevo.cpp index 9f8770d0efcac..a68326038cf99 100644 --- a/src/rpc/rpcevo.cpp +++ b/src/rpc/rpcevo.cpp @@ -330,7 +330,7 @@ static ProRegPL ParseProRegPLParams(const UniValue& params, unsigned int paramId // ip and port const std::string& strIpPort = params[paramIdx].get_str(); if (!strIpPort.empty()) { - if (!Lookup(strIpPort.c_str(), pl.addr, Params().GetDefaultPort(), false)) { + if (!Lookup(strIpPort, pl.addr, Params().GetDefaultPort(), false)) { throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("invalid network address %s", strIpPort)); } } diff --git a/src/test/netbase_tests.cpp b/src/test/netbase_tests.cpp index e49d67262c407..9af26b7cd90a9 100644 --- a/src/test/netbase_tests.cpp +++ b/src/test/netbase_tests.cpp @@ -104,7 +104,7 @@ BOOST_AUTO_TEST_CASE(netbase_splithost) bool static TestParse(std::string src, std::string canon) { - CService addr(LookupNumeric(src.c_str(), 65535)); + CService addr(LookupNumeric(src, 65535)); return canon == addr.ToString(); }