added login and permission fix

This commit is contained in:
duffyduck 2026-02-18 23:59:16 +01:00
parent 6172d9e2aa
commit 3579924883
5 changed files with 60 additions and 35 deletions

Binary file not shown.

Binary file not shown.

View File

@ -7,6 +7,7 @@ import (
"log" "log"
"os" "os"
"path/filepath" "path/filepath"
"strings"
"time" "time"
"golang.org/x/sys/unix" "golang.org/x/sys/unix"
@ -35,48 +36,58 @@ func fdToFile(fd int, name string) *os.File {
// VHCI-created devices don't get normal udev rules applied, so they // VHCI-created devices don't get normal udev rules applied, so they
// default to root-only access. // default to root-only access.
func fixVHCIDevicePermissions(port int) { func fixVHCIDevicePermissions(port int) {
// Wait for the device to finish enumerating and create device nodes // Wait for the device to finish enumerating and create device nodes.
// The kernel needs time to enumerate descriptors and bind drivers // The kernel needs time to enumerate descriptors and bind drivers.
for attempt := 0; attempt < 10; attempt++ { for attempt := 0; attempt < 15; attempt++ {
time.Sleep(500 * time.Millisecond) time.Sleep(500 * time.Millisecond)
// Find device nodes created by this VHCI port found := false
// VHCI creates devices under /sys/devices/platform/vhci_hcd.0/usbN/
// We look for video4linux devices // Walk the VHCI sysfs tree to find device nodes at any depth.
matches, _ := filepath.Glob("/sys/devices/platform/vhci_hcd.0/usb*/*/video4linux/video*") // Paths look like: vhci_hcd.0/usb3/3-1/3-1:1.0/video4linux/video0
for _, m := range matches { filepath.WalkDir("/sys/devices/platform/vhci_hcd.0", func(path string, d os.DirEntry, err error) error {
devName := filepath.Base(m) if err != nil {
devPath := "/dev/" + devName return nil
if _, err := os.Stat(devPath); err == nil { }
dir := filepath.Dir(path)
parent := filepath.Base(dir)
// video4linux devices → /dev/videoN
if parent == "video4linux" && strings.HasPrefix(d.Name(), "video") {
devPath := "/dev/" + d.Name()
if err := os.Chmod(devPath, 0666); err == nil {
log.Printf("[use] set permissions 0666 on %s", devPath)
found = true
}
}
// sound devices → /dev/snd/*
if parent == "sound" && strings.HasPrefix(d.Name(), "card") {
// For sound cards, chmod all related device nodes
sndDir := filepath.Join(path, "device")
if _, err := os.Stat(sndDir); err == nil {
filepath.WalkDir("/dev/snd", func(sndPath string, sd os.DirEntry, err error) error {
if err == nil && !sd.IsDir() {
os.Chmod(sndPath, 0666)
}
return nil
})
}
}
// input devices → /dev/input/eventN
if strings.HasPrefix(d.Name(), "event") && strings.Contains(path, "/input/input") {
devPath := "/dev/input/" + d.Name()
if err := os.Chmod(devPath, 0666); err == nil { if err := os.Chmod(devPath, 0666); err == nil {
log.Printf("[use] set permissions 0666 on %s", devPath) log.Printf("[use] set permissions 0666 on %s", devPath)
} }
} }
}
// Also check for other common device types (input, sound, etc.) return nil
for _, subsys := range []string{"sound/card*", "input/input*/event*"} { })
sysMatches, _ := filepath.Glob("/sys/devices/platform/vhci_hcd.0/usb*/*/" + subsys)
for _, m := range sysMatches {
devName := filepath.Base(m)
devPath := "/dev/" + devName
// For sound devices, also check /dev/snd/
if _, err := os.Stat(devPath); err == nil {
os.Chmod(devPath, 0666)
}
devPath = "/dev/snd/" + devName
if _, err := os.Stat(devPath); err == nil {
os.Chmod(devPath, 0666)
}
}
}
if attempt == 0 { if attempt >= 2 && found {
continue // first iteration: always wait more
}
// Check if we found any video devices
if len(matches) > 0 {
return return
} }
} }

View File

@ -272,6 +272,7 @@ func (um *UseManager) tunnelReadLoop(tunnel *useTunnel) {
} }
if err := um.client.SendTunnelData(tunnel.id, buf[:n]); err != nil { if err := um.client.SendTunnelData(tunnel.id, buf[:n]); err != nil {
log.Printf("[use] tunnel send error: %v", err)
return return
} }
} }
@ -326,11 +327,17 @@ func (um *UseManager) handleTunnelData(tunnelID string, data []byte) {
um.mu.RUnlock() um.mu.RUnlock()
if !exists { if !exists {
log.Printf("[use] tunnel data for unknown tunnel %s (%d bytes)", tunnelID[:8], len(data))
return return
} }
// Write to the tunnel socket (relay -> VHCI) // Write to the tunnel socket (relay -> VHCI)
tunnel.conn.Write(data) n, err := tunnel.conn.Write(data)
if err != nil {
log.Printf("[use] tunnel write error: %v", err)
} else if n != len(data) {
log.Printf("[use] tunnel short write: %d/%d", n, len(data))
}
} }
func (um *UseManager) handleClientLeft(msg *protocol.ClientLeft) { func (um *UseManager) handleClientLeft(msg *protocol.ClientLeft) {

View File

@ -421,10 +421,15 @@ func (s *Server) handleCmdSubmit(r io.Reader, hdr *URBHeader, retChan chan<- []b
5000, buf, 5000, buf,
) )
if err != nil { if err != nil {
log.Printf("[usbip-server] CTRL OUT seq=%d failed: %v", hdr.SeqNum, err)
status = -32 // -EPIPE status = -32 // -EPIPE
} else {
log.Printf("[usbip-server] CTRL OUT seq=%d OK (bmReqType=0x%02x bReq=0x%02x wVal=0x%04x)",
hdr.SeqNum, bmRequestType, bRequest, wValue)
} }
} }
log.Printf("[usbip-server] CTRL OUT seq=%d → response status=%d", hdr.SeqNum, status)
resp, err := BuildRetSubmit(hdr.SeqNum, hdr.DevID, hdr.Direction, hdr.Endpoint, status, nil) resp, err := BuildRetSubmit(hdr.SeqNum, hdr.DevID, hdr.Direction, hdr.Endpoint, status, nil)
if err != nil { if err != nil {
return err return err
@ -559,6 +564,8 @@ func (s *Server) handleCmdUnlink(r io.Reader, hdr *URBHeader, retChan chan<- []b
return err return err
} }
log.Printf("[usbip-server] UNLINK seq=%d target_seq=%d", hdr.SeqNum, body.UnlinkSeqNum)
s.mu.Lock() s.mu.Lock()
pending, exists := s.pendingURBs[body.UnlinkSeqNum] pending, exists := s.pendingURBs[body.UnlinkSeqNum]
if exists { if exists {