ait/os/bin/autoshadow/autoshadow.py
author om
Tue, 12 Nov 2013 11:31:34 +0100
branchom
changeset 2 c9bf2537109a
permissions -rwxr-xr-x
added C/C++ and Python sources
     1 #!/bin/env python
     2 # -*- coding: utf-8 -*-
     3 
     4 # ------------------------------------------------------------
     5 # autoshadow.py
     6 # 
     7 # Listen on DBus and mount any USB stick automatically
     8 # and invoke shadowfuse for it
     9 #
    10 # Autor: Oliver Maurhart, <oliver.maurhart@ait.ac.at>
    11 #
    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
    16 #
    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.
    20 # 
    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.
    25 # 
    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 # ------------------------------------------------------------
    31 
    32 
    33 # ------------------------------------------------------------
    34 # imports
    35 
    36 import argparse
    37 import dbus
    38 import dbus.glib
    39 import dbus.service
    40 import gobject
    41 import sys
    42 
    43 
    44 # ------------------------------------------------------------
    45 # const
    46 
    47 
    48 __version__ = "0.1"
    49 
    50 
    51 # ------------------------------------------------------------
    52 # code
    53 
    54 
    55 class AutoShadowService(dbus.service.Object):
    56     
    57     """The AutoShadowService is the DBus object which listens on UDisk2 events and decides to mount and shadow a device.
    58     
    59     This class incorporates a DBus service (at.ac.ait.opensecurity.AutoShadow) and binds
    60     itself to the /AutoShadow object.
    61     """
    62 
    63     def __init__(self):
    64         
    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')
    68         
    69         # get the UDisk2 system object
    70         try:
    71             udisk2 = bus.get_object('org.freedesktop.UDisks2', '/org/freedesktop/UDisks2')
    72         except:
    73             sys.stderr.write('Failed to aquire DBus Service org.freedesktop.UDisks2 object /org/freedesktop/UDisks2 on system DBus.\n')
    74             sys.exit(1)
    75             
    76         # connect our signal
    77         udisk2.connect_to_signal('InterfacesAdded', self.interface_added, sender_keyword='sender')
    78     
    79     
    80     def interface_added(*args, **kwargs):
    81         
    82         """Entry point for signal for new interfaces"""
    83         
    84         # a new interface has been added
    85         object_path = args[1]
    86         interfaces_and_properties = args[2]
    87         interface_keys = interfaces_and_properties.keys()
    88         
    89         if (interface_keys[0] == 'org.freedesktop.UDisks2.Drive'):
    90             
    91             # added a new 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))
    97         
    98         if (interface_keys[0] == 'org.freedesktop.UDisks2.Block'):
    99             
   100             # added a new device - filesystem?
   101             if ('org.freedesktop.UDisks2.Filesystem' in interface_keys):
   102                 
   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])
   108             
   109 
   110     def listen(self):
   111         """Start listening on DBus"""
   112         self.loop = gobject.MainLoop()
   113         self.loop.run()
   114 
   115 
   116     @dbus.service.method('at.ac.ait.opensecurity.AutoShadow')
   117     def Quit(self):
   118         """Terminate this service"""
   119         self.loop.quit()
   120 
   121 
   122     @dbus.service.method('at.ac.ait.opensecurity.AutoShadow', out_signature='s')
   123     def Version(self):
   124         """Give a version string"""
   125         return __version__
   126 
   127 
   128 def enforce_mount(udisk_object):
   129     
   130     """This function does the real mounting of drives. 
   131     It also enforces the MirrorFuse on these mounts.
   132     """
   133     
   134     print("ENFORCING mount of " + udisk_object)
   135 
   136 
   137 def main():             
   138             
   139     # parse command line
   140     parser = argparse.ArgumentParser(description = 'Automount USB storage devices and invoke shadowfuse for it.')
   141     args = parser.parse_args()
   142     
   143     # setup DBus event loop
   144     autoshadow_service = AutoShadowService()
   145     autoshadow_service.listen()    
   146     
   147 
   148 # start
   149 if __name__ == "__main__":
   150     main()
   151 
   152