Original project changes: Config restore: shutdown SSH RSAKeyGen as necessary, fixes issue

This commit is contained in:
Carsten Schmiemann 2022-11-01 14:50:52 +01:00
parent 54edebfb5b
commit 1bbb754ff7
5 changed files with 68 additions and 6 deletions

View File

@ -158,6 +158,7 @@ OvmsSSH::OvmsSSH()
using std::placeholders::_2;
MyEvents.RegisterEvent(tag,"network.mgr.init", std::bind(&OvmsSSH::NetManInit, this, _1, _2));
MyEvents.RegisterEvent(tag,"network.mgr.stop", std::bind(&OvmsSSH::NetManStop, this, _1, _2));
MyEvents.RegisterEvent(tag,"config.restore", std::bind(&OvmsSSH::ConfigRestore, this, _1, _2));
MyConfig.RegisterParam("ssh.server", "SSH server private key store", true, false);
MyConfig.RegisterParam("ssh.info", "SSH server information", false, true);
MyConfig.RegisterParam("ssh.keys", "SSH public key store", true, true);
@ -232,6 +233,14 @@ void OvmsSSH::NetManStop(std::string event, void* data)
}
}
void OvmsSSH::ConfigRestore(std::string event, void* data)
{
if (RSAKeyGenerator::KillInstance())
{
ESP_LOGW(tag, "RSAKeyGenerator killed by request");
}
}
int OvmsSSH::Authenticate(uint8_t type, WS_UserAuthData* data, void* ctx)
{
ConsoleSSH* cons = (ConsoleSSH*)ctx;
@ -1058,11 +1067,26 @@ int SendCallback(WOLFSSH* ssh, void* data, uint32_t size, void* ctx)
// Class RSAKeyGenerator
//-----------------------------------------------------------------------------
RSAKeyGenerator* RSAKeyGenerator::s_instance = NULL;
RSAKeyGenerator::RSAKeyGenerator() : TaskBase("RSAKeyGen", 7*1024, 0)
{
s_instance = this;
Instantiate();
}
RSAKeyGenerator::~RSAKeyGenerator()
{
s_instance = NULL;
}
bool RSAKeyGenerator::KillInstance()
{
if (!s_instance) return false;
s_instance->Kill();
return true;
}
void RSAKeyGenerator::Service()
{
// Generate a random 2048-bit SSH host key for the SSH server in DER format.

View File

@ -49,6 +49,7 @@ class OvmsSSH
void EventHandler(struct mg_connection *nc, int ev, void *p);
void NetManInit(std::string event, void* data);
void NetManStop(std::string event, void* data);
void ConfigRestore(std::string event, void* data);
static int Authenticate(uint8_t type, WS_UserAuthData* data, void* ctx);
WOLFSSH_CTX* ctx() { return m_ctx; }
@ -118,14 +119,18 @@ class ConsoleSSH : public OvmsConsole
class RSAKeyGenerator : public TaskBase
{
private:
static RSAKeyGenerator* s_instance;
public:
RSAKeyGenerator();
virtual ~RSAKeyGenerator() {}
virtual ~RSAKeyGenerator();
static bool KillInstance();
private:
void Service();
private:
byte m_der[1200]; // Big enough for 2048-bit private key
byte m_der[1200]; // Big enough for 2048-bit private key
};
#endif //#ifndef __CONSOLE_SSH_H__

View File

@ -44,6 +44,7 @@ static const char *TAG = "config";
#include "ovms_events.h"
#include "ovms_utils.h"
#include "ovms_boot.h"
#include "ovms_semaphore.h"
#ifdef CONFIG_OVMS_SC_ZIP
#include "zip_archive.h"
@ -852,7 +853,24 @@ bool OvmsConfig::Restore(std::string path, std::string password, OvmsWriter* wri
else
ESP_LOGD(TAG, "Restore: reading '%s'...", path.c_str());
m_store_lock.Lock();
// Lock config store:
if (!m_store_lock.Lock(pdMS_TO_TICKS(5000)))
{
if (writer)
writer->puts("Error: config store currently in use by another process");
else
ESP_LOGE(TAG, "Restore: timeout waiting for config lock");
return false;
}
// Signal & wait for components to shutdown:
{
OvmsSemaphore eventdone;
auto callback = [](const char* event, void* data) { ((OvmsSemaphore*)data)->Give(); };
MyEvents.SignalEvent("config.restore", &eventdone, callback);
eventdone.Take();
}
bool ok = true;
// unzip into restore directory:

View File

@ -165,10 +165,11 @@ void TaskBase::Task(void *object)
}
// This function should be overridden in the derived class to perform any
// cleanup operations that must be done before the task is deleted.
// cleanup operations that must be done after Service() has finished/stopped
// and before the TaskBase instance is deleted.
// This function should NOT be called from the destructor because it is
// called explicitly here before the object is deleted. That separation
// is needed so DeleteTask can clean up before deleting the task and still
// is needed so DeleteFromParent can clean up before deleting the task and still
// wait to delete the object until after the task is deleted.
void TaskBase::Cleanup()
{
@ -192,8 +193,21 @@ void TaskBase::DeleteFromParent()
// parent object's task.
void TaskBase::DeleteTask()
{
Cleanup();
if (m_taskid)
{
ESP_LOGD(TAG, "Task %s deletion at %u stack free", m_name, uxTaskGetStackHighWaterMark(m_taskid));
vTaskDelete(m_taskid);
}
Cleanup();
delete this;
}
// Kill: immediate task removal and instance deletion.
// ATT: This will terminate the running task (Service()) unconditionally!
// This function must NOT be called from the TaskBase object's own task.
void TaskBase::Kill()
{
if (m_parent)
m_parent->RemoveChild(this);
DeleteTask();
}

View File

@ -66,6 +66,7 @@ class TaskBase
public:
TaskBase(const char* name, int stack = DEFAULT_STACK, UBaseType_t priority = DEFAULT_PRIORITY, Parent* parent = NULL);
Parent* parent() { return m_parent; }
virtual void Kill();
protected:
virtual ~TaskBase();