diff --git a/configs/peer_list.example.dat b/configs/peer_list.example.dat index c94eb702..50a77385 100644 --- a/configs/peer_list.example.dat +++ b/configs/peer_list.example.dat @@ -1,7 +1,9 @@ # # This file sets the valid peer IDs allowed on a FNE. # -# Entry Format: "Peer ID,Peer Password,Peer Link (1 = Enabled / 0 = Disabled)" +# Entry Format: "Peer ID,Peer Password,Peer Link (1 = Enabled / 0 = Disabled),Peer Alias (optional)," #1234,,0, #5678,MYSECUREPASSWORD,0, #9876,MYSECUREPASSWORD,1, +#5432,MYSECUREPASSWORD,,Peer Alias 1, +#1012,MYSECUREPASSWORD,1,Peer Alias 2, diff --git a/src/common/lookups/PeerListLookup.cpp b/src/common/lookups/PeerListLookup.cpp index fee33719..f64d131c 100644 --- a/src/common/lookups/PeerListLookup.cpp +++ b/src/common/lookups/PeerListLookup.cpp @@ -46,16 +46,16 @@ void PeerListLookup::clear() /* Adds a new entry to the list. */ -void PeerListLookup::addEntry(uint32_t id, const std::string& password, bool peerLink) +void PeerListLookup::addEntry(uint32_t id, const std::string& alias, const std::string& password, bool peerLink) { - PeerId entry = PeerId(id, password, peerLink, false); + PeerId entry = PeerId(id, alias, password, peerLink, false); std::lock_guard lock(m_mutex); try { PeerId _entry = m_table.at(id); // if either the alias or the enabled flag doesn't match, update the entry if (_entry.peerId() == id) { - _entry = PeerId(id, password, peerLink, false); + _entry = PeerId(id, alias, password, peerLink, false); m_table[id] = _entry; } } catch (...) { @@ -87,7 +87,7 @@ PeerId PeerListLookup::find(uint32_t id) try { entry = m_table.at(id); } catch (...) { - entry = PeerId(0U, "", false, true); + entry = PeerId(0U, "", "", false, true); } return entry; @@ -201,22 +201,29 @@ bool PeerListLookup::load() // parse tokenized line uint32_t id = ::atoi(parsed[0].c_str()); + + // Parse optional alias field (at end of line to avoid breaking change with existing lists) + std::string alias = ""; + if (parsed.size() >= 4) + alias = parsed[3].c_str(); + + // Parse peer link flag bool peerLink = false; if (parsed.size() >= 3) peerLink = ::atoi(parsed[2].c_str()) == 1; - // Check for an optional alias field - if (parsed.size() >= 2) { - if (!parsed[1].empty()) { - m_table[id] = PeerId(id, parsed[1], peerLink, false); - LogDebug(LOG_HOST, "Loaded peer ID %u into peer ID lookup table, using unique peer password%s", id, - (peerLink) ? ", Peer-Link Enabled" : ""); - continue; - } - } + // Parse optional password + std::string password = ""; + if (parsed.size() >= 2) + password = parsed[1].c_str(); - m_table[id] = PeerId(id, "", peerLink, false); - LogDebug(LOG_HOST, "Loaded peer ID %u into peer ID lookup table, using master password%s", id, + // Load into table + m_table[id] = PeerId(id, alias, password, peerLink, false); + + // Log depending on what was loaded + LogDebug(LOG_HOST, "Loaded peer ID %u%s into peer ID lookup table, %s%s", id, + (!alias.empty() ? (" (" + alias + ")").c_str() : ""), + (!password.empty() ? "using unique peer password" : "using master password"), (peerLink) ? ", Peer-Link Enabled" : ""); } } @@ -258,20 +265,27 @@ bool PeerListLookup::save() for (auto& entry: m_table) { // Get the parameters uint32_t peerId = entry.first; + std::string alias = entry.second.peerAlias(); std::string password = entry.second.peerPassword(); // Format into a string line = std::to_string(peerId) + ","; - // Add the alias if we have one + // Add the password if we have one if (password.length() > 0) { line += password; - line += ","; } + line += ","; + // Add peerLink flag bool peerLink = entry.second.peerLink(); if (peerLink) { line += "1,"; } else { line += "0,"; } + // Add alias if we have one + if (alias.length() > 0) { + line += alias; + line += ","; + } // Add the newline line += "\n"; // Write to file diff --git a/src/common/lookups/PeerListLookup.h b/src/common/lookups/PeerListLookup.h index eed88808..b1b318ba 100644 --- a/src/common/lookups/PeerListLookup.h +++ b/src/common/lookups/PeerListLookup.h @@ -47,6 +47,7 @@ namespace lookups */ PeerId() : m_peerId(0U), + m_peerAlias(), m_peerPassword(), m_peerLink(false), m_peerDefault(false) @@ -56,12 +57,14 @@ namespace lookups /** * @brief Initializes a new instance of the PeerId class. * @param peerId Peer ID. + * @param peerAlias Peer alias * @param peerPassword Per Peer Password. * @param sendConfiguration Flag indicating this peer participates in peer link and should be sent configuration. * @param peerDefault Flag indicating this is a "default" (i.e. undefined) peer. */ - PeerId(uint32_t peerId, const std::string& peerPassword, bool peerLink, bool peerDefault) : + PeerId(uint32_t peerId, const std::string& peerAlias, const std::string& peerPassword, bool peerLink, bool peerDefault) : m_peerId(peerId), + m_peerAlias(peerAlias), m_peerPassword(peerPassword), m_peerLink(peerLink), m_peerDefault(peerDefault) @@ -77,6 +80,7 @@ namespace lookups { if (this != &data) { m_peerId = data.m_peerId; + m_peerAlias = data.m_peerAlias; m_peerPassword = data.m_peerPassword; m_peerLink = data.m_peerLink; m_peerDefault = data.m_peerDefault; @@ -88,13 +92,15 @@ namespace lookups /** * @brief Sets flag values. * @param peerId Peer ID. + * @param peerAlias Peer Alias * @param peerPassword Per Peer Password. * @param sendConfiguration Flag indicating this peer participates in peer link and should be sent configuration. * @param peerDefault Flag indicating this is a "default" (i.e. undefined) peer. */ - void set(uint32_t peerId, const std::string& peerPassword, bool peerLink, bool peerDefault) + void set(uint32_t peerId, const std::string& peerAlias, const std::string& peerPassword, bool peerLink, bool peerDefault) { m_peerId = peerId; + m_peerAlias = peerAlias; m_peerPassword = peerPassword; m_peerLink = peerLink; m_peerDefault = peerDefault; @@ -105,6 +111,10 @@ namespace lookups * @brief Peer ID. */ __READONLY_PROPERTY_PLAIN(uint32_t, peerId); + /** + * @breif Peer Alias + */ + __READONLY_PROPERTY_PLAIN(std::string, peerAlias); /** * @brief Per Peer Password. */ @@ -157,7 +167,7 @@ namespace lookups * @param password Per Peer Password. * @param peerLink Flag indicating this peer will participate in peer link and should be sent configuration. */ - void addEntry(uint32_t id, const std::string& password = "", bool peerLink = false); + void addEntry(uint32_t id, const std::string& alias = "", const std::string& password = "", bool peerLink = false); /** * @brief Removes an existing entry from the list. * @param peerId Unique peer ID to remove. diff --git a/src/fne/network/RESTAPI.cpp b/src/fne/network/RESTAPI.cpp index 46e39825..3b30f09d 100644 --- a/src/fne/network/RESTAPI.cpp +++ b/src/fne/network/RESTAPI.cpp @@ -1177,8 +1177,13 @@ void RESTAPI::restAPI_GetPeerList(const HTTPPayload& request, HTTPPayload& reply json::object peerObj = json::object(); uint32_t peerId = entry.first; + std::string peerAlias = entry.second.peerAlias(); + bool peerLink = entry.second.peerLink(); + bool peerPassword = !entry.second.peerPassword().empty(); // True if password is not empty, otherwise false peerObj["peerId"].set(peerId); - + peerObj["peerAlias"].set(peerAlias); + peerObj["peerLink"].set(peerLink); + peerObj["peerPassword"].set(peerPassword); peers.push_back(json::value(peerObj)); } } @@ -1203,14 +1208,51 @@ void RESTAPI::restAPI_PutPeerAdd(const HTTPPayload& request, HTTPPayload& reply, errorPayload(reply, "OK", HTTPPayload::OK); + // Validate peer ID (required) if (!req["peerId"].is()) { errorPayload(reply, "peerId was not a valid integer"); return; } - + // Get uint32_t peerId = req["peerId"].get(); - m_peerListLookup->addEntry(peerId); + // Get peer alias (optional) + std::string peerAlias = ""; + if (req.find("peerAlias") != req.end()) { + // Validate + if (!req["peerAlias"].is()) { + errorPayload(reply, "peerAlias was not a valid string"); + return; + } + // Get + peerAlias = req["peerAlias"].get(); + } + + // Get peer link setting (optional) + bool peerLink = false; + if (req.find("peerLink") != req.end()) { + // Validate + if (!req["peerLink"].is()) { + errorPayload(reply, "peerLink was not a valid boolean"); + return; + } + // Get + peerLink = req["peerLink"].get(); + } + + // Get peer password (optional) + std::string peerPassword = ""; + if (req.find("peerPassword") != req.end()) { + // Validate + if (!req["peerPassword"].is()) { + errorPayload(reply, "peerPassword was not a valid string"); + return; + } + // Get + peerPassword = req["peerPassword"].get(); + } + + m_peerListLookup->addEntry(peerId, peerAlias, peerPassword, peerLink); } /* REST API endpoint; implements put peer delete request. */