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 22, 2018
2 parents f918250 + e58a2a7 commit a653706
Show file tree
Hide file tree
Showing 3 changed files with 135 additions and 2 deletions.
130 changes: 129 additions & 1 deletion src/IpcClient.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,11 @@ IpcClient::IpcClient(std::string socketPath) : IIpcClient(socketPath)
// {{{ CA and gateways
_localRpcMethods.emplace("managementCaExists", std::bind(&IpcClient::caExists, this, std::placeholders::_1));
_localRpcMethods.emplace("managementCreateCa", std::bind(&IpcClient::createCa, this, std::placeholders::_1));
_localRpcMethods.emplace("managementCreateCert", std::bind(&IpcClient::createCert, this, std::placeholders::_1));
// }}}

// {{{ Device description files
_localRpcMethods.emplace("managementCopyDeviceDescriptionFile", std::bind(&IpcClient::copyDeviceDescriptionFile, this, std::placeholders::_1));
// }}}
}

Expand Down Expand Up @@ -338,8 +343,45 @@ void IpcClient::onConnect()
Ipc::Output::printCritical("Critical: Could not register RPC method managementCreateCa: " + result->structValue->at("faultString")->stringValue);
}
if (error) return;

parameters = std::make_shared<Ipc::Array>();
parameters->reserve(2);
parameters->push_back(std::make_shared<Ipc::Variable>("managementCreateCert"));
parameters->push_back(std::make_shared<Ipc::Variable>(Ipc::VariableType::tArray)); //Outer array
signature = std::make_shared<Ipc::Variable>(Ipc::VariableType::tArray); //Inner array (= signature)
signature->arrayValue->reserve(2);
signature->arrayValue->push_back(std::make_shared<Ipc::Variable>(Ipc::VariableType::tStruct)); //Return value
signature->arrayValue->push_back(std::make_shared<Ipc::Variable>(Ipc::VariableType::tString)); //1st parameter
parameters->back()->arrayValue->push_back(signature);
result = invoke("registerRpcMethod", parameters);
if (result->errorStruct)
{
error = true;
Ipc::Output::printCritical("Critical: Could not register RPC method managementCreateCert: " + result->structValue->at("faultString")->stringValue);
}
if (error) return;
//}}}

// {{{ Device description files
parameters = std::make_shared<Ipc::Array>();
parameters->reserve(2);
parameters->push_back(std::make_shared<Ipc::Variable>("managementCopyDeviceDescriptionFile"));
parameters->push_back(std::make_shared<Ipc::Variable>(Ipc::VariableType::tArray)); //Outer array
signature = std::make_shared<Ipc::Variable>(Ipc::VariableType::tArray); //Inner array (= signature)
signature->arrayValue->reserve(3);
signature->arrayValue->push_back(std::make_shared<Ipc::Variable>(Ipc::VariableType::tBoolean)); //Return value
signature->arrayValue->push_back(std::make_shared<Ipc::Variable>(Ipc::VariableType::tString)); //1st parameter
signature->arrayValue->push_back(std::make_shared<Ipc::Variable>(Ipc::VariableType::tInteger)); //2nd parameter
parameters->back()->arrayValue->push_back(signature);
result = invoke("registerRpcMethod", parameters);
if (result->errorStruct)
{
error = true;
Ipc::Output::printCritical("Critical: Could not register RPC method managementCopyDeviceDescriptionFile: " + result->structValue->at("faultString")->stringValue);
}
if (error) return;
// }}}

GD::out.printInfo("Info: RPC methods successfully registered.");
}
catch (const std::exception& ex)
Expand Down Expand Up @@ -978,7 +1020,7 @@ Ipc::PVariable IpcClient::createCa(Ipc::PArray& parameters)
}

if(_commandThread.joinable()) _commandThread.join();
_commandThread = std::thread(&IpcClient::executeCommand, this, "openssl genrsa -out /etc/homegear/ca/private/cakey.pem 4096 && openssl req -new -x509 -key /etc/homegear/ca/private/cakey.pem -out /etc/homegear/ca/cacert.pem -days 10958 -set_serial 0");
_commandThread = std::thread(&IpcClient::executeCommand, this, "openssl genrsa -out /etc/homegear/ca/private/cakey.pem 4096 && chmod 400 /etc/homegear/ca/private/cakey.pem && chown root:root /etc/homegear/ca/private/cakey.pem && openssl req -new -x509 -key /etc/homegear/ca/private/cakey.pem -out /etc/homegear/ca/cacert.pem -days 100000 -set_serial 0 -subj \"/C=HG/ST=HG/L=HG/O=HG/CN=Homegear CA\"");

return std::make_shared<Ipc::Variable>(true);
}
Expand All @@ -996,6 +1038,92 @@ Ipc::PVariable IpcClient::createCa(Ipc::PArray& parameters)
}
return Ipc::Variable::createError(-32500, "Unknown application error.");
}

