2 # -*- coding: utf-8 -*-
4 # ------------------------------------------------------------
7 # Listen on DBus and mount any USB stick automatically
8 # and invoke shadowfuse for it
10 # Autor: Oliver Maurhart, <oliver.maurhart@ait.ac.at>
12 # Copyright (C) 2013 AIT Austrian Institute of Technology
13 # AIT Austrian Institute of Technology GmbH
14 # Donau-City-Strasse 1 | 1220 Vienna | Austria
15 # http://www.ait.ac.at
17 # This program is free software; you can redistribute it and/or
18 # modify it under the terms of the GNU General Public License
19 # as published by the Free Software Foundation version 2.
21 # This program is distributed in the hope that it will be useful,
22 # but WITHOUT ANY WARRANTY; without even the implied warranty of
23 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 # GNU General Public License for more details.
26 # You should have received a copy of the GNU General Public License
27 # along with this program; if not, write to the Free Software
28 # Foundation, Inc., 51 Franklin Street, Fifth Floor,
29 # Boston, MA 02110-1301, USA.
30 # ------------------------------------------------------------
33 # ------------------------------------------------------------
44 # ------------------------------------------------------------
51 # ------------------------------------------------------------
55 class AutoShadowService(dbus.service.Object):
57 """The AutoShadowService is the DBus object which listens on UDisk2 events and decides to mount and shadow a device.
59 This class incorporates a DBus service (at.ac.ait.opensecurity.AutoShadow) and binds
60 itself to the /AutoShadow object.
65 bus = dbus.SystemBus()
66 bus_name = dbus.service.BusName('at.ac.ait.opensecurity.AutoShadow', bus)
67 dbus.service.Object.__init__(self, bus_name, '/AutoShadow')
69 # get the UDisk2 system object
71 udisk2 = bus.get_object('org.freedesktop.UDisks2', '/org/freedesktop/UDisks2')
73 sys.stderr.write('Failed to aquire DBus Service org.freedesktop.UDisks2 object /org/freedesktop/UDisks2 on system DBus.\n')
77 udisk2.connect_to_signal('InterfacesAdded', self.interface_added, sender_keyword='sender')
80 def interface_added(*args, **kwargs):
82 """Entry point for signal for new interfaces"""
84 # a new interface has been added
86 interfaces_and_properties = args[2]
87 interface_keys = interfaces_and_properties.keys()
89 if (interface_keys[0] == 'org.freedesktop.UDisks2.Drive'):
92 drive_values = interfaces_and_properties[interface_keys[0]]
93 drive_id = str(drive_values['Id'])
94 drive_vendor = str(drive_values['Vendor'])
95 drive_removeable = bool(drive_values['Removable'])
96 print('detected new drive: id=\'{0}\' vendor=\'{1}\' removeable={2}'.format(drive_id, drive_vendor, drive_removeable))
98 if (interface_keys[0] == 'org.freedesktop.UDisks2.Block'):
100 # added a new device - filesystem?
101 if ('org.freedesktop.UDisks2.Filesystem' in interface_keys):
103 # pick values of the device
104 device_values = interfaces_and_properties[interface_keys[0]]
105 device_path = bytearray(device_values['Device'][0:-1]).decode('latin-1')
106 print('detected new device: path=\'{0}\''.format(device_path))
107 enforce_mount('/org/freedesktop/UDisks2/block_devices/' + device_path.split('/')[-1])
111 """Start listening on DBus"""
112 self.loop = gobject.MainLoop()
116 @dbus.service.method('at.ac.ait.opensecurity.AutoShadow')
118 """Terminate this service"""
122 @dbus.service.method('at.ac.ait.opensecurity.AutoShadow', out_signature='s')
124 """Give a version string"""
128 def enforce_mount(udisk_object):
130 """This function does the real mounting of drives.
131 It also enforces the MirrorFuse on these mounts.
134 print("ENFORCING mount of " + udisk_object)
140 parser = argparse.ArgumentParser(description = 'Automount USB storage devices and invoke shadowfuse for it.')
141 args = parser.parse_args()
143 # setup DBus event loop
144 autoshadow_service = AutoShadowService()
145 autoshadow_service.listen()
149 if __name__ == "__main__":