Skip to content

Commit

Permalink
net: Avoid using C-style NUL-terminated strings as arguments in the n…
Browse files Browse the repository at this point in the history
…etbase interface

Adaptation of btc@9574de86ad703ad942cdd0eca79f48c0d42b102b
  • Loading branch information
furszy committed Aug 10, 2021
1 parent f30869d commit a751b9b
Show file tree
Hide file tree
Showing 8 changed files with 64 additions and 46 deletions.
12 changes: 6 additions & 6 deletions src/init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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));
}

Expand All @@ -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);
Expand All @@ -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));
Expand All @@ -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));
Expand Down
8 changes: 4 additions & 4 deletions src/net.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -1641,7 +1641,7 @@ std::vector<AddedNodeInfo> 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);
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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()));
}
Expand Down
68 changes: 43 additions & 25 deletions src/netbase.cpp
Original file line number Diff line number Diff line change
@@ -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"

Expand Down Expand Up @@ -81,13 +80,17 @@ void SplitHostPort(std::string in, int& portOut, std::string& hostOut)
hostOut = in;
}

bool static LookupIntern(const char* pszName, std::vector<CNetAddr>& vIP, unsigned int nMaxSolutions, bool fAllowLookup)
bool static LookupIntern(const std::string& name, std::vector<CNetAddr>& 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;
}
Expand All @@ -105,7 +108,7 @@ bool static LookupIntern(const char* pszName, std::vector<CNetAddr>& 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;

Expand Down Expand Up @@ -135,38 +138,45 @@ bool static LookupIntern(const char* pszName, std::vector<CNetAddr>& vIP, unsign
return (vIP.size() > 0);
}

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)
{
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<CNetAddr> 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<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)
{
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<CNetAddr> 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());
Expand All @@ -175,22 +185,28 @@ bool Lookup(const char* pszName, std::vector<CService>& 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<CService> 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;
}
Expand Down Expand Up @@ -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<CNetAddr> 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) {
Expand All @@ -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();
}
Expand Down
12 changes: 6 additions & 6 deletions src/netbase.h
Original file line number Diff line number Diff line change
Expand Up @@ -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<CNetAddr>& 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<CService>& 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<CNetAddr>& 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<CService>& 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 */
Expand Down
2 changes: 1 addition & 1 deletion src/qt/clientmodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -364,7 +364,7 @@ bool ClientModel::getTorInfo(std::string& ip_port) const
LOCK(cs_mapLocalHost);
for (const std::pair<const CNetAddr, LocalServiceInfo>& 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;
}
Expand Down
4 changes: 2 additions & 2 deletions src/rpc/net.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand Down
2 changes: 1 addition & 1 deletion src/rpc/rpcevo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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));
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/test/netbase_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}

Expand Down

0 comments on commit a751b9b

Please sign in to comment.