162306a36Sopenharmony_ci==============================================================
262306a36Sopenharmony_ciAuthorizing (or not) your USB devices to connect to the system
362306a36Sopenharmony_ci==============================================================
462306a36Sopenharmony_ci
562306a36Sopenharmony_ciCopyright (C) 2007 Inaky Perez-Gonzalez <inaky@linux.intel.com> Intel Corporation
662306a36Sopenharmony_ci
762306a36Sopenharmony_ciThis feature allows you to control if a USB device can be used (or
862306a36Sopenharmony_cinot) in a system. This feature will allow you to implement a lock-down
962306a36Sopenharmony_ciof USB devices, fully controlled by user space.
1062306a36Sopenharmony_ci
1162306a36Sopenharmony_ciAs of now, when a USB device is connected it is configured and
1262306a36Sopenharmony_ciits interfaces are immediately made available to the users.  With this
1362306a36Sopenharmony_cimodification, only if root authorizes the device to be configured will
1462306a36Sopenharmony_cithen it be possible to use it.
1562306a36Sopenharmony_ci
1662306a36Sopenharmony_ciUsage
1762306a36Sopenharmony_ci=====
1862306a36Sopenharmony_ci
1962306a36Sopenharmony_ciAuthorize a device to connect::
2062306a36Sopenharmony_ci
2162306a36Sopenharmony_ci	$ echo 1 > /sys/bus/usb/devices/DEVICE/authorized
2262306a36Sopenharmony_ci
2362306a36Sopenharmony_ciDe-authorize a device::
2462306a36Sopenharmony_ci
2562306a36Sopenharmony_ci	$ echo 0 > /sys/bus/usb/devices/DEVICE/authorized
2662306a36Sopenharmony_ci
2762306a36Sopenharmony_ciSet new devices connected to hostX to be deauthorized by default (ie:
2862306a36Sopenharmony_cilock down)::
2962306a36Sopenharmony_ci
3062306a36Sopenharmony_ci	$ echo 0 > /sys/bus/usb/devices/usbX/authorized_default
3162306a36Sopenharmony_ci
3262306a36Sopenharmony_ciRemove the lock down::
3362306a36Sopenharmony_ci
3462306a36Sopenharmony_ci	$ echo 1 > /sys/bus/usb/devices/usbX/authorized_default
3562306a36Sopenharmony_ci
3662306a36Sopenharmony_ciBy default, all USB devices are authorized.  Writing "2" to the
3762306a36Sopenharmony_ciauthorized_default attribute causes the kernel to authorize by default
3862306a36Sopenharmony_cionly devices connected to internal USB ports.
3962306a36Sopenharmony_ci
4062306a36Sopenharmony_ci
4162306a36Sopenharmony_ciExample system lockdown (lame)
4262306a36Sopenharmony_ci------------------------------
4362306a36Sopenharmony_ci
4462306a36Sopenharmony_ciImagine you want to implement a lockdown so only devices of type XYZ
4562306a36Sopenharmony_cican be connected (for example, it is a kiosk machine with a visible
4662306a36Sopenharmony_ciUSB port)::
4762306a36Sopenharmony_ci
4862306a36Sopenharmony_ci  boot up
4962306a36Sopenharmony_ci  rc.local ->
5062306a36Sopenharmony_ci
5162306a36Sopenharmony_ci   for host in /sys/bus/usb/devices/usb*
5262306a36Sopenharmony_ci   do
5362306a36Sopenharmony_ci      echo 0 > $host/authorized_default
5462306a36Sopenharmony_ci   done
5562306a36Sopenharmony_ci
5662306a36Sopenharmony_ciHookup an script to udev, for new USB devices::
5762306a36Sopenharmony_ci
5862306a36Sopenharmony_ci if device_is_my_type $DEV
5962306a36Sopenharmony_ci then
6062306a36Sopenharmony_ci   echo 1 > $device_path/authorized
6162306a36Sopenharmony_ci done
6262306a36Sopenharmony_ci
6362306a36Sopenharmony_ci
6462306a36Sopenharmony_ciNow, device_is_my_type() is where the juice for a lockdown is. Just
6562306a36Sopenharmony_cichecking if the class, type and protocol match something is the worse
6662306a36Sopenharmony_cisecurity verification you can make (or the best, for someone willing
6762306a36Sopenharmony_cito break it). If you need something secure, use crypto and Certificate
6862306a36Sopenharmony_ciAuthentication or stuff like that. Something simple for an storage key
6962306a36Sopenharmony_cicould be::
7062306a36Sopenharmony_ci
7162306a36Sopenharmony_ci function device_is_my_type()
7262306a36Sopenharmony_ci {
7362306a36Sopenharmony_ci   echo 1 > authorized		# temporarily authorize it
7462306a36Sopenharmony_ci                                # FIXME: make sure none can mount it
7562306a36Sopenharmony_ci   mount DEVICENODE /mntpoint
7662306a36Sopenharmony_ci   sum=$(md5sum /mntpoint/.signature)
7762306a36Sopenharmony_ci   if [ $sum = $(cat /etc/lockdown/keysum) ]
7862306a36Sopenharmony_ci   then
7962306a36Sopenharmony_ci        echo "We are good, connected"
8062306a36Sopenharmony_ci        umount /mntpoint
8162306a36Sopenharmony_ci        # Other stuff so others can use it
8262306a36Sopenharmony_ci   else
8362306a36Sopenharmony_ci        echo 0 > authorized
8462306a36Sopenharmony_ci   fi
8562306a36Sopenharmony_ci }
8662306a36Sopenharmony_ci
8762306a36Sopenharmony_ci
8862306a36Sopenharmony_ciOf course, this is lame, you'd want to do a real certificate
8962306a36Sopenharmony_civerification stuff with PKI, so you don't depend on a shared secret,
9062306a36Sopenharmony_cietc, but you get the idea. Anybody with access to a device gadget kit
9162306a36Sopenharmony_cican fake descriptors and device info. Don't trust that. You are
9262306a36Sopenharmony_ciwelcome.
9362306a36Sopenharmony_ci
9462306a36Sopenharmony_ci
9562306a36Sopenharmony_ciInterface authorization
9662306a36Sopenharmony_ci-----------------------
9762306a36Sopenharmony_ci
9862306a36Sopenharmony_ciThere is a similar approach to allow or deny specific USB interfaces.
9962306a36Sopenharmony_ciThat allows to block only a subset of an USB device.
10062306a36Sopenharmony_ci
10162306a36Sopenharmony_ciAuthorize an interface::
10262306a36Sopenharmony_ci
10362306a36Sopenharmony_ci	$ echo 1 > /sys/bus/usb/devices/INTERFACE/authorized
10462306a36Sopenharmony_ci
10562306a36Sopenharmony_ciDeauthorize an interface::
10662306a36Sopenharmony_ci
10762306a36Sopenharmony_ci	$ echo 0 > /sys/bus/usb/devices/INTERFACE/authorized
10862306a36Sopenharmony_ci
10962306a36Sopenharmony_ciThe default value for new interfaces
11062306a36Sopenharmony_cion a particular USB bus can be changed, too.
11162306a36Sopenharmony_ci
11262306a36Sopenharmony_ciAllow interfaces per default::
11362306a36Sopenharmony_ci
11462306a36Sopenharmony_ci	$ echo 1 > /sys/bus/usb/devices/usbX/interface_authorized_default
11562306a36Sopenharmony_ci
11662306a36Sopenharmony_ciDeny interfaces per default::
11762306a36Sopenharmony_ci
11862306a36Sopenharmony_ci	$ echo 0 > /sys/bus/usb/devices/usbX/interface_authorized_default
11962306a36Sopenharmony_ci
12062306a36Sopenharmony_ciPer default the interface_authorized_default bit is 1.
12162306a36Sopenharmony_ciSo all interfaces would authorized per default.
12262306a36Sopenharmony_ci
12362306a36Sopenharmony_ciNote:
12462306a36Sopenharmony_ci  If a deauthorized interface will be authorized so the driver probing must
12562306a36Sopenharmony_ci  be triggered manually by writing INTERFACE to /sys/bus/usb/drivers_probe
12662306a36Sopenharmony_ci
12762306a36Sopenharmony_ciFor drivers that need multiple interfaces all needed interfaces should be
12862306a36Sopenharmony_ciauthorized first. After that the drivers should be probed.
12962306a36Sopenharmony_ciThis avoids side effects.
130