xref: /NextBSD/lib/libasl/asl_util.c (revision 33da5adc555b3bc29986eeadca03829e4ad06b1e)
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