-
Notifications
You must be signed in to change notification settings - Fork 0
/
vpp-detect.m
134 lines (109 loc) · 4.16 KB
/
vpp-detect.m
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
/*
Simple application to detect if the provided app bundle is a VPP-distributed app.
- Written by: Mykola Grymalyuk
- Company: RIPEDA Consulting
Compile:
clang -arch x86_64 -arch arm64 -framework Foundation -o vpp-detect vpp-detect.m
Usage:
./vpp-detect <path to app bundle>
Return codes:
- 0: VPP
- 1: App Store (user-purchased)
- 2: OS Application (came with machine or downloded outside of App Store)
- 3: No App Store receipt found
- 4: Catch-all for any other errors
*/
#import <Foundation/Foundation.h>
#include <stdio.h>
#include <objc/objc.h>
typedef enum {
VPP = 0,
APP_STORE = 1,
OS_APPLICATION = 2,
NO_RECEIPT = 3,
CATCH_ALL = 4
} ReturnCode;
#define VERSION "1.0.1"
#define VERIFCATION_URL "https://buy.itunes.apple.com/verifyReceipt"
int isVPPApp(NSString *path)
{
/*
Supported return codes:
- 0: VPP
- 1: App Store (user-purchased)
- 2: OS Application (came with machine or downloded outside of App Store)
- 3: No App Store receipt found
*/
NSFileManager *fm = [NSFileManager defaultManager];
NSString *receiptPath = [path stringByAppendingPathComponent:@"Contents/_MASReceipt/receipt"];
if (![fm fileExistsAtPath:receiptPath]) {
printf("No receipt found at %s\n", [receiptPath UTF8String]);
return NO_RECEIPT;
}
NSData *receiptData = [NSData dataWithContentsOfFile:receiptPath];
if (!receiptData) {
printf("Unable to read receipt at %s\n", [receiptPath UTF8String]);
return NO_RECEIPT;
}
NSError *error = nil;
NSURL *url = [NSURL URLWithString:@VERIFCATION_URL];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[request setHTTPMethod:@"POST"];
NSString *receiptDataString = [receiptData base64EncodedStringWithOptions:0];
NSString *postString = [NSString stringWithFormat:@"{\"receipt-data\" : \"%@\"}", receiptDataString];
NSData *postData = [postString dataUsingEncoding:NSUTF8StringEncoding];
[request setHTTPBody:postData];
// TODO: Switch to async request
NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:&error];
if (error) {
printf("Error: %s\n", [[error description] UTF8String]);
return CATCH_ALL;
}
NSDictionary *results = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];
// Check 'receipt' key
if (![[results allKeys] containsObject:@"receipt"]) {
printf("No receipt key found in response, likely OS application or distribution outside of App Store\n");
return OS_APPLICATION;
}
// Check 'receipt' -> 'receipt_type' key
NSDictionary *receipt = [results objectForKey:@"receipt"];
if (![[receipt allKeys] containsObject:@"receipt_type"]) {
printf("No receipt key found in response, likely OS application or distribution outside of App Store\n");
return OS_APPLICATION;
}
/*
Valid values:
Production
ProductionVPP
ProductionSandbox
ProductionVPPSandbox
*/
NSString *receiptType = [receipt objectForKey:@"receipt_type"];
printf("Receipt type: %s\n", [receiptType UTF8String]);
if ([receiptType isEqualToString:@"ProductionVPP"] || [receiptType isEqualToString:@"ProductionVPPSandbox"]) {
printf("Applicaton is VPP\n");
return VPP;
} else if ([receiptType isEqualToString:@"Production"] || [receiptType isEqualToString:@"ProductionSandbox"]) {
printf("Applicaton is App Store\n");
return APP_STORE;
}
printf("Unknown reciept type! Please report this issue\n");
return CATCH_ALL;
}
int main(int argc, const char * argv[])
{
@autoreleasepool {
if (argc != 2) {
printf("Usage: %s <path to app bundle>\n", argv[0]);
return CATCH_ALL;
}
if (strcmp(argv[1], "--version") == 0) {
printf("%s\n", VERSION);
return 0;
}
NSString *path = [NSString stringWithUTF8String:argv[1]];
int result = isVPPApp(path);
printf("Result: %d\n", result);
return result;
}
}