-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathprivacy.sh
More file actions
executable file
·363 lines (310 loc) · 12.7 KB
/
privacy.sh
File metadata and controls
executable file
·363 lines (310 loc) · 12.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
#!/bin/bash
# Albator Privacy Configuration Script
# Enhanced with error handling, logging, and verification
set -euo pipefail # Exit on error, undefined vars, pipe failures
# Source common utilities
source "$(dirname "$0")"/utils.sh
# Dependency check
check_dependencies() {
local missing=()
for cmd in defaults launchctl; do
if ! command -v "$cmd" >/dev/null 2>&1; then
missing+=("$cmd")
fi
done
if [[ ${#missing[@]} -gt 0 ]]; then
echo "ERROR: Missing required tools: ${missing[*]}" >&2
echo "These are macOS system tools. Please ensure you are running on macOS." >&2
exit 1
fi
}
check_dependencies
# Configuration
SCRIPT_NAME="privacy.sh"
LOG_FILE="/tmp/albator_privacy.log"
BACKUP_DIR="/tmp/albator_backup/privacy"
DRY_RUN=${DRY_RUN:-false}
# Function to backup current setting
backup_setting() {
local domain=$1
local key=$2
local safe_domain
local safe_key
safe_domain=$(echo "$domain" | sed 's#^/##; s#[^A-Za-z0-9._-]#_#g')
safe_key=$(echo "$key" | sed 's#[^A-Za-z0-9._-]#_#g')
local backup_file="$BACKUP_DIR/${safe_domain}_${safe_key}.backup"
mkdir -p "$BACKUP_DIR"
if [[ "$domain" == "/Library/Preferences/"* ]]; then
sudo defaults read "$domain" "$key" 2>/dev/null > "$backup_file" || echo "NOT_SET" > "$backup_file"
else
defaults read "$domain" "$key" 2>/dev/null > "$backup_file" || echo "NOT_SET" > "$backup_file"
fi
log "INFO" "Backed up $domain $key to $backup_file"
}
# Function to apply setting with verification
apply_setting() {
local domain=$1
local key=$2
local value=$3
local value_type=$4
local description=$5
local use_sudo=${6:-false}
show_progress "Configuring: $description"
# Backup current setting
backup_setting "$domain" "$key"
local existing_value
if [[ "$use_sudo" == "true" ]]; then
existing_value=$(sudo defaults read "$domain" "$key" 2>/dev/null || echo "MISSING")
else
existing_value=$(defaults read "$domain" "$key" 2>/dev/null || echo "MISSING")
fi
if [[ "$existing_value" == "$value" ]] || [[ "$existing_value" == "1" && "$value" == "true" ]] || [[ "$existing_value" == "0" && "$value" == "false" ]]; then
show_success "$description already compliant"
record_noop "$description already compliant"
return 0
fi
# Apply setting
if [[ "$DRY_RUN" == "true" ]]; then
show_warning "DRY RUN: Would set $domain $key to $value"
record_plan_action "$domain/$key" "$description" "defaults write $domain $key -$value_type $value"
return 0
fi
if [[ "$use_sudo" == "true" ]]; then
if sudo defaults write "$domain" "$key" "-$value_type" "$value" 2>>"$LOG_FILE"; then
:
else
show_error "Failed to apply $description"
return 1
fi
else
if defaults write "$domain" "$key" "-$value_type" "$value" 2>>"$LOG_FILE"; then
:
else
show_error "Failed to apply $description"
return 1
fi
fi
# Verify setting was applied
local current_value
if [[ "$use_sudo" == "true" ]]; then
current_value=$(sudo defaults read "$domain" "$key" 2>/dev/null || echo "FAILED")
else
current_value=$(defaults read "$domain" "$key" 2>/dev/null || echo "FAILED")
fi
if [[ "$current_value" == "$value" ]] || [[ "$current_value" == "1" && "$value" == "true" ]] || [[ "$current_value" == "0" && "$value" == "false" ]]; then
show_success "$description"
local rollback_cmd
if [[ "$use_sudo" == "true" ]]; then
rollback_cmd="sudo defaults write $domain $key -$value_type $existing_value"
else
rollback_cmd="defaults write $domain $key -$value_type $existing_value"
fi
if [[ "$existing_value" == "MISSING" ]]; then
if [[ "$use_sudo" == "true" ]]; then
rollback_cmd="sudo defaults delete $domain $key"
else
rollback_cmd="defaults delete $domain $key"
fi
fi
record_rollback_change "$domain/$key" "$description" "$rollback_cmd"
return 0
else
show_error "Failed to verify $description (expected: $value, got: $current_value)"
return 1
fi
}
# Function to configure system setting
configure_system_setting() {
local command=$1
local description=$2
local verification_cmd=$3
local expected_output=$4
show_progress "Configuring: $description"
if [[ "$DRY_RUN" == "true" ]]; then
show_warning "DRY RUN: Would run: $command"
record_plan_action "$description" "$description" "$command"
return 0
fi
local -a command_parts
read -r -a command_parts <<< "$command"
if "${command_parts[@]}" 2>>"$LOG_FILE"; then
# Verify setting was applied
if [[ -n "$verification_cmd" ]]; then
local -a verification_parts
local current_value
read -r -a verification_parts <<< "$verification_cmd"
current_value=$("${verification_parts[@]}" 2>/dev/null || echo "FAILED")
if [[ "$current_value" == *"$expected_output"* ]]; then
show_success "$description"
record_rollback_change "$description" "system setting configured" ""
return 0
else
show_error "Failed to verify $description (expected: $expected_output, got: $current_value)"
return 1
fi
else
show_success "$description"
return 0
fi
else
show_error "Failed to configure $description"
return 1
fi
}
# Function to disable system service
disable_service() {
local service_name=$1
local description=$2
show_progress "Disabling: $description"
if [[ "$DRY_RUN" == "true" ]]; then
show_warning "DRY RUN: Would disable $service_name"
record_plan_action "$service_name" "$description" "launchctl unload -w /System/Library/LaunchDaemons/$service_name.plist"
return 0
fi
if sudo launchctl list | grep -q "$service_name" 2>/dev/null; then
if sudo launchctl unload -w "/System/Library/LaunchDaemons/$service_name.plist" 2>>"$LOG_FILE"; then
show_success "$description disabled"
record_rollback_change "$service_name" "$description disabled" "sudo launchctl load -w /System/Library/LaunchDaemons/$service_name.plist"
return 0
else
show_error "Failed to disable $description"
return 1
fi
else
show_success "$description already disabled"
record_noop "$description already disabled"
return 0
fi
}
# Main privacy configuration function
configure_privacy() {
local errors=0
show_progress "Starting privacy configuration..."
# Disable telemetry (diagnostic reports)
apply_setting "/Library/Preferences/com.apple.SubmitDiagInfo" "AutoSubmit" "false" "bool" "Diagnostic reports submission" "true" || ((errors++))
apply_setting "/Library/Preferences/com.apple.SubmitDiagInfo" "AutoSubmitVersion" "0" "int" "Diagnostic reports version submission" "true" || ((errors++))
# Disable Siri analytics
apply_setting "com.apple.assistant.analytics" "AnalyticsEnabled" "false" "bool" "Siri analytics" "false" || ((errors++))
# Disable modern telemetry service
apply_setting "com.apple.newTelemetryService" "AutoSubmit" "false" "bool" "New telemetry service" "true" || ((errors++))
# Configure Safari privacy settings
apply_setting "com.apple.Safari" "UniversalSearchEnabled" "false" "bool" "Safari universal search" "false" || ((errors++))
apply_setting "com.apple.Safari" "SuppressSearchSuggestions" "true" "bool" "Safari search suggestions suppression" "false" || ((errors++))
# Disable remote login (SSH)
configure_system_setting "sudo systemsetup -setremotelogin off" "Remote login (SSH)" "sudo systemsetup -getremotelogin" "Off" || ((errors++))
# Disable remote management
configure_system_setting "sudo /System/Library/CoreServices/RemoteManagement/ARDAgent.app/Contents/Resources/kickstart -deactivate -stop" "Remote management (ARD)" "" "" || ((errors++))
# Disable SMB network sharing
disable_service "com.apple.smbd" "SMB network sharing" || ((errors++))
# Configure mDNS (Bonjour) to disable multicast advertisements
show_progress "Configuring mDNS multicast advertisements..."
if [[ "$DRY_RUN" != "true" ]]; then
if sudo defaults write /System/Library/LaunchDaemons/com.apple.mDNSResponder.plist ProgramArguments -array-add "-NoMulticastAdvertisements" 2>>"$LOG_FILE"; then
show_success "mDNS multicast advertisements disabled"
record_rollback_change "com.apple.mDNSResponder" "disabled multicast advertisements" ""
else
show_error "Failed to disable mDNS multicast advertisements"
((errors++))
fi
else
show_warning "DRY RUN: Would disable mDNS multicast advertisements"
record_plan_action "com.apple.mDNSResponder" "Disable mDNS multicast advertisements" "defaults write /System/Library/LaunchDaemons/com.apple.mDNSResponder.plist ProgramArguments -array-add -NoMulticastAdvertisements"
fi
return $errors
}
# Function to verify all settings
verify_settings() {
local errors=0
show_progress "Verifying privacy settings..."
# Verification tests
local tests=(
"sudo defaults read /Library/Preferences/com.apple.SubmitDiagInfo AutoSubmit:0:Diagnostic reports disabled"
"defaults read com.apple.assistant.analytics AnalyticsEnabled:0:Siri analytics disabled"
"defaults read com.apple.Safari SuppressSearchSuggestions:1:Safari search suggestions disabled"
"sudo systemsetup -getremotelogin:Off:Remote login disabled"
)
for test in "${tests[@]}"; do
IFS=':' read -r cmd expected description <<< "$test"
local -a cmd_parts
read -r -a cmd_parts <<< "$cmd"
local actual
actual=$("${cmd_parts[@]}" 2>/dev/null || echo "FAILED")
if [[ "$actual" == *"$expected"* ]]; then
show_success "✓ $description"
else
show_error "✗ $description (expected: $expected, got: $actual)"
((errors++))
fi
done
# Check SMB service
if ! sudo launchctl list | grep -q "com.apple.smbd" 2>/dev/null; then
show_success "✓ SMB sharing disabled"
else
show_error "✗ SMB sharing still enabled"
((errors++))
fi
return $errors
}
# Main execution
main() {
echo "Albator Privacy Configuration Script"
echo "===================================="
# Parse command line arguments
while [[ $# -gt 0 ]]; do
case $1 in
--dry-run)
DRY_RUN=true
show_warning "Running in dry-run mode"
shift
;;
--help)
echo "Usage: $0 [--dry-run] [--help]"
echo " --dry-run Show what would be done without making changes"
echo " --help Show this help message"
exit 0
;;
*)
show_error "Unknown option: $1"
exit 1
;;
esac
done
# Initialize logging
mkdir -p "$(dirname "$LOG_FILE")"
log "INFO" "Starting privacy configuration script"
init_script_state
# Check against configured baseline version
local macos_version
macos_version=$(sw_vers -productVersion)
local min_macos
min_macos=$(get_min_macos_version)
if [[ "$macos_version" != "$min_macos"* ]]; then
show_warning "Configured baseline is macOS >= $min_macos, detected: $macos_version"
fi
# Run configuration
local config_errors=0
configure_privacy || config_errors=$?
# Run verification
local verify_errors=0
if [[ "$DRY_RUN" == "true" ]]; then
show_warning "Skipping verification in dry-run mode"
else
verify_settings || verify_errors=$?
fi
# Summary
local total_errors=$((config_errors + verify_errors))
echo ""
echo "===================================="
if [[ $total_errors -eq 0 ]]; then
show_success "Privacy configuration completed successfully!"
log "INFO" "Privacy configuration completed successfully"
exit_with_status 0
else
show_error "Privacy configuration completed with $total_errors errors"
show_error "Check log file: $LOG_FILE"
log "ERROR" "Privacy configuration completed with $total_errors errors"
exit_with_status "$total_errors"
fi
}
# Run main function with all arguments
main "$@"