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.