Forum: PC Hard- und Software usb-Zugriff uner python geht ncht wie erwartet


von R. F. (rfr)


Lesenswert?

Beim Zugriff auf das (angeschlossene) usb-device erhalte ich folgende 
Fehlermeldung:
----------------------------------------
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File 
"/usr/lib/python2.7/dist-packages/spyderlib/widgets/externalshell/sitecu 
stomize.py",  line 540, in runfile
    execfile(filename, namespace)
  File "/home/rfr/workspace/python/testUSBaccess.py", line 9, in 
<module>
    raise ValueError('Device not found')
ValueError: Device not found
>>> runfile('/home/rfr/workspace/python/testUSBaccess.py', 
wdir=r'/home/rfr/workspace/python')
DEVICE ID 173a:2198 on Bus 002 Address 011 =================
 bLength                :   0x12 (18 bytes)
 bDescriptorType        :    0x1 Device
 bcdUSB                 :  0x200 USB 2.0
 bDeviceClass           :    0x0 Specified at interface
 bDeviceSubClass        :    0x0
 bDeviceProtocol        :    0x0
 bMaxPacketSize0        :   0x20 (32 bytes)
 idVendor               : 0x173a
 idProduct              : 0x2198
 bcdDevice              :  0x100 Device 1.0
 iManufacturer          :    0x1 Error Accessing String
 iProduct               :    0x2 Error Accessing String
 iSerialNumber          :    0x3 Error Accessing String
 bNumConfigurations     :    0x1
  CONFIGURATION 1: 102 mA ==================================
   bLength              :    0x9 (9 bytes)
   bDescriptorType      :    0x2 Configuration
   wTotalLength         :   0x20 (32 bytes)
   bNumInterfaces       :    0x1
   bConfigurationValue  :    0x1
   iConfiguration       :    0x0
   bmAttributes         :   0x80 Bus Powered
   bMaxPower            :   0x33 (102 mA)
    INTERFACE 0: Mass Storage ==============================
     bLength            :    0x9 (9 bytes)
     bDescriptorType    :    0x4 Interface
     bInterfaceNumber   :    0x0
     bAlternateSetting  :    0x0
     bNumEndpoints      :    0x2
     bInterfaceClass    :    0x8 Mass Storage
     bInterfaceSubClass :    0x6
     bInterfaceProtocol :   0x50
     iInterface         :    0x0
      ENDPOINT 0x81: Bulk IN ===============================
       bLength          :    0x7 (7 bytes)
       bDescriptorType  :    0x5 Endpoint
       bEndpointAddress :   0x81 IN
       bmAttributes     :    0x2 Bulk
       wMaxPacketSize   :   0x40 (64 bytes)
       bInterval        :    0x0
      ENDPOINT 0x2: Bulk OUT ===============================
       bLength          :    0x7 (7 bytes)
       bDescriptorType  :    0x5 Endpoint
       bEndpointAddress :    0x2 OUT
       bmAttributes     :    0x2 Bulk
       wMaxPacketSize   :   0x40 (64 bytes)
       bInterval        :    0x0
EINS
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File 
"/usr/lib/python2.7/dist-packages/spyderlib/widgets/externalshell/sitecu 
stomize.py",  line 540, in runfile
    execfile(filename, namespace)
  File "/home/rfr/workspace/python/testUSBaccess.py", line 13, in 
<module>
    dev.set_configuration()
  File "/usr/local/lib/python2.7/dist-packages/usb/core.py", line 799, 
in set_configuration
    self._ctx.managed_set_configuration(self, configuration)
  File "/usr/local/lib/python2.7/dist-packages/usb/core.py", line 127, 
in managed_set_configuration
    self.managed_open()
  File "/usr/local/lib/python2.7/dist-packages/usb/core.py", line 105, 
in managed_open
    self.handle = self.backend.open_device(self.dev)
  File "/usr/local/lib/python2.7/dist-packages/usb/backend/libusb1.py", 
line 722, in open_device
    return _DeviceHandle(dev)
  File "/usr/local/lib/python2.7/dist-packages/usb/backend/libusb1.py", 
line 600, in _init_
    _check(_lib.libusb_open(self.devid, byref(self.handle)))
  File "/usr/local/lib/python2.7/dist-packages/usb/backend/libusb1.py", 
line 552, in _check
    raise USBError(_strerror(ret), ret, _libusb_errno[ret])
usb.core.USBError: [Errno 13] Access denied (insufficient permissions)
>>>
-----------------------------------
den folgende Source produziert:
_--------------------------
import usb.core
import usb.util

# find our device
dev = usb.core.find(idVendor=0x173a, idProduct=0x2198)
print dev
# was it found?
if dev is None:
    raise ValueError('Device not found')
print 'EINS'
# set the active configuration. With no arguments, the first
# configuration will be the active one
dev.set_configuration()

# get an endpoint instance
cfg = dev.get_active_configuration()
intf = cfg[(0,0)]

ep = usb.util.find_descriptor(
    intf,
    # match the first OUT endpoint
    custom_match = \
    lambda e: \
        usb.util.endpoint_direction(e.bEndpointAddress) == \
        usb.util.ENDPOINT_OUT)

assert ep is not None

# write the data
ep.write('test')
------------------------------------
Dazu folgende Fragen:

wie kann ich das Programm so schreiben, dass verschiedene IdVendors und 
IdProduct numbers erkannt werden können?

Was genau sagt mir die Fehlermeldung?

Grüsse

Robert

von Lukey S. (lukey3332)


Lesenswert?

>usb.core.USBError: [Errno 13] Access denied (insufficient permissions)

