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