Why does PyUSB / libusb require root (sudo) permissions on Linux? - python

I have been toying around with PyUSB lately, and found that it works beautifully on Linux (Ubuntu has libusb 0.1 and 1.0, as well as OpenUSB)... but only if I run the program with root privileges (with sudo, of course).
Can anyone tell me why it requires elevated privileges and, more importantly, if I can change the permissions somehow to make it work for normal user accounts?

You can change the permissions of your usb device node by creating a udev rule.
e.g. I added the following line to a file in /etc/udev/rules.d/
SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", MODE="0664", GROUP="usbusers"
This sets the owner of the device node to root:usbusers rather than root:root
After adding myself to the usbusers group, I can access the device.

See the answer that I gave here:
How can I comunicate with this device using pyusb?
Namely:
Set up a udev rules file for the specific device that you want normal users to be able to access. This will define the vendor id, the product id and a group.
The vendor and product id's can be found using the lsusb command.
1.
Create a udev rules file
ACTION=="add", SUBSYSTEMS=="usb", ATTRS{idVendor}=="171b", ATTRS{idProduct}=="2001", MODE="660", GROUP="plugdev"
Put this in a file called (for example) /lib/udev/rules.d/50-YourSoftwareName.rules (dig around in man udev for file naming rules)
NOTE: The old naming convention used /etc/udev/rules.d/filename.rules, that has changed.
2.
add the user names to the plugdev group
adduser username plugdev
3.
force the udev system to see your changes
sudo udevadm control --reload (that is minus minus reload)
sudo udevadm trigger
4.
unplug and replug the device
or
reboot your machine
The end result should be that all members of the group plugdev will now be able to access the device.
EDIT:
Note that on some systems the group plugdev may not be the group that you need. It can also be the group input in my experience, depending on what you are plugging in.

libusb allows you to manipulate arbitrary USB devices in arbitrary ways. You could format an external USB harddisk, for example.
In general, all direct hardware access requires root privileges, although I guess that actually full root privileges are not required, you should be fine with just CAP_SYS_RAWIO.

Related

Is there a way to use laptop's built-in biometric sensors in python applications?

I am trying to make an application using python that registers students' attendance. I'm planning to use my laptop's fingerprint built-in fingerprint device to identify the students and register the attendance.
I've tried some web searches but I couldn't find anyway to use built-in fingerprint devices for applications with python. Do you know any way to do it.
The device that i want to use for fingerprints is Lenovo ThinkPad L540.
I managed to find some stuff like windows biometric framework but those things were to be used with other languages.
https://learn.microsoft.com/en-us/windows/win32/secbiomet/biometric-service-api-portal?redirectedfrom=MSDN
This can not be done for now. The fingerprint sensor associated with laptop/mobile can be used for authentication purpose only. Means, you can add the more number of fingerprints who are eligible to access the device. Then, device will allow any one of them to unlock the device. It will not record whose fingerprint it is. It will just say, a fingerprint is authenticated or not.
For recording the attendance, you must go with the time attendances systems. if you want to build software based attendance system with the help of scanner, then you have to go with the fingerprint scanners like mfs100, zk7500 and etc.
From what I can tell, this absolutely can be done. The following link is for a python wrapper around the Windows Biometric Framework. It is around 4 years old, but the functionality it offers still seems to work fine.
https://github.com/luspock/FingerPrint
The identify function in this wrapper prints out the Sub Factor value whenever someone places a matching finger on the scanner. In my experimentation, the returned Sub Factor is unique to each finger that is stored. In the first day you use this, you would just fill a dictionary with sub factors and student names, then that is everything you need for your use case.
Considering that this wrapper only makes use of the system biometric unit pool, the drawback here is that you have to add all of your student's fingers to your PC through the windows sign-in options, meaning they would be able to unlock it. If you are okay with that, it seems like this will suit your needs.
It would also be possible for you to disable login with fingerprint and only use the system pool for this particular use case. That would give you what you want and keep your PC safe from anyone that has their fingerprint stored in the system pool.
If you want to make use of a private pool, you would have to add that functionality to the wrapper yourself. That's totally possible, but it would be a lot of work.
One thing to note about the Windows Biometric Framework is that it requires the process calling the function to have focus. In order for me to test the wrapper, I used the command-line through the Windows Console Host. Windows Terminal doesn't work, because it doesn't properly acquire focus. You can also use tkinter and call the functions with a button.

Get all visualsvn permissions for particular (user)SID from python WMI

I need to get all permissions for particular user in VisualSVN server by using the python WMI query.
Is it possible to get the permissions in a single query ?
Upgrade VisualSVN Server to version 3.4. The new release introduces PowerShell cmdlets for Subversion server and repositories administration and management. New cmdlets you are interested in are Get-SvnAccessRule and Select-SvnAccessRule. Depending on your task, you could use one of the cmdlets to
obtain a list of effective access rules on a particular repository path
Select-SvnAccessRule MyRepo -Path /MyProject/foo/bar
obtain a list of all access rules explicitly assigned for user account DOMAIN\username
Get-SvnAccessRule -AccountName DOMAIN\Username
obtain a list of access rules explicitly assigned for user account (its SID)
Get-SvnAccessRule -AccountId S-1-5-32-545

Creating a custom EC2 AMI from a qcow2 image file with Python