->Programm als root ausführen.

: Bearbeitet durch User
von Kaj (Gast)


Lesenswert?

R. F. schrieb:
> Was genau sagt mir die Fehlermeldung?

Einfach mal lesen...
> [Errno 13] Access denied (insufficient permissions)

Ganz nebenbei wuerd ich das Programm gleich so schreiben, dass es auch 
zu Python 3 kompatible ist. Gleich richtig machen erspart spaeter viel 
arbeit.

von Bernd K. (prof7bit)


Lesenswert?

Lukas S. schrieb:
>>usb.core.USBError: [Errno 13] Access denied (insufficient
> permissions)
>
> ->Programm als root ausführen.

Nein, das war noch nie die richtige Antwort. Stattdessen löst man das 
ganz einfach indem man die Rechte bedarfsgerecht vergibt.

von Lukas Straub (Gast)


Lesenswert?

>Nein, das war noch nie die richtige Antwort. Stattdessen löst man das
>ganz einfach indem man die Rechte bedarfsgerecht vergibt.
Oder nach öffnen des File Descriptors Privilegien droppen und sich am 
besten noch mit chroot() zusätzlich absichern  - wenn mans richtig 
machen will. :D

von Norbert (Gast)


Lesenswert?

Lukas Straub schrieb:
>>Nein, das war noch nie die richtige Antwort. Stattdessen löst man das
>>ganz einfach indem man die Rechte bedarfsgerecht vergibt.
> Oder nach öffnen des File Descriptors Privilegien droppen und sich am
> besten noch mit chroot() zusätzlich absichern  - wenn mans richtig
> machen will. :D

Genau, allen Menschen den Generalschlüssel zur Bundesbank geben und sie 
bitten kurz nach dem Betreten der Bank den Schlüssel abzugeben und nicht 
zum Tresoröffnen zu nutzen.

von Lukey S. (lukey3332)


Lesenswert?

Norbert schrieb:
> Lukas Straub schrieb:
>>>Nein, das war noch nie die richtige Antwort. Stattdessen löst man das
>>>ganz einfach indem man die Rechte bedarfsgerecht vergibt.
>> Oder nach öffnen des File Descriptors Privilegien droppen und sich am
>> besten noch mit chroot() zusätzlich absichern  - wenn mans richtig
>> machen will. :D
>
> Genau, allen Menschen den Generalschlüssel zur Bundesbank geben und sie
> bitten kurz nach dem Betreten der Bank den Schlüssel abzugeben und nicht
> zum Tresoröffnen zu nutzen.

Bei UNIX ist das so gang und gäbe und man kann sich sicher sein, dass es 
überall funktioniert.

von Norbert (Gast)


Lesenswert?

Lukas S. schrieb:

> Bei UNIX ist das so gang und gäbe und man kann sich sicher sein, dass es
> überall funktioniert.

Nein, das ist es nicht. Sonst müssten alle Programme die derart 
geschrieben wurden mit dem setuid Bit versehen werden und root gehören.
Das geht schon mal (dem Herrn sein Dank) mit scripts nicht.
1
#!/usr/bin/env python3
2
import os
3
4
print(os.getuid())
5
print(os.geteuid())
6
print(os.getresuid())
7
~
8
~
1
norbert@Entwicklung:/tmp$ l x.py 
2
-rwsr-xr-x 1 root root 99 Jan  8 20:12 x.py
3
norbert@Entwicklung:/tmp$ ./x.py 
4
1000
5
1000
6
(1000, 1000, 1000)
7
norbert@Entwicklung:/tmp$

Wie man sieht wird das 's' von '-rwsr-xr-x' freundlicherweise ignoriert 
und ich habe bei Programmausführung weiterhin meine Rechte und nicht 
root-Rechte.

Schreibt man das Gleiche zB. in C, dann geht es natürlich (ist aber 
schmutzig weil unnötig).

Also, auf unixoiden Systemen versucht man die Anzahl der SUID Programme 
so gering wie möglich zu halten.

Daemons geben selbstverständlich alle Rechte die sie nicht benötigen ab 
oder laufen in einem speziellen Kontext.

Dementsprechend nicht maximale Rechte vergeben und hoffen,
sondern nur minimal nötige Rechte und entspannt zurücklehnen.

von R. F. (rfr)


Lesenswert?

Also, ich will auf den Bus zugreifen. Wie stelle ich die Rechte richtig 
ein, und wie ermittlele ich, welche Rechte ich brauche?

Grüsse

Robert

von Detlef G. (legospieler)


Lesenswert?

Hallo Robert,

sobald du mit einem USB-Gerät kommunizieren willst, sind 
Schreib-/Leserechte erforderlich. Lege eine udev-Regel an, die die 
Rechte entsprechend einstellt.

1. Im Ordner /etc/udev/rules.d eine Textdatei z.B. 99-local.rules 
anlegen und folgende Regel hineinschreiben:
1
ACTION=="add", SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ATTR{idVendor}=="173a", ATTR{idProduct}=="2198", RUN{builtin}+="uaccess"

2. Konfiguration vom udev-Dienst neu lesen lassen:
1
 udevadm control -R
 aus.

3. Das USB-Gerät trennen und wieder verbinden.

Dann sollte dein Script auch ohne root-Rechte laufen.

Falls nicht, kannst du mit
1
 udevadm monitor -u
 die Aktionen anzeigen lassen, während das Gerät wieder verbunden wird. 
Es sollte dann sichtbar sein, dass "uaccess" gesetzt wird.


Viel Spaß,
Detlef

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.