diff --git a/PROTOCOL.md b/PROTOCOL.md index 1e14dda6..8b686bcb 100644 --- a/PROTOCOL.md +++ b/PROTOCOL.md @@ -880,6 +880,32 @@ The device should answer: } ``` +#### Controller wants the device to perform re-enrollment +Controller sends this command to trigger re-enrollment, i.e. update of operational certificate. Extreme care must be taken. +```json +{ "jsonrpc" : "2.0" , + "method" : "reenroll" , + "params" : { + "serial" : , + "when" : Optional - + }, + "id" : +} +``` + +The device should answer: +```json +{ "jsonrpc" : "2.0" , + "result" : { + "serial" : , + "status" : { + "error" : <0 or the value of $? from the shell running the command, 255 signifies a timeout>, + "txt" : + }, + "id" : +} +``` + #### Controller wants the device to switch to another controller Controller sends this when the device should change the controller it connects to without looking up a new redirector. diff --git a/src/RESTAPI/RESTAPI_device_commandHandler.cpp b/src/RESTAPI/RESTAPI_device_commandHandler.cpp index 6d1580a0..2d7aa7da 100644 --- a/src/RESTAPI/RESTAPI_device_commandHandler.cpp +++ b/src/RESTAPI/RESTAPI_device_commandHandler.cpp @@ -170,6 +170,7 @@ namespace OpenWifi { {APCommands::Commands::powercycle, false, true, &RESTAPI_device_commandHandler::PowerCycle, 60000ms}, {APCommands::Commands::fixedconfig, false, true, &RESTAPI_device_commandHandler::FixedConfig, 120000ms}, {APCommands::Commands::cablediagnostics, false, true, &RESTAPI_device_commandHandler::CableDiagnostics, 120000ms}, + {APCommands::Commands::reenroll, false, true, &RESTAPI_device_commandHandler::ReEnroll, 120000ms}, }; @@ -1651,4 +1652,45 @@ namespace OpenWifi { *ParsedBody_, *Request, *Response, timeout, nullptr, this, Logger_); } + + void RESTAPI_device_commandHandler::ReEnroll( + const std::string &CMD_UUID, uint64_t CMD_RPC, + [[maybe_unused]] std::chrono::milliseconds timeout, + [[maybe_unused]] const GWObjects::DeviceRestrictions &Restrictions) { + + if(UserInfo_.userinfo.userRole != SecurityObjects::ROOT && + UserInfo_.userinfo.userRole != SecurityObjects::ADMIN) { + CallCanceled("REENROLL", CMD_UUID, CMD_RPC, RESTAPI::Errors::ACCESS_DENIED); + return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED); + } + + poco_debug(Logger_, fmt::format("REENROLL({},{}): TID={} user={} serial={}", CMD_UUID, + CMD_RPC, TransactionId_, Requester(), SerialNumber_)); + + if(IsDeviceSimulated(SerialNumber_)) { + CallCanceled("REENROLL", CMD_UUID, CMD_RPC, RESTAPI::Errors::SimulatedDeviceNotSupported); + return BadRequest(RESTAPI::Errors::SimulatedDeviceNotSupported); + } + + GWObjects::ReEnroll PR; + if(!PR.from_json(ParsedBody_)) { + return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters); + } + + GWObjects::CommandDetails Cmd; + Cmd.SerialNumber = SerialNumber_; + Cmd.SubmittedBy = Requester(); + Cmd.UUID = CMD_UUID; + Cmd.Command = uCentralProtocol::REENROLL; + std::ostringstream os; + ParsedBody_->stringify(os); + Cmd.Details = os.str(); + Cmd.RunAt = PR.when; + Cmd.ErrorCode = 0; + Cmd.WaitingForFile = 0; + + return RESTAPI_RPC::WaitForCommand(CMD_RPC, APCommands::Commands::reenroll, false, Cmd, + *ParsedBody_, *Request, *Response, timeout, nullptr, this, + Logger_); + } } // namespace OpenWifi diff --git a/src/RESTAPI/RESTAPI_device_commandHandler.h b/src/RESTAPI/RESTAPI_device_commandHandler.h index 25f22d9f..d99c974e 100644 --- a/src/RESTAPI/RESTAPI_device_commandHandler.h +++ b/src/RESTAPI/RESTAPI_device_commandHandler.h @@ -74,6 +74,8 @@ namespace OpenWifi { const GWObjects::DeviceRestrictions &R); void CableDiagnostics(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout, const GWObjects::DeviceRestrictions &R); + void ReEnroll(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout, + const GWObjects::DeviceRestrictions &R); static auto PathName() { return std::list{"/api/v1/device/{serialNumber}/{command}"}; diff --git a/src/RESTObjects/RESTAPI_GWobjects.cpp b/src/RESTObjects/RESTAPI_GWobjects.cpp index f5939fe5..b7c7cfd9 100644 --- a/src/RESTObjects/RESTAPI_GWobjects.cpp +++ b/src/RESTObjects/RESTAPI_GWobjects.cpp @@ -821,4 +821,14 @@ namespace OpenWifi::GWObjects { } return false; } + + bool ReEnroll::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + field_from_json(Obj, "serial", serialNumber); + field_from_json(Obj, "when", when); + return true; + } catch (const Poco::Exception &E) { + } + return false; + } } // namespace OpenWifi::GWObjects diff --git a/src/RESTObjects/RESTAPI_GWobjects.h b/src/RESTObjects/RESTAPI_GWobjects.h index e8e40376..a0842908 100644 --- a/src/RESTObjects/RESTAPI_GWobjects.h +++ b/src/RESTObjects/RESTAPI_GWobjects.h @@ -546,6 +546,12 @@ namespace OpenWifi::GWObjects { std::uint64_t when; std::vector ports; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; + struct ReEnroll { + std::string serialNumber; + std::uint64_t when; + bool from_json(const Poco::JSON::Object::Ptr &Obj); }; } // namespace OpenWifi::GWObjects diff --git a/src/framework/ow_constants.h b/src/framework/ow_constants.h index 0a617e55..971bd105 100644 --- a/src/framework/ow_constants.h +++ b/src/framework/ow_constants.h @@ -583,6 +583,7 @@ namespace OpenWifi::RESTAPI::Protocol { static const char *FIXEDCONFIG = "fixedconfig"; static const char *CABLEDIAGNOSTICS = "cable-diagnostics"; + static const char *REENROLL = "re-enroll"; } // namespace OpenWifi::RESTAPI::Protocol namespace OpenWifi::uCentralProtocol { @@ -698,6 +699,8 @@ namespace OpenWifi::uCentralProtocol { static const char *FIXEDCONFIG = "fixedconfig"; static const char *CABLEDIAGNOSTICS = "cable-diagnostics"; + static const char *REENROLL = "re-enroll"; + } // namespace OpenWifi::uCentralProtocol @@ -797,6 +800,7 @@ namespace OpenWifi::APCommands { powercycle, fixedconfig, cablediagnostics, + reenroll, unknown }; @@ -812,7 +816,8 @@ namespace OpenWifi::APCommands { RESTAPI::Protocol::PING, RESTAPI::Protocol::SCRIPT, RESTAPI::Protocol::RRM, RESTAPI::Protocol::CERTUPDATE, RESTAPI::Protocol::TRANSFER, RESTAPI::Protocol::POWERCYCLE, - RESTAPI::Protocol::FIXEDCONFIG, RESTAPI::Protocol::CABLEDIAGNOSTICS + RESTAPI::Protocol::FIXEDCONFIG, RESTAPI::Protocol::CABLEDIAGNOSTICS, + RESTAPI::Protocol::REENROLL }; inline const char *to_string(Commands Cmd) { return uCentralAPCommands[(uint8_t)Cmd]; }