How do identify a USB modem /dev on LINUX with Python - python

If I have a USB modem that I am accessing using Python pyserial module, it requires the device to be identified '/dev/ttyACM0 for example. If the modem is attached to a USB hub it no longer appears in /dev/tty...
How do identify it programmatically from my Python code so regardless of whether it has been changed or not, or the machine rebooted I can locate the modem?
Note:
I can always see the device using lsusb, but if it is attached to a USB hub it does not appear as /dev/tty... device

This sounds like a bug in the linux kernel. If you can, try a more recent version.
If that fails, check the last few lines of the output of dmesg or in the file /var/log/messages (the latter depends on your distribution; if that file doesn't exist or doesn't contain what you're looking for, then check the other files in /var/log; sorting by time with ls -rt helps).
After identifying the device, you might see a pattern.
Another approach is the major and minor number. If you run ls -l /dev, you'll see output like this:
crw--w---- 1 root tty 4, 0 2011-12-19 09:15 tty0
The c means "character device" and the 4, 0 means it's the console device unit 0.
The 4 is the major number which identifies the type of device. See /proc/devices for a list of major numbers and the respective device drivers.
If you plug in the model directly, note the major number. After plugging it into a hub, try to find devices with the same number.

Instead of doing some voodoo in Python, try writing a udev rule which gives your device a much more useful name like /dev/my-serial-thingy. Using that from Python is way easier.

Related

How to check if a different program is using the camera/microphone in python ubuntu

I'm trying to check in python (ubuntu) if a different program is using the camera/microphone of my computer.
I thought of which syscalls are being used when accessing the camera/microphone.
I know that the syscalls "access" and "open" are being used but there are probably specific parameters for that.
And if I know which syscalls are being used, how can I also know if the
program is using those specific syscalls?
I have an example code in which I'm checking if a file.exe added any new files:
if "open(\"" + file_path + "\", O_WRONLY|O_CREAT|O_TRUNC|O_CLOEXEC, 0666) = 3" in system_calls_list:
programs_which_added_new_files.append(file_path)
First, I have created a file which adds new files and than I wrote all the syscalls of the file to a list (system_calls_list). And than I'm checking if it has a specific syscall (open) with specific parameters. If it dos'e, I can know that the file I'm checking added new files and than append it's path to a different list (programs_which_added_new_files). The same concept should go to camera/microphone.
Thank you for your help :)
The problem is that there exists multiple audio frameworks for Linux.
The oldest, OSS, uses multiple device names under /dev that you are supposed to open (see list here). It is unlikely that you have this installed on a recent Ubuntu.
What you are probably using is ALSA and PulseAudio. In this case, the program is probably connecting to PulseAudio over a UNIX socket (for example /run/user/1000/pulse/native), but this is an implementation detail of PulseAudio (in particular it can also work over IP). You should use the PulseAudio API to find out, for example if you run pactl list source-outputs you should see a list of clients and the recording devices they are connected to.

Raspberry pi protection against reverse engineering the codes

