Hardware authentication for Linux using ordinary USB Flash Drives.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

157 lines
5.3 KiB

  1. #!/usr/bin/env python2.4
  2. import dbus
  3. import sys
  4. from xml.dom import minidom
  5. class Device:
  6. def __init__(self, udi):
  7. self.__udi = udi
  8. self.__findStorageDevice()
  9. deviceObj = bus.get_object('org.freedesktop.Hal',
  10. udi)
  11. deviceProperties = deviceObj.GetAllProperties(
  12. dbus_interface = 'org.freedesktop.Hal.Device')
  13. self.vendor = deviceProperties['usb_device.vendor']
  14. self.product = deviceProperties['info.product']
  15. self.serialNumber = deviceProperties['usb_device.serial']
  16. def __findStorageDevice(self):
  17. for child in halManager.FindDeviceByCapability('storage'):
  18. obj = bus.get_object('org.freedesktop.Hal',
  19. child)
  20. properties = obj.GetAllProperties(
  21. dbus_interface = 'org.freedesktop.Hal.Device')
  22. if properties['storage.physical_device'] == self.__udi + '_if0':
  23. self.__storageUdi = child
  24. return
  25. raise Exception, '%s is not a storage device.' % self.__udi
  26. def __repr__(self):
  27. return "%s %s (%s)" % (self.vendor, self.product, self.serialNumber)
  28. def volumes(self):
  29. vols = []
  30. for volume in halManager.FindDeviceByCapability('volume'):
  31. deviceObj = bus.get_object('org.freedesktop.Hal',
  32. volume)
  33. deviceProperties = deviceObj.GetAllProperties(
  34. dbus_interface = 'org.freedesktop.Hal.Device')
  35. if deviceProperties['block.storage_device'] != self.__storageUdi:
  36. continue
  37. vols.append({'uuid' : deviceProperties['volume.uuid'],
  38. 'device' : deviceProperties['block.device']})
  39. return vols
  40. def listOptions(question, options, force = False):
  41. if force == False and len(options) == 1:
  42. return 0
  43. while True:
  44. try:
  45. print question
  46. for i in range(len(options)):
  47. print "%d) %s" % (i, options[i])
  48. print
  49. sys.stdout.write('[%s-%s]: ' % (0, len(options) - 1))
  50. optionId = int(sys.stdin.readline())
  51. print
  52. if optionId not in range(len(options)):
  53. raise Exception
  54. return optionId
  55. except KeyboardInterrupt: sys.exit()
  56. except Exception: pass
  57. else: break
  58. def addDevice(options):
  59. devices = []
  60. for udi in halManager.FindDeviceStringMatch('info.bus', 'usb_device'):
  61. try:
  62. devices.append(Device(udi))
  63. except Exception, ex:
  64. pass
  65. if len(devices) == 0:
  66. print 'No devices detected.'
  67. sys.exit()
  68. device = devices[listOptions("Please select the device you wish to add.",
  69. devices, force = options['force'])]
  70. volumes = device.volumes()
  71. volume = volumes[listOptions("Which volume would you like to use for " \
  72. "storing data ?",
  73. ["%s (UUID: %s)" % (volume['device'],
  74. volume['uuid'])
  75. for volume in volumes],
  76. force = options['force'])]
  77. print 'Name\t\t: %s' % options['deviceName']
  78. print 'Vendor\t\t: %s' % device.vendor
  79. print 'Model\t\t: %s' % device.product
  80. print 'Serial\t\t: %s' % device.serialNumber
  81. print 'Volume UUID\t: %s (%s)' % (volume['uuid'], volume['device'])
  82. print
  83. print 'Save device to %s ?' % options['configFile']
  84. sys.stdout.write('[y/n] ')
  85. if sys.stdin.readline().strip() != 'y':
  86. sys.exit(1)
  87. doc = minidom.parse(options['configFile'])
  88. devs = doc.getElementsByTagName('devices')
  89. dev = doc.createElement('device')
  90. dev.attributes['id'] = options['deviceName']
  91. devs[0].appendChild(dev)
  92. for name, value in (('vendor', device.vendor),
  93. ('model', device.product),
  94. ('serial', device.serialNumber),
  95. ('volume_uuid', volume['uuid'])):
  96. e = doc.createElement(name)
  97. t = doc.createTextNode(value)
  98. e.appendChild(t)
  99. dev.appendChild(e)
  100. f = open(options['configFile'], 'w')
  101. f.write(doc.toxml())
  102. f.close()
  103. print 'Done.'
  104. def usage():
  105. print 'Usage: %s [--config file] --add-device <name> [--no-autodetect]' % sys.argv[0]
  106. sys.exit(1)
  107. import getopt
  108. try:
  109. opts, args = getopt.getopt(sys.argv[1:], "ha:nc:",
  110. ["help", "add-device=", "no-autodetect",
  111. "config="])
  112. except getopt.GetoptError:
  113. usage()
  114. if len(args) != 0:
  115. usage()
  116. options = { 'force' : False, 'deviceName' : None,
  117. 'configFile' : '/etc/pam_usb/pusb.conf' }
  118. for o, a in opts:
  119. if o in ("-h", "--help"):
  120. usage()
  121. if o in ("-a", "--add-device"):
  122. options['deviceName'] = a
  123. if o in ("-n", "--no-autodetect"):
  124. options['force'] = True
  125. if o in ("-c", "--config"):
  126. options['configFile'] = a
  127. if options['deviceName'] is None:
  128. usage()
  129. bus = dbus.SystemBus()
  130. halService = bus.get_object('org.freedesktop.Hal',
  131. '/org/freedesktop/Hal/Manager')
  132. halManager = dbus.Interface(halService, 'org.freedesktop.Hal.Manager')
  133. addDevice(options)