Skip to content

Commit

Permalink
Merge branch 'dev'
Browse files Browse the repository at this point in the history
  • Loading branch information
hfedcba committed May 29, 2018
2 parents 9572529 + 8f6ee7a commit 6e88249
Show file tree
Hide file tree
Showing 9 changed files with 55 additions and 14 deletions.
2 changes: 1 addition & 1 deletion debian/control
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@ Homepage: https://homegear.eu

Package: homegear-gateway
Architecture: any
Depends: ${shlibs:Depends}, ${misc:Depends}, libhomegear-base (= <BASELIBVER>), libgcrypt20, libgnutlsxx28, libgpg-error0 (>= 1.10), procps, insserv
Depends: ${shlibs:Depends}, ${misc:Depends}, libhomegear-base (= <BASELIBVER>), libgcrypt20, libgnutlsxx28, libgpg-error0 (>= 1.10), procps
Description: Universal communication gateway for Homegear
Universal communication gateway for Homegear
8 changes: 8 additions & 0 deletions misc/Config Directory/gateway.conf
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ listenAddress = ::
# Default: 2017
port = 2017

# The port number the gateway listens on if unconfigured.
# Default: 2018
portUnconfigured = 2018

# Default: runAsUser = root
# runAsUser = homegear

Expand Down Expand Up @@ -38,6 +42,10 @@ dataPath = /var/lib/homegear-gateway
# Default: lockfilePath = /var/lock
lockfilePath = /var/lock

# Path to the GPIO root directory. Only relevant if one of the communication modules needs GPIO access.
# Default: gpioPath = /sys/class/gpio
gpioPath = /sys/class/gpio

### TLS options ###

# The path to the certificate authority's certificate.
Expand Down
6 changes: 3 additions & 3 deletions src/Families/HomeMaticCc1101.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ HomeMaticCc1101::HomeMaticCc1101(BaseLib::SharedObjects* bl) : ICommunicationInt
_sendingPending = false;
_firstPacket = true;
_updateMode = false;
_gpio.reset(new BaseLib::LowLevel::Gpio(bl));
_gpio.reset(new BaseLib::LowLevel::Gpio(bl, GD::settings.gpioPath()));

