Skip to content

Commit 8148a85

Browse files
committed
Signed v1.0.6
1 parent 07f3f39 commit 8148a85

File tree

10 files changed

+339
-40
lines changed

10 files changed

+339
-40
lines changed

DNS Easy Switcher.xcodeproj/project.pbxproj

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -307,7 +307,7 @@
307307
CODE_SIGN_IDENTITY = "Apple Development";
308308
CODE_SIGN_STYLE = Automatic;
309309
COMBINE_HIDPI_IMAGES = YES;
310-
CURRENT_PROJECT_VERSION = 6;
310+
CURRENT_PROJECT_VERSION = 7;
311311
DEVELOPMENT_ASSET_PATHS = "\"DNS Easy Switcher/Preview Content\"";
312312
DEVELOPMENT_TEAM = 6645MJMX63;
313313
ENABLE_HARDENED_RUNTIME = YES;
@@ -321,7 +321,7 @@
321321
"@executable_path/../Frameworks",
322322
);
323323
MACOSX_DEPLOYMENT_TARGET = 14.0;
324-
MARKETING_VERSION = 1.0.5;
324+
MARKETING_VERSION = 1.0.6;
325325
PRODUCT_BUNDLE_IDENTIFIER = com.linfordsoftware.dnseasyswitcher;
326326
PRODUCT_NAME = "$(TARGET_NAME)";
327327
PROVISIONING_PROFILE_SPECIFIER = "";
@@ -340,7 +340,7 @@
340340
CODE_SIGN_IDENTITY = "Apple Development";
341341
CODE_SIGN_STYLE = Automatic;
342342
COMBINE_HIDPI_IMAGES = YES;
343-
CURRENT_PROJECT_VERSION = 6;
343+
CURRENT_PROJECT_VERSION = 7;
344344
DEVELOPMENT_ASSET_PATHS = "\"DNS Easy Switcher/Preview Content\"";
345345
DEVELOPMENT_TEAM = 6645MJMX63;
346346
ENABLE_HARDENED_RUNTIME = YES;
@@ -354,7 +354,7 @@
354354
"@executable_path/../Frameworks",
355355
);
356356
MACOSX_DEPLOYMENT_TARGET = 14.0;
357-
MARKETING_VERSION = 1.0.5;
357+
MARKETING_VERSION = 1.0.6;
358358
PRODUCT_BUNDLE_IDENTIFIER = com.linfordsoftware.dnseasyswitcher;
359359
PRODUCT_NAME = "$(TARGET_NAME)";
360360
PROVISIONING_PROFILE_SPECIFIER = "";

DNS Easy Switcher/DNSManager.swift

Lines changed: 141 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -185,21 +185,154 @@ class DNSManager {
185185
return
186186
}
187187

188-
// Format DNS servers with port if specified
189-
let formattedPrimary = formatDNSWithPort(primary)
190-
let formattedSecondary = secondary.isEmpty ? "" : formatDNSWithPort(secondary)
188+
// Check if primary or secondary contains a port specification
189+
let primaryHasPort = primary.contains(":")
190+
let secondaryHasPort = !secondary.isEmpty && secondary.contains(":")
191191

