diff --git a/Platform/Shared/ContentView.swift b/Platform/Shared/ContentView.swift index b2c51d84d..62c20ca6d 100644 --- a/Platform/Shared/ContentView.swift +++ b/Platform/Shared/ContentView.swift @@ -36,7 +36,8 @@ struct ContentView: View { @State private var newPopupPresented = false @State private var openSheetPresented = false @Environment(\.openURL) var openURL - + @AppStorage("ServerAutostart") private var isServerAutostart: Bool = false + var body: some View { VMNavigationListView() .overlay(data.showSettingsModal ? AnyView(EmptyView()) : AnyView(BusyOverlay())) @@ -70,6 +71,11 @@ struct ContentView: View { .onAppear { Task { await data.listRefresh() + #if os(macOS) + if isServerAutostart { + await data.remoteServer.start() + } + #endif } Task { await releaseHelper.fetchReleaseNotes() diff --git a/Platform/macOS/SettingsView.swift b/Platform/macOS/SettingsView.swift index 265620aa8..4485a773f 100644 --- a/Platform/macOS/SettingsView.swift +++ b/Platform/macOS/SettingsView.swift @@ -190,6 +190,7 @@ struct ServerSettingsView: View { @AppStorage("ServerAutostart") var isServerAutostart: Bool = false @AppStorage("ServerExternal") var isServerExternal: Bool = false + @AppStorage("ServerAutoblock") var isServerAutoblock: Bool = false @AppStorage("ServerPort") var serverPort: Int = 0 @AppStorage("ServerPasswordRequired") var isServerPasswordRequired: Bool = false @AppStorage("ServerPassword") var serverPassword: String = "" @@ -203,6 +204,8 @@ struct ServerSettingsView: View { Toggle("Automatically start UTM server", isOn: $isServerAutostart) } Section(header: Text("Network")) { + Toggle("Reject unknown connections by default", isOn: $isServerAutoblock) + .help("If checked, you will not be prompted about any unknown connection and they will be rejected.") Toggle("Allow access from external clients", isOn: $isServerExternal) .help("By default, the server is only available on LAN but setting this will use UPnP/NAT-PMP to port forward to WAN.") .onChange(of: isServerExternal) { newValue in diff --git a/Remote/UTMRemoteServer.swift b/Remote/UTMRemoteServer.swift index 5885a4f20..cbfdc5af8 100644 --- a/Remote/UTMRemoteServer.swift +++ b/Remote/UTMRemoteServer.swift @@ -40,6 +40,7 @@ actor UTMRemoteServer { @Setting("ServerAutostart") private var isServerAutostart: Bool = false @Setting("ServerExternal") private var isServerExternal: Bool = false + @Setting("ServerAutoblock") private var isServerAutoblock: Bool = false @Setting("ServerPort") private var serverPort: Int = 0 @Setting("ServerPasswordRequired") private var isServerPasswordRequired: Bool = false @Setting("ServerPassword") private var serverPassword: String = "" @@ -127,7 +128,8 @@ actor UTMRemoteServer { registerNotifications() listener = Task { await withErrorNotification { - for try await connection in Connection.advertise(forServiceType: service, txtRecord: metadata, identity: keyManager.identity) { + let port = serverPort > 0 ? NWEndpoint.Port(integerLiteral: UInt16(serverPort)) : .any + for try await connection in Connection.advertise(on: port, forServiceType: service, txtRecord: metadata, identity: keyManager.identity) { if let connection = try? await Connection(connection: connection) { await newRemoteConnection(connection) } @@ -164,6 +166,9 @@ actor UTMRemoteServer { if await state.isApproved(fingerprint) { await notifyNewConnection(remoteAddress: remoteAddress, fingerprint: fingerprint) await establishConnection(connection) + } else if isServerAutoblock { + await state.block(fingerprint) + connection.close() } else { pendingConnections[fingerprint] = connection await notifyNewConnection(remoteAddress: remoteAddress, fingerprint: fingerprint, isUnknown: true)