_localRpcMethods.emplace("sendPacket", std::bind(&HomeMaticCc1101::sendPacket, this, std::placeholders::_1));
_localRpcMethods.emplace("enableUpdateMode", std::bind(&HomeMaticCc1101::enableUpdateMode, this, std::placeholders::_1));
Expand Down Expand Up @@ -367,7 +367,7 @@ void HomeMaticCc1101::openDevice()
{
try
{
if(_fileDescriptor->descriptor != -1) closeDevice();
if(_fileDescriptor && _fileDescriptor->descriptor != -1) closeDevice();

_lockfile = GD::bl->settings.lockFilePath() + "LCK.." + GD::settings.device().substr(GD::settings.device().find_last_of('/') + 1);
int lockfileDescriptor = open(_lockfile.c_str(), O_WRONLY | O_EXCL | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
Expand Down Expand Up @@ -870,7 +870,7 @@ BaseLib::PVariable HomeMaticCc1101::sendPacket(BaseLib::PArray& parameters)
{
if(parameters->size() != 2 || parameters->at(1)->type != BaseLib::VariableType::tString || parameters->at(1)->stringValue.empty()) return BaseLib::Variable::createError(-1, "Invalid parameters.");

if(_fileDescriptor->descriptor == -1 || !_gpio->isOpen(GD::settings.gpio1()) || _stopped) return BaseLib::Variable::createError(-1, "SPI device or GPIO is not open.");
if(!_fileDescriptor || _fileDescriptor->descriptor == -1 || !_gpio->isOpen(GD::settings.gpio1()) || _stopped) return BaseLib::Variable::createError(-1, "SPI device or GPIO is not open.");

std::vector<uint8_t> decodedPacket = _bl->hf.getUBinary(parameters->at(1)->stringValue);
bool burst = decodedPacket.at(2) & 0x10;
Expand Down
2 changes: 1 addition & 1 deletion src/Families/HomeMaticCulfw.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ HomeMaticCulfw::HomeMaticCulfw(BaseLib::SharedObjects* bl) : ICommunicationInter
_localRpcMethods.emplace("enableUpdateMode", std::bind(&HomeMaticCulfw::enableUpdateMode, this, std::placeholders::_1));
_localRpcMethods.emplace("disableUpdateMode", std::bind(&HomeMaticCulfw::disableUpdateMode, this, std::placeholders::_1));

_gpio.reset(new BaseLib::LowLevel::Gpio(bl));
_gpio.reset(new BaseLib::LowLevel::Gpio(bl, GD::settings.gpioPath()));

start();
}
Expand Down
24 changes: 18 additions & 6 deletions src/RpcServer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ bool RpcServer::start()
{
try
{
_unconfigured = false;

if(GD::settings.family().empty())
{
GD::out.printError("Error: Setting family in gateway.conf is empty.");
Expand Down Expand Up @@ -134,12 +136,13 @@ bool RpcServer::start()
serverInfo.dhParamFile = dhFile;
serverInfo.requireClientCert = true;
}
else GD::out.printWarning("Warning: Gateway is not fully configured yet.");
serverInfo.newConnectionCallback = std::bind(&RpcServer::newConnection, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3);
serverInfo.packetReceivedCallback = std::bind(&RpcServer::packetReceived, this, std::placeholders::_1, std::placeholders::_2);

_tcpServer = std::make_shared<BaseLib::TcpSocket>(_bl, serverInfo);
std::string boundAddress;
_tcpServer->startServer(GD::settings.listenAddress(), std::to_string(GD::settings.port()), boundAddress);
_tcpServer->startServer(GD::settings.listenAddress(), std::to_string(_unconfigured ? GD::settings.portUnconfigured() : GD::settings.port()), boundAddress);
_stopped = false;

return true;
Expand Down Expand Up @@ -187,6 +190,7 @@ void RpcServer::stop()

void RpcServer::restart()
{
GD::out.printMessage("Restarting server.");
stop();
start();
}
Expand All @@ -200,10 +204,6 @@ BaseLib::PVariable RpcServer::configure(BaseLib::PArray& parameters)
if(parameters->at(0)->stringValue.size() < 128 || parameters->at(0)->stringValue.size() > 100000) return BaseLib::Variable::createError(-2, "Data is invalid.");

BaseLib::Security::Gcrypt aes(GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_GCM, GCRY_CIPHER_SECURE);
std::vector<uint8_t> iv = _bl->hf.getUBinary(parameters->at(0)->stringValue.substr(0, 64));
std::vector<uint8_t> counter(16);
aes.setCounter(counter);
aes.setIv(iv);

std::vector<uint8_t> key;
if(!BaseLib::Security::Hash::sha256(GD::bl->hf.getUBinary(GD::settings.configurationPassword()), key) || key.empty())
Expand All @@ -213,7 +213,13 @@ BaseLib::PVariable RpcServer::configure(BaseLib::PArray& parameters)
}
aes.setKey(key);

std::vector<uint8_t> payload = _bl->hf.getUBinary(parameters->at(0)->stringValue.substr(64));
std::vector<uint8_t> iv = _bl->hf.getUBinary(parameters->at(0)->stringValue.substr(0, 24));
aes.setIv(iv);

std::vector<uint8_t> counter(16);
aes.setCounter(counter);

std::vector<uint8_t> payload = _bl->hf.getUBinary(parameters->at(0)->stringValue.substr(24));
if(!aes.authenticate(payload)) return BaseLib::Variable::createError(-2, "Data is invalid.");

std::vector<uint8_t> decryptedData;
Expand Down Expand Up @@ -245,8 +251,14 @@ BaseLib::PVariable RpcServer::configure(BaseLib::PArray& parameters)
if(chown(certPath.c_str(), userId, groupId) == -1) GD::out.printWarning("Warning: Could net set owner on " + certPath + ": " + std::string(strerror(errno)));
if(chmod(certPath.c_str(), S_IRUSR | S_IWUSR) == -1) GD::out.printWarning("Warning: Could net set permissions on " + certPath + ": " + std::string(strerror(errno)));;

GD::out.printMessage("Remote configuration was successful.");

return std::make_shared<BaseLib::Variable>();
}
catch(BaseLib::Security::GcryptException& ex)
{
GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, "Error decrypting data: " + ex.what());
}
catch(BaseLib::Exception& ex)
{
GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
Expand Down
17 changes: 17 additions & 0 deletions src/Settings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ void Settings::reset()
{
_listenAddress = "::";
_port = 2017;
_portUnconfigured = 2018;
_runAsUser = "";
_runAsGroup = "";
_debugLevel = 3;
Expand All @@ -48,6 +49,7 @@ void Settings::reset()
_logFilePath = "/var/log/homegear-gateway/";
_dataPath = "/var/lib/homegear-gateway/";
_lockFilePath = "/var/lock/";
_gpioPath = "/sys/class/gpio/";
_secureMemorySize = 65536;
_caFile = "";
_certPath = "";
Expand All @@ -64,6 +66,8 @@ void Settings::reset()
_device = "";
_gpio1 = -1;
_gpio2 = -1;
_oscillatorFrequency = -1;
_interruptPin = -1;
}

bool Settings::changed()
Expand Down Expand Up @@ -130,6 +134,12 @@ void Settings::load(std::string filename, std::string executablePath)
if(_port < 1 || _port > 65535) _port = 2017;
GD::bl->out.printDebug("Debug: port set to " + std::to_string(_port));
}
else if(name == "portunconfigured")
{
_portUnconfigured = BaseLib::Math::getNumber(value);
if(_portUnconfigured < 1 || _portUnconfigured > 65535) _portUnconfigured = 2018;
GD::bl->out.printDebug("Debug: portUnconfigured set to " + std::to_string(_portUnconfigured));
}
else if(name == "runasuser")
{
_runAsUser = value;
Expand Down Expand Up @@ -186,6 +196,13 @@ void Settings::load(std::string filename, std::string executablePath)
GD::bl->settings.setLockFilePath(_lockFilePath);
GD::bl->out.printDebug("Debug: lockfilePath set to " + _lockFilePath);
}
else if(name == "gpiopath")
{
_gpioPath = value;
if(_gpioPath.empty()) _gpioPath = "/sys/class/gpio/";
if(_gpioPath.back() != '/') _gpioPath.push_back('/');
GD::bl->out.printDebug("Debug: gpioPath set to " + _gpioPath);
}
else if(name == "securememorysize")
{
_secureMemorySize = BaseLib::Math::getNumber(value);
Expand Down
4 changes: 4 additions & 0 deletions src/Settings.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ class Settings

std::string listenAddress() { return _listenAddress; }
int32_t port() { return _port; }
int32_t portUnconfigured() { return _portUnconfigured; }
std::string runAsUser() { return _runAsUser; }
std::string runAsGroup() { return _runAsGroup; }
int32_t debugLevel() { return _debugLevel; }
Expand All @@ -52,6 +53,7 @@ class Settings
std::string logFilePath() { return _logFilePath; }
std::string dataPath() { return _dataPath; }
std::string lockFilePath() { return _lockFilePath; }
std::string gpioPath() { return _gpioPath; }
uint32_t secureMemorySize() { return _secureMemorySize; }
std::string caFile() { return _caFile; }
std::string certPath() { return _certPath; }
Expand All @@ -77,6 +79,7 @@ class Settings

std::string _listenAddress;
int32_t _port = 2017;
int32_t _portUnconfigured = 2018;
std::string _runAsUser;
std::string _runAsGroup;
int32_t _debugLevel = 3;
Expand All @@ -86,6 +89,7 @@ class Settings
std::string _logFilePath;
std::string _dataPath;
std::string _lockFilePath;
std::string _gpioPath;
uint32_t _secureMemorySize = 65536;
std::string _caFile;
std::string _certPath;
Expand Down
4 changes: 2 additions & 2 deletions src/UPnP.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -304,7 +304,7 @@ void UPnP::setPackets()
{
try
{
std::string notifyPacketBase = "NOTIFY * HTTP/1.1\r\nHOST: 239.255.255.250:1900\r\nCACHE-CONTROL: max-age=1800\r\nSERVER: Homegear Gateway " + std::string(VERSION) + "\r\nLOCATION: " + "binrpcs://" + _address + ":" + std::to_string(GD::settings.port()) + "/\r\nHG-FAMILY-ID: " + std::to_string(GD::rpcServer->familyId()) + "\r\nHG-GATEWAY-CONFIGURED: " + (GD::rpcServer->isUnconfigured() ? "0" : "1") + "\r\n";
std::string notifyPacketBase = "NOTIFY * HTTP/1.1\r\nHOST: 239.255.255.250:1900\r\nCACHE-CONTROL: max-age=1800\r\nSERVER: Homegear Gateway " + std::string(VERSION) + "\r\nLOCATION: " + "binrpcs://" + _address + ":" + std::to_string(GD::settings.port()) + "/\r\nHG-FAMILY-ID: " + std::to_string(GD::rpcServer->familyId()) + "\r\nHG-GATEWAY-CONFIGURED: " + (GD::rpcServer->isUnconfigured() ? "0" : "1") + "\r\nHG-GATEWAY-PORT-UNCONFIGURED: " + std::to_string(GD::settings.portUnconfigured()) + "\r\n";
std::string alivePacketRoot = notifyPacketBase + "NT: upnp:rootdevice\r\nUSN: " + _st + "::upnp:rootdevice\r\nNTS: ssdp:alive\r\n\r\n";
std::string alivePacketRootUUID = notifyPacketBase + "NT: " + _st + "\r\nUSN: " + _st + "\r\nNTS: ssdp:alive\r\n\r\n";
std::string alivePacket = notifyPacketBase + "NT: urn:schemas-upnp-org:device:basic:1\r\nUSN: " + _st + "\r\nNTS: ssdp:alive\r\n\r\n";
Expand All @@ -319,7 +319,7 @@ void UPnP::setPackets()
_packets.byebyeRootUUID = std::vector<char>(&byebyePacketRootUUID.at(0), &byebyePacketRootUUID.at(0) + byebyePacketRootUUID.size());
_packets.byebye = std::vector<char>(&byebyePacket.at(0), &byebyePacket.at(0) + byebyePacket.size());

std::string okPacketBase = std::string("HTTP/1.1 200 OK\r\nCache-Control: max-age=1800\r\nLocation: ") + "binrpcs://" + _address + ":" + std::to_string(GD::settings.port()) + "/\r\nServer: Homegear Gateway " + std::string(VERSION) + "\r\nHG-Family-ID: " + std::to_string(GD::rpcServer->familyId()) + "\r\nHG-Gateway-Configured: " + (GD::rpcServer->isUnconfigured() ? "0" : "1") + "\r\n";
std::string okPacketBase = std::string("HTTP/1.1 200 OK\r\nCache-Control: max-age=1800\r\nLocation: ") + "binrpcs://" + _address + ":" + std::to_string(GD::settings.port()) + "/\r\nServer: Homegear Gateway " + std::string(VERSION) + "\r\nHG-Family-ID: " + std::to_string(GD::rpcServer->familyId()) + "\r\nHG-Gateway-Configured: " + (GD::rpcServer->isUnconfigured() ? "0" : "1") + "\r\nHG-Gateway-Port-Unconfigured: " + std::to_string(GD::settings.portUnconfigured()) + "\r\n";
std::string okPacketRoot = okPacketBase + "ST: upnp:rootdevice\r\nUSN: " + _st + "::upnp:rootdevice\r\n\r\n";
std::string okPacketRootUUID = okPacketBase + "ST: " + _st + "\r\nUSN: " + _st + "\r\n\r\n";
std::string okPacket = okPacketBase + "ST: urn:schemas-upnp-org:device:basic:1\r\nUSN: " + _st + "\r\n\r\n";
Expand Down
2 changes: 1 addition & 1 deletion src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -603,7 +603,7 @@ int main(int argc, char* argv[])
else if(arg == "-v")
{
std::cout << "Homegear Gateway version " << VERSION << std::endl;
std::cout << "Copyright (c) 2013-2017 Sathya Laufer" << std::endl << std::endl;
std::cout << "Copyright (c) 2013-2018 Homegear GmbH" << std::endl << std::endl;
exit(0);
}
else
Expand Down

0 comments on commit 6e88249

Please sign in to comment.