|
#!/usr/bin/env python
|
|
#
|
|
# Copyright (c) 2003-2007 Andrea Luzzardi <scox@sig11.org>
|
|
#
|
|
# This file is part of the pam_usb project. pam_usb is free software;
|
|
# you can redistribute it and/or modify it under the terms of the GNU General
|
|
# Public License version 2, as published by the Free Software Foundation.
|
|
#
|
|
# pam_usb 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., 59 Temple
|
|
# Place, Suite 330, Boston, MA 02111-1307 USA
|
|
|
|
|
|
import dbus
|
|
import sys
|
|
import os
|
|
from xml.dom import minidom
|
|
|
|
class Device:
|
|
def __init__(self, udi):
|
|
self.__udi = udi
|
|
self.__findStorageDevice()
|
|
deviceObj = bus.get_object('org.freedesktop.Hal',
|
|
udi)
|
|
deviceProperties = deviceObj.GetAllProperties(
|
|
dbus_interface = 'org.freedesktop.Hal.Device')
|
|
self.vendor = deviceProperties['usb_device.vendor']
|
|
self.product = deviceProperties['info.product']
|
|
self.serialNumber = deviceProperties['usb_device.serial']
|
|
|
|
def __findStorageDevice(self):
|
|
for child in halManager.FindDeviceByCapability('storage'):
|
|
obj = bus.get_object('org.freedesktop.Hal',
|
|
child)
|
|
properties = obj.GetAllProperties(
|
|
dbus_interface = 'org.freedesktop.Hal.Device')
|
|
if properties['storage.physical_device'] == self.__udi + '_if0':
|
|
self.__storageUdi = child
|
|
return
|
|
raise Exception, '%s is not a storage device.' % self.__udi
|
|
|
|
def __repr__(self):
|
|
return "%s %s (%s)" % (self.vendor, self.product, self.serialNumber)
|
|
|
|
def volumes(self):
|
|
vols = []
|
|
for volume in halManager.FindDeviceByCapability('volume'):
|
|
deviceObj = bus.get_object('org.freedesktop.Hal',
|
|
volume)
|
|
deviceProperties = deviceObj.GetAllProperties(
|
|
dbus_interface = 'org.freedesktop.Hal.Device')
|
|
if deviceProperties['block.storage_device'] != self.__storageUdi:
|
|
continue
|
|
vols.append({'uuid' : deviceProperties['volume.uuid'],
|
|
'device' : deviceProperties['block.device']})
|
|
return vols
|
|
|
|
def listOptions(question, options, force = False):
|
|
if force == False and len(options) == 1:
|
|
return 0
|
|
while True:
|
|
try:
|
|
print question
|
|
for i in range(len(options)):
|
|
print "%d) %s" % (i, options[i])
|
|
print
|
|
sys.stdout.write('[%s-%s]: ' % (0, len(options) - 1))
|
|
optionId = int(sys.stdin.readline())
|
|
print
|
|
if optionId not in range(len(options)):
|
|
raise Exception
|
|
return optionId
|
|
except KeyboardInterrupt: sys.exit()
|
|
except Exception: pass
|
|
else: break
|
|
|
|
def addDevice(options):
|
|
devices = []
|
|
|
|
for udi in halManager.FindDeviceStringMatch('info.bus', 'usb_device'):
|
|
try:
|
|
devices.append(Device(udi))
|
|
except Exception, ex:
|
|
pass
|
|
|
|
if len(devices) == 0:
|
|
print 'No devices detected.'
|
|
sys.exit()
|
|
|
|
device = devices[listOptions("Please select the device you wish to add.",
|
|
devices, force = options['force'])]
|
|
volumes = device.volumes()
|
|
volume = volumes[listOptions("Which volume would you like to use for " \
|
|
"storing data ?",
|
|
["%s (UUID: %s)" % (volume['device'],
|
|
volume['uuid'])
|
|
for volume in volumes],
|
|
force = options['force'])]
|
|
|
|
print 'Name\t\t: %s' % options['deviceName']
|
|
print 'Vendor\t\t: %s' % device.vendor
|
|
print 'Model\t\t: %s' % device.product
|
|
print 'Serial\t\t: %s' % device.serialNumber
|
|
if volume['uuid'] != '':
|
|
print 'Volume UUID\t: %s (%s)' % (volume['uuid'], volume['device'])
|
|
else:
|
|
print
|
|
print 'WARNING: No UUID detected for device %s. One time pads will be disabled.' % volume['device']
|
|
print
|
|
print 'Save device to %s ?' % options['configFile']
|
|
|
|
sys.stdout.write('[y/n] ')
|
|
if sys.stdin.readline().strip() != 'y':
|
|
sys.exit(1)
|
|
|
|
try:
|
|
doc = minidom.parse(options['configFile'])
|
|
except Exception, err:
|
|
print 'Unable to read %s: %s' % (options['configFile'], err)
|
|
sys.exit(1)
|
|
|
|
devs = doc.getElementsByTagName('devices')
|
|
dev = doc.createElement('device')
|
|
dev.attributes['id'] = options['deviceName']
|
|
devs[0].appendChild(dev)
|
|
|
|
for name, value in (('vendor', device.vendor),
|
|
('model', device.product),
|
|
('serial', device.serialNumber),
|
|
('volume_uuid', volume['uuid'])):
|
|
e = doc.createElement(name)
|
|
t = doc.createTextNode(value)
|
|
e.appendChild(t)
|
|
dev.appendChild(e)
|
|
|
|
# Disable one time pads if there's no device UUID
|
|
if volume['uuid'] == '':
|
|
e = doc.createElement('option')
|
|
e.setAttribute('name', 'one_time_pad')
|
|
e.appendChild(doc.createTextNode('false'))
|
|
dev.appendChild(e)
|
|
|
|
try:
|
|
f = open(options['configFile'], 'w')
|
|
f.write(doc.toxml())
|
|
f.close()
|
|
except Exception, err:
|
|
print 'Unable to save %s: %s' % (options['configFile'], err)
|
|
sys.exit(1)
|
|
else:
|
|
print 'Done.'
|
|
|
|
def usage():
|
|
print 'Usage: %s [--config file] --add-device <name> [--no-autodetect]' % os.path.basename(__file__)
|
|
sys.exit(1)
|
|
|
|
import getopt
|
|
|
|
try:
|
|
opts, args = getopt.getopt(sys.argv[1:], "ha:nc:",
|
|
["help", "add-device=", "no-autodetect",
|
|
"config="])
|
|
except getopt.GetoptError:
|
|
usage()
|
|
|
|
if len(args) != 0:
|
|
usage()
|
|
|
|
options = { 'force' : False, 'deviceName' : None,
|
|
'configFile' : '/etc/pusb/pusb.conf' }
|
|
|
|
for o, a in opts:
|
|
if o in ("-h", "--help"):
|
|
usage()
|
|
if o in ("-a", "--add-device"):
|
|
options['deviceName'] = a
|
|
if o in ("-n", "--no-autodetect"):
|
|
options['force'] = True
|
|
if o in ("-c", "--config"):
|
|
options['configFile'] = a
|
|
|
|
if options['deviceName'] is None:
|
|
usage()
|
|
|
|
bus = dbus.SystemBus()
|
|
halService = bus.get_object('org.freedesktop.Hal',
|
|
'/org/freedesktop/Hal/Manager')
|
|
halManager = dbus.Interface(halService, 'org.freedesktop.Hal.Manager')
|
|
|
|
try:
|
|
addDevice(options)
|
|
except KeyboardInterrupt:
|
|
sys.exit(1)
|
|
|