Skip to content
This repository has been archived by the owner on Apr 26, 2020. It is now read-only.

Commit

Permalink
First working draft
Browse files Browse the repository at this point in the history
  • Loading branch information
kalkin committed Sep 27, 2016
1 parent 6faa3d3 commit 3232052
Show file tree
Hide file tree
Showing 6 changed files with 195 additions and 10 deletions.
10 changes: 3 additions & 7 deletions qubes/dbus/__init__.py → qubesdbus/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,7 @@
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

from __future__ import print_function
from __future__ import absolute_import


class Receiver(object):
''' Forward the event to org.qubes.dbus.EventService '''
@staticmethod
def fire_event(event, args, kwargs):
print("{!s}: {!s} \n {!s}".format(event, args, kwargs))
from .constants import * # pylint: disable=wildcard-import
from .proxy import QubesDbusProxy
3 changes: 3 additions & 0 deletions qubesdbus/constants.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
PATH_PREFIX = '/org/qubes'
NAME_PREFIX = 'org.qubes'
VERSION = 1
143 changes: 143 additions & 0 deletions qubesdbus/proxy.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
#!/usr/bin/env python2
# -*- encoding: utf8 -*-
#
# The Qubes OS Project, https://www.qubes-os.org/
#
# Copyright (C) 2016 Bahtiar `kalkin-` Gadimov <[email protected]>
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

from __future__ import absolute_import

import logging

import dbus
from qubes import Qubes
from qubes.vm.qubesvm import QubesVM
from systemd.journal import JournalHandler

from .constants import NAME_PREFIX, PATH_PREFIX, VERSION

try:
# Check for mypy dependencies pylint: disable=ungrouped-imports
from typing import Any, Optional, Union # pylint: disable=unused-import
from qubesdbus.service import _DbusServiceObject # pylint:disable=unused-import
except ImportError:
pass

log = logging.getLogger('qubesdbus.proxy')
log.addHandler(JournalHandler(SYSLOG_IDENTIFIER='qubesdbus.proxy'))
log.setLevel(logging.DEBUG)

INTERFACE_NAME = "%s.QubesSignals%s" % (NAME_PREFIX, VERSION)
SESSION_BUS = dbus.SessionBus()
MANAGER_NAME = "%s.DomainManager%s" % (NAME_PREFIX, VERSION)
MANAGER_PATH = "%s/DomainManager%s" % (PATH_PREFIX, VERSION)
GARBAGE = [
'domain-is-fully-usable', # only important for internal core-admin?
]


class QubesDbusProxy(object):
# pylint: disable=too-few-public-methods
def __init__(self, *args, **kwargs):
super(QubesDbusProxy, self).__init__(*args, **kwargs)
self.domains = {} # type: Dict[int, bool]

def forward(self, obj, event_name, *args, **kwargs):
# type: (Union[Qubes, QubesVM], str, *Any, **Any) -> None
# pylint: disable=redefined-variable-type
if isinstance(obj, QubesVM):
# let's play a game called guess in which state is the domain?
if not hasattr(obj, 'qid'):
# just reading domain from qubes.xml and preparing for
# populating it, we can ignore this event
log.info('%s some domain', event_name)
return
else:
qid = obj.qid
log.info('Received %s => %s', qid, event_name)
if qid not in self.domains.keys():
self.domains[qid] = False

if event_name == 'domain-load':
self.domains[qid] = True

if self.domains[qid]:
log.info("Would forward event to existing domain %s", qid)
try:
args = serialize(args)
kwargs = zip(kwargs.keys(), serialize(kwargs.values()))
log.info("%s : %s : %s", event_name, args, kwargs)
except TypeError as ex:
msg = "%s: %s" % (event_name, ex.message)
log.error(msg)

@staticmethod
def old_forward(obj, event_name, *args, **kwargs):
# pylint: disable=redefined-variable-type
try:
proxy = get_proxy(obj)
if event_name.startswith('property-set'):
log.debug('Received %s from %s', event_name, obj)
p_name = args[0]
p_value = str(args[1])
set_method = proxy.get_dbus_method(
'Set', 'org.freedesktop.DBus.Properties')
set_method('', p_name, p_value)
elif event_name in GARBAGE:
log.debug("Droping event %s", event_name)
elif isinstance(obj, QubesVM):
log.debug("Forwarding event %s", event_name)
forward_signal_func = proxy.get_dbus_method(
'ForwardSignal', 'org.qubes.Signals')
if not args:
args = ['']
if not kwargs:
kwargs = {'fpp': 'bar'}

forward_signal_func(event_name, args, kwargs)
else:
log.info("Do not know how to handle %s event", event_name)
if args:
log.info(args)
if kwargs:
log.warn(kwargs)
except TypeError as ex:
msg = "%s: %s" % (event_name, ex.message)
log.error(msg)


def serialize(args):
result = []
for val in args:
if isinstance(val, QubesVM):
result.append(val.qid)
else:
str(val)
return result


def get_proxy(obj):
# type: (Union[Qubes, QubesVM]) -> dbus.proxies.ProxyObject
identifier = str(obj)
if isinstance(obj, Qubes):
return SESSION_BUS.get_object(MANAGER_NAME, MANAGER_PATH)
elif isinstance(obj, QubesVM):
domain_path = '/'.join([MANAGER_PATH, 'domains', identifier]).replace(
'-', '_')
return SESSION_BUS.get_object(MANAGER_NAME, domain_path)
else:
log.error("Unknown sender object %s", obj)
return
40 changes: 40 additions & 0 deletions qubesdbus/service.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#!/usr/bin/env python2
# -*- encoding: utf8 -*-
#
# The Qubes OS Project, https://www.qubes-os.org/
#
# Copyright (C) 2016 Bahtiar `kalkin-` Gadimov <[email protected]>
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

# pylint: disable=missing-docstring,invalid-name

from __future__ import absolute_import

import dbus
import dbus.mainloop.glib
from qubesdbus import NAME_PREFIX, PATH_PREFIX, VERSION


class _DbusServiceObject(dbus.service.Object):
def __init__(self):
self.bus_path = ''.join([PATH_PREFIX, '/', self.__class__.__name__,
str(VERSION)])
self.bus_name = ''.join([NAME_PREFIX, '.', self.__class__.__name__,
str(VERSION)])
dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
bus = dbus.service.BusName(self.bus_name, dbus.SessionBus())
dbus.service.BusName(self.bus_name, dbus.SessionBus())
# avoid pylint super-on-old-class error
dbus.service.Object.__init__(self, bus, self.bus_path)
3 changes: 3 additions & 0 deletions rpm_spec/qubes-dbus.spec
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,12 @@ foo bar
%install

python setup.py install --single-version-externally-managed -O1 --root=$RPM_BUILD_ROOT --record=INSTALLED_FILES
mkdir -p $RPM_BUILD_ROOT/usr/share
cp -r dbus-1 $RPM_BUILD_ROOT/usr/share/dbus-1

%clean
rm -rf $RPM_BUILD_ROOT

%files -f INSTALLED_FILES
%defattr(-,root,root)
/usr/share/dbus-1/services/org.qubes.DomainManager1.service
6 changes: 3 additions & 3 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@
description='Qubes DBus package',
license='GPL2+',
url='https://www.qubes-os.org/',
packages=['qubes.dbus'],
packages=['qubesdbus'],
entry_points={
'qubes.events.receivers': [
'test = qubes.dbus:Receiver'
'qubes.ext': [
'qubesdbus = qubesdbus:QubesDbusProxy'
]
})

0 comments on commit 3232052

Please sign in to comment.