Ipc::PVariable IpcClient::createCert(Ipc::PArray& parameters)
{
try
{
if(parameters->size() != 1) return Ipc::Variable::createError(-1, "Wrong parameter count.");
if(parameters->at(0)->type != Ipc::VariableType::tString) return Ipc::Variable::createError(-1, "Parameter is not of type String.");

if(!BaseLib::Io::directoryExists("/etc/homegear/ca") || !BaseLib::Io::fileExists("/etc/homegear/ca/private/cakey.pem")) return Ipc::Variable::createError(-2, "No CA found.");
if(_commandThreadRunning) return Ipc::Variable::createError(-2, "A command is already being executed.");

std::string commonName;
commonName.reserve(parameters->at(0)->stringValue.size());
for(std::string::const_iterator i = parameters->at(0)->stringValue.begin(); i != parameters->at(0)->stringValue.end(); ++i)
{
if(isalpha(*i) || isdigit(*i) || (*i == '_') || (*i == '-') || (*i == ' ')) commonName.push_back(*i);
}

std::string filename = BaseLib::HelperFunctions::stripNonAlphaNumeric(commonName);

std::string output;
BaseLib::HelperFunctions::exec("cat /etc/homegear/ca/index.txt | grep -c \"CN=" + commonName + "\"", output);
BaseLib::HelperFunctions::trim(output);
if(output != "0") return Ipc::Variable::createError(-3, "A certificate with this common name already exists.");

{
std::lock_guard<std::mutex> outputGuard(_commandOutputMutex);
_commandStatus = 256;
_commandOutput = "";
}

if(_commandThread.joinable()) _commandThread.join();
_commandThread = std::thread(&IpcClient::executeCommand, this, "cd /etc/homegear/ca; openssl genrsa -out private/" + filename + ".key 4096; chown homegear:homegear private/" + filename + ".key; chmod 440 private/" + filename + ".key; openssl req -new -key private/" + filename + ".key -out newcert.csr -subj \"/C=HG/ST=HG/L=HG/O=HG/CN=" + commonName + "\"; openssl ca -in newcert.csr -out certs/" + filename + ".crt -days 100000 -batch; rm newcert.csr");

auto result = std::make_shared<Ipc::Variable>(Ipc::VariableType::tStruct);
result->structValue->emplace("filenamePrefix", std::make_shared<Ipc::Variable>(filename));
result->structValue->emplace("commonNameUsed", std::make_shared<Ipc::Variable>(commonName));
result->structValue->emplace("caPath", std::make_shared<Ipc::Variable>("/etc/homegear/ca/cacert.pem"));
result->structValue->emplace("certPath", std::make_shared<Ipc::Variable>("/etc/homegear/ca/certs/" + filename + ".crt"));
result->structValue->emplace("keyPath", std::make_shared<Ipc::Variable>("/etc/homegear/ca/private/" + filename + ".key"));

return result;
}
catch (const std::exception& ex)
{
GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
}
catch (Ipc::IpcException& ex)
{
GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
}
catch (...)
{
GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__);
}
return Ipc::Variable::createError(-32500, "Unknown application error.");
}
// }}}

// {{{ Device description files
Ipc::PVariable IpcClient::copyDeviceDescriptionFile(Ipc::PArray& parameters)
{
try
{
if(parameters->size() != 2) return Ipc::Variable::createError(-1, "Wrong parameter count.");
if(parameters->at(0)->type != Ipc::VariableType::tString) return Ipc::Variable::createError(-1, "Parameter 1 is not of type String.");
if(parameters->at(1)->type != Ipc::VariableType::tInteger && parameters->at(1)->type != Ipc::VariableType::tInteger64) return Ipc::Variable::createError(-1, "Parameter 2 is not of type Integer.");

BaseLib::HelperFunctions::stripNonPrintable(parameters->at(0)->stringValue);

return std::make_shared<Ipc::Variable>(GD::bl->io.copyFile(parameters->at(0)->stringValue, "/etc/homegear/devices/" + std::to_string(parameters->at(1)->integerValue) + "/"+ BaseLib::HelperFunctions::splitLast(parameters->at(0)->stringValue, '/').second));
}
catch (const std::exception& ex)
{
GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
}
catch (Ipc::IpcException& ex)
{
GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
}
catch (...)
{
GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__);
}
return Ipc::Variable::createError(-32500, "Unknown application error.");
}
// }}}

// }}}
5 changes: 5 additions & 0 deletions src/IpcClient.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,11 @@ class IpcClient : public Ipc::IIpcClient
// {{{ CA and gateways
Ipc::PVariable caExists(Ipc::PArray& parameters);
Ipc::PVariable createCa(Ipc::PArray& parameters);
Ipc::PVariable createCert(Ipc::PArray& parameters);
// }}}

// {{{ Device description files
Ipc::PVariable copyDeviceDescriptionFile(Ipc::PArray& parameters);
// }}}
};

Expand Down
2 changes: 1 addition & 1 deletion src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -583,7 +583,7 @@ int main(int argc, char* argv[])
else if(arg == "-v")
{
std::cout << "Homegear Management version " << VERSION << std::endl;
std::cout << "Copyright (c) 2013-2018 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 a653706

Please sign in to comment.