Problem
I want to secure my Raspberry pi in a special way.
I would like to start up raspberry pi without entering a password as pi user.
However, I want pi user to have zero privilege. Cant read a file, cant copy a file, simply nothing. And without access to root->'sudo su'. On the other hand when raspberry pi starts itself with pi user, I want backend process to be running as root. So to put it simply, I want it like in a zoo - two worlds but neither of them can enter the other. Clients can be present, see what process are running, see files in directories, but cant read it, copy, remove and etc. In the same time I want the backend to be untouched and running and writing files.
Reason:
I have raspberri pi product - customer get it home, when plug in power supply,RPi starts up and runs backend programs with root privilege and communicates with my desktop software.
But I dont want curious customer that plugs in HDMI and see my code. I also dont want him to take the SD card and extract the code.
I heard its possible to reverse engineer the code even if compiled. So I simply want the programs(python script) to be there but cannot be accessed in any way.
Is it possible to make such protection?
Thanks in advance
You may consider to use the following approach
Use at least two levels of hashing with MAC address and ARM chip serial number (via cat /proc/cpuinfo) with additional secret keys. Run your program only if the stored license key is the same as the result of doubly-hashed functions.
Optionally, you could rewrite critical part of your code in C, compile it statically, and remove all debug symbols. Call it using Python.
Quick optimization of your code using cython. Call its generated shared objects with a python caller script. Distribute only the shared objects and the python caller script.
This will prevent most people from reverse engineering your codes.
Just to be clear, "cant read a file" means "can't run a program", which means "can't see what process are running, see files in directories".
From your question, I don't understand why you'd even leave the pi user in place...
... runs backend programs with root privilege
Never a good idea - use service accounts instead.
But I dont want curious customer that plugs in HDMI and see my code.
Then don't enable the HDMI output, don't have a graphical desktop installed and disable the login prompt. You might want to look at a "minimal" / "lite" image.
Remember that the UART can present a login prompt, so make sure that's disabled too.
And as the config.txt and kernel need to be in cleartext in the boot partition they can be easily swapped... thus these steps are not going to be terribly effective.
I also dont want him to take the SD card and extract the code.
You could look at encrypting the filesystems (e.g: LUKS), but the Raspberry Pi has no native ability to store data and identify itself... so your encryption key can only be something like the MAC address, or stored in cleartext on the SD card...
Fundamentally this is just going to be a deterrent from casual "oh what's this" investigations.
"Physical access is total access"... once you put it in the customer's hands, you're looking at deterrents more than absolutes.
I heard its possible to reverse engineer the code even if compiled. So I simply want the programs (python script) to be there but cannot be accessed in any way.
Python doesn't get compiled until runtime, so you'll need to ship the device with your source code on it...
If you really want to secure your Intellectual Property, then perhaps the Raspberry Pi isn't the best option? It's up to you to balance cost vs security.

Turn off specific USB port in windows with python

