1*fdd8201dSApple OSS Distributions #include <darwintest.h>
2*fdd8201dSApple OSS Distributions #include <darwintest_utils.h>
3*fdd8201dSApple OSS Distributions #include <errno.h>
4*fdd8201dSApple OSS Distributions #include <fcntl.h>
5*fdd8201dSApple OSS Distributions #include <stdlib.h>
6*fdd8201dSApple OSS Distributions #include <sys/mount.h>
7*fdd8201dSApple OSS Distributions #include <sys/wait.h>
8*fdd8201dSApple OSS Distributions #include <sys/stat.h>
9*fdd8201dSApple OSS Distributions #include <unistd.h>
10*fdd8201dSApple OSS Distributions #include <stdio.h>
11*fdd8201dSApple OSS Distributions #include <string.h>
12*fdd8201dSApple OSS Distributions
13*fdd8201dSApple OSS Distributions #include <IOKit/IOKitLib.h>
14*fdd8201dSApple OSS Distributions #include <Kernel/IOKit/crypto/AppleKeyStoreDefs.h>
15*fdd8201dSApple OSS Distributions #include <Kernel/sys/content_protection.h>
16*fdd8201dSApple OSS Distributions
17*fdd8201dSApple OSS Distributions #define CPT_IO_SIZE 4096
18*fdd8201dSApple OSS Distributions #define CPT_AKS_BUF_SIZE 256
19*fdd8201dSApple OSS Distributions #define CPT_MAX_PASS_LEN 64
20*fdd8201dSApple OSS Distributions
21*fdd8201dSApple OSS Distributions #define GET_PROT_CLASS(fd) \
22*fdd8201dSApple OSS Distributions fcntl((fd), F_GETPROTECTIONCLASS)
23*fdd8201dSApple OSS Distributions
24*fdd8201dSApple OSS Distributions #define SET_PROT_CLASS(fd, prot_class) \
25*fdd8201dSApple OSS Distributions fcntl((fd), F_SETPROTECTIONCLASS, (prot_class))
26*fdd8201dSApple OSS Distributions
27*fdd8201dSApple OSS Distributions #define KEYSTORECTL_PATH "/usr/local/bin/keystorectl"
28*fdd8201dSApple OSS Distributions #define KEYBAGDTEST_PATH "/usr/local/bin/keybagdTest"
29*fdd8201dSApple OSS Distributions #define TEMP_DIR_TEMPLATE "/tmp/data_protection_test.XXXXXXXX"
30*fdd8201dSApple OSS Distributions #define TEST_PASSCODE "IAmASecurePassword"
31*fdd8201dSApple OSS Distributions
32*fdd8201dSApple OSS Distributions int g_fd = -1;
33*fdd8201dSApple OSS Distributions int g_dir_fd = -1;
34*fdd8201dSApple OSS Distributions int g_subdir_fd = -1;
35*fdd8201dSApple OSS Distributions int g_passcode_set = 0;
36*fdd8201dSApple OSS Distributions
37*fdd8201dSApple OSS Distributions char g_test_tempdir[PATH_MAX] = TEMP_DIR_TEMPLATE;
38*fdd8201dSApple OSS Distributions char g_filepath[PATH_MAX] = "";
39*fdd8201dSApple OSS Distributions char g_dirpath[PATH_MAX] = "";
40*fdd8201dSApple OSS Distributions char g_subdirpath[PATH_MAX] = "";
41*fdd8201dSApple OSS Distributions
42*fdd8201dSApple OSS Distributions int apple_key_store(
43*fdd8201dSApple OSS Distributions uint32_t command,
44*fdd8201dSApple OSS Distributions uint64_t * inputs,
45*fdd8201dSApple OSS Distributions uint32_t input_count,
46*fdd8201dSApple OSS Distributions void * input_structs,
47*fdd8201dSApple OSS Distributions size_t input_struct_count,
48*fdd8201dSApple OSS Distributions uint64_t * outputs,
49*fdd8201dSApple OSS Distributions uint32_t * output_count
50*fdd8201dSApple OSS Distributions );
51*fdd8201dSApple OSS Distributions int spawn_proc(char * const command[]);
52*fdd8201dSApple OSS Distributions int supports_content_prot(void);
53*fdd8201dSApple OSS Distributions char* dp_class_num_to_string(int num);
54*fdd8201dSApple OSS Distributions int lock_device(void);
55*fdd8201dSApple OSS Distributions int unlock_device(char * passcode);
56*fdd8201dSApple OSS Distributions int set_passcode(char * new_passcode, char * old_passcode);
57*fdd8201dSApple OSS Distributions int clear_passcode(char * passcode);
58*fdd8201dSApple OSS Distributions int has_passcode(void);
59*fdd8201dSApple OSS Distributions void setup(void);
60*fdd8201dSApple OSS Distributions void cleanup(void);
61*fdd8201dSApple OSS Distributions
62*fdd8201dSApple OSS Distributions T_DECL(data_protection,
63*fdd8201dSApple OSS Distributions "Verify behavior of the various data protection classes") {
64*fdd8201dSApple OSS Distributions int local_result = -1;
65*fdd8201dSApple OSS Distributions int new_prot_class = -1;
66*fdd8201dSApple OSS Distributions int old_prot_class = -1;
67*fdd8201dSApple OSS Distributions int current_byte = 0;
68*fdd8201dSApple OSS Distributions char rd_buffer[CPT_IO_SIZE];
69*fdd8201dSApple OSS Distributions char wr_buffer[CPT_IO_SIZE];
70*fdd8201dSApple OSS Distributions
71*fdd8201dSApple OSS Distributions #if TARGET_OS_OSX && defined(__arm64__)
72*fdd8201dSApple OSS Distributions T_SKIP("ASM support not yet implemented (rdar://61591896)");
73*fdd8201dSApple OSS Distributions #endif /* TARGET_OS_OSX && defined(__arm64__) */
74*fdd8201dSApple OSS Distributions
75*fdd8201dSApple OSS Distributions setup();
76*fdd8201dSApple OSS Distributions
77*fdd8201dSApple OSS Distributions /*
78*fdd8201dSApple OSS Distributions * Ensure we can freely read and change
79*fdd8201dSApple OSS Distributions * protection classes when unlocked.
80*fdd8201dSApple OSS Distributions */
81*fdd8201dSApple OSS Distributions for (
82*fdd8201dSApple OSS Distributions new_prot_class = PROTECTION_CLASS_A;
83*fdd8201dSApple OSS Distributions new_prot_class <= PROTECTION_CLASS_F;
84*fdd8201dSApple OSS Distributions new_prot_class++
85*fdd8201dSApple OSS Distributions ) {
86*fdd8201dSApple OSS Distributions T_ASSERT_NE(
87*fdd8201dSApple OSS Distributions old_prot_class = GET_PROT_CLASS(g_fd),
88*fdd8201dSApple OSS Distributions -1,
89*fdd8201dSApple OSS Distributions "Get protection class when locked"
90*fdd8201dSApple OSS Distributions );
91*fdd8201dSApple OSS Distributions T_WITH_ERRNO;
92*fdd8201dSApple OSS Distributions T_ASSERT_NE(
93*fdd8201dSApple OSS Distributions SET_PROT_CLASS(g_fd, new_prot_class),
94*fdd8201dSApple OSS Distributions -1,
95*fdd8201dSApple OSS Distributions "Should be able to change protection "
96*fdd8201dSApple OSS Distributions "from %s to %s while unlocked",
97*fdd8201dSApple OSS Distributions dp_class_num_to_string(old_prot_class),
98*fdd8201dSApple OSS Distributions dp_class_num_to_string(new_prot_class)
99*fdd8201dSApple OSS Distributions );
100*fdd8201dSApple OSS Distributions }
101*fdd8201dSApple OSS Distributions
102*fdd8201dSApple OSS Distributions /* Query the filesystem for the default CP level (Is it C?) */
103*fdd8201dSApple OSS Distributions #ifndef F_GETDEFAULTPROTLEVEL
104*fdd8201dSApple OSS Distributions #define F_GETDEFAULTPROTLEVEL 79
105*fdd8201dSApple OSS Distributions #endif
106*fdd8201dSApple OSS Distributions
107*fdd8201dSApple OSS Distributions T_WITH_ERRNO;
108*fdd8201dSApple OSS Distributions T_ASSERT_NE(
109*fdd8201dSApple OSS Distributions old_prot_class = fcntl(g_fd, F_GETDEFAULTPROTLEVEL),
110*fdd8201dSApple OSS Distributions -1,
111*fdd8201dSApple OSS Distributions "Get default protection level for filesystem"
112*fdd8201dSApple OSS Distributions );
113*fdd8201dSApple OSS Distributions
114*fdd8201dSApple OSS Distributions /* XXX: Do we want to do anything with the level? What should it be? */
115*fdd8201dSApple OSS Distributions
116*fdd8201dSApple OSS Distributions /*
117*fdd8201dSApple OSS Distributions * files are allowed to move into F, but not out of it. They can also
118*fdd8201dSApple OSS Distributions * only do so when they do not have content.
119*fdd8201dSApple OSS Distributions */
120*fdd8201dSApple OSS Distributions close(g_fd);
121*fdd8201dSApple OSS Distributions unlink(g_filepath);
122*fdd8201dSApple OSS Distributions
123*fdd8201dSApple OSS Distributions /* re-create the file */
124*fdd8201dSApple OSS Distributions T_WITH_ERRNO;
125*fdd8201dSApple OSS Distributions T_ASSERT_GE(
126*fdd8201dSApple OSS Distributions g_fd = open(g_filepath, O_CREAT | O_EXCL | O_RDWR | O_CLOEXEC),
127*fdd8201dSApple OSS Distributions 0,
128*fdd8201dSApple OSS Distributions "Recreate test file"
129*fdd8201dSApple OSS Distributions );
130*fdd8201dSApple OSS Distributions
131*fdd8201dSApple OSS Distributions /* Try making a class A file while locked. */
132*fdd8201dSApple OSS Distributions T_ASSERT_EQ(lock_device(), 0, "*** Lock device ***");
133*fdd8201dSApple OSS Distributions
134*fdd8201dSApple OSS Distributions T_WITH_ERRNO;
135*fdd8201dSApple OSS Distributions T_ASSERT_EQ(
136*fdd8201dSApple OSS Distributions SET_PROT_CLASS(g_fd, PROTECTION_CLASS_A),
137*fdd8201dSApple OSS Distributions -1,
138*fdd8201dSApple OSS Distributions "Should not be able to change protection "
139*fdd8201dSApple OSS Distributions "from class D to class A when locked"
140*fdd8201dSApple OSS Distributions );
141*fdd8201dSApple OSS Distributions T_ASSERT_EQ(unlock_device(TEST_PASSCODE), 0, "*** Unlock device ***");
142*fdd8201dSApple OSS Distributions
143*fdd8201dSApple OSS Distributions /* Attempt opening/IO to a class A file while unlocked. */
144*fdd8201dSApple OSS Distributions T_WITH_ERRNO;
145*fdd8201dSApple OSS Distributions T_ASSERT_EQ(
146*fdd8201dSApple OSS Distributions SET_PROT_CLASS(g_fd, PROTECTION_CLASS_A),
147*fdd8201dSApple OSS Distributions 0,
148*fdd8201dSApple OSS Distributions "Should be able to change protection "
149*fdd8201dSApple OSS Distributions "from class D to class A when unlocked"
150*fdd8201dSApple OSS Distributions );
151*fdd8201dSApple OSS Distributions
152*fdd8201dSApple OSS Distributions close(g_fd);
153*fdd8201dSApple OSS Distributions
154*fdd8201dSApple OSS Distributions T_WITH_ERRNO;
155*fdd8201dSApple OSS Distributions T_ASSERT_GE(
156*fdd8201dSApple OSS Distributions g_fd = open(g_filepath, O_RDWR | O_CLOEXEC),
157*fdd8201dSApple OSS Distributions 0,
158*fdd8201dSApple OSS Distributions "Should be able to open a class A file when unlocked");
159*fdd8201dSApple OSS Distributions
160*fdd8201dSApple OSS Distributions /*
161*fdd8201dSApple OSS Distributions * TODO: Write specific data we can check for. If we're going to do
162*fdd8201dSApple OSS Distributions * that, the write scheme should be deliberately ugly.
163*fdd8201dSApple OSS Distributions */
164*fdd8201dSApple OSS Distributions current_byte = 0;
165*fdd8201dSApple OSS Distributions
166*fdd8201dSApple OSS Distributions while (current_byte < CPT_IO_SIZE) {
167*fdd8201dSApple OSS Distributions local_result = pwrite(
168*fdd8201dSApple OSS Distributions g_fd,
169*fdd8201dSApple OSS Distributions &wr_buffer[current_byte],
170*fdd8201dSApple OSS Distributions CPT_IO_SIZE - current_byte,
171*fdd8201dSApple OSS Distributions current_byte
172*fdd8201dSApple OSS Distributions );
173*fdd8201dSApple OSS Distributions
174*fdd8201dSApple OSS Distributions T_WITH_ERRNO;
175*fdd8201dSApple OSS Distributions T_ASSERT_NE(
176*fdd8201dSApple OSS Distributions local_result,
177*fdd8201dSApple OSS Distributions -1,
178*fdd8201dSApple OSS Distributions "Should be able to write to "
179*fdd8201dSApple OSS Distributions "a class A file when unlocked"
180*fdd8201dSApple OSS Distributions );
181*fdd8201dSApple OSS Distributions
182*fdd8201dSApple OSS Distributions current_byte += local_result;
183*fdd8201dSApple OSS Distributions }
184*fdd8201dSApple OSS Distributions
185*fdd8201dSApple OSS Distributions current_byte = 0;
186*fdd8201dSApple OSS Distributions
187*fdd8201dSApple OSS Distributions while (current_byte < CPT_IO_SIZE) {
188*fdd8201dSApple OSS Distributions local_result = pread(
189*fdd8201dSApple OSS Distributions g_fd,
190*fdd8201dSApple OSS Distributions &rd_buffer[current_byte],
191*fdd8201dSApple OSS Distributions CPT_IO_SIZE - current_byte,
192*fdd8201dSApple OSS Distributions current_byte
193*fdd8201dSApple OSS Distributions );
194*fdd8201dSApple OSS Distributions
195*fdd8201dSApple OSS Distributions T_WITH_ERRNO;
196*fdd8201dSApple OSS Distributions T_ASSERT_NE(
197*fdd8201dSApple OSS Distributions local_result,
198*fdd8201dSApple OSS Distributions -1,
199*fdd8201dSApple OSS Distributions "Should be able to read from "
200*fdd8201dSApple OSS Distributions "a class A file when unlocked"
201*fdd8201dSApple OSS Distributions );
202*fdd8201dSApple OSS Distributions
203*fdd8201dSApple OSS Distributions current_byte += local_result;
204*fdd8201dSApple OSS Distributions }
205*fdd8201dSApple OSS Distributions
206*fdd8201dSApple OSS Distributions /*
207*fdd8201dSApple OSS Distributions * Again, but now while locked; and try to change the file class
208*fdd8201dSApple OSS Distributions * as well.
209*fdd8201dSApple OSS Distributions */
210*fdd8201dSApple OSS Distributions T_ASSERT_EQ(lock_device(), 0, "*** Lock device ***");
211*fdd8201dSApple OSS Distributions
212*fdd8201dSApple OSS Distributions T_ASSERT_LE(
213*fdd8201dSApple OSS Distributions pread(g_fd, rd_buffer, CPT_IO_SIZE, 0),
214*fdd8201dSApple OSS Distributions 0,
215*fdd8201dSApple OSS Distributions "Should not be able to read from a class A file when locked"
216*fdd8201dSApple OSS Distributions );
217*fdd8201dSApple OSS Distributions
218*fdd8201dSApple OSS Distributions T_ASSERT_LE(
219*fdd8201dSApple OSS Distributions pwrite(g_fd, wr_buffer, CPT_IO_SIZE, 0),
220*fdd8201dSApple OSS Distributions 0,
221*fdd8201dSApple OSS Distributions "Should not be able to write to a class A file when locked"
222*fdd8201dSApple OSS Distributions );
223*fdd8201dSApple OSS Distributions
224*fdd8201dSApple OSS Distributions T_ASSERT_EQ(
225*fdd8201dSApple OSS Distributions SET_PROT_CLASS(g_fd, PROTECTION_CLASS_D),
226*fdd8201dSApple OSS Distributions -1,
227*fdd8201dSApple OSS Distributions "Should not be able to change protection "
228*fdd8201dSApple OSS Distributions "from class A to class D when locked"
229*fdd8201dSApple OSS Distributions );
230*fdd8201dSApple OSS Distributions
231*fdd8201dSApple OSS Distributions /* Try to open and truncate the file. */
232*fdd8201dSApple OSS Distributions close(g_fd);
233*fdd8201dSApple OSS Distributions
234*fdd8201dSApple OSS Distributions T_ASSERT_EQ(
235*fdd8201dSApple OSS Distributions g_fd = open(g_filepath, O_RDWR | O_TRUNC | O_CLOEXEC),
236*fdd8201dSApple OSS Distributions -1,
237*fdd8201dSApple OSS Distributions "Should not be able to open and truncate "
238*fdd8201dSApple OSS Distributions "a class A file when locked"
239*fdd8201dSApple OSS Distributions );
240*fdd8201dSApple OSS Distributions
241*fdd8201dSApple OSS Distributions /* Try to open the file */
242*fdd8201dSApple OSS Distributions T_ASSERT_EQ(
243*fdd8201dSApple OSS Distributions g_fd = open(g_filepath, O_RDWR | O_CLOEXEC),
244*fdd8201dSApple OSS Distributions -1,
245*fdd8201dSApple OSS Distributions "Should not be able to open a class A file when locked"
246*fdd8201dSApple OSS Distributions );
247*fdd8201dSApple OSS Distributions
248*fdd8201dSApple OSS Distributions /* What about class B files? */
249*fdd8201dSApple OSS Distributions T_ASSERT_EQ(unlock_device(TEST_PASSCODE), 0, "*** Unlock device ***");
250*fdd8201dSApple OSS Distributions
251*fdd8201dSApple OSS Distributions T_ASSERT_GE(
252*fdd8201dSApple OSS Distributions g_fd = open(g_filepath, O_RDWR | O_CLOEXEC),
253*fdd8201dSApple OSS Distributions 0,
254*fdd8201dSApple OSS Distributions "Should be able to open a class A file when unlocked"
255*fdd8201dSApple OSS Distributions );
256*fdd8201dSApple OSS Distributions
257*fdd8201dSApple OSS Distributions T_WITH_ERRNO;
258*fdd8201dSApple OSS Distributions T_ASSERT_EQ(
259*fdd8201dSApple OSS Distributions SET_PROT_CLASS(g_fd, PROTECTION_CLASS_D),
260*fdd8201dSApple OSS Distributions 0,
261*fdd8201dSApple OSS Distributions "Should be able to change protection "
262*fdd8201dSApple OSS Distributions "class from A to D when unlocked"
263*fdd8201dSApple OSS Distributions );
264*fdd8201dSApple OSS Distributions
265*fdd8201dSApple OSS Distributions T_ASSERT_EQ(lock_device(), 0, "*** Lock device ***");
266*fdd8201dSApple OSS Distributions
267*fdd8201dSApple OSS Distributions /* Can we create a class B file while locked? */
268*fdd8201dSApple OSS Distributions T_ASSERT_EQ(
269*fdd8201dSApple OSS Distributions SET_PROT_CLASS(g_fd, PROTECTION_CLASS_B),
270*fdd8201dSApple OSS Distributions 0,
271*fdd8201dSApple OSS Distributions "Should be able to change protection "
272*fdd8201dSApple OSS Distributions "class from D to B when locked"
273*fdd8201dSApple OSS Distributions );
274*fdd8201dSApple OSS Distributions
275*fdd8201dSApple OSS Distributions T_ASSERT_EQ(
276*fdd8201dSApple OSS Distributions GET_PROT_CLASS(g_fd),
277*fdd8201dSApple OSS Distributions PROTECTION_CLASS_B,
278*fdd8201dSApple OSS Distributions "File should now have class B protection"
279*fdd8201dSApple OSS Distributions );
280*fdd8201dSApple OSS Distributions
281*fdd8201dSApple OSS Distributions /*
282*fdd8201dSApple OSS Distributions * We should also be able to read/write to the
283*fdd8201dSApple OSS Distributions * file descriptor while it is open.
284*fdd8201dSApple OSS Distributions */
285*fdd8201dSApple OSS Distributions current_byte = 0;
286*fdd8201dSApple OSS Distributions
287*fdd8201dSApple OSS Distributions while (current_byte < CPT_IO_SIZE) {
288*fdd8201dSApple OSS Distributions local_result = pwrite(
289*fdd8201dSApple OSS Distributions g_fd,
290*fdd8201dSApple OSS Distributions &wr_buffer[current_byte],
291*fdd8201dSApple OSS Distributions CPT_IO_SIZE - current_byte,
292*fdd8201dSApple OSS Distributions current_byte
293*fdd8201dSApple OSS Distributions );
294*fdd8201dSApple OSS Distributions
295*fdd8201dSApple OSS Distributions T_WITH_ERRNO;
296*fdd8201dSApple OSS Distributions T_ASSERT_NE(
297*fdd8201dSApple OSS Distributions local_result,
298*fdd8201dSApple OSS Distributions -1,
299*fdd8201dSApple OSS Distributions "Should be able to write to a "
300*fdd8201dSApple OSS Distributions "new class B file when locked"
301*fdd8201dSApple OSS Distributions );
302*fdd8201dSApple OSS Distributions
303*fdd8201dSApple OSS Distributions current_byte += local_result;
304*fdd8201dSApple OSS Distributions }
305*fdd8201dSApple OSS Distributions
306*fdd8201dSApple OSS Distributions current_byte = 0;
307*fdd8201dSApple OSS Distributions
308*fdd8201dSApple OSS Distributions while (current_byte < CPT_IO_SIZE) {
309*fdd8201dSApple OSS Distributions local_result = pread(
310*fdd8201dSApple OSS Distributions g_fd,
311*fdd8201dSApple OSS Distributions &rd_buffer[current_byte],
312*fdd8201dSApple OSS Distributions CPT_IO_SIZE - current_byte,
313*fdd8201dSApple OSS Distributions current_byte
314*fdd8201dSApple OSS Distributions );
315*fdd8201dSApple OSS Distributions
316*fdd8201dSApple OSS Distributions T_ASSERT_NE(
317*fdd8201dSApple OSS Distributions local_result,
318*fdd8201dSApple OSS Distributions -1,
319*fdd8201dSApple OSS Distributions "Should be able to read from a "
320*fdd8201dSApple OSS Distributions "new class B file when locked"
321*fdd8201dSApple OSS Distributions );
322*fdd8201dSApple OSS Distributions
323*fdd8201dSApple OSS Distributions current_byte += local_result;
324*fdd8201dSApple OSS Distributions }
325*fdd8201dSApple OSS Distributions
326*fdd8201dSApple OSS Distributions /* We should not be able to open a class B file under lock. */
327*fdd8201dSApple OSS Distributions close(g_fd);
328*fdd8201dSApple OSS Distributions T_WITH_ERRNO;
329*fdd8201dSApple OSS Distributions T_ASSERT_EQ(
330*fdd8201dSApple OSS Distributions g_fd = open(g_filepath, O_RDWR | O_CLOEXEC),
331*fdd8201dSApple OSS Distributions -1,
332*fdd8201dSApple OSS Distributions "Should not be able to open a class B file when locked"
333*fdd8201dSApple OSS Distributions );
334*fdd8201dSApple OSS Distributions
335*fdd8201dSApple OSS Distributions unlink(g_filepath);
336*fdd8201dSApple OSS Distributions
337*fdd8201dSApple OSS Distributions /* We still need to test directory semantics. */
338*fdd8201dSApple OSS Distributions T_WITH_ERRNO;
339*fdd8201dSApple OSS Distributions T_ASSERT_NE(
340*fdd8201dSApple OSS Distributions mkdir(g_dirpath, 0x0777),
341*fdd8201dSApple OSS Distributions -1,
342*fdd8201dSApple OSS Distributions "Should be able to create a new directory when locked"
343*fdd8201dSApple OSS Distributions );
344*fdd8201dSApple OSS Distributions
345*fdd8201dSApple OSS Distributions /* The newly created directory should not have a protection class. */
346*fdd8201dSApple OSS Distributions T_ASSERT_NE(
347*fdd8201dSApple OSS Distributions g_dir_fd = open(g_dirpath, O_RDONLY | O_CLOEXEC),
348*fdd8201dSApple OSS Distributions -1,
349*fdd8201dSApple OSS Distributions "Should be able to open an unclassed directory when locked"
350*fdd8201dSApple OSS Distributions );
351*fdd8201dSApple OSS Distributions
352*fdd8201dSApple OSS Distributions T_ASSERT_TRUE(
353*fdd8201dSApple OSS Distributions GET_PROT_CLASS(g_dir_fd) == PROTECTION_CLASS_D ||
354*fdd8201dSApple OSS Distributions GET_PROT_CLASS(g_dir_fd) == PROTECTION_CLASS_DIR_NONE,
355*fdd8201dSApple OSS Distributions "Directory protection class sholud be D or NONE"
356*fdd8201dSApple OSS Distributions );
357*fdd8201dSApple OSS Distributions
358*fdd8201dSApple OSS Distributions T_ASSERT_EQ(
359*fdd8201dSApple OSS Distributions SET_PROT_CLASS(g_dir_fd, PROTECTION_CLASS_A),
360*fdd8201dSApple OSS Distributions 0,
361*fdd8201dSApple OSS Distributions "Should be able to change a directory from "
362*fdd8201dSApple OSS Distributions "class D to class A while locked"
363*fdd8201dSApple OSS Distributions );
364*fdd8201dSApple OSS Distributions
365*fdd8201dSApple OSS Distributions T_ASSERT_EQ(
366*fdd8201dSApple OSS Distributions SET_PROT_CLASS(g_dir_fd, PROTECTION_CLASS_D),
367*fdd8201dSApple OSS Distributions 0,
368*fdd8201dSApple OSS Distributions "Should be able to change a directory from "
369*fdd8201dSApple OSS Distributions "class A to class D while locked"
370*fdd8201dSApple OSS Distributions );
371*fdd8201dSApple OSS Distributions
372*fdd8201dSApple OSS Distributions /*
373*fdd8201dSApple OSS Distributions * Do all files created in the directory properly inherit the
374*fdd8201dSApple OSS Distributions * directory's protection class?
375*fdd8201dSApple OSS Distributions */
376*fdd8201dSApple OSS Distributions T_SETUPBEGIN;
377*fdd8201dSApple OSS Distributions T_ASSERT_LT(
378*fdd8201dSApple OSS Distributions strlcpy(g_filepath, g_dirpath, PATH_MAX),
379*fdd8201dSApple OSS Distributions PATH_MAX,
380*fdd8201dSApple OSS Distributions "Construct path for file in the directory"
381*fdd8201dSApple OSS Distributions );
382*fdd8201dSApple OSS Distributions T_ASSERT_LT(
383*fdd8201dSApple OSS Distributions strlcat(g_filepath, "test_file", PATH_MAX),
384*fdd8201dSApple OSS Distributions PATH_MAX,
385*fdd8201dSApple OSS Distributions "Construct path for file in the directory"
386*fdd8201dSApple OSS Distributions );
387*fdd8201dSApple OSS Distributions T_SETUPEND;
388*fdd8201dSApple OSS Distributions
389*fdd8201dSApple OSS Distributions T_ASSERT_EQ(unlock_device(TEST_PASSCODE), 0, "*** Unlock device ***");
390*fdd8201dSApple OSS Distributions
391*fdd8201dSApple OSS Distributions for (
392*fdd8201dSApple OSS Distributions new_prot_class = PROTECTION_CLASS_A;
393*fdd8201dSApple OSS Distributions new_prot_class <= PROTECTION_CLASS_D;
394*fdd8201dSApple OSS Distributions new_prot_class++
395*fdd8201dSApple OSS Distributions ) {
396*fdd8201dSApple OSS Distributions int getclass_dir;
397*fdd8201dSApple OSS Distributions
398*fdd8201dSApple OSS Distributions T_WITH_ERRNO;
399*fdd8201dSApple OSS Distributions T_ASSERT_NE(
400*fdd8201dSApple OSS Distributions old_prot_class = GET_PROT_CLASS(g_dir_fd),
401*fdd8201dSApple OSS Distributions -1,
402*fdd8201dSApple OSS Distributions "Get protection class for the directory"
403*fdd8201dSApple OSS Distributions );
404*fdd8201dSApple OSS Distributions
405*fdd8201dSApple OSS Distributions T_WITH_ERRNO;
406*fdd8201dSApple OSS Distributions T_ASSERT_EQ(
407*fdd8201dSApple OSS Distributions SET_PROT_CLASS(g_dir_fd, new_prot_class),
408*fdd8201dSApple OSS Distributions 0,
409*fdd8201dSApple OSS Distributions "Should be able to change directory "
410*fdd8201dSApple OSS Distributions "protection from %s to %s",
411*fdd8201dSApple OSS Distributions dp_class_num_to_string(old_prot_class),
412*fdd8201dSApple OSS Distributions dp_class_num_to_string(new_prot_class)
413*fdd8201dSApple OSS Distributions );
414*fdd8201dSApple OSS Distributions
415*fdd8201dSApple OSS Distributions T_EXPECT_EQ(
416*fdd8201dSApple OSS Distributions getclass_dir = GET_PROT_CLASS(g_dir_fd),
417*fdd8201dSApple OSS Distributions new_prot_class,
418*fdd8201dSApple OSS Distributions "Get protection class for the directory"
419*fdd8201dSApple OSS Distributions );
420*fdd8201dSApple OSS Distributions
421*fdd8201dSApple OSS Distributions T_WITH_ERRNO;
422*fdd8201dSApple OSS Distributions T_ASSERT_GE(
423*fdd8201dSApple OSS Distributions g_fd = open(g_filepath, O_CREAT | O_EXCL | O_CLOEXEC, 0777),
424*fdd8201dSApple OSS Distributions 0,
425*fdd8201dSApple OSS Distributions "Should be able to create file in "
426*fdd8201dSApple OSS Distributions "%s directory when unlocked",
427*fdd8201dSApple OSS Distributions dp_class_num_to_string(new_prot_class)
428*fdd8201dSApple OSS Distributions );
429*fdd8201dSApple OSS Distributions
430*fdd8201dSApple OSS Distributions T_WITH_ERRNO;
431*fdd8201dSApple OSS Distributions T_ASSERT_NE(
432*fdd8201dSApple OSS Distributions local_result = GET_PROT_CLASS(g_fd),
433*fdd8201dSApple OSS Distributions -1,
434*fdd8201dSApple OSS Distributions "Get the new file's protection class"
435*fdd8201dSApple OSS Distributions );
436*fdd8201dSApple OSS Distributions
437*fdd8201dSApple OSS Distributions T_ASSERT_EQ(
438*fdd8201dSApple OSS Distributions local_result,
439*fdd8201dSApple OSS Distributions new_prot_class,
440*fdd8201dSApple OSS Distributions "File should have %s protection",
441*fdd8201dSApple OSS Distributions dp_class_num_to_string(new_prot_class)
442*fdd8201dSApple OSS Distributions );
443*fdd8201dSApple OSS Distributions
444*fdd8201dSApple OSS Distributions close(g_fd);
445*fdd8201dSApple OSS Distributions unlink(g_filepath);
446*fdd8201dSApple OSS Distributions }
447*fdd8201dSApple OSS Distributions
448*fdd8201dSApple OSS Distributions /* Do we disallow creation of a class F directory? */
449*fdd8201dSApple OSS Distributions T_ASSERT_NE(
450*fdd8201dSApple OSS Distributions SET_PROT_CLASS(g_dir_fd, PROTECTION_CLASS_F),
451*fdd8201dSApple OSS Distributions 0,
452*fdd8201dSApple OSS Distributions "Should not be able to create class F directory"
453*fdd8201dSApple OSS Distributions );
454*fdd8201dSApple OSS Distributions
455*fdd8201dSApple OSS Distributions /*
456*fdd8201dSApple OSS Distributions * Are class A and class B semantics followed for when
457*fdd8201dSApple OSS Distributions * we create these files during lock?
458*fdd8201dSApple OSS Distributions */
459*fdd8201dSApple OSS Distributions T_WITH_ERRNO;
460*fdd8201dSApple OSS Distributions T_ASSERT_EQ(
461*fdd8201dSApple OSS Distributions SET_PROT_CLASS(g_dir_fd, PROTECTION_CLASS_A),
462*fdd8201dSApple OSS Distributions 0,
463*fdd8201dSApple OSS Distributions "Should be able to change protection "
464*fdd8201dSApple OSS Distributions "from class F to class A when unlocked"
465*fdd8201dSApple OSS Distributions );
466*fdd8201dSApple OSS Distributions
467*fdd8201dSApple OSS Distributions T_ASSERT_EQ(lock_device(), 0, "*** Lock device ***");
468*fdd8201dSApple OSS Distributions
469*fdd8201dSApple OSS Distributions T_ASSERT_EQ(
470*fdd8201dSApple OSS Distributions g_fd = open(g_filepath, O_CREAT | O_EXCL | O_CLOEXEC, 0777),
471*fdd8201dSApple OSS Distributions -1,
472*fdd8201dSApple OSS Distributions "Should not be able to create a new file "
473*fdd8201dSApple OSS Distributions "in a class A directory when locked"
474*fdd8201dSApple OSS Distributions );
475*fdd8201dSApple OSS Distributions
476*fdd8201dSApple OSS Distributions T_ASSERT_EQ(unlock_device(TEST_PASSCODE), 0, "*** Unlock device ***");
477*fdd8201dSApple OSS Distributions
478*fdd8201dSApple OSS Distributions T_WITH_ERRNO;
479*fdd8201dSApple OSS Distributions T_ASSERT_EQ(
480*fdd8201dSApple OSS Distributions SET_PROT_CLASS(g_dir_fd, PROTECTION_CLASS_B),
481*fdd8201dSApple OSS Distributions 0,
482*fdd8201dSApple OSS Distributions "Should be able to change directory "
483*fdd8201dSApple OSS Distributions "from class A to class B when unlocked"
484*fdd8201dSApple OSS Distributions );
485*fdd8201dSApple OSS Distributions
486*fdd8201dSApple OSS Distributions T_ASSERT_EQ(lock_device(), 0, "*** Lock device ***");
487*fdd8201dSApple OSS Distributions
488*fdd8201dSApple OSS Distributions T_ASSERT_GE(
489*fdd8201dSApple OSS Distributions g_fd = open(g_filepath, O_CREAT | O_EXCL | O_RDWR | O_CLOEXEC, 0777),
490*fdd8201dSApple OSS Distributions 0,
491*fdd8201dSApple OSS Distributions "Should be able to create a new file "
492*fdd8201dSApple OSS Distributions "in class B directory when locked"
493*fdd8201dSApple OSS Distributions );
494*fdd8201dSApple OSS Distributions
495*fdd8201dSApple OSS Distributions T_ASSERT_NE(
496*fdd8201dSApple OSS Distributions local_result = GET_PROT_CLASS(g_fd),
497*fdd8201dSApple OSS Distributions -1,
498*fdd8201dSApple OSS Distributions "Get the new file's protection class"
499*fdd8201dSApple OSS Distributions );
500*fdd8201dSApple OSS Distributions
501*fdd8201dSApple OSS Distributions T_ASSERT_EQ(
502*fdd8201dSApple OSS Distributions local_result,
503*fdd8201dSApple OSS Distributions PROTECTION_CLASS_B,
504*fdd8201dSApple OSS Distributions "File should inherit protection class of class B directory"
505*fdd8201dSApple OSS Distributions );
506*fdd8201dSApple OSS Distributions
507*fdd8201dSApple OSS Distributions /* What happens when we try to create new subdirectories? */
508*fdd8201dSApple OSS Distributions T_ASSERT_EQ(unlock_device(TEST_PASSCODE), 0, "*** Unlock device ***");
509*fdd8201dSApple OSS Distributions
510*fdd8201dSApple OSS Distributions for (
511*fdd8201dSApple OSS Distributions new_prot_class = PROTECTION_CLASS_A;
512*fdd8201dSApple OSS Distributions new_prot_class <= PROTECTION_CLASS_D;
513*fdd8201dSApple OSS Distributions new_prot_class++
514*fdd8201dSApple OSS Distributions ) {
515*fdd8201dSApple OSS Distributions T_WITH_ERRNO;
516*fdd8201dSApple OSS Distributions T_ASSERT_EQ(
517*fdd8201dSApple OSS Distributions SET_PROT_CLASS(g_dir_fd, new_prot_class),
518*fdd8201dSApple OSS Distributions 0,
519*fdd8201dSApple OSS Distributions "Change directory to %s",
520*fdd8201dSApple OSS Distributions dp_class_num_to_string(new_prot_class)
521*fdd8201dSApple OSS Distributions );
522*fdd8201dSApple OSS Distributions
523*fdd8201dSApple OSS Distributions T_WITH_ERRNO;
524*fdd8201dSApple OSS Distributions T_ASSERT_NE(
525*fdd8201dSApple OSS Distributions mkdir(g_subdirpath, 0x0777),
526*fdd8201dSApple OSS Distributions -1,
527*fdd8201dSApple OSS Distributions "Create subdirectory in %s directory",
528*fdd8201dSApple OSS Distributions dp_class_num_to_string(new_prot_class)
529*fdd8201dSApple OSS Distributions );
530*fdd8201dSApple OSS Distributions
531*fdd8201dSApple OSS Distributions T_WITH_ERRNO;
532*fdd8201dSApple OSS Distributions T_ASSERT_NE(
533*fdd8201dSApple OSS Distributions g_subdir_fd = open(g_subdirpath, O_RDONLY | O_CLOEXEC),
534*fdd8201dSApple OSS Distributions -1,
535*fdd8201dSApple OSS Distributions "Should be able to open subdirectory in %s directory",
536*fdd8201dSApple OSS Distributions dp_class_num_to_string(new_prot_class)
537*fdd8201dSApple OSS Distributions );
538*fdd8201dSApple OSS Distributions
539*fdd8201dSApple OSS Distributions T_ASSERT_NE(
540*fdd8201dSApple OSS Distributions local_result = GET_PROT_CLASS(g_subdir_fd),
541*fdd8201dSApple OSS Distributions -1,
542*fdd8201dSApple OSS Distributions "Get protection class of new subdirectory "
543*fdd8201dSApple OSS Distributions "of %s directory",
544*fdd8201dSApple OSS Distributions dp_class_num_to_string(new_prot_class)
545*fdd8201dSApple OSS Distributions );
546*fdd8201dSApple OSS Distributions
547*fdd8201dSApple OSS Distributions T_ASSERT_EQ(
548*fdd8201dSApple OSS Distributions local_result,
549*fdd8201dSApple OSS Distributions new_prot_class,
550*fdd8201dSApple OSS Distributions "New subdirectory should have same class as %s parent",
551*fdd8201dSApple OSS Distributions dp_class_num_to_string(new_prot_class)
552*fdd8201dSApple OSS Distributions );
553*fdd8201dSApple OSS Distributions
554*fdd8201dSApple OSS Distributions close(g_subdir_fd);
555*fdd8201dSApple OSS Distributions rmdir(g_subdirpath);
556*fdd8201dSApple OSS Distributions }
557*fdd8201dSApple OSS Distributions }
558*fdd8201dSApple OSS Distributions
559*fdd8201dSApple OSS Distributions void
setup(void)560*fdd8201dSApple OSS Distributions setup(void)
561*fdd8201dSApple OSS Distributions {
562*fdd8201dSApple OSS Distributions int ret = 0;
563*fdd8201dSApple OSS Distributions int local_result = -1;
564*fdd8201dSApple OSS Distributions
565*fdd8201dSApple OSS Distributions T_SETUPBEGIN;
566*fdd8201dSApple OSS Distributions
567*fdd8201dSApple OSS Distributions T_ATEND(cleanup);
568*fdd8201dSApple OSS Distributions
569*fdd8201dSApple OSS Distributions T_WITH_ERRNO;
570*fdd8201dSApple OSS Distributions T_ASSERT_NOTNULL(
571*fdd8201dSApple OSS Distributions mkdtemp(g_test_tempdir),
572*fdd8201dSApple OSS Distributions "Create temporary directory for test"
573*fdd8201dSApple OSS Distributions );
574*fdd8201dSApple OSS Distributions T_LOG("Test temp dir: %s", g_test_tempdir);
575*fdd8201dSApple OSS Distributions
576*fdd8201dSApple OSS Distributions T_ASSERT_NE(
577*fdd8201dSApple OSS Distributions local_result = supports_content_prot(),
578*fdd8201dSApple OSS Distributions -1,
579*fdd8201dSApple OSS Distributions "Get content protection support status"
580*fdd8201dSApple OSS Distributions );
581*fdd8201dSApple OSS Distributions
582*fdd8201dSApple OSS Distributions if (local_result == 0) {
583*fdd8201dSApple OSS Distributions T_SKIP("Data protection not supported on this system");
584*fdd8201dSApple OSS Distributions }
585*fdd8201dSApple OSS Distributions
586*fdd8201dSApple OSS Distributions T_ASSERT_EQ(
587*fdd8201dSApple OSS Distributions has_passcode(),
588*fdd8201dSApple OSS Distributions 0,
589*fdd8201dSApple OSS Distributions "Device should not have existing passcode"
590*fdd8201dSApple OSS Distributions );
591*fdd8201dSApple OSS Distributions
592*fdd8201dSApple OSS Distributions T_ASSERT_EQ(
593*fdd8201dSApple OSS Distributions set_passcode(TEST_PASSCODE, NULL),
594*fdd8201dSApple OSS Distributions 0,
595*fdd8201dSApple OSS Distributions "Set test passcode"
596*fdd8201dSApple OSS Distributions );
597*fdd8201dSApple OSS Distributions
598*fdd8201dSApple OSS Distributions bzero(g_filepath, PATH_MAX);
599*fdd8201dSApple OSS Distributions bzero(g_dirpath, PATH_MAX);
600*fdd8201dSApple OSS Distributions bzero(g_subdirpath, PATH_MAX);
601*fdd8201dSApple OSS Distributions
602*fdd8201dSApple OSS Distributions ret |= (strlcat(g_filepath, g_test_tempdir, PATH_MAX) == PATH_MAX);
603*fdd8201dSApple OSS Distributions ret |= (strlcat(g_filepath, "/", PATH_MAX) == PATH_MAX);
604*fdd8201dSApple OSS Distributions ret |= (strlcpy(g_dirpath, g_filepath, PATH_MAX) == PATH_MAX);
605*fdd8201dSApple OSS Distributions ret |= (strlcat(g_filepath, "test_file", PATH_MAX) == PATH_MAX);
606*fdd8201dSApple OSS Distributions ret |= (strlcat(g_dirpath, "test_dir/", PATH_MAX) == PATH_MAX);
607*fdd8201dSApple OSS Distributions ret |= (strlcpy(g_subdirpath, g_dirpath, PATH_MAX) == PATH_MAX);
608*fdd8201dSApple OSS Distributions ret |= (strlcat(g_subdirpath, "test_subdir/", PATH_MAX) == PATH_MAX);
609*fdd8201dSApple OSS Distributions
610*fdd8201dSApple OSS Distributions T_QUIET;
611*fdd8201dSApple OSS Distributions T_ASSERT_EQ(ret, 0, "Initialize test path strings");
612*fdd8201dSApple OSS Distributions
613*fdd8201dSApple OSS Distributions T_WITH_ERRNO;
614*fdd8201dSApple OSS Distributions T_ASSERT_GE(
615*fdd8201dSApple OSS Distributions g_fd = open(g_filepath, O_CREAT | O_EXCL | O_RDWR | O_CLOEXEC, 0777),
616*fdd8201dSApple OSS Distributions 0,
617*fdd8201dSApple OSS Distributions "Create test file"
618*fdd8201dSApple OSS Distributions );
619*fdd8201dSApple OSS Distributions
620*fdd8201dSApple OSS Distributions T_SETUPEND;
621*fdd8201dSApple OSS Distributions }
622*fdd8201dSApple OSS Distributions
623*fdd8201dSApple OSS Distributions void
cleanup(void)624*fdd8201dSApple OSS Distributions cleanup(void)
625*fdd8201dSApple OSS Distributions {
626*fdd8201dSApple OSS Distributions T_LOG("Cleaning up…");
627*fdd8201dSApple OSS Distributions
628*fdd8201dSApple OSS Distributions if (g_subdir_fd >= 0) {
629*fdd8201dSApple OSS Distributions T_LOG("Cleanup: closing fd %d", g_subdir_fd);
630*fdd8201dSApple OSS Distributions close(g_subdir_fd);
631*fdd8201dSApple OSS Distributions }
632*fdd8201dSApple OSS Distributions
633*fdd8201dSApple OSS Distributions if (g_subdirpath[0]) {
634*fdd8201dSApple OSS Distributions T_LOG("Cleanup: removing %s", g_subdirpath);
635*fdd8201dSApple OSS Distributions rmdir(g_subdirpath);
636*fdd8201dSApple OSS Distributions }
637*fdd8201dSApple OSS Distributions
638*fdd8201dSApple OSS Distributions if (g_fd >= 0) {
639*fdd8201dSApple OSS Distributions T_LOG("Cleanup: closing fd %d", g_fd);
640*fdd8201dSApple OSS Distributions close(g_fd);
641*fdd8201dSApple OSS Distributions }
642*fdd8201dSApple OSS Distributions
643*fdd8201dSApple OSS Distributions if (g_filepath[0]) {
644*fdd8201dSApple OSS Distributions T_LOG("Cleanup: removing %s", g_filepath);
645*fdd8201dSApple OSS Distributions unlink(g_filepath);
646*fdd8201dSApple OSS Distributions }
647*fdd8201dSApple OSS Distributions
648*fdd8201dSApple OSS Distributions if (g_dir_fd >= 0) {
649*fdd8201dSApple OSS Distributions T_LOG("Cleanup: closing fd %d", g_dir_fd);
650*fdd8201dSApple OSS Distributions close(g_dir_fd);
651*fdd8201dSApple OSS Distributions }
652*fdd8201dSApple OSS Distributions
653*fdd8201dSApple OSS Distributions if (g_dirpath[0]) {
654*fdd8201dSApple OSS Distributions T_LOG("Cleanup: removing %s", g_dirpath);
655*fdd8201dSApple OSS Distributions rmdir(g_dirpath);
656*fdd8201dSApple OSS Distributions }
657*fdd8201dSApple OSS Distributions
658*fdd8201dSApple OSS Distributions if (strcmp(g_test_tempdir, TEMP_DIR_TEMPLATE)) {
659*fdd8201dSApple OSS Distributions T_LOG("Cleanup: removing %s", g_test_tempdir);
660*fdd8201dSApple OSS Distributions rmdir(g_test_tempdir);
661*fdd8201dSApple OSS Distributions }
662*fdd8201dSApple OSS Distributions
663*fdd8201dSApple OSS Distributions if (g_passcode_set) {
664*fdd8201dSApple OSS Distributions T_LOG("Cleanup: unlocking device");
665*fdd8201dSApple OSS Distributions if (unlock_device(TEST_PASSCODE)) {
666*fdd8201dSApple OSS Distributions T_LOG("Warning: failed to unlock device in cleanup");
667*fdd8201dSApple OSS Distributions }
668*fdd8201dSApple OSS Distributions
669*fdd8201dSApple OSS Distributions T_LOG("Cleanup: clearing passcode");
670*fdd8201dSApple OSS Distributions if (clear_passcode(TEST_PASSCODE)) {
671*fdd8201dSApple OSS Distributions T_LOG("Warning: failed to clear passcode in cleanup");
672*fdd8201dSApple OSS Distributions }
673*fdd8201dSApple OSS Distributions }
674*fdd8201dSApple OSS Distributions }
675*fdd8201dSApple OSS Distributions
676*fdd8201dSApple OSS Distributions int
set_passcode(char * new_passcode,char * old_passcode)677*fdd8201dSApple OSS Distributions set_passcode(char * new_passcode, char * old_passcode)
678*fdd8201dSApple OSS Distributions {
679*fdd8201dSApple OSS Distributions int result = -1;
680*fdd8201dSApple OSS Distributions
681*fdd8201dSApple OSS Distributions #ifdef KEYBAG_ENTITLEMENTS
682*fdd8201dSApple OSS Distributions /* If we're entitled, we can set the passcode ourselves. */
683*fdd8201dSApple OSS Distributions uint64_t inputs[] = {device_keybag_handle};
684*fdd8201dSApple OSS Distributions uint32_t input_count = (sizeof(inputs) / sizeof(*inputs));
685*fdd8201dSApple OSS Distributions void * input_structs = NULL;
686*fdd8201dSApple OSS Distributions size_t input_struct_count = 0;
687*fdd8201dSApple OSS Distributions char buffer[CPT_AKS_BUF_SIZE];
688*fdd8201dSApple OSS Distributions char * buffer_ptr = buffer;
689*fdd8201dSApple OSS Distributions uint32_t old_passcode_len = 0;
690*fdd8201dSApple OSS Distributions uint32_t new_passcode_len = 0;
691*fdd8201dSApple OSS Distributions
692*fdd8201dSApple OSS Distributions T_LOG("%s(): using keybag entitlements", __func__);
693*fdd8201dSApple OSS Distributions
694*fdd8201dSApple OSS Distributions old_passcode_len = strnlen(old_passcode, CPT_MAX_PASS_LEN);
695*fdd8201dSApple OSS Distributions new_passcode_len = strnlen(new_passcode, CPT_MAX_PASS_LEN);
696*fdd8201dSApple OSS Distributions
697*fdd8201dSApple OSS Distributions if ((old_passcode == NULL) || (old_passcode_len == CPT_MAX_PASS_LEN)) {
698*fdd8201dSApple OSS Distributions old_passcode = "";
699*fdd8201dSApple OSS Distributions old_passcode_len = 0;
700*fdd8201dSApple OSS Distributions }
701*fdd8201dSApple OSS Distributions if ((new_passcode == NULL) || (new_passcode_len == CPT_MAX_PASS_LEN)) {
702*fdd8201dSApple OSS Distributions new_passcode = "";
703*fdd8201dSApple OSS Distributions new_passcode_len = 0;
704*fdd8201dSApple OSS Distributions }
705*fdd8201dSApple OSS Distributions
706*fdd8201dSApple OSS Distributions *((uint32_t *) buffer_ptr) = ((uint32_t) 2);
707*fdd8201dSApple OSS Distributions buffer_ptr += sizeof(uint32_t);
708*fdd8201dSApple OSS Distributions
709*fdd8201dSApple OSS Distributions *((uint32_t *) buffer_ptr) = old_passcode_len;
710*fdd8201dSApple OSS Distributions buffer_ptr += sizeof(uint32_t);
711*fdd8201dSApple OSS Distributions
712*fdd8201dSApple OSS Distributions memcpy(buffer_ptr, old_passcode, old_passcode_len);
713*fdd8201dSApple OSS Distributions buffer_ptr += ((old_passcode_len + sizeof(uint32_t) - 1) &
714*fdd8201dSApple OSS Distributions ~(sizeof(uint32_t) - 1));
715*fdd8201dSApple OSS Distributions
716*fdd8201dSApple OSS Distributions *((uint32_t *) buffer_ptr) = new_passcode_len;
717*fdd8201dSApple OSS Distributions buffer_ptr += sizeof(uint32_t);
718*fdd8201dSApple OSS Distributions
719*fdd8201dSApple OSS Distributions memcpy(buffer_ptr, new_passcode, new_passcode_len);
720*fdd8201dSApple OSS Distributions buffer_ptr += ((new_passcode_len + sizeof(uint32_t) - 1) &
721*fdd8201dSApple OSS Distributions ~(sizeof(uint32_t) - 1));
722*fdd8201dSApple OSS Distributions
723*fdd8201dSApple OSS Distributions input_structs = buffer;
724*fdd8201dSApple OSS Distributions input_struct_count = (buffer_ptr - buffer);
725*fdd8201dSApple OSS Distributions
726*fdd8201dSApple OSS Distributions result = apple_key_store(
727*fdd8201dSApple OSS Distributions kAppleKeyStoreKeyBagSetPasscode,
728*fdd8201dSApple OSS Distributions inputs,
729*fdd8201dSApple OSS Distributions input_count,
730*fdd8201dSApple OSS Distributions input_structs,
731*fdd8201dSApple OSS Distributions input_struct_count,
732*fdd8201dSApple OSS Distributions NULL,
733*fdd8201dSApple OSS Distributions NULL
734*fdd8201dSApple OSS Distributions );
735*fdd8201dSApple OSS Distributions #else
736*fdd8201dSApple OSS Distributions /*
737*fdd8201dSApple OSS Distributions * If we aren't entitled, we'll need to use
738*fdd8201dSApple OSS Distributions * keystorectl to set the passcode.
739*fdd8201dSApple OSS Distributions */
740*fdd8201dSApple OSS Distributions T_LOG("%s(): using keystorectl", __func__);
741*fdd8201dSApple OSS Distributions
742*fdd8201dSApple OSS Distributions if (
743*fdd8201dSApple OSS Distributions (old_passcode == NULL) ||
744*fdd8201dSApple OSS Distributions (strnlen(old_passcode, CPT_MAX_PASS_LEN) == CPT_MAX_PASS_LEN)
745*fdd8201dSApple OSS Distributions ) {
746*fdd8201dSApple OSS Distributions old_passcode = "";
747*fdd8201dSApple OSS Distributions }
748*fdd8201dSApple OSS Distributions
749*fdd8201dSApple OSS Distributions if (
750*fdd8201dSApple OSS Distributions (new_passcode == NULL) ||
751*fdd8201dSApple OSS Distributions (strnlen(new_passcode, CPT_MAX_PASS_LEN) == CPT_MAX_PASS_LEN)
752*fdd8201dSApple OSS Distributions ) {
753*fdd8201dSApple OSS Distributions new_passcode = "";
754*fdd8201dSApple OSS Distributions }
755*fdd8201dSApple OSS Distributions
756*fdd8201dSApple OSS Distributions char * const keystorectl_args[] = {
757*fdd8201dSApple OSS Distributions KEYBAGDTEST_PATH,
758*fdd8201dSApple OSS Distributions "syspass",
759*fdd8201dSApple OSS Distributions old_passcode,
760*fdd8201dSApple OSS Distributions new_passcode,
761*fdd8201dSApple OSS Distributions NULL
762*fdd8201dSApple OSS Distributions };
763*fdd8201dSApple OSS Distributions result = spawn_proc(keystorectl_args);
764*fdd8201dSApple OSS Distributions #endif /* KEYBAG_ENTITLEMENTS */
765*fdd8201dSApple OSS Distributions if (result == 0 && new_passcode != NULL) {
766*fdd8201dSApple OSS Distributions g_passcode_set = 1;
767*fdd8201dSApple OSS Distributions } else if (result == 0 && new_passcode == NULL) {
768*fdd8201dSApple OSS Distributions g_passcode_set = 0;
769*fdd8201dSApple OSS Distributions }
770*fdd8201dSApple OSS Distributions
771*fdd8201dSApple OSS Distributions return result;
772*fdd8201dSApple OSS Distributions }
773*fdd8201dSApple OSS Distributions
774*fdd8201dSApple OSS Distributions int
clear_passcode(char * passcode)775*fdd8201dSApple OSS Distributions clear_passcode(char * passcode)
776*fdd8201dSApple OSS Distributions {
777*fdd8201dSApple OSS Distributions /*
778*fdd8201dSApple OSS Distributions * For the moment, this will set the passcode to the empty string
779*fdd8201dSApple OSS Distributions * (a known value); this will most likely need to change, or running
780*fdd8201dSApple OSS Distributions * this test may ruin everything™
781*fdd8201dSApple OSS Distributions */
782*fdd8201dSApple OSS Distributions return set_passcode(NULL, passcode);
783*fdd8201dSApple OSS Distributions }
784*fdd8201dSApple OSS Distributions
785*fdd8201dSApple OSS Distributions int
has_passcode(void)786*fdd8201dSApple OSS Distributions has_passcode(void)
787*fdd8201dSApple OSS Distributions {
788*fdd8201dSApple OSS Distributions return set_passcode(NULL, NULL);
789*fdd8201dSApple OSS Distributions }
790*fdd8201dSApple OSS Distributions
791*fdd8201dSApple OSS Distributions int
lock_device(void)792*fdd8201dSApple OSS Distributions lock_device(void)
793*fdd8201dSApple OSS Distributions {
794*fdd8201dSApple OSS Distributions int result = -1;
795*fdd8201dSApple OSS Distributions
796*fdd8201dSApple OSS Distributions /*
797*fdd8201dSApple OSS Distributions * Pass in the path to keybagdTest instead. By doing this, we bypass
798*fdd8201dSApple OSS Distributions * the shortcut to get in to the keybag via IOKit and instead use the
799*fdd8201dSApple OSS Distributions * pre-existing command line tool.
800*fdd8201dSApple OSS Distributions *
801*fdd8201dSApple OSS Distributions * This also goes through the normal "lock → locking (10s) → locked"
802*fdd8201dSApple OSS Distributions * flow that would normally occuring during system runtime when the
803*fdd8201dSApple OSS Distributions * lock button is depressed. To ensure that our single threaded test
804*fdd8201dSApple OSS Distributions * works properly in this case, poll until we can't create a class A
805*fdd8201dSApple OSS Distributions * file to be safe.
806*fdd8201dSApple OSS Distributions */
807*fdd8201dSApple OSS Distributions char * const kbd_args[] = {KEYBAGDTEST_PATH, "lock", NULL};
808*fdd8201dSApple OSS Distributions result = spawn_proc(kbd_args);
809*fdd8201dSApple OSS Distributions if (result) {
810*fdd8201dSApple OSS Distributions return result;
811*fdd8201dSApple OSS Distributions }
812*fdd8201dSApple OSS Distributions
813*fdd8201dSApple OSS Distributions /*
814*fdd8201dSApple OSS Distributions * Delete the file if it is present. Note that this may fail if the
815*fdd8201dSApple OSS Distributions * file is actually not there. So don't bomb out if we can't delete
816*fdd8201dSApple OSS Distributions * this file right now.
817*fdd8201dSApple OSS Distributions */
818*fdd8201dSApple OSS Distributions (void) unlink("/private/var/foo_test_file");
819*fdd8201dSApple OSS Distributions
820*fdd8201dSApple OSS Distributions while (1) {
821*fdd8201dSApple OSS Distributions int dp_fd;
822*fdd8201dSApple OSS Distributions
823*fdd8201dSApple OSS Distributions dp_fd = open_dprotected_np(
824*fdd8201dSApple OSS Distributions "/private/var/foo_test_file",
825*fdd8201dSApple OSS Distributions O_RDWR | O_CREAT,
826*fdd8201dSApple OSS Distributions PROTECTION_CLASS_A,
827*fdd8201dSApple OSS Distributions 0
828*fdd8201dSApple OSS Distributions );
829*fdd8201dSApple OSS Distributions
830*fdd8201dSApple OSS Distributions if (dp_fd >= 0) {
831*fdd8201dSApple OSS Distributions /* delete it and sleep */
832*fdd8201dSApple OSS Distributions close(dp_fd);
833*fdd8201dSApple OSS Distributions result = unlink("/private/var/foo_test_file");
834*fdd8201dSApple OSS Distributions
835*fdd8201dSApple OSS Distributions if (result) {
836*fdd8201dSApple OSS Distributions return result;
837*fdd8201dSApple OSS Distributions }
838*fdd8201dSApple OSS Distributions
839*fdd8201dSApple OSS Distributions sync();
840*fdd8201dSApple OSS Distributions sleep(1);
841*fdd8201dSApple OSS Distributions } else {
842*fdd8201dSApple OSS Distributions /* drop out of our polling loop. */
843*fdd8201dSApple OSS Distributions break;
844*fdd8201dSApple OSS Distributions }
845*fdd8201dSApple OSS Distributions }
846*fdd8201dSApple OSS Distributions
847*fdd8201dSApple OSS Distributions /*
848*fdd8201dSApple OSS Distributions * Note that our loop breakout condition is whether or not we can
849*fdd8201dSApple OSS Distributions * create a class A file, so that loop may execute up to 10 times
850*fdd8201dSApple OSS Distributions * (due to the 10s grace period). By the time we get here, we assume
851*fdd8201dSApple OSS Distributions * that we didn't hit any of the error cases above.
852*fdd8201dSApple OSS Distributions */
853*fdd8201dSApple OSS Distributions
854*fdd8201dSApple OSS Distributions return 0;
855*fdd8201dSApple OSS Distributions }
856*fdd8201dSApple OSS Distributions
857*fdd8201dSApple OSS Distributions int
unlock_device(char * passcode)858*fdd8201dSApple OSS Distributions unlock_device(char * passcode)
859*fdd8201dSApple OSS Distributions {
860*fdd8201dSApple OSS Distributions int result = -1;
861*fdd8201dSApple OSS Distributions
862*fdd8201dSApple OSS Distributions #ifdef KEYBAG_ENTITLEMENTS
863*fdd8201dSApple OSS Distributions /* If we're entitled, we can unlock the device ourselves. */
864*fdd8201dSApple OSS Distributions uint64_t inputs[] = {device_keybag_handle};
865*fdd8201dSApple OSS Distributions uint32_t input_count = (sizeof(inputs) / sizeof(*inputs));
866*fdd8201dSApple OSS Distributions size_t input_struct_count = 0;
867*fdd8201dSApple OSS Distributions
868*fdd8201dSApple OSS Distributions T_LOG("%s(): using keybag entitlements", __func__);
869*fdd8201dSApple OSS Distributions
870*fdd8201dSApple OSS Distributions input_struct_count = strnlen(passcode, CPT_MAX_PASS_LEN);
871*fdd8201dSApple OSS Distributions if ((passcode == NULL) || (input_struct_count == CPT_MAX_PASS_LEN)) {
872*fdd8201dSApple OSS Distributions passcode = "";
873*fdd8201dSApple OSS Distributions input_struct_count = 0;
874*fdd8201dSApple OSS Distributions }
875*fdd8201dSApple OSS Distributions
876*fdd8201dSApple OSS Distributions result = apple_key_store(
877*fdd8201dSApple OSS Distributions kAppleKeyStoreKeyBagUnlock,
878*fdd8201dSApple OSS Distributions inputs,
879*fdd8201dSApple OSS Distributions input_count,
880*fdd8201dSApple OSS Distributions passcode,
881*fdd8201dSApple OSS Distributions input_struct_count,
882*fdd8201dSApple OSS Distributions NULL,
883*fdd8201dSApple OSS Distributions NULL
884*fdd8201dSApple OSS Distributions );
885*fdd8201dSApple OSS Distributions #else
886*fdd8201dSApple OSS Distributions /*
887*fdd8201dSApple OSS Distributions * If we aren't entitled, we'll need to use
888*fdd8201dSApple OSS Distributions * keystorectl to unlock the device.
889*fdd8201dSApple OSS Distributions */
890*fdd8201dSApple OSS Distributions T_LOG("%s(): using keystorectl", __func__);
891*fdd8201dSApple OSS Distributions
892*fdd8201dSApple OSS Distributions if (
893*fdd8201dSApple OSS Distributions (passcode == NULL) ||
894*fdd8201dSApple OSS Distributions (strnlen(passcode, CPT_MAX_PASS_LEN) == CPT_MAX_PASS_LEN)
895*fdd8201dSApple OSS Distributions ) {
896*fdd8201dSApple OSS Distributions passcode = "";
897*fdd8201dSApple OSS Distributions }
898*fdd8201dSApple OSS Distributions
899*fdd8201dSApple OSS Distributions char * const keystorectl_args[] = {
900*fdd8201dSApple OSS Distributions KEYSTORECTL_PATH, "unlock", passcode, NULL
901*fdd8201dSApple OSS Distributions };
902*fdd8201dSApple OSS Distributions
903*fdd8201dSApple OSS Distributions result = spawn_proc(keystorectl_args);
904*fdd8201dSApple OSS Distributions #endif /* KEYBAG_ENTITLEMENTS */
905*fdd8201dSApple OSS Distributions
906*fdd8201dSApple OSS Distributions return result;
907*fdd8201dSApple OSS Distributions }
908*fdd8201dSApple OSS Distributions
909*fdd8201dSApple OSS Distributions /*
910*fdd8201dSApple OSS Distributions * Code based on Mobile Key Bag; specifically
911*fdd8201dSApple OSS Distributions * MKBDeviceSupportsContentProtection and
912*fdd8201dSApple OSS Distributions * MKBDeviceFormattedForContentProtection.
913*fdd8201dSApple OSS Distributions *
914*fdd8201dSApple OSS Distributions * We want to verify that we support content protection, and that
915*fdd8201dSApple OSS Distributions * we are formatted for it.
916*fdd8201dSApple OSS Distributions */
917*fdd8201dSApple OSS Distributions int
supports_content_prot(void)918*fdd8201dSApple OSS Distributions supports_content_prot(void)
919*fdd8201dSApple OSS Distributions {
920*fdd8201dSApple OSS Distributions int local_result = -1;
921*fdd8201dSApple OSS Distributions int result = -1;
922*fdd8201dSApple OSS Distributions uint32_t buffer_size = 1;
923*fdd8201dSApple OSS Distributions char buffer[buffer_size];
924*fdd8201dSApple OSS Distributions io_registry_entry_t defaults = IO_OBJECT_NULL;
925*fdd8201dSApple OSS Distributions kern_return_t k_result = KERN_FAILURE;
926*fdd8201dSApple OSS Distributions struct statfs statfs_results;
927*fdd8201dSApple OSS Distributions
928*fdd8201dSApple OSS Distributions defaults = IORegistryEntryFromPath(
929*fdd8201dSApple OSS Distributions kIOMasterPortDefault,
930*fdd8201dSApple OSS Distributions kIODeviceTreePlane ":/defaults"
931*fdd8201dSApple OSS Distributions );
932*fdd8201dSApple OSS Distributions
933*fdd8201dSApple OSS Distributions if (defaults == IO_OBJECT_NULL) {
934*fdd8201dSApple OSS Distributions /* Assume data protection is unsupported */
935*fdd8201dSApple OSS Distributions T_LOG(
936*fdd8201dSApple OSS Distributions "%s(): no defaults entry in IORegistry",
937*fdd8201dSApple OSS Distributions __func__
938*fdd8201dSApple OSS Distributions );
939*fdd8201dSApple OSS Distributions return 0;
940*fdd8201dSApple OSS Distributions }
941*fdd8201dSApple OSS Distributions
942*fdd8201dSApple OSS Distributions k_result = IORegistryEntryGetProperty(
943*fdd8201dSApple OSS Distributions defaults,
944*fdd8201dSApple OSS Distributions "content-protect",
945*fdd8201dSApple OSS Distributions buffer,
946*fdd8201dSApple OSS Distributions &buffer_size
947*fdd8201dSApple OSS Distributions );
948*fdd8201dSApple OSS Distributions
949*fdd8201dSApple OSS Distributions if (k_result != KERN_SUCCESS) {
950*fdd8201dSApple OSS Distributions /* Assume data protection is unsupported */
951*fdd8201dSApple OSS Distributions T_LOG(
952*fdd8201dSApple OSS Distributions "%s(): no content-protect property in IORegistry",
953*fdd8201dSApple OSS Distributions __func__
954*fdd8201dSApple OSS Distributions );
955*fdd8201dSApple OSS Distributions return 0;
956*fdd8201dSApple OSS Distributions }
957*fdd8201dSApple OSS Distributions
958*fdd8201dSApple OSS Distributions /*
959*fdd8201dSApple OSS Distributions * At this point, we SUPPORT content protection… but are we
960*fdd8201dSApple OSS Distributions * formatted for it? This is ugly; we should be testing the file
961*fdd8201dSApple OSS Distributions * system we'll be testing in, not just /tmp/.
962*fdd8201dSApple OSS Distributions */
963*fdd8201dSApple OSS Distributions local_result = statfs(g_test_tempdir, &statfs_results);
964*fdd8201dSApple OSS Distributions
965*fdd8201dSApple OSS Distributions if (local_result == -1) {
966*fdd8201dSApple OSS Distributions T_LOG(
967*fdd8201dSApple OSS Distributions "%s(): failed to statfs the test directory, errno = %s",
968*fdd8201dSApple OSS Distributions __func__, strerror(errno)
969*fdd8201dSApple OSS Distributions );
970*fdd8201dSApple OSS Distributions return -1;
971*fdd8201dSApple OSS Distributions } else if (statfs_results.f_flags & MNT_CPROTECT) {
972*fdd8201dSApple OSS Distributions return 1;
973*fdd8201dSApple OSS Distributions } else {
974*fdd8201dSApple OSS Distributions T_LOG(
975*fdd8201dSApple OSS Distributions "%s(): filesystem not formatted for data protection",
976*fdd8201dSApple OSS Distributions __func__
977*fdd8201dSApple OSS Distributions );
978*fdd8201dSApple OSS Distributions return 0;
979*fdd8201dSApple OSS Distributions }
980*fdd8201dSApple OSS Distributions }
981*fdd8201dSApple OSS Distributions
982*fdd8201dSApple OSS Distributions /*
983*fdd8201dSApple OSS Distributions * Shamelessly ripped from keystorectl routines;
984*fdd8201dSApple OSS Distributions * a wrapper for invoking the AKS user client.
985*fdd8201dSApple OSS Distributions */
986*fdd8201dSApple OSS Distributions int
apple_key_store(uint32_t command,uint64_t * inputs,uint32_t input_count,void * input_structs,size_t input_struct_count,uint64_t * outputs,uint32_t * output_count)987*fdd8201dSApple OSS Distributions apple_key_store(uint32_t command,
988*fdd8201dSApple OSS Distributions uint64_t * inputs,
989*fdd8201dSApple OSS Distributions uint32_t input_count,
990*fdd8201dSApple OSS Distributions void * input_structs,
991*fdd8201dSApple OSS Distributions size_t input_struct_count,
992*fdd8201dSApple OSS Distributions uint64_t * outputs,
993*fdd8201dSApple OSS Distributions uint32_t * output_count)
994*fdd8201dSApple OSS Distributions {
995*fdd8201dSApple OSS Distributions int result = -1;
996*fdd8201dSApple OSS Distributions io_connect_t connection = IO_OBJECT_NULL;
997*fdd8201dSApple OSS Distributions io_registry_entry_t apple_key_bag_service = IO_OBJECT_NULL;
998*fdd8201dSApple OSS Distributions kern_return_t k_result = KERN_FAILURE;
999*fdd8201dSApple OSS Distributions IOReturn io_result = IO_OBJECT_NULL;
1000*fdd8201dSApple OSS Distributions
1001*fdd8201dSApple OSS Distributions apple_key_bag_service = IOServiceGetMatchingService(
1002*fdd8201dSApple OSS Distributions kIOMasterPortDefault,
1003*fdd8201dSApple OSS Distributions IOServiceMatching(kAppleKeyStoreServiceName)
1004*fdd8201dSApple OSS Distributions );
1005*fdd8201dSApple OSS Distributions if (apple_key_bag_service == IO_OBJECT_NULL) {
1006*fdd8201dSApple OSS Distributions T_LOG(
1007*fdd8201dSApple OSS Distributions "%s: failed to match kAppleKeyStoreServiceName",
1008*fdd8201dSApple OSS Distributions __func__
1009*fdd8201dSApple OSS Distributions );
1010*fdd8201dSApple OSS Distributions goto end;
1011*fdd8201dSApple OSS Distributions }
1012*fdd8201dSApple OSS Distributions
1013*fdd8201dSApple OSS Distributions k_result = IOServiceOpen(
1014*fdd8201dSApple OSS Distributions apple_key_bag_service,
1015*fdd8201dSApple OSS Distributions mach_task_self(),
1016*fdd8201dSApple OSS Distributions 0,
1017*fdd8201dSApple OSS Distributions &connection
1018*fdd8201dSApple OSS Distributions );
1019*fdd8201dSApple OSS Distributions if (k_result != KERN_SUCCESS) {
1020*fdd8201dSApple OSS Distributions T_LOG(
1021*fdd8201dSApple OSS Distributions "%s: failed to open AppleKeyStore: "
1022*fdd8201dSApple OSS Distributions "IOServiceOpen() returned %d",
1023*fdd8201dSApple OSS Distributions __func__, k_result
1024*fdd8201dSApple OSS Distributions );
1025*fdd8201dSApple OSS Distributions goto end;
1026*fdd8201dSApple OSS Distributions }
1027*fdd8201dSApple OSS Distributions
1028*fdd8201dSApple OSS Distributions k_result = IOConnectCallMethod(
1029*fdd8201dSApple OSS Distributions connection,
1030*fdd8201dSApple OSS Distributions kAppleKeyStoreUserClientOpen,
1031*fdd8201dSApple OSS Distributions NULL, 0, NULL, 0, NULL, NULL, NULL, NULL
1032*fdd8201dSApple OSS Distributions );
1033*fdd8201dSApple OSS Distributions if (k_result != KERN_SUCCESS) {
1034*fdd8201dSApple OSS Distributions T_LOG(
1035*fdd8201dSApple OSS Distributions "%s: call to AppleKeyStore method "
1036*fdd8201dSApple OSS Distributions "kAppleKeyStoreUserClientOpen failed",
1037*fdd8201dSApple OSS Distributions __func__
1038*fdd8201dSApple OSS Distributions );
1039*fdd8201dSApple OSS Distributions goto close;
1040*fdd8201dSApple OSS Distributions }
1041*fdd8201dSApple OSS Distributions
1042*fdd8201dSApple OSS Distributions io_result = IOConnectCallMethod(
1043*fdd8201dSApple OSS Distributions connection, command, inputs, input_count, input_structs,
1044*fdd8201dSApple OSS Distributions input_struct_count, outputs, output_count, NULL, NULL
1045*fdd8201dSApple OSS Distributions );
1046*fdd8201dSApple OSS Distributions if (io_result != kIOReturnSuccess) {
1047*fdd8201dSApple OSS Distributions T_LOG("%s: call to AppleKeyStore method %d failed", __func__, command);
1048*fdd8201dSApple OSS Distributions goto close;
1049*fdd8201dSApple OSS Distributions }
1050*fdd8201dSApple OSS Distributions
1051*fdd8201dSApple OSS Distributions result = 0;
1052*fdd8201dSApple OSS Distributions
1053*fdd8201dSApple OSS Distributions close:
1054*fdd8201dSApple OSS Distributions IOServiceClose(apple_key_bag_service);
1055*fdd8201dSApple OSS Distributions end:
1056*fdd8201dSApple OSS Distributions return result;
1057*fdd8201dSApple OSS Distributions }
1058*fdd8201dSApple OSS Distributions
1059*fdd8201dSApple OSS Distributions /*
1060*fdd8201dSApple OSS Distributions * Helper function for launching tools
1061*fdd8201dSApple OSS Distributions */
1062*fdd8201dSApple OSS Distributions int
spawn_proc(char * const command[])1063*fdd8201dSApple OSS Distributions spawn_proc(char * const command[])
1064*fdd8201dSApple OSS Distributions {
1065*fdd8201dSApple OSS Distributions pid_t pid = 0;
1066*fdd8201dSApple OSS Distributions int launch_tool_ret = 0;
1067*fdd8201dSApple OSS Distributions bool waitpid_ret = true;
1068*fdd8201dSApple OSS Distributions int status = 0;
1069*fdd8201dSApple OSS Distributions int signal = 0;
1070*fdd8201dSApple OSS Distributions int timeout = 30;
1071*fdd8201dSApple OSS Distributions
1072*fdd8201dSApple OSS Distributions launch_tool_ret = dt_launch_tool(&pid, command, false, NULL, NULL);
1073*fdd8201dSApple OSS Distributions T_EXPECT_EQ(launch_tool_ret, 0, "launch tool: %s", command[0]);
1074*fdd8201dSApple OSS Distributions if (launch_tool_ret != 0) {
1075*fdd8201dSApple OSS Distributions return 1;
1076*fdd8201dSApple OSS Distributions }
1077*fdd8201dSApple OSS Distributions
1078*fdd8201dSApple OSS Distributions waitpid_ret = dt_waitpid(pid, &status, &signal, timeout);
1079*fdd8201dSApple OSS Distributions T_EXPECT_TRUE(waitpid_ret, "%s should succeed", command[0]);
1080*fdd8201dSApple OSS Distributions if (waitpid_ret == false) {
1081*fdd8201dSApple OSS Distributions if (status != 0) {
1082*fdd8201dSApple OSS Distributions T_LOG("%s exited %d", command[0], status);
1083*fdd8201dSApple OSS Distributions }
1084*fdd8201dSApple OSS Distributions if (signal != 0) {
1085*fdd8201dSApple OSS Distributions T_LOG("%s received signal %d", command[0], signal);
1086*fdd8201dSApple OSS Distributions }
1087*fdd8201dSApple OSS Distributions return 1;
1088*fdd8201dSApple OSS Distributions }
1089*fdd8201dSApple OSS Distributions
1090*fdd8201dSApple OSS Distributions return 0;
1091*fdd8201dSApple OSS Distributions }
1092*fdd8201dSApple OSS Distributions
1093*fdd8201dSApple OSS Distributions char*
dp_class_num_to_string(int num)1094*fdd8201dSApple OSS Distributions dp_class_num_to_string(int num)
1095*fdd8201dSApple OSS Distributions {
1096*fdd8201dSApple OSS Distributions switch (num) {
1097*fdd8201dSApple OSS Distributions case 0:
1098*fdd8201dSApple OSS Distributions return "unclassed";
1099*fdd8201dSApple OSS Distributions case PROTECTION_CLASS_A:
1100*fdd8201dSApple OSS Distributions return "class A";
1101*fdd8201dSApple OSS Distributions case PROTECTION_CLASS_B:
1102*fdd8201dSApple OSS Distributions return "class B";
1103*fdd8201dSApple OSS Distributions case PROTECTION_CLASS_C:
1104*fdd8201dSApple OSS Distributions return "class C";
1105*fdd8201dSApple OSS Distributions case PROTECTION_CLASS_D:
1106*fdd8201dSApple OSS Distributions return "class D";
1107*fdd8201dSApple OSS Distributions case PROTECTION_CLASS_E:
1108*fdd8201dSApple OSS Distributions return "class E";
1109*fdd8201dSApple OSS Distributions case PROTECTION_CLASS_F:
1110*fdd8201dSApple OSS Distributions return "class F";
1111*fdd8201dSApple OSS Distributions default:
1112*fdd8201dSApple OSS Distributions return "<unknown class>";
1113*fdd8201dSApple OSS Distributions }
1114*fdd8201dSApple OSS Distributions }
1115*fdd8201dSApple OSS Distributions
1116*fdd8201dSApple OSS Distributions #if 0
1117*fdd8201dSApple OSS Distributions int
1118*fdd8201dSApple OSS Distributions device_lock_state(void)
1119*fdd8201dSApple OSS Distributions {
1120*fdd8201dSApple OSS Distributions /*
1121*fdd8201dSApple OSS Distributions * TODO: Actually implement this.
1122*fdd8201dSApple OSS Distributions *
1123*fdd8201dSApple OSS Distributions * We fail if a passcode already exists, and the methods being used
1124*fdd8201dSApple OSS Distributions * to lock/unlock the device in this test appear to be synchronous…
1125*fdd8201dSApple OSS Distributions * do we need this function?
1126*fdd8201dSApple OSS Distributions */
1127*fdd8201dSApple OSS Distributions int result = -1;
1128*fdd8201dSApple OSS Distributions
1129*fdd8201dSApple OSS Distributions return result;
1130*fdd8201dSApple OSS Distributions }
1131*fdd8201dSApple OSS Distributions
1132*fdd8201dSApple OSS Distributions /* Determines if we will try to test class C semanatics. */
1133*fdd8201dSApple OSS Distributions int
1134*fdd8201dSApple OSS Distributions unlocked_since_boot()
1135*fdd8201dSApple OSS Distributions {
1136*fdd8201dSApple OSS Distributions /*
1137*fdd8201dSApple OSS Distributions * TODO: Actually implement this.
1138*fdd8201dSApple OSS Distributions *
1139*fdd8201dSApple OSS Distributions * The actual semantics for CP mean that even with this primative,
1140*fdd8201dSApple OSS Distributions * we would need to set a passcode and then reboot the device in
1141*fdd8201dSApple OSS Distributions * order to test this; this function will probably be rather
1142*fdd8201dSApple OSS Distributions * worthless as a result.
1143*fdd8201dSApple OSS Distributions */
1144*fdd8201dSApple OSS Distributions int result = 1;
1145*fdd8201dSApple OSS Distributions
1146*fdd8201dSApple OSS Distributions return result;
1147*fdd8201dSApple OSS Distributions }
1148*fdd8201dSApple OSS Distributions #endif
1149