I'm writing a service that needs to register custom AMIs in each EC2 region based on a qcow2 image file.
I have been exploring the apache-libcloud and boto libraries, but it seems the AMI registration functions are built to create an AMI based on a running instance, and I want to base the AMI on my qcow2 image file.
If there isn't an easy solution to this problem, I'll take a complex one. If for some reason this is impossible with a qcow2 image file, I also have access to the RAW image files.
I've succeeded in doing this programmatically. My solution uses raw image files, since they are the ones that can be directly written to a disk. If you need to convert from qcow2 image files, you can do it manually with qemu-img, or see a simple Python implementation of the conversion.
An outline of my process for AMI registration based on a raw image file:
Select an AMI and corresponding AKI to use as a "utility instance". It doesn't have to be the same operating system as the image you're attempting to register. If the AMI has requiretty enabled in /etc/sudoers, you need to make sure that you request a pseudo-terminal when attempting to SSH into the node, such as with Paramiko's Channel.get_pty() method.
Spin up a utility instance based on the AMI and AKI selected. It must be EBS optimized (m1.large size instances work well with EBS) and should have a secondary EBS volume attached that is large enough for the entire uncompressed image you want to register. I use /dev/sdb for this device name.
Once the utility instance is accessible via SSH, have it write the raw image file to the secondary volume. Personally, I pull a .raw.xz file from the Internet that is the image I want to write, so my utility command is sudo sh -c 'curl RAW_XZ_URL | xzcat > /dev/xvdb. Note that in all of my experience, /dev/sdX devices are accessed as /dev/xvdX on the actual instance, but this might not be the case everywhere.
Once the utility command completes, you can destroy the utility node, assuming that you've made your /dev/sdb volume not delete upon node termination. If you haven't, just stop the node. If executing the utility command programmatically, you can use Paramiko's Channel.recv_exit_status() method to wait until the command completes, and then check for a 0 exit status indicating success.
Once the utility instance is no longer running, take a snapshot of the /dev/sdb volume.
Once the snapshot completes, you can register it as an AMI. Make sure to use the same AKI that you've been using this whole time, as well as the proper root device name (I use full disk images, so my root device name is /dev/sda rather than /dev/sda1). Amazon suggests you use hd0 pv-grub AKIs nowadays, not hd00.
One way this can all be accomplished is through the apache-libcloud and paramiko Python libraries, both pip-installable. A good example is the Fedimg library, which implements this exact method in order to automatically register new AMIs in all EC2 regions as Fedora cloud image builds complete.
When actually implementing this process, there is quite a bit of timing, exception-handling, and other "gotchas" involved. This is simply an outline of the steps one must take to resolve the challenge via my method.

Django and root processes

In my Django project I need to be able to check whether a host on the LAN is up using an ICMP ping. I found this SO question which answers how to ping something in Python and this SO question which links to resources explaining how to use the sodoers file.
The Setting
A Device model stores an IP address for a host on the LAN, and after adding a new Device instance to the DB (via a custom view, not the admin) I envisage checking to see if the device responds to a ping using an AJAX call to an API which exposes the capability.
The Problem
However (from the docstring of a library suggested in the the first SO question) "Note that ICMP messages can only be sent from processes running as root."
I don't want to run Django as the root user, since it is bad practice. However this part of the process (sending and ICMP ping) needs to run as root. If with a Django view I wish to send off a ping packet to test the liveness of a host then Django itself is required to be running as root since that is the process which would be invoking the ping.
Solutions
These are the solutions I can think of, and my question is are there any better ways to only execute select parts of a Django project as root, other than these:
Run Django as root (please no!)
Put a "ping request" in a queue that another processes -- run as root -- can periodically check and fulfil. Maybe something like celery.
Is there not a simpler way?
I want something like a "Django run as root" library, is this possible?
Absolutely no way, do not run the Django code as root!
I would run a daemon as root (written in Python, why not) and then IPC between the Django instance and your daemon. As long as you're sure to validate the content and properly handle it (e.g. use subprocess.call with an array etc) and only pass in data (not commands to execute) it should be fine.
Here is an example client and server, using web.py
Server: http://gist.github.com/788639
Client: http://gist.github.com/788658
You'll need to install webpy.org but it's worth having around anyway. If you can hard-wire the IP (or hostname) into the server and remove the argument, all the better.
What's your OS here? You might be able to write a little program that does what you want given a parameter, and stick that in the sudoers file, and give your django user permission to run it as root.
/etc/sudoers
I don't know what kind of system you're on, but on any box I've encountered, one does not have to be root to run the command-line ping program (it has the suid bit set, so it becomes root as necessary). So you could just invoke that. It's a bit more overhead, but probably negligible compared to network latency.

How to mark a device in a way that can be retrived by HAL but does not require mounting or changing the label

I'm trying to find a way to mark a USB flash device in a way that I can programmaticly test for without mounting it or changing the label.
Are there any properties I can modify about a device that will not cause it to behave/look differently to the user?
Running Ubuntu Jaunty.
You cannot modify this property, but the tuple (vendor_id, product_id, serial_number) is unique to each device, so you can use this as mark that is already there.
You can enumerate the devices on the USB bus using lsusb or usblib.
Changing the VID/PID might make your device non-usable without custom drivers. HAL isn't supposed to auto-mount your flash drives for you.
That being said, you could always sneak something into the boot sector and/or the beginning part of the drive. There are a lot of spare bytes in there that can be used for custom purposes - both nefarious and otherwise.

Categories