24 #include <sys/types.h> 26 #include "dbusgateway.h" 27 #include "dbusgatewayparser.h" 33 constexpr
const char *DBusGatewayInstance::SESSION_CONFIG;
34 constexpr
const char *DBusGatewayInstance::SYSTEM_CONFIG;
37 const std::string &gatewayDir,
38 std::shared_ptr<ContainerAbstractInterface> container) :
43 m_proxyStdin(INVALID_FD)
45 std::string name = container->
id();
46 std::string socketName = (m_type == SessionProxy ?
"sess_" :
"sys_") + name +
".sock";
47 m_socket = buildPath(gatewayDir, socketName);
50 m_entireConfig = json_object();
51 m_busConfig = json_array();
53 const char* unusedTypeStr;
54 if (m_type == SessionProxy) {
55 typeStr = SESSION_CONFIG;
56 unusedTypeStr = SYSTEM_CONFIG;
59 typeStr = SYSTEM_CONFIG;
60 unusedTypeStr = SESSION_CONFIG;
62 json_object_set(m_entireConfig, typeStr, m_busConfig);
65 json_t* emptyArray = json_array();
66 json_object_set(m_entireConfig, unusedTypeStr, emptyArray);
69 DBusGatewayInstance::~DBusGatewayInstance()
86 if (!parser.parseDBusConfig(element, typeStr, m_busConfig)) {
89 log_warning() <<
"Failed to parse DBus configuration element";
101 if (!m_activatedOnce) {
103 std::string variable = std::string(
"DBUS_")
104 + (m_type == SessionProxy ?
"SESSION" :
"SYSTEM")
105 + std::string(
"_BUS_ADDRESS");
106 std::string value =
"unix:path=" + buildPath(
"/gateways", socketName());
107 getContainer()->setEnvironmentVariable(variable, value);
109 std::vector<std::string> commandVec = {
"dbus-proxy",
111 m_type == SessionProxy ?
"session" :
"system"};
114 std::vector<std::string> envVec;
116 bool hasEnvVar =
false;
117 std::string envValue = Glib::getenv(variable, hasEnvVar);
120 if (SessionProxy == m_type) {
121 log_error() <<
"Using DBus gateway in session mode" 122 <<
" and no " + variable +
" set in host environment, dbus-proxy won't work";
125 log_warn() <<
"Using DBus gateway in system mode" 126 <<
" and no " + variable +
" set in host environment, this could be a problem";
129 envVec.push_back(variable +
"=" + envValue);
132 if (!startDBusProxy(commandVec, envVec)) {
139 char *config_c = json_dumps(m_entireConfig, JSON_COMPACT);
140 std::string config = std::string(config_c);
144 return testDBusConnection(config);
147 bool DBusGatewayInstance::testDBusConnection(
const std::string &configuration)
150 std::string config{configuration + std::string(
"\n")};
152 ssize_t count = config.length() *
sizeof(char);
153 log_debug() <<
"Expected config byte length " << count;
155 log_debug() <<
"Config: " << config;
157 ssize_t configWrite = write(m_proxyStdin, config.c_str(), count);
160 if (-1 == configWrite) {
161 log_error() <<
"Failed to write to STDIN of dbus-proxy: " << strerror(errno);
163 }
else if (configWrite == (ssize_t)count) {
164 log_debug() <<
"Wrote " << configWrite <<
" bytes to dbus-proxy";
166 if (isSocketCreated()) {
167 log_debug() <<
"Found D-Bus socket: " << m_socket;
170 log_error() <<
"Did not find any D-Bus socket: " << m_socket;
175 log_error() <<
"Failed to write to STDIN of dbus-proxy!";
180 bool DBusGatewayInstance::startDBusProxy(
const std::vector<std::string> &commandVec,
181 const std::vector<std::string> &envVec)
185 Glib::spawn_async_with_pipes(
".",
188 Glib::SPAWN_STDOUT_TO_DEV_NULL
189 | Glib::SPAWN_STDERR_TO_DEV_NULL
190 | Glib::SPAWN_SEARCH_PATH
191 | Glib::SPAWN_DO_NOT_REAP_CHILD,
195 }
catch (
const Glib::Error &ex) {
196 log_error() <<
"Failed to launch dbus-proxy";
200 m_activatedOnce =
true;
201 log_debug() <<
"Started dbus-proxy: " << m_pid;
206 bool DBusGatewayInstance::isSocketCreated()
const 211 if (count >= maxCount) {
212 log_error() <<
"Could not find dbus-proxy socket, error: " << strerror(errno);
217 }
while (access(m_socket.c_str(), F_OK) == -1);
225 if (
nullptr != m_entireConfig) {
226 json_decref(m_entireConfig);
227 m_entireConfig =
nullptr;
230 if (m_pid != INVALID_PID) {
231 log_debug() <<
"Killing dbus-proxy with pid " << m_pid;
234 kill(m_pid, SIGKILL);
235 waitpid(m_pid,
nullptr, 0);
236 Glib::spawn_close_pid(m_pid);
238 log_debug() <<
"dbus-proxy pid not set or already dead: " << m_pid;
241 if (access(m_socket.c_str(), F_OK) != -1) {
242 if (unlink(m_socket.c_str()) == -1) {
243 log_error() <<
"Could not remove " << m_socket <<
": " << strerror(errno);
248 log_debug() <<
"Socket not accessible, has it been removed already?";
252 if (close(m_proxyStdin) == -1) {
253 log_warning() <<
"Could not close stdin of dbus-proxy";
259 std::string DBusGatewayInstance::socketName()
261 return basename(m_socket.c_str());
virtual bool isActivated()
Is the gateway activated or not?
virtual bool readConfigElement(const json_t *element) override
Gateway specific parsing of config elements.
virtual std::string id() const
Returns the ID of the gateway.
virtual bool teardownGateway() override
Implements Gateway::teardownGateway.
virtual bool teardown()
Restore system to the state prior to launching of gateway.
Gateway base class for SoftwareContainer.
std::shared_ptr< ContainerAbstractInterface > getContainer()
Get a handle to the associated container.
Developers guide to adding a config item:
DBusGatewayInstance(ProxyType type, const std::string &gatewayDir, std::shared_ptr< ContainerAbstractInterface > container)
Spawn the proxy and use the supplied path for the socket.
virtual bool activateGateway()
Implements Gateway::activateGateway.