Allow disabling SSH
The intent behind this commit is to add the dropbear service, monitor
the Enabled and Running properties, and then update the
dropbear.socket to allow disabling/enabling SSH.
Tested:
1.
busctl introspect xyz.openbmc_project.Control.Service.Manager /xyz/openbmc_project/control/service/dropbear
xyz.openbmc_project.Control.Service.Attributes interface
.Enabled property b false emits-change writable
.Masked property b false emits-change writable
.Running property b true emits-change writable
Open a new SSH connection:
sudo ssh username@<IP>
Successfully connected
2.
busctl set-property xyz.openbmc_project.Control.Service.Manager /xyz/openbmc_project/control/service/dropbear xyz.openbmc_project.Control.Service.Attributes Running b false
busctl introspect xyz.openbmc_project.Control.Service.Manager /xyz/openbmc_project/control/service/dropbear
xyz.openbmc_project.Control.Service.Attributes interface
.Enabled property b false emits-change writable
.Masked property b false emits-change writable
.Running property b false emits-change writable
Open a new SSH connection:
sudo ssh username@<IP>
ssh: connect to host <IP> port 22: Connection refused
Signed-off-by: George Liu <liuxiwei@inspur.com>
Change-Id: I5d004f7f49c25fc90b93dabd124fe0d3d93ca822
diff --git a/src/main.cpp b/src/main.cpp
index f8d1f22..1d9ebed 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -34,28 +34,9 @@
// Base service name list. All instance of these services and
// units(service/socket) will be managed by this daemon.
-static std::array<std::string, 5> serviceNames = {
- "phosphor-ipmi-net", "bmcweb", "phosphor-ipmi-kcs", "start-ipkvm",
- "obmc-console"};
-
-using ListUnitsType =
- std::tuple<std::string, std::string, std::string, std::string, std::string,
- std::string, sdbusplus::message::object_path, uint32_t,
- std::string, sdbusplus::message::object_path>;
-
-enum class ListUnitElements
-{
- name,
- descriptionString,
- loadState,
- activeState,
- subState,
- followedUnit,
- objectPath,
- queuedJobType,
- jobType,
- jobObject
-};
+static std::array<std::string, 6> serviceNames = {
+ "phosphor-ipmi-net", "bmcweb", "phosphor-ipmi-kcs",
+ "start-ipkvm", "obmc-console", "dropbear"};
enum class UnitType
{
diff --git a/src/srvcfg_manager.cpp b/src/srvcfg_manager.cpp
index 038d11a..bd23b44 100644
--- a/src/srvcfg_manager.cpp
+++ b/src/srvcfg_manager.cpp
@@ -96,7 +96,8 @@
if (subStateIt != propertyMap.end())
{
subStateValue = std::get<std::string>(subStateIt->second);
- if (subStateValue == subStateRunning)
+ if (subStateValue == subStateRunning ||
+ subStateValue == subStateListening)
{
unitRunningState = true;
}
@@ -111,6 +112,13 @@
void ServiceConfig::queryAndUpdateProperties()
{
+ std::string objectPath =
+ isDropBearService ? socketObjectPath : serviceObjectPath;
+ if (objectPath.empty())
+ {
+ return;
+ }
+
conn->async_method_call(
[this](boost::system::error_code ec,
const boost::container::flat_map<std::string, VariantType>&
@@ -173,8 +181,7 @@
return;
}
},
- sysdService, serviceObjectPath, dBusPropIntf, dBusGetAllMethod,
- sysdUnitIntf);
+ sysdService, objectPath, dBusPropIntf, dBusGetAllMethod, sysdUnitIntf);
return;
}
@@ -213,6 +220,10 @@
instanceName(instanceName_), serviceObjectPath(serviceObjPath_),
socketObjectPath(socketObjPath_)
{
+ if (baseUnitName == "dropbear")
+ {
+ isDropBearService = true;
+ }
instantiatedUnitName = baseUnitName + addInstanceName(instanceName, "@");
updatedFlag = 0;
queryAndUpdateProperties();
@@ -247,13 +258,45 @@
phosphor::logging::log<phosphor::logging::level::INFO>(
"Applying new settings.",
phosphor::logging::entry("OBJPATH=%s", objPath.c_str()));
- if (subStateValue == "running")
+ if (subStateValue == subStateRunning || subStateValue == subStateListening)
{
if (!socketObjectPath.empty())
{
systemdUnitAction(conn, yield, getSocketUnitName(), sysdStopUnit);
}
- systemdUnitAction(conn, yield, getServiceUnitName(), sysdStopUnit);
+ if (!isDropBearService)
+ {
+ systemdUnitAction(conn, yield, getServiceUnitName(), sysdStopUnit);
+ }
+ else
+ {
+ // Get the ListUnits property, find all the services of
+ // `dropbear@<ip><port>.service` and stop the service through
+ // the systemdUnitAction method
+ boost::system::error_code ec;
+ auto listUnits =
+ conn->yield_method_call<std::vector<ListUnitsType>>(
+ yield, ec, sysdService, sysdObjPath, sysdMgrIntf,
+ "ListUnits");
+
+ checkAndThrowInternalFailure(
+ ec, "yield_method_call error: ListUnits failed");
+
+ for (const auto& unit : listUnits)
+ {
+ const auto& service =
+ std::get<static_cast<int>(ListUnitElements::name)>(unit);
+ const auto& status =
+ std::get<static_cast<int>(ListUnitElements::subState)>(
+ unit);
+ if (service.find("dropbear@") != std::string::npos &&
+ service.find(".service") != std::string::npos &&
+ status == subStateRunning)
+ {
+ systemdUnitAction(conn, yield, service, sysdStopUnit);
+ }
+ }
+ }
}
if (updatedFlag & (1 << static_cast<uint8_t>(UpdatedProp::port)))
@@ -297,6 +340,10 @@
{
unitFiles = {getServiceUnitName()};
}
+ else if (!socketObjectPath.empty() && isDropBearService)
+ {
+ unitFiles = {getSocketUnitName()};
+ }
else
{
unitFiles = {getSocketUnitName(), getServiceUnitName()};
@@ -321,7 +368,11 @@
systemdUnitAction(conn, yield, getSocketUnitName(),
sysdRestartUnit);
}
- systemdUnitAction(conn, yield, getServiceUnitName(), sysdRestartUnit);
+ if (!isDropBearService)
+ {
+ systemdUnitAction(conn, yield, getServiceUnitName(),
+ sysdRestartUnit);
+ }
}
// Reset the flag
diff --git a/src/utils.cpp b/src/utils.cpp
index b4ed9f7..0eba710 100644
--- a/src/utils.cpp
+++ b/src/utils.cpp
@@ -15,8 +15,8 @@
*/
#include "utils.hpp"
-static inline void checkAndThrowInternalFailure(boost::system::error_code& ec,
- const std::string& msg)
+void checkAndThrowInternalFailure(boost::system::error_code& ec,
+ const std::string& msg)
{
if (ec)
{