This is my first post, and I kind of have seen that the more specific the better, so I'll try to be super clear, and thanks in advance!
What I want:
I need to scan images from 2 or more scanners at the same time, these scanners are from the same brand and model, in this case Epson Perfection V600, I need different time intervals for at least 40 captures over a course of 20 hours.
My approach
I decided to use Windows, I already have a program in Python that does what I want with just one scanner, or with two from different models. But here is where you guys come in:
The problem
Windows always prints with the same scanner, Since they are from the same brand and model it always uses the same one, and I cannot use two different scanners because that will cause the images not to be comparable. Nevertheless, when I use two different scanners, I don't have such problem. I need to find a way to print with each scanner. I thought in buying a USB hub and control it with python as well, but apparently given libsub implementation in windows, I will not be able to control it. So I'm currently Looking for a way to disable an specific USB port so the program will only recognize one device, scan with it, disable that one, re-enable the other one, and so on.
What I have access to:
Right now I'm using Windows 10, 64 bits, python kernel 3 in a python 3.5 version inside a Conda environment, conda version (4.5.11).
Ubuntu 16.04, 64 bits, with pyinsane working, in a python 3.5 environment inside conda (don't have the conda version at hand).
One Epson perfection V600.
Two Canon Lide200, working only in windows, because drivers are not available in Ubuntu.
What I have also tried
Using Ubuntu,
I thought it was a good Idea, but the Epson drivers webpage fails to connect to the repository containing the rest of the Epson files, letting me only partially download the files, I already tried to contact the owner of the Docky repository, but he fails to contact me.
The error:
W: The repository 'http://ppa.launchpad.net/docky-core/ppa/ubuntu Xenial Release' does not have a Release file.
N: Data from such a repository can't be authenticated and is therefore potentially dangerous to use.
N: See apt-secure(8) manpage for repository creation and user configuration details.
E: Failed to fetch http://ppa.launchpad.net/docky-core/ppa/ubuntu/dists/xenial/main/binary-amd64/Packages 404 Not Found
E: Some index files failed to download. They have been ignored, or old ones used instead.
when I manually try to enter the site's repository I found that
All links to XENIAL drivers are down, actually the whole Xenial
Folder is missing.
Also then thought it was a good idea to ignore this message, but I
Need the Epwoka driver to run Epson scanners in Ubuntu, and that
a whole problem by itself. Aside from that, is not known if Epson
Perfection V600 is going to be possible to be controlled by the
PyInsane lib, since is marked as untested.
Using Windows
I thought in buying an USB hub and to controlled as shown in this thread, but apparently is not possible in windows.
I already installed libsub, usb.util, libusb1,USB (for the core functions) and usb1, but I don't know (I think is not possible) to disable and re-enable a specific USB port with them.
Can't disable the drivers since that mean all USB will be down to connect with the scanners.
Device manager is not helping, because of the inability of telling which device is which.
Cannot change the name of the scanner (yes, printers can have specific names) but scanners can't.
Can't buy another scanner, I'm stuck with Epson.
My code for Scanning
import pyinsane2
def Scan(Device, dpi):
pyinsane2.init()
try:
pyinsane2.set_scanner_opt(Device, 'resolution', [dpi])
pyinsane2.set_scanner_opt(Device, 'mode', ['Color'])
pyinsane2.maximize_scan_area(Device)
scan_session = Device.scan(multiple=False)
try:
while True:
scan_session.scan.read()
except EOFError:
pass
Image = scan_session.images[-1]
finally:
pyinsane2.exit()
return(Image)
devices = pyinsane2.get_devices()
image_a = Scan(devices[0], 75)
image_b = Scan(devices[1], 75)
a = devices[1]
b = devices[0]
a == b #Different
a.dev_type == b.dev_type
a.model == b.model
a.name == b.name #Different
a.nice_name == b.nice_name
a.options == b.options
a.reload_options == b.reload_options #Different
a.scan == b.scan #Different
a.srcs == b.srcs #Different
a.vendor == b.vendor
I put a sticki note inside each Scanner, one with an "a" the other one with a "b" and it always scans with the scanner that I plugged in first
This is what I would like to do (and doing it manually works): .
This is what I get when trying in python:
Any solution will help me, get creative! I was thinking on using a .bat file to disable an specific port and calling it with Python. But I couldn't find a way to make it.Keep in mind that doing it manually is not an option 'cause of the 20 to 40 hours of continuous image acquisition.
Thanks!
~Diego

usb automatic detection in python for linux env

I'm using polling command(glob('/dev/tty[A-Za-z]*')) in python to detect usb devices connected to my linux pc in regular interval for my application. Is there any way to detect usb devices connected automatically?
Here is a start. You can find your usb vendor here. You got to code yourself a current_list_usb, set a time interval to check so you can compare and see if a new device is attached or not. Some code to use when importing usb module:
import usb, usb.core, usb.util, usb.backend.libusb1
...snippet...
# usb.core.find()
# find our device
dev = usb.core.find(idVendor= ...., idProduct= ....)
#dev_1 = usb.util.find_descriptor(cfg, find_all =True)
# was it found?
if dev is None:
raise ValueError('Device not found')
#x = dev.set_configuration()
#print (dev)
#print (help(usb.core))
if usb.core.find(find_all=True, bDeviceClass=7) is None:
raise ValueError('No printer found')
The normal way to do this is to make a udev rule that tells your program a new tty exists.
A custom udev rule may look something like this(let's call it /etc/udev/rules.d/50-custom-tty.rules:
KERNEL=="ttyUSB[0-9]+", RUN+="/usr/bin/my-program"
Here's a good guide on writing udev rules.
In this case, the program /usr/bin/my-program will run whenever a new ttyUSB device is created in /dev; udev will set a bunch of environment variables to tell you exactly what was just plugged in. You can then notify your main program that a new ttyUSB exists, and it should use it. Note that whatever program you run should be small, as otherwise the udev daemon will kill it if it takes too long.
I'd suggest using libudev and creating a udev monitor object to detect hotplugged devices. Here is a starting point for you to learn about libudev and its monitor feature:
https://www.freedesktop.org/software/systemd/man/libudev.html
There might be a good Python library already that wraps udev so you can use its features without writing C code.

Python pyserial - how can I determine the number of serial ports?

I would like to determine the number of available serial ports, including those provided by USB adapters, under both Linux and windows without having to adapt the program for specific platforms.
I seem to be chasing my tail at the moment and would appreciate another angle on this.
Using pyserial is easy enough on either platform for using the ports, but how do you find out how many ports are available?
Does the example not work for you:
http://pyserial.svn.sourceforge.net/viewvc/checkout/pyserial/trunk/pyserial/examples/scan.py
It is a bit brute force (it just tries to connect to every port and ones that throw an exception are ignored as not present).

Categories