192+
// If no custom ports are specified, use the standard network setup method
193+
if !primaryHasPort && !secondaryHasPort {
194+
// Standard DNS servers without ports
195+
var servers = [primary]
196+
if !secondary.isEmpty {
197+
servers.append(secondary)
198+
}
199+
200+
setStandardDNS(services: services, servers: servers, completion: completion)
201+
return
202+
}
203+
204+
// For DNS servers with custom ports, we need to modify the resolver configuration
205+
let resolverContent = createResolverContent(primary, secondary)
206+
207+
// We'll use the existing executeWithAuthentication method which properly handles
208+
// authentication with Touch ID or admin password
209+
let createDirCmd = "sudo mkdir -p /etc/resolver"
210+
executeWithAuthentication(command: createDirCmd) { dirSuccess in
211+
if !dirSuccess {
212+
print("Failed to create resolver directory")
213+
completion(false)
214+
return
215+
}
216+
217+
// Now write the resolver content
218+
let writeFileCmd = "echo '\(resolverContent)' | sudo tee /etc/resolver/custom > /dev/null"
219+
self.executeWithAuthentication(command: writeFileCmd) { fileSuccess in
220+
if !fileSuccess {
221+
print("Failed to write resolver configuration")
222+
completion(false)
223+
return
224+
}
225+
226+
// Set permissions
227+
let permCmd = "sudo chmod 644 /etc/resolver/custom"
228+
self.executeWithAuthentication(command: permCmd) { permSuccess in
229+
if !permSuccess {
230+
print("Failed to set resolver file permissions")
231+
completion(false)
232+
return
233+
}
234+
235+
// Also set standard DNS servers to ensure proper resolution
236+
let standardServers = self.formatDNSWithoutPorts(primary, secondary)
237+
self.setStandardDNS(services: services, servers: standardServers, completion: completion)
238+
}
239+
}
240+
}
241+
}
242+
243+
private func createResolverContent(_ primary: String, _ secondary: String) -> String {
244+
var resolverContent = "# Custom DNS configuration with port\n"
245+
246+
// Add nameserver entries with port specification
247+
if primary.contains(":") {
248+
let components = primary.components(separatedBy: ":")
249+
if components.count == 2, let port = Int(components[1]) {
250+
resolverContent += "nameserver \(components[0])\n"
251+
resolverContent += "port \(port)\n"
252+
}
253+
} else {
254+
resolverContent += "nameserver \(primary)\n"
255+
}
256+
257+
if !secondary.isEmpty {
258+
if secondary.contains(":") {
259+
let components = secondary.components(separatedBy: ":")
260+
if components.count == 2, let port = Int(components[1]) {
261+
resolverContent += "nameserver \(components[0])\n"
262+
resolverContent += "port \(port)\n"
263+
}
264+
} else {
265+
resolverContent += "nameserver \(secondary)\n"
266+
}
267+
}
268+
269+
return resolverContent
270+
}
271+
272+
func disableDNS(completion: @escaping (Bool) -> Void) {
273+
let services = findActiveServices()
274+
guard !services.isEmpty else {
275+
completion(false)
276+
return
277+
}
278+
279+
// Remove any custom resolver configuration
280+
let removeResolverCmd = "sudo rm -f /etc/resolver/custom"
281+
282+
executeWithAuthentication(command: removeResolverCmd) { _ in
283+
// Continue with normal DNS reset regardless of resolver removal success
284+
let dispatchGroup = DispatchGroup()
285+
var allSucceeded = true
286+
287+
for service in services {
288+
dispatchGroup.enter()
289+
290+
let command = "/usr/sbin/networksetup -setdnsservers '\(service)' empty"
291+
292+
self.executeWithAuthentication(command: command) { success in
293+
if !success {
294+
allSucceeded = false
295+
}
296+
dispatchGroup.leave()
297+
}
298+
}
299+
300+
dispatchGroup.notify(queue: .main) {
301+
completion(allSucceeded)
302+
}
303+
}
304+
}
305+
306+
// Helper method to get DNS addresses without port specifications
307+
private func formatDNSWithoutPorts(_ primary: String, _ secondary: String) -> [String] {
308+
var servers: [String] = []
309+
310+
// Extract IP address without port
311+
if primary.contains(":") {
312+
servers.append(primary.components(separatedBy: ":")[0])
313+
} else {
314+
servers.append(primary)
315+
}
316+
317+
if !secondary.isEmpty {
318+
if secondary.contains(":") {
319+
servers.append(secondary.components(separatedBy: ":")[0])
320+
} else {
321+
servers.append(secondary)
322+
}
323+
}
324+
325+
return servers
326+
}
327+
328+
// Helper method to set standard DNS settings
329+
private func setStandardDNS(services: [String], servers: [String], completion: @escaping (Bool) -> Void) {
192330
let dispatchGroup = DispatchGroup()
193331
var allSucceeded = true
194332

195333
for service in services {
196334
dispatchGroup.enter()
197335

198-
var servers = [formattedPrimary]
199-
if !formattedSecondary.isEmpty {
200-
servers.append(formattedSecondary)
201-
}
202-
203336
let dnsArgs = servers.joined(separator: " ")
204337
let dnsCommand = "/usr/sbin/networksetup -setdnsservers '\(service)' \(dnsArgs)"
205338
let ipv6Command = "/usr/sbin/networksetup -setv6off '\(service)'; /usr/sbin/networksetup -setv6automatic '\(service)'"
@@ -235,34 +368,6 @@ class DNSManager {
235368
return dnsServer
236369
}
237370

238-
func disableDNS(completion: @escaping (Bool) -> Void) {
239-
let services = findActiveServices()
240-
guard !services.isEmpty else {
241-
completion(false)
242-
return
243-
}
244-
245-
let dispatchGroup = DispatchGroup()
246-
var allSucceeded = true
247-
248-
for service in services {
249-
dispatchGroup.enter()
250-
251-
let command = "/usr/sbin/networksetup -setdnsservers '\(service)' empty"
252-
253-
executeWithAuthentication(command: command) { success in
254-
if !success {
255-
allSucceeded = false
256-
}
257-
dispatchGroup.leave()
258-
}
259-
}
260-
261-
dispatchGroup.notify(queue: .main) {
262-
completion(allSucceeded)
263-
}
264-
}
265-
266371
private func executePrivilegedCommand(arguments: [String]) -> Bool {
267372
let services = findActiveServices()
268373
guard !services.isEmpty else { return false }
Binary file not shown.
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3+
<plist version="1.0">
4+
<dict>
5+
<key>BuildMachineOSBuild</key>
6+
<string>23F79</string>
7+
<key>CFBundleDevelopmentRegion</key>
8+
<string>en</string>
9+
<key>CFBundleDisplayName</key>
10+
<string>DNS Easy Switcher</string>
11+
<key>CFBundleExecutable</key>
12+
<string>DNS Easy Switcher</string>
13+
<key>CFBundleIconFile</key>
14+
<string>AppIcon</string>
15+
<key>CFBundleIconName</key>
16+
<string>AppIcon</string>
17+
<key>CFBundleIdentifier</key>
18+
<string>com.linfordsoftware.dnseasyswitcher</string>
19+
<key>CFBundleInfoDictionaryVersion</key>
20+
<string>6.0</string>
21+
<key>CFBundleName</key>
22+
<string>DNS Easy Switcher</string>
23+
<key>CFBundlePackageType</key>
24+
<string>APPL</string>
25+
<key>CFBundleShortVersionString</key>
26+
<string>1.0.5</string>
27+
<key>CFBundleSupportedPlatforms</key>
28+
<array>
29+
<string>MacOSX</string>
30+
</array>
31+
<key>CFBundleVersion</key>
32+
<string>7</string>
33+
<key>DTCompiler</key>
34+
<string>com.apple.compilers.llvm.clang.1_0</string>
35+
<key>DTPlatformBuild</key>
36+
<string></string>
37+
<key>DTPlatformName</key>
38+
<string>macosx</string>
39+
<key>DTPlatformVersion</key>
40+
<string>14.0</string>
41+
<key>DTSDKBuild</key>
42+
<string>23A334</string>
43+
<key>DTSDKName</key>
44+
<string>macosx14.0</string>
45+
<key>DTXcode</key>
46+
<string>1501</string>
47+
<key>DTXcodeBuild</key>
48+
<string>15A507</string>
49+
<key>LSApplicationCategoryType</key>
50+
<string>public.app-category.utilities</string>
51+
<key>LSMinimumSystemVersion</key>
52+
<string>14.0</string>
53+
</dict>
54+
</plist>
Binary file not shown.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
APPL????
Binary file not shown.
Binary file not shown.

0 commit comments

Comments
 (0)