]> git.saurik.com Git - apple/ipsec.git/blame - ipsec-tools/racoon/plog.c
ipsec-317.220.1.tar.gz
[apple/ipsec.git] / ipsec-tools / racoon / plog.c
CommitLineData
52b7d2ce
A
1/* $Id: plog.c,v 1.6.10.1 2005/12/07 10:19:51 vanhu Exp $ */
2
3/*
4 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the project nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32#include "config.h"
33
34#include <sys/types.h>
35#include <sys/param.h>
36
37#include <stdlib.h>
65c25746 38#include <fcntl.h>
52b7d2ce
A
39#include <stdio.h>
40#include <string.h>
41#include <errno.h>
42#ifdef HAVE_STDARG_H
43#include <stdarg.h>
44#else
45#include <varargs.h>
46#endif
47#if TIME_WITH_SYS_TIME
48# include <sys/time.h>
49# include <time.h>
50#else
51# if HAVE_SYS_TIME_H
52# include <sys/time.h>
53# else
54# include <time.h>
55# endif
56#endif
57#include <ctype.h>
58#include <err.h>
e8d9021d
A
59#include <pthread.h>
60#include <unistd.h>
65c25746
A
61#include <asl.h>
62#include <syslog.h>
63#include <asl_private.h>
52b7d2ce
A
64
65#include "var.h"
66#include "misc.h"
67#include "plog.h"
52b7d2ce
A
68#include "debug.h"
69#include "gcmalloc.h"
65c25746 70#include "preferences.h"
52b7d2ce
A
71
72#ifndef VA_COPY
d1e348cf 73# define VA_COPY(dst,src) memcpy(&(dst), (src), sizeof(va_list))
52b7d2ce
A
74#endif
75
65c25746
A
76const char *plog_facility = "com.apple.racoon";
77const char *plog_session_id = "com.apple.racoon.sessionid";
78const char *plog_session_type = "com.apple.racoon.sessiontype";
79const char *plog_session_ver = "com.apple.racoon.sessionversion";
80
52b7d2ce
A
81extern int print_pid;
82
83char *pname = NULL;
65c25746
A
84u_int32_t loglevel = ASL_LEVEL_NOTICE;
85//u_int32_t loglevel = ASL_LEVEL_DEBUG;
52b7d2ce
A
86int f_foreground = 0;
87
88int print_location = 0;
89
65c25746
A
90char *logfile = NULL;
91int logfile_fd = -1;
92char logFileStr[MAXPATHLEN+1];
93char *gSessId = NULL;
94char *gSessType = NULL;
95char *gSessVer = NULL;
96aslclient logRef = NULL;
52b7d2ce
A
97
98void
65c25746 99plogdump_asl (aslmsg msg, int pri, const char *fmt, ...)
e8d9021d 100{
65c25746
A
101 caddr_t buf;
102 size_t buflen = 512;
103 va_list args;
104 char *level;
e8d9021d 105
65c25746
A
106 switch (pri) {
107 case ASL_LEVEL_INFO:
108 level = ASL_STRING_INFO;
109 break;
52b7d2ce 110
65c25746
A
111 case ASL_LEVEL_NOTICE:
112 level = ASL_STRING_NOTICE;
113 break;
52b7d2ce 114
65c25746
A
115 case ASL_LEVEL_WARNING:
116 level = ASL_STRING_WARNING;
117 break;
118
119 case ASL_LEVEL_ERR:
120 level = ASL_STRING_ERR;
121 break;
122
123 case ASL_LEVEL_DEBUG:
124 level = ASL_STRING_DEBUG;
125 break;
126
127 default:
52b7d2ce 128 return;
65c25746 129 }
52b7d2ce 130
65c25746 131 asl_set(msg, ASL_KEY_LEVEL, level);
52b7d2ce 132
65c25746
A
133 buf = racoon_malloc(buflen);
134 if (buf) {
135 buf[0] = '\0';
136 va_start(args, fmt);
137 vsnprintf(buf, buflen, fmt, args);
138// asl_set(msg, ASL_KEY_MESSAGE, buf);
139 va_end(args);
140 racoon_free(buf);
52b7d2ce
A
141 }
142}
143
144void
65c25746 145plogdump_func(int pri, void *data, size_t len, const char *fmt, ...)
52b7d2ce
A
146{
147 caddr_t buf;
148 size_t buflen;
149 int i, j;
65c25746
A
150 va_list args;
151 char fmt_buf[512];
52b7d2ce
A
152
153 /*
154 * 2 words a bytes + 1 space 4 bytes + 1 newline 32 bytes
155 * + 2 newline + '\0'
156 */
157 buflen = (len * 2) + (len / 4) + (len / 32) + 3;
158 buf = racoon_malloc(buflen);
159
160 i = 0;
161 j = 0;
162 while (j < len) {
163 if (j % 32 == 0)
164 buf[i++] = '\n';
165 else
166 if (j % 4 == 0)
167 buf[i++] = ' ';
168 snprintf(&buf[i], buflen - i, "%02x",
169 ((unsigned char *)data)[j] & 0xff);
170 i += 2;
171 j++;
172 }
173 if (buflen - i >= 2) {
174 buf[i++] = '\n';
175 buf[i] = '\0';
176 }
65c25746
A
177
178 fmt_buf[0] = '\n';
179 va_start(args, fmt);
180 vsnprintf(fmt_buf, sizeof(fmt_buf), fmt, args);
181 va_end(args);
182
183 plog(pri, "%s %s", fmt_buf, buf);
52b7d2ce
A
184
185 racoon_free(buf);
186}
187
188void
65c25746 189clog_func (clog_err_t *cerr, clog_err_op_t cerr_op, int pri, const char *function, const char *line, const char *fmt, ...)
52b7d2ce 190{
65c25746
A
191 clog_err_t *new, *p;
192 va_list args;
e8d9021d 193
65c25746 194 if (!cerr) {
52b7d2ce
A
195 return;
196 }
e8d9021d 197
65c25746
A
198 if (!(new = racoon_calloc(1, sizeof(*cerr)))) {
199 return;
200 }
201 // fill in new
202 cerr->clog_err_level = pri; /* will be used for filtering */
203 /* TODO */
204 //cerr->clog_err_code;
205 //cerr->client_id;
206 //cerr->client_type;
207 va_start(args, fmt);
208 cerr->description_len = vasprintf(&cerr->description, fmt, args);
209 va_end(args);
210 cerr->function = function;
211 cerr->line = line;
212
213 // add new to the tail
214 TAILQ_FOREACH(p, &cerr->chain_head, chain) {
215 if (TAILQ_NEXT(p, chain) == NULL) {
216 TAILQ_NEXT(p, chain) = new;
217 new->chain.tqe_prev = &TAILQ_NEXT(p, chain);
218 break;
219 }
220 }
221
222 if (cerr_op == CLOG_ERR_DUMP) {
223 char *prev = NULL, *backtrace = NULL;
224
225 TAILQ_FOREACH(p, &cerr->chain_head, chain) {
226 // collapse list into backtrace
227 if (cerr->description) {
228 if (backtrace) {
229 prev = backtrace;
230 backtrace = NULL;
231 asprintf(&backtrace, "%s\n\t\t-> %s", prev, cerr->description);
232 free(prev);
233 } else {
234 asprintf(&backtrace, "%s", cerr->description);
235 }
236 }
237 }
238
239 if (backtrace) {
240 // use plog to dump event.
241 plog(pri, "%s", backtrace);
242 }
243 }
52b7d2ce
A
244}
245
246void
65c25746 247plogsetfile(file)
52b7d2ce
A
248 char *file;
249{
65c25746
A
250 syslog(LOG_NOTICE, "%s: about to add racoon log file: %s\n", __FUNCTION__, file? file:"bad file path");
251 if (logfile != NULL) {
52b7d2ce 252 racoon_free(logfile);
65c25746
A
253 if (logfile_fd != -1) {
254 asl_remove_log_file(logRef, logfile_fd);
255 asl_close_auxiliary_file(logfile_fd);
256 logfile_fd = -1;
257 }
258 }
d1e348cf
A
259 logfile = racoon_strdup(file);
260 STRDUP_FATAL(logfile);
d9c572c0 261 if ((logfile_fd = open(logfile, O_CREAT | O_WRONLY | O_APPEND | O_NOFOLLOW, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) >= 0) {
65c25746
A
262 asl_add_log_file(logRef, logfile_fd);
263 } else {
264 syslog(LOG_NOTICE, "%s: failed to add racoon log file: %s. error %d\n", __FUNCTION__, file? file:"bad file path", errno);
265 }
52b7d2ce
A
266}
267
268void
65c25746 269plogresetfile(file)
52b7d2ce
A
270 char *file;
271{
52b7d2ce 272 /* if log paths equal - do nothing */
e8d9021d 273 if (logfile == NULL && file == NULL) {
52b7d2ce 274 return;
e8d9021d 275 }
65c25746 276 if (logfile != NULL && file != NULL) {
e8d9021d 277 if (!strcmp(logfile, file)) {
52b7d2ce 278 return;
e8d9021d 279 }
65c25746
A
280 if (logfile_fd != -1) {
281 asl_remove_log_file(logRef, logfile_fd);
282 close(logfile_fd);
283 logfile_fd = -1;
284 }
52b7d2ce 285 }
65c25746
A
286
287 if (logfile) {
288 racoon_free(logfile);
289 logfile = NULL;
290 }
291
52b7d2ce 292 if (file)
65c25746
A
293 plogsetfile(file);
294}
e8d9021d 295
65c25746
A
296int
297ploggetlevel(void)
298{
299 return loglevel;
300}
d1e348cf 301
65c25746
A
302void
303plogsetlevel(int level)
d1e348cf 304{
65c25746
A
305 int mask;
306
307 if (level && level >= ASL_LEVEL_EMERG && level <= ASL_LEVEL_DEBUG) {
308 loglevel = level;
d1e348cf 309 }
65c25746
A
310 if (loglevel >= ASL_LEVEL_INFO) {
311 mask = ASL_FILTER_MASK_TUNNEL;
312 } else {
313 mask = 0;
314 }
315 mask |= ASL_FILTER_MASK_UPTO(loglevel);
316 syslog(LOG_DEBUG, "%s: about to set racoon's log level %d, mask %x\n", __FUNCTION__, level, mask);
317 asl_set_filter(NULL, mask);
d1e348cf 318}
65c25746
A
319
320void
321plogsetlevelstr(char *levelstr)
322{
323 if (!levelstr) {
324 return;
325 }
326
327 if (strncmp(levelstr, ASL_STRING_EMERG, sizeof(ASL_STRING_EMERG) - 1) == 0) {
328 plogsetlevel(ASL_LEVEL_EMERG);
329 } else if (strncmp(levelstr, ASL_STRING_ALERT, sizeof(ASL_STRING_ALERT) - 1) == 0) {
330 plogsetlevel(ASL_LEVEL_ALERT);
331 } else if (strncmp(levelstr, ASL_STRING_CRIT, sizeof(ASL_STRING_CRIT) - 1) == 0) {
332 plogsetlevel(ASL_LEVEL_CRIT);
333 } else if (strncmp(levelstr, ASL_STRING_ERR, sizeof(ASL_STRING_ERR) - 1) == 0) {
334 plogsetlevel(ASL_LEVEL_ERR);
335 } else if (strncmp(levelstr, ASL_STRING_WARNING, sizeof(ASL_STRING_NOTICE) - 1) == 0) {
336 plogsetlevel(ASL_LEVEL_WARNING);
337 } else if (strncmp(levelstr, ASL_STRING_NOTICE, sizeof(ASL_STRING_NOTICE) - 1) == 0) {
338 plogsetlevel(ASL_LEVEL_NOTICE);
339 } else if (strncmp(levelstr, ASL_STRING_INFO, sizeof(ASL_STRING_INFO) - 1) == 0) {
340 plogsetlevel(ASL_LEVEL_INFO);
341 } else if (strncmp(levelstr, ASL_STRING_DEBUG, sizeof(ASL_STRING_DEBUG) - 1) == 0) {
342 plogsetlevel(ASL_LEVEL_DEBUG);
343 }
344}
345
346void
347plogsetlevelquotedstr (char *levelquotedstr)
348{
349 int len;
350
351 if (!levelquotedstr) {
352 plog(ASL_LEVEL_ERR, "Null log level (quoted string)");
353 return;
354 }
355
356 len = strlen(levelquotedstr);
357 if (len < 3 ||
358 levelquotedstr[0] != '"' ||
359 levelquotedstr[len - 1] != '"') {
360 plog(ASL_LEVEL_ERR, "Invalid log level (quoted string): %s", levelquotedstr);
361 return;
362 }
363 // skip quotes
364 levelquotedstr[len - 1] = '\0';
365 plogsetlevelstr(&levelquotedstr[1]);
366}
367
368void
369plogreadprefs (void)
370{
371 CFPropertyListRef globals;
372 CFStringRef logFileRef;
373 CFNumberRef debugLevelRef;
374 CFStringRef debugLevelStringRef;
375 char logLevelStr[16];
376 int level = 0;
377
378 logLevelStr[0] = 0;
379
380 SCPreferencesSynchronize(gPrefs);
381
382 globals = SCPreferencesGetValue(gPrefs, CFSTR("Global"));
383 if (!globals || (CFGetTypeID(globals) != CFDictionaryGetTypeID())) {
384 return;
385 }
386 debugLevelRef = CFDictionaryGetValue(globals, CFSTR("DebugLevel"));
387 if (debugLevelRef && (CFGetTypeID(debugLevelRef) == CFNumberGetTypeID())) {
388 CFNumberGetValue(debugLevelRef, kCFNumberSInt32Type, &level);
389 plogsetlevel(level);
390 } else {
391 debugLevelStringRef = CFDictionaryGetValue(globals, CFSTR("DebugLevelString"));
392 if (debugLevelStringRef && (CFGetTypeID(debugLevelStringRef) == CFStringGetTypeID())) {
393 CFStringGetCString(debugLevelStringRef, logLevelStr, sizeof(logLevelStr), kCFStringEncodingMacRoman);
394 plogsetlevelstr(logLevelStr);
395 }
396 }
397
398 logFileRef = CFDictionaryGetValue(globals, CFSTR("DebugLogfile"));
399 if (!logFileRef || (CFGetTypeID(logFileRef) != CFStringGetTypeID())) {
400 return;
401 }
402 CFStringGetCString(logFileRef, logFileStr, MAXPATHLEN, kCFStringEncodingMacRoman);
403 plogsetfile(logFileStr);
404}
405
406void
407ploginit(void)
408{
409 logFileStr[0] = 0;
410 logRef = NULL;//asl_open(NULL, plog_facility, 0);
411 plogsetlevel(ASL_LEVEL_NOTICE);
412 //plogsetlevel(ASL_LEVEL_DEBUG);
413 plogreadprefs();
414}
415
416void
417plogsetsessioninfo (const char *session_id,
418 const char *session_type,
419 const char *session_ver)
420{
421 if (gSessId) {
422 free(gSessId);
423 }
424 if (!session_id) {
425 gSessId = NULL;
426 } else {
427 gSessId = strdup(session_id);
428 }
429 if (gSessId) {
430 free(gSessId);
431 }
432 if (!session_type) {
433 gSessType = NULL;
434 } else {
435 gSessType = strdup(session_id);
436 }
437 if (gSessVer) {
438 free(gSessVer);
439 }
440 if (!session_ver) {
441 gSessVer = NULL;
442 } else {
443 gSessVer = strdup(session_ver);
444 }
445}
446
447char *
448createCStringFromCFString(CFAllocatorRef allocator, CFStringRef cfstr)
449{
450 CFIndex cstr_len = CFStringGetMaximumSizeForEncoding(CFStringGetLength(cfstr), kCFStringEncodingUTF8) + 1;
451 char *cstr = (char *)CFAllocatorAllocate(allocator, cstr_len, 0);
452 CFStringGetCString(cfstr, cstr, cstr_len, kCFStringEncodingUTF8);
453 return cstr;
454}
455
456void
457plogcf(int priority, CFStringRef fmt, ...)
458{
459 va_list args;
460 CFStringRef cfstr;
461 char *cstr;
462
463 va_start(args, fmt);
464 cfstr = CFStringCreateWithFormatAndArguments(kCFAllocatorDefault, NULL, fmt, args);
465 va_end(args);
466
467 cstr = createCStringFromCFString(kCFAllocatorDefault, cfstr);
468 plog(priority, "%s", cstr);
469
470 CFAllocatorDeallocate(kCFAllocatorDefault, cstr);
471 CFRelease(cfstr);
472}
473
474