-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathparse.js
More file actions
104 lines (92 loc) Β· 3.65 KB
/
Copy pathparse.js
File metadata and controls
104 lines (92 loc) Β· 3.65 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
#!/usr/bin/env node
/**
* parse.js β Parse iOS .mobileprovision files
* Usage: node parse.js path/to/profile.mobileprovision
*/
const fs = require('fs');
const path = require('path');
const { execSync } = require('child_process');
const profilePath = process.argv[2];
if (!profilePath || !fs.existsSync(profilePath)) {
console.error('Usage: node parse.js <path-to-.mobileprovision>');
process.exit(1);
}
// .mobileprovision is a PKCS#7 SignedData structure
// Extract the embedded plist using OpenSSL
const cmds = [
// Convert DER to PEM
`security cms -D -i "${profilePath}" -o /tmp/provision.plist 2>/dev/null || openssl cms -inform DER -in "${profilePath}" -out /tmp/provision.plist -outform PEM 2>/dev/null`,
// Or directly extract
`openssl asn1parse -in "${profilePath}" -inform DER -strparse 4 2>/dev/null | grep plist || true`,
];
let plistContent = '';
for (const cmd of cmds) {
try {
const result = execSync(cmd, { encoding: 'utf8', stdio: 'pipe' });
if (result.includes('plist')) {
plistContent = result;
break;
}
} catch(e) {}
}
// Alternative: use macOS security binary if available
if (!plistContent) {
try {
execSync(`security cms -D -i "${profilePath}" -o /tmp/plist.txt 2>/dev/null`);
plistContent = fs.readFileSync('/tmp/plist.txt', 'utf8');
} catch(e) {
// Fallback: manual binary parsing
const buf = fs.readFileSync(profilePath);
const start = buf.indexOf(Buffer.from('<?xml'));
const end = buf.indexOf(Buffer.from('</plist>'));
if (start >= 0 && end > start) {
plistContent = buf.toString('utf8', start, end + 8);
}
}
}
if (!plistContent) {
console.error('Could not extract plist. Try: security cms -D -i <file> -o out.plist');
process.exit(1);
}
// Parse the plist (basic key extraction)
const parseValue = (str) => {
const keyMatch = str.match(/<key>([^<]+)<\/key>\s*<([^>]+)>([^<]*)</g);
return keyMatch || [];
};
console.log('\nπ± iOS Provisioning Profile\n');
console.log(`File: ${path.basename(profilePath)}`);
// Extract key info
const nameMatch = plistContent.match(/<key>Name<\/key>\s*<string>([^<]+)<\/string>/);
const uuidMatch = plistContent.match(/<key>UUID<\/key>\s*<string>([^<]+)<\/string>/);
const typeMatch = plistContent.match(/<key>ProvisionedDevices<\/key>/);
const expiryMatch = plistContent.match(/<key>ExpirationDate<\/key>\s*<date>([^<]+)<\/date>/);
if (nameMatch) console.log(`Name: ${nameMatch[1]}`);
if (uuidMatch) console.log(`UUID: ${uuidMatch[1]}`);
if (expiryMatch) {
const expDate = new Date(expiryMatch[1]);
const isValid = expDate > new Date();
console.log(`Expires: ${expDate.toISOString()} ${isValid ? 'β
' : 'β EXPIRED'}`);
}
// List provisioned devices
const devicesMatch = plistContent.match(/<key>ProvisionedDevices<\/key>\s*<array>([\s\S]*?)<\/array>/);
if (devicesMatch) {
const deviceList = devicesMatch[1].match(/<string>([^<]+)<\/string>/g) || [];
console.log(`\nProvisioned Devices (${deviceList.length}):`);
deviceList.slice(0, 10).forEach((dev, i) => {
const udid = dev.match(/>([^<]+)<\/string>/)[1];
console.log(` ${i+1}. ${udid}`);
});
if (deviceList.length > 10) console.log(` ... and ${deviceList.length - 10} more`);
}
// Entitlements
const entsMatch = plistContent.match(/<key>Entitlements<\/key>\s*<dict>([\s\S]*?)<\/dict>/);
if (entsMatch) {
const ents = entsMatch[1].match(/<key>([^<]+)<\/key>/g) || [];
console.log(`\nEntitlements (${ents.length}):`);
ents.slice(0, 10).forEach(e => {
const name = e.match(/>([^<]+)<\/key>/)[1];
console.log(` β’ ${name}`);
});
if (ents.length > 10) console.log(` ... and ${ents.length - 10} more`);
}
console.log('\nβ
Done. Full plist saved to: /tmp/plist.txt');