Skip to content

Commit da68a0b

Browse files
committed
Include stripped config in debugging bundle
1 parent 8a07e71 commit da68a0b

File tree

5 files changed

+87
-8
lines changed

5 files changed

+87
-8
lines changed

apple/client/DebugBundle.swift

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -109,21 +109,23 @@ private class DebugBundleBuilder {
109109
let bundleTimestamp = Date()
110110
let jsonEncoder = JSONEncoder()
111111
let logStartTimestamp: Date
112+
let appState: AppState?
112113

113114
let dispatchQueue = DispatchQueue.global(qos: .userInitiated)
114115
var lock = NSLock()
115116
var pendingTasks = PendingTasks()
116117
var tasks: [String: TaskResult] = [:]
117118

118-
init() throws {
119+
init(appState: AppState?) throws {
120+
self.appState = appState
119121
self.tmpFolder = try FileManager.default.url(
120122
for: FileManager.SearchPathDirectory.itemReplacementDirectory,
121123
in: FileManager.SearchPathDomainMask.userDomainMask,
122124
appropriateFor: FileManager.default.temporaryDirectory,
123125
create: true
124126
)
125127
self.archiveFolder = self.tmpFolder.appending(
126-
component: "Obscura Debuging Archive \(utcDateFormat.string(from: self.bundleTimestamp))"
128+
component: "Obscura Debugging Archive \(utcDateFormat.string(from: self.bundleTimestamp))"
127129
)
128130
try FileManager.default.createDirectory(
129131
at: self.archiveFolder,
@@ -371,6 +373,24 @@ private class DebugBundleBuilder {
371373
}
372374
}
373375

376+
func bundleNEDebugInfo() async {
377+
guard let manager = self.appState?.manager else {
378+
self.writeError(name: "ne-debug-info", error: "appState or manager is nil")
379+
return
380+
}
381+
do {
382+
let neDebugInfoJsonString = try await runNeJsonCommand(manager, NeManagerCmd.getDebugInfo.json(), attemptTimeout: .seconds(10))
383+
let value = try JSONSerialization.jsonObject(with: Data(neDebugInfoJsonString.utf8))
384+
let json = try JSONSerialization.data(
385+
withJSONObject: value,
386+
options: [.fragmentsAllowed, .prettyPrinted, .sortedKeys]
387+
)
388+
try self.writeFile(name: "ne-debug-info.json", data: json)
389+
} catch {
390+
self.writeError(name: "ne-debug-info", error: error)
391+
}
392+
}
393+
374394
func bundleTask(_ name: String, _ block: @escaping (BundleTask) async throws -> Void) {
375395
BundleTask(self, name, block)
376396
}
@@ -395,6 +415,7 @@ private class DebugBundleBuilder {
395415
}
396416

397417
self.bundleTask("extensions") { _task in try await self.bundleExtensions() }
418+
self.bundleTask("ne-debug-info") { _task in await self.bundleNEDebugInfo() }
398419
self.bundleTask("info") { _task in try self.bundleInfo() }
399420

400421
self.bundleCmd("arp", ["/usr/sbin/arp", "-na"])
@@ -556,7 +577,7 @@ public class DebugBundleRC {
556577
}
557578
}
558579

559-
func _createDebuggingArchive() async throws -> String {
580+
func _createDebuggingArchive(appState: AppState?) async throws -> String {
560581
let _activity = ProcessInfo.processInfo.beginActivity(
561582
options: [
562583
.automaticTerminationDisabled,
@@ -569,7 +590,7 @@ func _createDebuggingArchive() async throws -> String {
569590

570591
var start = SuspendingClock.now
571592

572-
let builder = try DebugBundleBuilder()
593+
let builder = try DebugBundleBuilder(appState: appState)
573594
await builder.bundleAll()
574595
let zipPath = try builder.createArchive()
575596

@@ -587,7 +608,7 @@ func createDebuggingArchive(appState: AppState?) async throws -> String {
587608
_debugBundleRc = DebugBundleRC(appState)
588609
}
589610
do {
590-
let path = try await _createDebuggingArchive()
611+
let path = try await _createDebuggingArchive(appState: appState)
591612
_ = appState?.osStatus.update { value in
592613
value.debugBundleStatus.setPath(path)
593614
}

apple/shared/NetworkExtensionIpc.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ enum NeManagerCmdResult: Codable {
1010
}
1111

1212
enum NeManagerCmd: Codable {
13+
case getDebugInfo
1314
case apiGetAccountInfo
1415
case getStatus(knownVersion: UUID?)
1516
case getTrafficStats

rustlib/src/config/persistence.rs

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,51 @@ pub struct Config {
246246
pub cached_account_status: Option<AccountStatus>,
247247
}
248248

249+
// Redact sensitive fields by default
250+
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
251+
pub struct ConfigDebug {
252+
pub api_url: Option<String>,
253+
pub local_tunnels_ids: Vec<String>,
254+
pub in_new_account_flow: bool,
255+
pub pinned_exits: Vec<String>,
256+
pub pinned_locations: Option<Vec<PinnedLocation>>,
257+
pub last_chosen_exit: Option<String>,
258+
pub use_wireguard_key_cache: (),
259+
pub has_account_id: bool,
260+
pub has_cached_auth_token: bool,
261+
}
262+
263+
impl From<Config> for ConfigDebug {
264+
fn from(config: Config) -> Self {
265+
let Config {
266+
api_url,
267+
account_id,
268+
old_account_ids: _,
269+
local_tunnels_ids,
270+
exit: (),
271+
in_new_account_flow,
272+
cached_auth_token,
273+
pinned_exits,
274+
pinned_locations,
275+
last_chosen_exit,
276+
wireguard_key_cache: _,
277+
use_wireguard_key_cache,
278+
cached_account_status: _,
279+
} = config;
280+
Self {
281+
api_url,
282+
local_tunnels_ids,
283+
in_new_account_flow,
284+
pinned_exits,
285+
pinned_locations,
286+
last_chosen_exit,
287+
use_wireguard_key_cache,
288+
has_account_id: account_id.is_some(),
289+
has_cached_auth_token: cached_auth_token.is_some(),
290+
}
291+
}
292+
}
293+
249294
#[serde_with::serde_as]
250295
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)]
251296
pub struct PinnedLocation {

rustlib/src/manager.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ use uuid::Uuid;
2121

2222
use crate::{
2323
client_state::AccountStatus,
24-
config::{Config, ConfigLoadError, ConfigSaveError, PinnedLocation},
24+
config::{Config, ConfigDebug, ConfigLoadError, ConfigSaveError, PinnedLocation},
2525
errors::ApiError,
2626
tunnel_state::TunnelState,
2727
};
@@ -307,6 +307,15 @@ impl Manager {
307307
pub fn rotate_wg_key(&self) -> Result<(), ConfigSaveError> {
308308
self.client_state.rotate_wg_key()
309309
}
310+
311+
pub fn get_debug_info(&self) -> DebugInfo {
312+
DebugInfo { config: self.client_state.get_config().into() }
313+
}
314+
}
315+
316+
#[derive(Debug, Serialize, Deserialize)]
317+
pub struct DebugInfo {
318+
config: ConfigDebug,
310319
}
311320

312321
#[derive(Debug, Copy, Clone, Serialize, Deserialize)]

rustlib/src/manager_cmd.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use serde::{Deserialize, Serialize};
99
use strum::IntoStaticStr;
1010
use uuid::Uuid;
1111

12-
use crate::manager::{Manager, ManagerTrafficStats, Status};
12+
use crate::manager::{DebugInfo, Manager, ManagerTrafficStats, Status};
1313
use crate::{config::ConfigSaveError, errors::ApiError};
1414
use crate::{config::PinnedLocation, manager::TunnelArgs};
1515

@@ -75,6 +75,7 @@ impl From<&ApiError> for ManagerCmdErrorCode {
7575
pub enum ManagerCmd {
7676
ApiGetAccountInfo {},
7777
ApiListExit {},
78+
GetDebugInfo {},
7879
GetStatus { known_version: Option<Uuid> },
7980
GetTrafficStats {},
8081
Login { account_id: AccountId, validate: bool },
@@ -91,10 +92,11 @@ pub enum ManagerCmd {
9192
#[serde(untagged)]
9293
pub enum ManagerCmdOk {
9394
Empty,
94-
GetTrafficStats(ManagerTrafficStats),
9595
ApiListExit(<ListExits2 as Cmd>::Output),
9696
ApiGetAccountInfo(<GetAccountInfo as Cmd>::Output),
97+
GetDebugInfo(DebugInfo),
9798
GetStatus(Status),
99+
GetTrafficStats(ManagerTrafficStats),
98100
}
99101

100102
impl ManagerCmd {
@@ -145,6 +147,7 @@ impl ManagerCmd {
145147
Ok(()) => Ok(ManagerCmdOk::Empty),
146148
Err(err) => Err((&err).into()),
147149
},
150+
ManagerCmd::GetDebugInfo {} => Ok(ManagerCmdOk::GetDebugInfo(manager.get_debug_info())),
148151
}
149152
}
150153
}

0 commit comments

Comments
 (0)