1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/ait/os/bin/autoshadow/autoshadow.py Tue Nov 12 11:31:34 2013 +0100
1.3 @@ -0,0 +1,152 @@
1.4 +#!/bin/env python
1.5 +# -*- coding: utf-8 -*-
1.6 +
1.7 +# ------------------------------------------------------------
1.8 +# autoshadow.py
1.9 +#
1.10 +# Listen on DBus and mount any USB stick automatically
1.11 +# and invoke shadowfuse for it
1.12 +#
1.13 +# Autor: Oliver Maurhart, <oliver.maurhart@ait.ac.at>
1.14 +#
1.15 +# Copyright (C) 2013 AIT Austrian Institute of Technology
1.16 +# AIT Austrian Institute of Technology GmbH
1.17 +# Donau-City-Strasse 1 | 1220 Vienna | Austria
1.18 +# http://www.ait.ac.at
1.19 +#
1.20 +# This program is free software; you can redistribute it and/or
1.21 +# modify it under the terms of the GNU General Public License
1.22 +# as published by the Free Software Foundation version 2.
1.23 +#
1.24 +# This program is distributed in the hope that it will be useful,
1.25 +# but WITHOUT ANY WARRANTY; without even the implied warranty of
1.26 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1.27 +# GNU General Public License for more details.
1.28 +#
1.29 +# You should have received a copy of the GNU General Public License
1.30 +# along with this program; if not, write to the Free Software
1.31 +# Foundation, Inc., 51 Franklin Street, Fifth Floor,
1.32 +# Boston, MA 02110-1301, USA.
1.33 +# ------------------------------------------------------------
1.34 +
1.35 +
1.36 +# ------------------------------------------------------------
1.37 +# imports
1.38 +
1.39 +import argparse
1.40 +import dbus
1.41 +import dbus.glib
1.42 +import dbus.service
1.43 +import gobject
1.44 +import sys
1.45 +
1.46 +
1.47 +# ------------------------------------------------------------
1.48 +# const
1.49 +
1.50 +
1.51 +__version__ = "0.1"
1.52 +
1.53 +
1.54 +# ------------------------------------------------------------
1.55 +# code
1.56 +
1.57 +
1.58 +class AutoShadowService(dbus.service.Object):
1.59 +
1.60 + """The AutoShadowService is the DBus object which listens on UDisk2 events and decides to mount and shadow a device.
1.61 +
1.62 + This class incorporates a DBus service (at.ac.ait.opensecurity.AutoShadow) and binds
1.63 + itself to the /AutoShadow object.
1.64 + """
1.65 +
1.66 + def __init__(self):
1.67 +
1.68 + bus = dbus.SystemBus()
1.69 + bus_name = dbus.service.BusName('at.ac.ait.opensecurity.AutoShadow', bus)
1.70 + dbus.service.Object.__init__(self, bus_name, '/AutoShadow')
1.71 +
1.72 + # get the UDisk2 system object
1.73 + try:
1.74 + udisk2 = bus.get_object('org.freedesktop.UDisks2', '/org/freedesktop/UDisks2')
1.75 + except:
1.76 + sys.stderr.write('Failed to aquire DBus Service org.freedesktop.UDisks2 object /org/freedesktop/UDisks2 on system DBus.\n')
1.77 + sys.exit(1)
1.78 +
1.79 + # connect our signal
1.80 + udisk2.connect_to_signal('InterfacesAdded', self.interface_added, sender_keyword='sender')
1.81 +
1.82 +
1.83 + def interface_added(*args, **kwargs):
1.84 +
1.85 + """Entry point for signal for new interfaces"""
1.86 +
1.87 + # a new interface has been added
1.88 + object_path = args[1]
1.89 + interfaces_and_properties = args[2]
1.90 + interface_keys = interfaces_and_properties.keys()
1.91 +
1.92 + if (interface_keys[0] == 'org.freedesktop.UDisks2.Drive'):
1.93 +
1.94 + # added a new drive
1.95 + drive_values = interfaces_and_properties[interface_keys[0]]
1.96 + drive_id = str(drive_values['Id'])
1.97 + drive_vendor = str(drive_values['Vendor'])
1.98 + drive_removeable = bool(drive_values['Removable'])
1.99 + print('detected new drive: id=\'{0}\' vendor=\'{1}\' removeable={2}'.format(drive_id, drive_vendor, drive_removeable))
1.100 +
1.101 + if (interface_keys[0] == 'org.freedesktop.UDisks2.Block'):
1.102 +
1.103 + # added a new device - filesystem?
1.104 + if ('org.freedesktop.UDisks2.Filesystem' in interface_keys):
1.105 +
1.106 + # pick values of the device
1.107 + device_values = interfaces_and_properties[interface_keys[0]]
1.108 + device_path = bytearray(device_values['Device'][0:-1]).decode('latin-1')
1.109 + print('detected new device: path=\'{0}\''.format(device_path))
1.110 + enforce_mount('/org/freedesktop/UDisks2/block_devices/' + device_path.split('/')[-1])
1.111 +
1.112 +
1.113 + def listen(self):
1.114 + """Start listening on DBus"""
1.115 + self.loop = gobject.MainLoop()
1.116 + self.loop.run()
1.117 +
1.118 +
1.119 + @dbus.service.method('at.ac.ait.opensecurity.AutoShadow')
1.120 + def Quit(self):
1.121 + """Terminate this service"""
1.122 + self.loop.quit()
1.123 +
1.124 +
1.125 + @dbus.service.method('at.ac.ait.opensecurity.AutoShadow', out_signature='s')
1.126 + def Version(self):
1.127 + """Give a version string"""
1.128 + return __version__
1.129 +
1.130 +
1.131 +def enforce_mount(udisk_object):
1.132 +
1.133 + """This function does the real mounting of drives.
1.134 + It also enforces the MirrorFuse on these mounts.
1.135 + """
1.136 +
1.137 + print("ENFORCING mount of " + udisk_object)
1.138 +
1.139 +
1.140 +def main():
1.141 +
1.142 + # parse command line
1.143 + parser = argparse.ArgumentParser(description = 'Automount USB storage devices and invoke shadowfuse for it.')
1.144 + args = parser.parse_args()
1.145 +
1.146 + # setup DBus event loop
1.147 + autoshadow_service = AutoShadowService()
1.148 + autoshadow_service.listen()
1.149 +
1.150 +
1.151 +# start
1.152 +if __name__ == "__main__":
1.153 + main()
1.154 +
1.155 +