pull/32/head
Geoffrey Merck 4 years ago
parent 25accc9621
commit b70b15e7fe

@ -22,18 +22,22 @@
#include <unordered_map>
#include <vector>
#include <boost/algorithm/string.hpp>
#include <thread>
#include <chrono>
#include "DGWRemoteControlApp.h"
#include "DGWRemoteControlConfig.h"
#include "Version.h"
#include "ProgramArgs.h"
#include "Log.h"
#include "DStarDefines.h"
#include "SHA256.h"
const std::string NAME_OPTION("name");
const std::string REPEATER_PARAM("Callsign");
const std::string ACTION_PARAM("Action");
const std::string RECONNECT_PARAM("Param1");
const std::string REFLECTOR_PARAM("Param2");
const std::string CONFIG_FILENAME("dgwremotecontrol.cfg");
int main(int argc, const char* argv[])
{
@ -49,6 +53,118 @@ int main(int argc, const char* argv[])
return 1;
}
CDGWRemoteControlConfig config(std::string(CFG_DIR) + "/" + CONFIG_FILENAME);
TRemoteGateway gatewayConfig;
if(!config.load() || !config.getGateway(name, gatewayConfig)) {
::fprintf(stderr, "Configuration failed to load\n");
return 1;
}
std::string password(gatewayConfig.m_password);
CRemoteControlRemoteControlHandler handler(gatewayConfig.m_address, gatewayConfig.m_port);
bool ret = handler.open();
if (!ret) {
::fprintf(stderr, "dgwremotecontrol: unable to open the UDP port\n");
return 1;
}
ret = handler.login();
if (!ret) {
handler.close();
::fprintf(stderr, "dgwremotecontrol: unable to login to the gateway/starnetserver\n");
return 1;
}
unsigned int count = 0U;
while (count < 10U) {
std::this_thread::sleep_for(std::chrono::milliseconds(100U));
RC_TYPE type = handler.readType();
if (type == RCT_RANDOM)
break;
if (type == RCT_NONE)
handler.retry();
count++;
}
if (count >= 10U) {
handler.close();
::fprintf(stderr, "dgwremotecontrol: unable to get a response from the gateway/starnetserver\n");
return 1;
}
unsigned int rnd = handler.readRandom();
sendHash(&handler, password, rnd);
count = 0U;
while (count < 10U) {
std::this_thread::sleep_for(std::chrono::milliseconds(100U));
RC_TYPE type = handler.readType();
if (type == RCT_ACK)
break;
if (type == RCT_NAK) {
handler.close();
::fprintf(stderr, "dgwremotecontrol: invalid password sent to the gateway/starnetserver\n");
return 1;
}
if (type == RCT_NONE)
handler.retry();
count++;
}
if (count >= 10U) {
handler.close();
::fprintf(stderr, "dgwremotecontrol: unable to get a response from the gateway/starnetserver\n");
return 1;
}
handler.setLoggedIn(true);
if (actionText == "drop")
handler.logoff(repeater, user);
else
handler.link(repeater, reconnect, reflector);
count = 0U;
while (count < 10U) {
std::this_thread::sleep_for(std::chrono::milliseconds(100U));
RC_TYPE type = handler.readType();
if (type == RCT_ACK)
break;
if (type == RCT_NAK) {
handler.close();
::fprintf(stderr, "dgwremotecontrol: drop/link/unlink command rejected by the gateway/starnetserver\n");
return 1;
}
if (type == RCT_NONE)
handler.retry();
count++;
}
if (count >= 10U) {
handler.close();
::fprintf(stderr, "dgwremotecontrol: unable to get a response from the gateway/starnetserver\n");
return 1;
}
::fprintf(stdout, "dgwremotecontrol: command accepted by the gateway/starnetserver\n");
handler.logout();
handler.close();
return 0;
}
@ -76,7 +192,7 @@ bool getCLIParams(int argc, const char* argv[], std::string& name, std::string&
actionText = boost::to_lower_copy(positionalArgs[1]);
if(actionText != "link") {
CLog::logError("Invalid action %s. Expected link", positionalArgs[1].c_str());
::fprintf(stderr, "Invalid action %s. Expected link\n", positionalArgs[1].c_str());
ret = false;
}
@ -94,7 +210,7 @@ bool getCLIParams(int argc, const char* argv[], std::string& name, std::string&
else if(reconnectText == "180") reconnect = RECONNECT_180MINS;
else if(reconnectText == "fixed") reconnect = RECONNECT_FIXED;
else {
CLog::logError("Invalid reconnect value %s. Valid values are 5,10,15,20,25,30,60,90,120,180,fixed", positionalArgs[2].c_str());
::fprintf(stderr, "Invalid reconnect value %s. Valid values are 5,10,15,20,25,30,60,90,120,180,fixed\n", positionalArgs[2].c_str());
ret = false;
}
reflector = boost::to_upper_copy(positionalArgs[3]);
@ -105,7 +221,7 @@ bool getCLIParams(int argc, const char* argv[], std::string& name, std::string&
repeater = positionalArgs[0];
actionText = boost::to_lower_copy(positionalArgs[1]);
if(actionText != "unlink") {
CLog::logError("Invalid action %s. Expected unlink", positionalArgs[1].c_str());
::fprintf(stderr, "Invalid action %s. Expected unlink\n", positionalArgs[1].c_str());
ret = false;
}
reconnect = RECONNECT_NEVER;
@ -117,7 +233,7 @@ bool getCLIParams(int argc, const char* argv[], std::string& name, std::string&
actionText = boost::to_lower_copy(positionalArgs[1]);
if(actionText != "drop") {
CLog::logError("Invalid action %s. Expected drop", positionalArgs[1].c_str());
::fprintf(stderr, "Invalid action %s. Expected drop\n", positionalArgs[1].c_str());
ret = false;
}
@ -138,3 +254,24 @@ bool getCLIParams(int argc, const char* argv[], std::string& name, std::string&
return ret;
}
void sendHash(CRemoteControlRemoteControlHandler* handler, const std::string& password, unsigned int rnd)
{
assert(handler != NULL);
unsigned int len = password.length() + sizeof(unsigned int);
unsigned char* in = new unsigned char[len];
unsigned char* out = new unsigned char[32U];
::memcpy(in, &rnd, sizeof(unsigned int));
for (unsigned int i = 0U; i < password.length(); i++)
in[i + sizeof(unsigned int)] = password.at(i);
CSHA256 sha256;
sha256.buffer(in, len, out);
handler->sendHash(out, 32U);
delete[] in;
delete[] out;
}

@ -21,5 +21,7 @@
#include <string>
#include "Defs.h"
#include "RemoteControlRemoteControlHandler.h"
bool getCLIParams(int argc, const char* argv[], std::string& name, std::string& repeater, std::string& actionText, RECONNECT& reconnect, std::string& user, std::string& reflector);
bool getCLIParams(int argc, const char* argv[], std::string& name, std::string& repeater, std::string& actionText, RECONNECT& reconnect, std::string& user, std::string& reflector);
void sendHash(CRemoteControlRemoteControlHandler* handler, const std::string& password, unsigned int rnd);

@ -17,12 +17,78 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <cassert>
#include <cstring>
#include "DGWRemoteControlConfig.h"
#include "Log.h"
#include "StringUtils.h"
CDGWRemoteControlConfig::CDGWRemoteControlConfig(const std::string& fileName) :
m_fileName(fileName),
m_gateways()
{
assert(!fileName.empty());
}
CDGWRemoteControlConfig::~CDGWRemoteControlConfig()
{
for(auto gw : m_gateways) {
delete gw;
}
m_gateways.clear();
}
bool CDGWRemoteControlConfig::load()
{
CConfig cfg(m_fileName);
bool ret = open(cfg);
if(ret) {
ret = loadGateways(cfg) && ret;
}
return ret;
}
bool load()
bool CDGWRemoteControlConfig::loadGateways(CConfig & cfg)
{
return false;
for(unsigned int i = 1U; i <= 4U; i++) {
auto section = CStringUtils::string_format("gateway_%u", i);
TRemoteGateway * gateway = new TRemoteGateway();
bool ret = cfg.getValue(section, "name", gateway->m_name, 0U, 1024U, section);
ret = cfg.getValue(section, "address", gateway->m_address, 0U, 1024U, "127.0.0.1") && ret;
ret = cfg.getValue(section, "port", gateway->m_port, 1U, 65535U, 4242U) && ret;
ret = cfg.getValue(section, "password", gateway->m_password, 0U, 1024U, "") && ret;
if(!ret || gateway->m_password.empty()) {
delete gateway;
continue;
}
m_gateways.push_back(gateway);
}
return m_gateways.size() != 0;
}
bool CDGWRemoteControlConfig::getGateway(const std::string& name, TRemoteGateway& gateway)
{
if(m_gateways.size() == 0U)
return false;
for(auto gw : m_gateways) {
if(strcasecmp(name.c_str(), gw->m_name.c_str()) == 0)
{
gateway = *gw;
return true;
}
}
gateway = *(m_gateways[0]);
return true;
}
bool CDGWRemoteControlConfig::open(CConfig & cfg)

@ -20,22 +20,29 @@
#pragma once
#include <string>
#include <vector>
#include "Config.h"
typedef struct {
std::string callsign;
std::string address;
std::string m_name;
std::string m_address;
unsigned int m_port;
std::string m_password;
} TRemoteGateway;
class CDGWRemoteControlConfig
{
public:
CDGWRemoteControlConfig(const std::string& pathName);
CDGWRemoteControlConfig(const std::string& fileName);
~CDGWRemoteControlConfig();
bool load();
bool getGateway(const std::string& name, TRemoteGateway& gateway);
private:
bool open(CConfig& config);
bool loadGateways(CConfig& config);
std::string m_fileName;
std::vector<TRemoteGateway *> m_gateways;
};

@ -2,11 +2,13 @@
# When invoking dgwremotecontrol without name parameter, the first gateway of the config file is used
[gateway_1]
name=hill_top
address=127.0.0.1
port=4242
password=CHANGE_ME
[gateway_2]
name=city_center
address=127.0.0.1
port=4242
password=CHANGE_ME
Loading…
Cancel
Save

Powered by TurnKey Linux.