Skip to content

Commit

Permalink
Initial implementation of TunnelVision exploit detection
Browse files Browse the repository at this point in the history
  • Loading branch information
diegoreymendez committed Oct 15, 2024
1 parent f9fbb59 commit 34599ae
Show file tree
Hide file tree
Showing 6 changed files with 108 additions and 1 deletion.
1 change: 1 addition & 0 deletions DuckDuckGoVPN/DuckDuckGoVPNAppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import PixelKit
import Subscription
import VPNAppLauncher
import os.log
import SystemConfiguration

@objc(Application)
final class DuckDuckGoVPNApplication: NSApplication {
Expand Down
13 changes: 12 additions & 1 deletion LocalPackages/NetworkProtectionMac/Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ let package = Package(
.library(name: "NetworkProtectionIPC", targets: ["NetworkProtectionIPC"]),
.library(name: "NetworkProtectionProxy", targets: ["NetworkProtectionProxy"]),
.library(name: "NetworkProtectionUI", targets: ["NetworkProtectionUI"]),
.library(name: "VPNAppLauncher", targets: ["VPNAppLauncher"]),
.library(name: "VPNAppLauncher", targets: ["VPNAppLauncher"])
],
dependencies: [
.package(url: "https://github.com/duckduckgo/BrowserServicesKit", exact: "199.1.0"),
Expand Down Expand Up @@ -96,12 +96,23 @@ let package = Package(
]
),

// MARK: - VPNGuardian

.target(
name: "VPNGuardian",
dependencies: [],
swiftSettings: [
.define("DEBUG", .when(configuration: .debug))
]
),

// MARK: - NetworkProtectionUI

.target(
name: "NetworkProtectionUI",
dependencies: [
"VPNPixels",
"VPNGuardian",
.product(name: "NetworkProtection", package: "BrowserServicesKit"),
.product(name: "PixelKit", package: "BrowserServicesKit"),
.product(name: "SwiftUIExtensions", package: "SwiftUIExtensions"),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import Combine
import Foundation
import NetworkProtection
import SwiftUI
@_implementationOnly import VPNGuardian

@MainActor
public final class TunnelControllerViewModel: ObservableObject {
Expand Down Expand Up @@ -248,6 +249,28 @@ public final class TunnelControllerViewModel: ObservableObject {
}
}

func showAlert() {
let alert = NSAlert()
alert.messageText = "Be Scared"
alert.informativeText = "They're watching you"

// Add "Connect" button
alert.addButton(withTitle: "Connect")

// Add "Disconnect" button
alert.addButton(withTitle: "Disconnect")

// Show the alert as a modal dialog
let response = alert.runModal()

// Handle the user's choice
if response == .alertFirstButtonReturn {
print("Connect tapped")
} else if response == .alertSecondButtonReturn {
print("Disconnect tapped")
}
}

/// Convenience binding to be able to both query and toggle NetP.
///
@MainActor
Expand All @@ -271,6 +294,12 @@ public final class TunnelControllerViewModel: ObservableObject {
self.internalIsRunning = newValue

if newValue {
if let data = VPNGuardian().getDHCPOption121(),
data.count > 0 {

self.showAlert()
}

self.startNetworkProtection()
} else {
self.stopNetworkProtection()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
//
// VPNGuardian.m
// NetworkProtectionMac
//
// Created by ddg on 10/15/24.
//

#import "VPNGuardian.h"
#import "SystemConfiguration/SCDynamicStoreCopyDHCPInfo.h"

@implementation VPNGuardian

- (NSData *)getDHCPOption121 {
SCDynamicStoreRef store = SCDynamicStoreCreate(NULL, CFSTR("DHCPOptionDetector"), NULL, NULL);
if (!store) return nil;

// Create a key pattern to match the relevant network service entity for IPv4 DHCP
CFStringRef dhcpPattern = SCDynamicStoreKeyCreateNetworkServiceEntity(NULL,
kSCDynamicStoreDomainState, // domain = "State:"
kSCCompAnyRegex, // serviceID = "[^/]+" (1 or more non-slash chars)
kSCEntNetDHCP // entity = "DHCP"
);

CFDictionaryRef dhcpInfo = SCDynamicStoreCopyDHCPInfo(store, NULL);
if (!dhcpInfo) {
CFRelease(dhcpPattern);
CFRelease(store);
return nil;
}

CFDataRef optionData = DHCPInfoGetOptionData(dhcpInfo, 121);
NSData *result = nil;

if (optionData) {
CFRetain(optionData);
result = CFBridgingRelease(optionData);
}

CFRelease(dhcpInfo);
CFRelease(dhcpPattern);
CFRelease(store);

return result;
}

@end
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
//
// DHCPOptionDetector.h
// NetworkProtectionMac
//
// Created by ddg on 10/15/24.
//


#import <Foundation/Foundation.h>
#import <SystemConfiguration/SystemConfiguration.h>

@interface VPNGuardian : NSObject

- (nullable NSData *)getDHCPOption121;

@end
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
module VPNGuardian {
header "VPNGuardian.h" // or any other public header you want to expose
export *
}

0 comments on commit 34599ae

Please sign in to comment.