1/*
2 * Copyright (c) 2014 Apple Inc. All Rights Reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24
25#include <stdio.h>
26
27#include <utilities/SecCFRelease.h>
28#include <utilities/SecCFWrappers.h>
29#include <utilities/SecIOFormat.h>
30
31#include "utilities_regressions.h"
32#include "utilities/debugging.h"
33#include "utilities/debugging_test.h"
34
35#define kTestCount (39)
36
37static void
38tests(void) {
39    ok(IsScopeActive(ASL_LEVEL_ERR, NULL), "Errors are active by default");
40
41    ok(!IsScopeActive(ASL_LEVEL_INFO, CFSTR("testscope")), "scope is off");
42
43    ApplyScopeListForIDC("-first", kScopeIDXPC);
44
45    ok(IsScopeActive(ASL_LEVEL_INFO, CFSTR("testscope")), "scope is on");
46    ok(!IsScopeActive(ASL_LEVEL_INFO, CFSTR("first")), "scope is off");
47
48    ApplyScopeListForIDC("first", kScopeIDXPC);
49
50    ok(IsScopeActive(ASL_LEVEL_INFO, CFSTR("first")), "scope is on");
51    ok(!IsScopeActive(ASL_LEVEL_INFO, CFSTR("testscope")), "scope is off");
52
53    ApplyScopeListForIDC("testscope, bar, baz,frog", kScopeIDXPC);
54
55    ok(IsScopeActive(ASL_LEVEL_INFO, CFSTR("testscope")), "scope is on");
56    ok(IsScopeActive(ASL_LEVEL_INFO, CFSTR("bar")), "scope is on");
57    ok(IsScopeActive(ASL_LEVEL_INFO, CFSTR("baz")), "scope is on");
58    ok(IsScopeActive(ASL_LEVEL_INFO, CFSTR("frog")), "scope is on");
59    ok(!IsScopeActive(ASL_LEVEL_INFO, CFSTR("bonzo")), "scope is off");
60    ok(!IsScopeActive(ASL_LEVEL_INFO, CFSTR("nothing")), "scope is off");
61
62    ApplyScopeListForID(CFSTR("-bonzo, boy"), kScopeIDDefaults);
63
64    ok(IsScopeActive(ASL_LEVEL_INFO, CFSTR("testscope")), "scope is on");
65    ok(IsScopeActive(ASL_LEVEL_INFO, CFSTR("bar")), "scope is on");
66    ok(IsScopeActive(ASL_LEVEL_INFO, CFSTR("baz")), "scope is on");
67    ok(IsScopeActive(ASL_LEVEL_INFO, CFSTR("frog")), "scope is on");
68    ok(!IsScopeActive(ASL_LEVEL_INFO, CFSTR("bonzo")), "scope is off");
69    ok(IsScopeActive(ASL_LEVEL_INFO, CFSTR("nothing")), "scope is on");
70
71    ApplyScopeListForID(CFSTR(""), kScopeIDDefaults);
72
73    ok(IsScopeActive(ASL_LEVEL_INFO, CFSTR("testscope")), "scope is on");
74    ok(IsScopeActive(ASL_LEVEL_INFO, CFSTR("bar")), "scope is on");
75    ok(IsScopeActive(ASL_LEVEL_INFO, CFSTR("baz")), "scope is on");
76    ok(IsScopeActive(ASL_LEVEL_INFO, CFSTR("frog")), "scope is on");
77    ok(!IsScopeActive(ASL_LEVEL_INFO, CFSTR("bonzo")), "scope is off");
78    ok(!IsScopeActive(ASL_LEVEL_INFO, CFSTR("nothing")), "scope is on");
79
80    int value = ASL_LEVEL_NOTICE;
81    CFNumberRef noticeNumber = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &value);
82
83    value = ASL_LEVEL_INFO;
84    CFNumberRef infoNumber = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &value);
85
86    CFDictionaryRef settings_dictionary = CFDictionaryCreateForCFTypes(kCFAllocatorDefault,
87                                                                       CFSTR(ASL_STRING_DEBUG),     CFSTR("-baz"),
88                                                                       CFSTR(ASL_STRING_WARNING),   CFSTR("baz,bar"),
89                                                                       noticeNumber,                CFSTR("bar"),
90                                                                       infoNumber,                  CFSTR("baz"),
91                                                                       NULL);
92
93    ApplyScopeDictionaryForID(settings_dictionary, kScopeIDXPC);
94
95    ok(!IsScopeActive(ASL_LEVEL_INFO, CFSTR("testscope")), "scope is off");
96    ok(!IsScopeActive(ASL_LEVEL_INFO, CFSTR("bar")), "scope is off");
97    ok(IsScopeActive(ASL_LEVEL_INFO, CFSTR("baz")), "scope is on");
98
99    ok(!IsScopeActive(ASL_LEVEL_NOTICE, CFSTR("testscope")), "scope is off");
100    ok(IsScopeActive(ASL_LEVEL_NOTICE, CFSTR("bar")), "scope is on");
101    ok(!IsScopeActive(ASL_LEVEL_NOTICE, CFSTR("baz")), "scope is off");
102
103    ok(!IsScopeActive(ASL_LEVEL_WARNING, CFSTR("testscope")), "scope is off");
104    ok(IsScopeActive(ASL_LEVEL_WARNING, CFSTR("bar")), "scope is on");
105    ok(IsScopeActive(ASL_LEVEL_WARNING, CFSTR("baz")), "scope is on");
106
107    ok(IsScopeActive(ASL_LEVEL_DEBUG, CFSTR("testscope")), "scope is on");
108    ok(IsScopeActive(ASL_LEVEL_DEBUG, CFSTR("bar")), "scope is on");
109    ok(!IsScopeActive(ASL_LEVEL_DEBUG, CFSTR("baz")), "scope is off");
110
111    ok(!IsScopeActive(ASL_LEVEL_ALERT, CFSTR("testscope")), "scope is off");
112    ok(!IsScopeActive(ASL_LEVEL_ALERT, CFSTR("bar")), "scope is off");
113    ok(!IsScopeActive(ASL_LEVEL_ALERT, CFSTR("baz")), "scope is off");
114
115    CFReleaseSafe(noticeNumber);
116    CFReleaseSafe(infoNumber);
117    CFReleaseSafe(settings_dictionary);
118
119    ApplyScopeListForIDC("", kScopeIDXPC);
120    ApplyScopeListForIDC("", kScopeIDDefaults);
121
122}
123
124#if !defined(NDEBUG)
125#define kTestLogCount (6 + 5)
126#else
127#define kTestLogCount (6 + 1)
128#endif
129
130static void
131testLog()
132{
133    int value = ASL_LEVEL_NOTICE;
134    CFNumberRef noticeNumber = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &value);
135
136    value = ASL_LEVEL_INFO;
137    CFNumberRef infoNumber = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &value);
138
139    CFDictionaryRef settings_dictionary = CFDictionaryCreateForCFTypes(kCFAllocatorDefault,
140                                                                       CFSTR(ASL_STRING_DEBUG),     CFSTR("-baz"),
141                                                                       CFSTR(ASL_STRING_WARNING),   CFSTR("baz,bar"),
142                                                                       noticeNumber,                CFSTR("-bar"),
143                                                                       infoNumber,                  CFSTR("baz"),
144                                                                       NULL);
145
146
147    ApplyScopeDictionaryForID(settings_dictionary, kScopeIDXPC);
148
149    __block int level = -1;
150    __block CFStringRef scope = NULL;
151    __block CFStringRef message = NULL;
152    __block CFStringRef file = NULL;
153    __block CFStringRef function = NULL;
154    __block int line = 0;
155
156    __block bool called = false;
157
158    security_log_handler verify = ^(int level_sent, CFStringRef scope_sent, const char *functionC,
159                                     const char *fileC, int line_sent, CFStringRef message_sent) {
160        called = true;
161
162        level = level_sent;
163        scope = CFRetainSafe(scope_sent);
164        file = CFStringCreateWithCString(kCFAllocatorDefault, fileC, kCFStringEncodingUTF8);
165        function = CFStringCreateWithCString(kCFAllocatorDefault, functionC, kCFStringEncodingUTF8);
166        line = line_sent;
167        message = CFRetainSafe(message_sent);
168    };
169
170    add_security_log_handler(verify);
171
172    called = false; CFReleaseNull(scope); CFReleaseNull(message); CFReleaseNull(file); CFReleaseNull(function); level = -1; line = 0;
173
174    secdebug("bar", "Get this!");
175
176#if !defined(NDEBUG)
177    is(called, true, "Handler called");
178    is(level, ASL_LEVEL_DEBUG, "level");
179    eq_cf(scope, CFSTR("bar"), "Scope");
180    eq_cf(message, CFSTR("Get this!"), "message");
181    eq_cf(function, CFSTR("testLog"), "function");
182#else
183    is(called, false, "Handler not called");
184#endif
185
186    called = false;
187    CFReleaseNull(scope);
188    CFReleaseNull(message);
189    CFReleaseNull(function);
190
191    secnotice("bunz", "Get this, too!");
192
193    is(called, true, "Handler called");
194    is(level, ASL_LEVEL_NOTICE, "level");
195    eq_cf(scope, CFSTR("bunz"), "Scope");
196    eq_cf(message, CFSTR("Get this, too!"), "message");
197    eq_cf(function, CFSTR("testLog"), "function");
198
199    CFReleaseNull(scope);
200    CFReleaseNull(message);
201    CFReleaseNull(function);
202
203    remove_security_log_handler(verify);
204
205    CFReleaseSafe(settings_dictionary);
206    CFReleaseSafe(infoNumber);
207    CFReleaseSafe(noticeNumber);
208
209    CFPropertyListRef result = CopyCurrentScopePlist();
210
211    ok(result, "exported");
212
213    CFReleaseSafe(result);
214}
215
216int
217su_07_debugging(int argc, char *const *argv) {
218    plan_tests(kTestCount + kTestLogCount);
219    tests();
220    testLog();
221
222    return 0;
223}
224