]> git.saurik.com Git - apple/security.git/blob - SecurityTests/regressions/test/testsecevent.c
Security-57740.1.18.tar.gz
[apple/security.git] / SecurityTests / regressions / test / testsecevent.c
1 #include "testsecevent.h"
2
3 #include <assert.h>
4 #include <CoreFoundation/CFRunLoop.h>
5 #include <sys/time.h>
6
7 #include "testmore.h"
8 #include "testeventqueue.h"
9
10 static OSStatus test_sec_event_callback(SecKeychainEvent keychainEvent,
11 SecKeychainCallbackInfo *info, void *inContext)
12 {
13 if (keychainEvent == kSecLockEvent || keychainEvent == kSecUnlockEvent)
14 {
15 return 0;
16 }
17
18 CallbackData cd;
19 cd.event = keychainEvent;
20 cd.version = info->version;
21 cd.itemRef = info->item;
22 cd.keychain = info->keychain;
23 cd.pid = info->pid;
24
25 if (cd.itemRef)
26 {
27 CFRetain (cd.itemRef);
28 }
29
30 if (cd.keychain)
31 {
32 CFRetain (cd.keychain);
33 }
34
35
36 TEQ_Enqueue (&cd);
37
38 return 0;
39 }
40
41 OSStatus test_sec_event_register(SecKeychainEventMask mask)
42 {
43 return SecKeychainAddCallback(test_sec_event_callback, mask, NULL);
44 }
45
46 OSStatus test_sec_event_deregister()
47 {
48 return SecKeychainRemoveCallback(test_sec_event_callback);
49 }
50
51 double GetCurrentTime()
52 {
53 struct timeval tv;
54 gettimeofday(&tv, NULL);
55
56 double d = tv.tv_sec + tv.tv_usec / 1000000.0;
57 return d;
58 }
59
60
61
62 /* Get the next keychain event, and optionally return the events
63 keychain, item and pid. */
64 int test_is_sec_event(SecKeychainEvent event, SecKeychainRef *keychain,
65 SecKeychainItemRef *item, pid_t *pid, const char *description,
66 const char *directive, const char *reason, const char *file, unsigned line)
67 {
68 int expected = event == 0 ? 0 : 1;
69
70 if (event == 0) // looking for no event?
71 {
72 if (TEQ_ItemsInQueue() == 0)
73 {
74 return test_ok(TRUE,
75 description, directive, reason, file, line,
76 "", 0, 0);
77 }
78 }
79
80
81 double startTime = GetCurrentTime();
82 double nextTime = startTime + 2.0;
83 double currentTime;
84
85 while ((currentTime = GetCurrentTime()) < nextTime)
86 {
87 /* Run the runloop until we get an event. Don't hang for
88 more than 0.15 seconds though. */
89 SInt32 result = kCFRunLoopRunHandledSource;
90
91 if (TEQ_ItemsInQueue () == 0) // are there events left over?
92 result = CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.0, TRUE);
93
94 switch (result)
95 {
96 case kCFRunLoopRunFinished:
97 return test_ok(0, description, directive, reason, file, line,
98 "# no sources registered in runloop\n");
99 case kCFRunLoopRunStopped:
100 return test_ok(0, description, directive, reason, file, line,
101 "# runloop was stopped\n");
102 case kCFRunLoopRunTimedOut:
103 continue;
104
105 case kCFRunLoopRunHandledSource:
106 {
107 CallbackData cd;
108 bool dataInQueue;
109
110 if (expected)
111 {
112 dataInQueue = TEQ_Dequeue (&cd);
113 if (dataInQueue)
114 {
115 if (keychain != NULL)
116 *keychain = cd.keychain;
117 else if (cd.keychain)
118 CFRelease(cd.keychain);
119
120 if (item != NULL)
121 *item = cd.itemRef;
122 else if (cd.itemRef)
123 CFRelease(cd.itemRef);
124
125 return test_ok(cd.event == event,
126 description, directive, reason, file, line,
127 "# got: '%d'\n"
128 "# expected: '%d'\n",
129 cd.event, event);
130 }
131 else
132 {
133
134 // oops, we didn't get an event, even though we were looking for one.
135 return test_ok(0, description, directive, reason, file, line,
136 "# event expected but not received\n");
137 }
138 }
139
140 /* We didn't expect anything and we got one event or more. Report them */
141 dataInQueue = TEQ_Dequeue (&cd);
142 int unexpected_events = 0;
143 while (dataInQueue)
144 {
145 test_diag(directive, reason, file, line,
146 " got unexpected event: '%d'", cd.event);
147 unexpected_events++;
148 TEQ_Release (&cd);
149 dataInQueue = TEQ_Dequeue (&cd);
150 }
151 return test_ok(unexpected_events == 0, description, directive, reason, file, line,
152 "# got %d unexpected events\n", unexpected_events);
153 }
154
155 default:
156 return test_ok(0, description, directive, reason, file, line,
157 "# runloop returned: '%d'\n"
158 "# expected: 'kCFRunLoopRunHandledSource'\n",
159 result);
160 }
161 }
162
163 if (expected)
164 return test_ok(0, description, directive, reason,
165 file, line, "# runloop timed out waiting for event : %d\n",
166 event);
167 else
168 return test_ok(TRUE, description, directive, reason, file, line,
169 "# got %d unexpected events\n", 0);
170
171 }