Forráskód Böngészése

home: remove URI automation scheme

The URL automation scheme has been replaced by AppleScript support. We are
removing it due to potential abuse by attackers to launch a VM from the web
browser without user knowledge.

Resolves #6155
osy 1 éve
szülő
commit
4d88c3535e

+ 0 - 61
Platform/Shared/ContentView.swift

@@ -154,67 +154,6 @@ struct ContentView: View {
             }
             }
         }
         }
     }
     }
-    
-    @MainActor private func handleUTMURL(with components: URLComponents) async throws {
-        func findVM() -> VMData? {
-            if let vmName = components.queryItems?.first(where: { $0.name == "name" })?.value {
-                return data.virtualMachines.first(where: { $0.detailsTitleLabel == vmName })
-            } else {
-                return nil
-            }
-        }
-        
-        if let action = components.host {
-            switch action {
-            case "start":
-                if let vm = findVM(), vm.state == .stopped {
-                    data.run(vm: vm)
-                }
-                break
-            case "stop":
-                if let vm = findVM(), vm.state == .started {
-                    try await vm.wrapped!.stop(usingMethod: .force)
-                    data.stop(vm: vm)
-                }
-                break
-            case "restart":
-                if let vm = findVM(), vm.state == .started {
-                    try await vm.wrapped!.restart()
-                }
-                break
-            case "pause":
-                if let vm = findVM(), vm.state == .started {
-                    let shouldSaveOnPause: Bool
-                    if let vm = vm.wrapped as? (any UTMSpiceVirtualMachine) {
-                        shouldSaveOnPause = !vm.isRunningAsDisposible
-                    } else {
-                        shouldSaveOnPause = true
-                    }
-                    try await vm.wrapped!.pause()
-                    if shouldSaveOnPause {
-                        try? await vm.wrapped!.saveSnapshot(name: nil)
-                    }
-                }
-            case "resume":
-                if let vm = findVM(), vm.state == .paused {
-                    try await vm.wrapped!.resume()
-                }
-                break
-            case "sendText":
-                if let vm = findVM(), vm.state == .started {
-                    data.automationSendText(to: vm, urlComponents: components)
-                }
-                break
-            case "click":
-                if let vm = findVM(), vm.state == .started {
-                    data.automationSendMouse(to: vm, urlComponents: components)
-                }
-                break
-            default:
-                return
-            }
-        }
-    }
 }
 }
 
 
 extension ContentView: DropDelegate {
 extension ContentView: DropDelegate {

+ 0 - 63
Platform/UTMData.swift

@@ -901,69 +901,6 @@ struct AlertMessage: Identifiable {
             }
             }
         }
         }
     }
     }
-    
-    // MARK: - Automation Features
-    
-    /// Send text as keyboard input to VM
-    /// - Parameters:
-    ///   - vm: VM to send text to
-    ///   - components: Data (see UTM Wiki for details)
-    func automationSendText(to vm: VMData, urlComponents components: URLComponents) {
-        guard let queryItems = components.queryItems else { return }
-        guard let text = queryItems.first(where: { $0.name == "text" })?.value else { return }
-        #if os(macOS)
-        trySendTextSpice(vm: vm, text: text)
-        #else
-        trySendTextSpice(text)
-        #endif
-    }
-    
-    /// Send mouse/tablet coordinates to VM
-    /// - Parameters:
-    ///   - vm: VM to send mouse/tablet coordinates to
-    ///   - components: Data (see UTM Wiki for details)
-    func automationSendMouse(to vm: VMData, urlComponents components: URLComponents) {
-        guard let qemuVm = vm.wrapped as? any UTMSpiceVirtualMachine else { return } // FIXME: implement for Apple VM
-        guard !qemuVm.config.displays.isEmpty else { return }
-        guard let queryItems = components.queryItems else { return }
-        /// Parse targeted position
-        var x: CGFloat? = nil
-        var y: CGFloat? = nil
-        let nf = NumberFormatter()
-        nf.allowsFloats = false
-        if let xStr = components.queryItems?.first(where: { item in
-            item.name == "x"
-        })?.value {
-            x = nf.number(from: xStr) as? CGFloat
-        }
-        if let yStr = components.queryItems?.first(where: { item in
-            item.name == "y"
-        })?.value {
-            y = nf.number(from: yStr) as? CGFloat
-        }
-        guard let xPos = x, let yPos = y else { return }
-        let point = CGPoint(x: xPos, y: yPos)
-        /// Parse which button should be clicked
-        var button: CSInputButton = .left
-        if let buttonStr = queryItems.first(where: { $0.name == "button"})?.value {
-            switch buttonStr {
-            case "middle":
-                button = .middle
-                break
-            case "right":
-                button = .right
-                break
-            default:
-                break
-            }
-        }
-        /// All parameters parsed, perform the click
-        #if os(macOS)
-        tryClickAtPoint(vm: vm, point: point, button: button)
-        #else
-        tryClickAtPoint(point: point, button: button)
-        #endif
-    }
 
 
     // MARK: - AltKit
     // MARK: - AltKit
     
     

+ 0 - 19
Platform/iOS/UTMDataExtension.swift

