1 /*
2 * Copyright (c) 2006-2013 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 OR NON-INFRINGEMENT. Please see the
18 * License for the specific language governing rights and limitations
19 * under the License."
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24 #include <string.h>
25 #include <sys/types.h>
26 #include <sys/socket.h>
27 #include <sys/user.h>
28 #include <sys/un.h>
29 #include <fcntl.h>
30 #include <stdint.h>
31 #include <stdlib.h>
32 #include <errno.h>
33 #include <unistd.h>
34 #include <libutil.h>
35 #include <Block.h>
36 #include <dispatch/dispatch.h>
37 #include <os/base.h>
38 #include <os/assumes.h>
39 #include <xpc/xpc.h>
40 #include <syslog.h>
41 #include <asl_private.h>
42
43 static uint8_t *b64charset = (uint8_t *)"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
44
45 static int
asl_is_utf8_char(const unsigned char * p,int * state,int * ctype)46 asl_is_utf8_char(const unsigned char *p, int *state, int *ctype)
47 {
48 switch (*state)
49 {
50 case 0:
51 {
52 *ctype = 0;
53
54 if (*p >= 0x80)
55 {
56 *state = 1;
57 if ((*p >= 0xc2) && (*p <= 0xdf)) *ctype = 1;
58 else if (*p == 0xe0) *ctype = 2;
59 else if ((*p >= 0xe1) && (*p <= 0xef)) *ctype = 3;
60 else if (*p == 0xf0) *ctype = 4;
61 else if ((*p >= 0xf1) && (*p <= 0xf3)) *ctype = 5;
62 else if (*p == 0xf4) *ctype = 6;
63 else return 0;
64 }
65
66 break;
67 }
68
69 case 1:
70 {
71 switch (*ctype)
72 {
73 case 1:
74 {
75 if ((*p >= 0x80) && (*p <= 0xbf)) *state = 0;
76 else return 0;
77 break;
78 }
79
80 case 2:
81 {
82 if ((*p >= 0xa0) && (*p <= 0xbf)) *state = 2;
83 else return 0;
84 break;
85 }
86
87 case 3:
88 {
89 if ((*p >= 0x80) && (*p <= 0xbf)) *state = 2;
90 else return 0;
91 break;
92 }
93
94 case 4:
95 {
96 if ((*p >= 0x90) && (*p <= 0xbf)) *state = 2;
97 else return 0;
98 break;
99 }
100
101 case 5:
102 {
103 if ((*p >= 0x80) && (*p <= 0xbf)) *state = 2;
104 else return 0;
105 break;
106 }
107
108 case 6:
109 {
110 if ((*p >= 0x80) && (*p <= 0x8f)) *state = 2;
111 else return 0;
112 break;
113 }
114
115 default: return 0;
116 }
117
118 break;
119 }
120
121 case 2:
122 {
123 if ((*ctype >= 2) && (*ctype <= 3))
124 {
125 if ((*p >= 0x80) && (*p <= 0xbf)) *state = 0;
126 else return 0;
127 }
128 else if ((*ctype >= 4) && (*ctype <= 6))
129 {
130 if ((*p >= 0x80) && (*p <= 0xbf)) *state = 3;
131 else return 0;
132 }
133 else
134 {
135 return 0;
136 }
137
138 break;
139 }
140
141 case 3:
142 {
143 if ((*ctype >= 4) && (*ctype <= 6))
144 {
145 if ((*p >= 0x80) && (*p <= 0xbf)) *state = 0;
146 else return 0;
147 }
148 else
149 {
150 return 0;
151 }
152
153 break;
154 }
155
156 default: return 0;
157 }
158
159 return 1;
160 }
161
162 __private_extern__ int
asl_is_utf8(const char * str)163 asl_is_utf8(const char *str)
164 {
165 const unsigned char *p;
166 int flag = 1;
167 int state = 0;
168 int ctype = 0;
169
170 if (str == NULL) return flag;
171
172 for (p = (const unsigned char *)str; (*p != '\0') && (flag == 1); p++)
173 {
174 flag = asl_is_utf8_char(p, &state, &ctype);
175 }
176
177 return flag;
178 }
179
180 __private_extern__ uint8_t *
asl_b64_encode(const uint8_t * buf,size_t len)181 asl_b64_encode(const uint8_t *buf, size_t len)
182 {
183 uint8_t *out;
184 uint8_t b;
185 size_t i0, i1, i2, j, outlen;
186
187 if (buf == NULL) return NULL;
188 if (len == 0) return NULL;
189
190 outlen = ((len + 2) / 3) * 4;
191 out = (uint8_t *)malloc(outlen + 1);
192 if (out == NULL)
193 {
194 errno = ENOMEM;
195 return NULL;
196 }
197
198 out[outlen] = 0;
199
200 i0 = 0;
201 i1 = 1;
202 i2 = 2;
203 j = 0;
204
205 while (i2 < len)
206 {
207 b = buf[i0] >> 2;
208 out[j++] = b64charset[b];
209
210 b = ((buf[i0] & 0x03) << 4) | (buf[i1] >> 4);
211 out[j++] = b64charset[b];
212
213 b = ((buf[i1] & 0x0f) << 2) | ((buf[i2] & 0xc0) >> 6);
214 out[j++] = b64charset[b];
215
216 b = buf[i2] & 0x3f;
217 out[j++] = b64charset[b];
218
219 i0 += 3;
220 i1 = i0 + 1;
221 i2 = i1 + 1;
222 }
223
224 if (i0 < len)
225 {
226 b = buf[i0] >> 2;
227 out[j++] = b64charset[b];
228
229 b = (buf[i0] & 0x03) << 4;
230
231 if (i1 < len) b |= (buf[i1] >> 4);
232 out[j++] = b64charset[b];
233
234 if (i1 >= len)
235 {
236 out[j++] = '=';
237 out[j++] = '=';
238 return out;
239 }
240
241 b = (buf[i1] & 0x0f) << 2;
242 out[j++] = b64charset[b];
243 out[j++] = '=';
244 }
245
246 return out;
247 }
248
249 int
asl_syslog_faciliy_name_to_num(const char * name)250 asl_syslog_faciliy_name_to_num(const char *name)
251 {
252 if (name == NULL) return -1;
253
254 if (strcaseeq(name, "auth")) return LOG_AUTH;
255 if (strcaseeq(name, "authpriv")) return LOG_AUTHPRIV;
256 if (strcaseeq(name, "cron")) return LOG_CRON;
257 if (strcaseeq(name, "daemon")) return LOG_DAEMON;
258 if (strcaseeq(name, "ftp")) return LOG_FTP;
259 // if (strcaseeq(name, "install")) return LOG_INSTALL;
260 if (strcaseeq(name, "kern")) return LOG_KERN;
261 if (strcaseeq(name, "lpr")) return LOG_LPR;
262 if (strcaseeq(name, "mail")) return LOG_MAIL;
263 // if (strcaseeq(name, "netinfo")) return LOG_NETINFO;
264 // if (strcaseeq(name, "remoteauth")) return LOG_REMOTEAUTH;
265 if (strcaseeq(name, "news")) return LOG_NEWS;
266 if (strcaseeq(name, "security")) return LOG_AUTH;
267 if (strcaseeq(name, "syslog")) return LOG_SYSLOG;
268 if (strcaseeq(name, "user")) return LOG_USER;
269 if (strcaseeq(name, "uucp")) return LOG_UUCP;
270 if (strcaseeq(name, "local0")) return LOG_LOCAL0;
271 if (strcaseeq(name, "local1")) return LOG_LOCAL1;
272 if (strcaseeq(name, "local2")) return LOG_LOCAL2;
273 if (strcaseeq(name, "local3")) return LOG_LOCAL3;
274 if (strcaseeq(name, "local4")) return LOG_LOCAL4;
275 if (strcaseeq(name, "local5")) return LOG_LOCAL5;
276 if (strcaseeq(name, "local6")) return LOG_LOCAL6;
277 if (strcaseeq(name, "local7")) return LOG_LOCAL7;
278 if (strcaseeq(name, "launchd")) return LOG_LAUNCHD;
279
280 return -1;
281 }
282
283 const char *
asl_syslog_faciliy_num_to_name(int n)284 asl_syslog_faciliy_num_to_name(int n)
285 {
286 if (n < 0) return NULL;
287
288 if (n == LOG_AUTH) return "auth";
289 if (n == LOG_AUTHPRIV) return "authpriv";
290 if (n == LOG_CRON) return "cron";
291 if (n == LOG_DAEMON) return "daemon";
292 if (n == LOG_FTP) return "ftp";
293 // if (n == LOG_INSTALL) return "install";
294 if (n == LOG_KERN) return "kern";
295 if (n == LOG_LPR) return "lpr";
296 if (n == LOG_MAIL) return "mail";
297 // if (n == LOG_NETINFO) return "netinfo";
298 // if (n == LOG_REMOTEAUTH) return "remoteauth";
299 if (n == LOG_NEWS) return "news";
300 if (n == LOG_AUTH) return "security";
301 if (n == LOG_SYSLOG) return "syslog";
302 if (n == LOG_USER) return "user";
303 if (n == LOG_UUCP) return "uucp";
304 if (n == LOG_LOCAL0) return "local0";
305 if (n == LOG_LOCAL1) return "local1";
306 if (n == LOG_LOCAL2) return "local2";
307 if (n == LOG_LOCAL3) return "local3";
308 if (n == LOG_LOCAL4) return "local4";
309 if (n == LOG_LOCAL5) return "local5";
310 if (n == LOG_LOCAL6) return "local6";
311 if (n == LOG_LOCAL7) return "local7";
312 if (n == LOG_LAUNCHD) return "launchd";
313
314 return NULL;
315 }
316
317 __private_extern__ char *
get_argv0()318 get_argv0()
319 {
320 struct kinfo_proc *proc = kinfo_getproc(getpid());
321 char *argv0;
322
323 if (proc == NULL)
324 return (NULL);
325
326 argv0 = strdup(proc->ki_comm);
327 free(proc);
328 return (argv0);
329 }
330
331 #if 0
332 static xpc_connection_t
333 _create_aslmanager_connection(void)
334 {
335 xpc_connection_t connection;
336
337 connection = xpc_connection_create_mach_service(ASLMANAGER_SERVICE_NAME, NULL, XPC_CONNECTION_MACH_SERVICE_PRIVILEGED);
338 xpc_connection_set_event_handler(connection, ^(xpc_object_t xobj) { if (xobj != NULL) {}; });
339 xpc_connection_resume(connection);
340
341 return connection;
342 }
343
344 int
345 asl_trigger_aslmanager(void)
346 {
347 xpc_connection_t connection = _create_aslmanager_connection();
348 if (connection == NULL) return -1;
349
350 xpc_object_t request = xpc_dictionary_create(NULL, NULL, 0);
351 if (request == NULL) return -1;
352
353 xpc_object_t reply = xpc_connection_send_message_with_reply_sync(connection, request);
354
355 if (reply != NULL) xpc_release(reply);
356 xpc_release(request);
357 xpc_release(connection);
358 return 0;
359 }
360 #endif
361