implemented gmp_rsa_public_key.encrypt() method
[strongswan.git] / src / scepclient / loglite.c
1 /* error logging functions
2 * Copyright (C) 1997 Angelos D. Keromytis.
3 * Copyright (C) 1998-2001 D. Hugh Redelmeier.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * for more details.
14 */
15
16 #include <stdio.h>
17 #include <stdlib.h>
18 #include <ctype.h>
19 #include <stdarg.h>
20 #include <syslog.h>
21 #include <errno.h>
22 #include <string.h>
23 #include <unistd.h>
24 #include <signal.h> /* used only if MSG_NOSIGNAL not defined */
25 #include <libgen.h>
26 #include <sys/stat.h>
27 #include <sys/types.h>
28
29 #include <freeswan.h>
30 #include <debug.h>
31
32 #include <constants.h>
33 #include <defs.h>
34 #include <log.h>
35 #include <whack.h>
36
37 bool
38 log_to_stderr = FALSE, /* should log go to stderr? */
39 log_to_syslog = TRUE; /* should log go to syslog? */
40
41 /**
42 * @brief scepclient dbg function
43 */
44 static void scepclient_dbg(int level, char *fmt, ...)
45 {
46 int priority = LOG_INFO;
47 int debug_level;
48 char buffer[8192];
49 char *current = buffer, *next;
50 va_list args;
51
52 if (cur_debugging & DBG_PRIVATE)
53 {
54 debug_level = 4;
55 }
56 else if (cur_debugging & DBG_RAW)
57 {
58 debug_level = 3;
59 }
60 else if (cur_debugging & DBG_PARSING)
61 {
62 debug_level = 2;
63 }
64 else
65 {
66 debug_level = 1;
67 }
68
69 if (level <= debug_level)
70 {
71 va_start(args, fmt);
72
73 if (log_to_stderr)
74 {
75 if (level > 1)
76 {
77 fprintf(stderr, "| ");
78 }
79 vfprintf(stderr, fmt, args);
80 fprintf(stderr, "\n");
81 }
82 if (log_to_syslog)
83 {
84 /* write in memory buffer first */
85 vsnprintf(buffer, sizeof(buffer), fmt, args);
86
87 /* do a syslog with every line */
88 while (current)
89 {
90 next = strchr(current, '\n');
91 if (next)
92 {
93 *(next++) = '\0';
94 }
95 syslog(priority, "%s%s\n", (level > 1)? "| ":"", current);
96 current = next;
97 }
98 }
99 va_end(args);
100 }
101 }
102
103 void init_log(const char *program)
104 {
105 /* enable scepclient bugging hook */
106 dbg = scepclient_dbg;
107
108 if (log_to_stderr)
109 {
110 setbuf(stderr, NULL);
111 }
112 if (log_to_syslog)
113 {
114 openlog(program, LOG_CONS | LOG_NDELAY | LOG_PID, LOG_AUTHPRIV);
115 }
116 }
117
118 void close_log(void)
119 {
120 if (log_to_syslog)
121 closelog();
122 }
123
124 void plog(const char *message, ...)
125 {
126 va_list args;
127 char m[LOG_WIDTH]; /* longer messages will be truncated */
128
129 va_start(args, message);
130 vsnprintf(m, sizeof(m), message, args);
131 va_end(args);
132
133 if (log_to_stderr)
134 fprintf(stderr, "%s\n", m);
135 if (log_to_syslog)
136 syslog(LOG_WARNING, "%s", m);
137 }
138
139 void loglog(int mess_no, const char *message, ...)
140 {
141 va_list args;
142 char m[LOG_WIDTH]; /* longer messages will be truncated */
143
144 va_start(args, message);
145 vsnprintf(m, sizeof(m), message, args);
146 va_end(args);
147
148 if (log_to_stderr)
149 fprintf(stderr, "%s\n", m);
150 if (log_to_syslog)
151 syslog(LOG_WARNING, "%s", m);
152 }
153
154 void log_errno_routine(int e, const char *message, ...)
155 {
156 va_list args;
157 char m[LOG_WIDTH]; /* longer messages will be truncated */
158
159 va_start(args, message);
160 vsnprintf(m, sizeof(m), message, args);
161 va_end(args);
162
163 if (log_to_stderr)
164 fprintf(stderr, "ERROR: %s. Errno %d: %s\n", m, e, strerror(e));
165 if (log_to_syslog)
166 syslog(LOG_ERR, "ERROR: %s. Errno %d: %s", m, e, strerror(e));
167 }
168
169 void exit_log(const char *message, ...)
170 {
171 va_list args;
172 char m[LOG_WIDTH]; /* longer messages will be truncated */
173
174 va_start(args, message);
175 vsnprintf(m, sizeof(m), message, args);
176 va_end(args);
177
178 if (log_to_stderr)
179 fprintf(stderr, "FATAL ERROR: %s\n", m);
180 if (log_to_syslog)
181 syslog(LOG_ERR, "FATAL ERROR: %s", m);
182 exit(1);
183 }
184
185 void exit_log_errno_routine(int e, const char *message, ...)
186 {
187 va_list args;
188 char m[LOG_WIDTH]; /* longer messages will be truncated */
189
190 va_start(args, message);
191 vsnprintf(m, sizeof(m), message, args);
192 va_end(args);
193
194 if (log_to_stderr)
195 fprintf(stderr, "FATAL ERROR: %s. Errno %d: %s\n", m, e, strerror(e));
196 if (log_to_syslog)
197 syslog(LOG_ERR, "FATAL ERROR: %s. Errno %d: %s", m, e, strerror(e));
198 exit(1);
199 }
200
201 void whack_log(int mess_no, const char *message, ...)
202 {
203 va_list args;
204 char m[LOG_WIDTH]; /* longer messages will be truncated */
205
206 va_start(args, message);
207 vsnprintf(m, sizeof(m), message, args);
208 va_end(args);
209
210 fprintf(stderr, "%s\n", m);
211 }
212
213 /* Build up a diagnostic in a static buffer.
214 * Although this would be a generally useful function, it is very
215 * hard to come up with a discipline that prevents different uses
216 * from interfering. It is intended that by limiting it to building
217 * diagnostics, we will avoid this problem.
218 * Juggling is performed to allow an argument to be a previous
219 * result: the new string may safely depend on the old one. This
220 * restriction is not checked in any way: violators will produce
221 * confusing results (without crashing!).
222 */
223 char diag_space[sizeof(diag_space)];
224
225 err_t builddiag(const char *fmt, ...)
226 {
227 static char diag_space[LOG_WIDTH]; /* longer messages will be truncated */
228 char t[sizeof(diag_space)]; /* build result here first */
229 va_list args;
230
231 va_start(args, fmt);
232 t[0] = '\0'; /* in case nothing terminates string */
233 vsnprintf(t, sizeof(t), fmt, args);
234 va_end(args);
235 strcpy(diag_space, t);
236 return diag_space;
237 }
238
239 /* Debugging message support */
240
241 #ifdef DEBUG
242
243 void switch_fail(int n, const char *file_str, unsigned long line_no)
244 {
245 char buf[30];
246
247 snprintf(buf, sizeof(buf), "case %d unexpected", n);
248 passert_fail(buf, file_str, line_no);
249 }
250
251 void passert_fail(const char *pred_str, const char *file_str, unsigned long line_no)
252 {
253 /* we will get a possibly unplanned prefix. Hope it works */
254 loglog(RC_LOG_SERIOUS, "ASSERTION FAILED at %s:%lu: %s", file_str, line_no, pred_str);
255 abort(); /* exiting correctly doesn't always work */
256 }
257
258 lset_t
259 base_debugging = DBG_NONE, /* default to reporting nothing */
260 cur_debugging = DBG_NONE;
261
262 void pexpect_log(const char *pred_str, const char *file_str, unsigned long line_no)
263 {
264 /* we will get a possibly unplanned prefix. Hope it works */
265 loglog(RC_LOG_SERIOUS, "EXPECTATION FAILED at %s:%lu: %s", file_str, line_no, pred_str);
266 }
267
268 /* log a debugging message (prefixed by "| ") */
269
270 void DBG_log(const char *message, ...)
271 {
272 va_list args;
273 char m[LOG_WIDTH]; /* longer messages will be truncated */
274
275 va_start(args, message);
276 vsnprintf(m, sizeof(m), message, args);
277 va_end(args);
278
279 if (log_to_stderr)
280 fprintf(stderr, "| %s\n", m);
281 if (log_to_syslog)
282 syslog(LOG_DEBUG, "| %s", m);
283 }
284
285 /* dump raw bytes in hex to stderr (for lack of any better destination) */
286
287 void DBG_dump(const char *label, const void *p, size_t len)
288 {
289 # define DUMP_LABEL_WIDTH 20 /* arbitrary modest boundary */
290 # define DUMP_WIDTH (4 * (1 + 4 * 3) + 1)
291 char buf[DUMP_LABEL_WIDTH + DUMP_WIDTH];
292 char *bp;
293 const unsigned char *cp = p;
294
295 bp = buf;
296
297 if (label != NULL && label[0] != '\0')
298 {
299 /* Handle the label. Care must be taken to avoid buffer overrun. */
300 size_t llen = strlen(label);
301
302 if (llen + 1 > sizeof(buf))
303 {
304 DBG_log("%s", label);
305 }
306 else
307 {
308 strcpy(buf, label);
309 if (buf[llen-1] == '\n')
310 {
311 buf[llen-1] = '\0'; /* get rid of newline */
312 DBG_log("%s", buf);
313 }
314 else if (llen < DUMP_LABEL_WIDTH)
315 {
316 bp = buf + llen;
317 }
318 else
319 {
320 DBG_log("%s", buf);
321 }
322 }
323 }
324
325 do {
326 int i, j;
327
328 for (i = 0; len!=0 && i!=4; i++)
329 {
330 *bp++ = ' ';
331 for (j = 0; len!=0 && j!=4; len--, j++)
332 {
333 static const char hexdig[] = "0123456789abcdef";
334
335 *bp++ = ' ';
336 *bp++ = hexdig[(*cp >> 4) & 0xF];
337 *bp++ = hexdig[*cp & 0xF];
338 cp++;
339 }
340 }
341 *bp = '\0';
342 DBG_log("%s", buf);
343 bp = buf;
344 } while (len != 0);
345 # undef DUMP_LABEL_WIDTH
346 # undef DUMP_WIDTH
347 }
348
349 #endif /* DEBUG */