@@ -51,23 +51,4 @@ extension UTMData {
     func close(vm: VMData) {
     func close(vm: VMData) {
         // do nothing
         // do nothing
     }
     }
-    
-    func tryClickAtPoint(point: CGPoint, button: CSInputButton) {
-        if let vc = vmVC as? VMDisplayMetalViewController, let input = vc.vmInput {
-            input.sendMouseButton(button, pressed: true)
-            DispatchQueue.main.asyncAfter(deadline: .now() + 0.02) {
-                input.sendMouseButton(button, pressed: false)
-            }
-        }
-    }
-    
-    func trySendTextSpice(_ text: String) {
-        if let vc = vmVC as? VMDisplayMetalViewController {
-            #if !os(visionOS) // FIXME: broken in visionOS
-            vc.keyboardView.insertText(text)
-            #endif
-        } else if let vc = vmVC as? VMDisplayTerminalViewController {
-            vc.vmSerialPort.write(text.data(using: .nonLossyASCII)!)
-        }
-    }
 }
 }

+ 0 - 107
Platform/macOS/UTMDataExtension.swift

@@ -129,111 +129,4 @@ extension UTMData {
             }
             }
         }
         }
     }
     }
-    
-    func trySendTextSpice(vm: VMData, text: String) {
-        guard text.count > 0 else { return }
-        if let vc = vmWindows[vm] as? VMDisplayQemuMetalWindowController {
-            KeyCodeMap.createKeyMapIfNeeded()
-            
-            func sleep() {
-                Thread.sleep(forTimeInterval: 0.05)
-            }
-            func keyDown(keyCode: Int) {
-                if let scanCodes = KeyCodeMap.keyCodeToScanCodes[keyCode] {
-                    vc.keyDown(scanCode: Int(scanCodes.down))
-                    sleep()
-                }
-            }
-            func keyUp(keyCode: Int) {
-                /// Due to how Spice works we need to send keyUp for the .down scan code
-                /// instead of sending the key down for the scan code that indicates key up.
-                if let scanCodes = KeyCodeMap.keyCodeToScanCodes[keyCode] {
-                    vc.keyUp(scanCode: Int(scanCodes.down))
-                    sleep()
-                }
-            }
-            func press(keyCode: Int) {
-                keyDown(keyCode: keyCode)
-                keyUp(keyCode: keyCode)
-            }
-            
-            func simulateKeyPress(_ keyCodeDict: [String: Int]) {
-                /// Press modifier keys if necessary
-                let optionUsed = keyCodeDict["option"] == 1
-                if optionUsed {
-                    keyDown(keyCode: kVK_Option)
-                    sleep()
-                }
-                let shiftUsed = keyCodeDict["shift"] == 1
-                if shiftUsed {
-                    keyDown(keyCode: kVK_Shift)
-                    sleep()
-                }
-                let fnUsed = keyCodeDict["function"] == 1
-                if fnUsed {
-                    keyDown(keyCode: kVK_Function)
-                    sleep()
-                }
-                let ctrlUsed = keyCodeDict["control"] == 1
-                if ctrlUsed {
-                    keyDown(keyCode: kVK_Control)
-                    sleep()
-                }
-                let cmdUsed = keyCodeDict["command"] == 1
-                if cmdUsed {
-                    keyDown(keyCode: kVK_Command)
-                    sleep()
-                }
-                /// Press the key now
-                let keyCode = keyCodeDict["virtKeyCode"]!
-                press(keyCode: keyCode)
-                /// Release modifiers
-                if optionUsed {
-                    keyUp(keyCode: kVK_Option)
-                    sleep()
-                }
-                if shiftUsed {
-                    keyUp(keyCode: kVK_Shift)
-                    sleep()
-                }
-                if fnUsed {
-                    keyUp(keyCode: kVK_Function)
-                    sleep()
-                }
-                if ctrlUsed {
-                    keyUp(keyCode: kVK_Control)
-                    sleep()
-                }
-                if cmdUsed {
-                    keyUp(keyCode: kVK_Command)
-                    sleep()
-                }
-            }
-            DispatchQueue.global(qos: .userInitiated).async {
-                text.enumerated().forEach { stringItem in
-                    let char = stringItem.element
-                    /// drop unknown chars
-                    if let keyCodeDict = KeyCodeMap.characterToKeyCode(character: char) {
-                        simulateKeyPress(keyCodeDict)
-                    } else {
-                        logger.warning("SendText dropping unknown char: \(char)")
-                    }
-                }
-            }
-        } else if let terminal = vmWindows[vm] as? VMDisplayTerminal {
-            terminal.sendString(text)
-        }
-    }
-    
-    func tryClickAtPoint(vm: VMData, point: CGPoint, button: CSInputButton) {
-        if let vc = vmWindows[vm] as? VMDisplayQemuMetalWindowController {
-            vc.mouseMove(absolutePoint: point, button: [])
-            DispatchQueue.main.asyncAfter(deadline: .now() + 0.02) {
-                vc.mouseDown(button: button)
-                DispatchQueue.main.asyncAfter(deadline: .now() + 0.02) {
-                    vc.mouseUp(button: button)
-                }
-            }
-        }
-    }
 }
 }