Line data Source code
1 : #include "burp.h"
2 : #include "alloc.h"
3 : #include "asfd.h"
4 : #include "async.h"
5 : #include "cmd.h"
6 : #include "cntr.h"
7 : #include "iobuf.h"
8 : #include "log.h"
9 : #include "strlist.h"
10 :
11 : const char *prog="unknown";
12 : const char *prog_long="unknown";
13 :
14 : static struct fzp *logfzp=NULL;
15 : // Start with all logging on, so that something is said when initial startup
16 : // goes wrong - for example, reading the conf file.
17 : static int do_syslog=1;
18 : static int do_stdout=1;
19 : static int do_progress_counter=1;
20 : static int syslog_opened=0;
21 : static int json=0;
22 :
23 0 : void log_init(char *progname)
24 : {
25 0 : prog_long=progname;
26 0 : if((prog=strrchr(progname, '/'))) prog++;
27 0 : else prog=progname;
28 0 : }
29 :
30 : #ifndef UTEST
31 : static char *gettm(void)
32 : {
33 : time_t t=0;
34 : const struct tm *ctm=NULL;
35 : static char tmbuf[32]="";
36 :
37 : time(&t);
38 : ctm=localtime(&t);
39 : // Windows does not like the %T strftime format option - you get
40 : // complaints under gdb.
41 : strftime(tmbuf, sizeof(tmbuf), "%Y-%m-%d %H:%M:%S", ctm);
42 : return tmbuf;
43 : }
44 : #endif
45 :
46 1093 : void logp(const char *fmt, ...)
47 : {
48 : #ifndef UTEST
49 : int pid;
50 : char buf[512]="";
51 : va_list ap;
52 : va_start(ap, fmt);
53 : vsnprintf(buf, sizeof(buf), fmt, ap);
54 : pid=(int)getpid();
55 : if(logfzp)
56 : fzp_printf(logfzp, "%s: %s[%d] %s", gettm(), prog, pid, buf);
57 : else
58 : {
59 : if(do_syslog)
60 : syslog(LOG_INFO, "%s", buf);
61 : if(do_stdout)
62 : {
63 : if(json)
64 : {
65 : char *cp=NULL;
66 : if((cp=strrchr(buf, '\n'))) *cp='\0';
67 : // To help programs parsing the monitor output,
68 : // log things with simple JSON.
69 : fprintf(stdout, "{ \"logline\": \"%s\" }\n", buf);
70 : }
71 : else
72 : fprintf(stdout, "%s: %s[%d] %s",
73 : gettm(), prog, pid, buf);
74 : }
75 : }
76 : va_end(ap);
77 : #endif
78 1093 : }
79 :
80 0 : void logp_ssl_err(const char *fmt, ...)
81 : {
82 0 : char buf[512]="";
83 : va_list ap;
84 0 : va_start(ap, fmt);
85 : vsnprintf(buf, sizeof(buf), fmt, ap);
86 0 : va_end(ap);
87 : logp("%s", buf);
88 0 : if(logfzp) fzp_ERR_print_errors_fp(logfzp);
89 : else
90 : {
91 0 : if(do_syslog)
92 : {
93 : // FIX THIS: How to send to syslog?
94 : static BIO *bio_err=NULL;
95 0 : if(!bio_err) bio_err=BIO_new_fp(stderr, BIO_NOCLOSE);
96 0 : ERR_print_errors(bio_err);
97 : }
98 0 : if(do_stdout)
99 : {
100 0 : if(!json)
101 : {
102 : static BIO *bio_err=NULL;
103 0 : if(!bio_err) bio_err=BIO_new_fp(stdout,
104 : BIO_NOCLOSE);
105 0 : ERR_print_errors(bio_err);
106 : }
107 : }
108 : }
109 0 : }
110 :
111 : // For the counters.
112 0 : void logc(const char *fmt, ...)
113 : {
114 0 : char buf[512]="";
115 : va_list ap;
116 0 : va_start(ap, fmt);
117 : vsnprintf(buf, sizeof(buf), fmt, ap);
118 0 : if(logfzp)
119 0 : fzp_printf(logfzp, "%s", buf); // for the server side
120 : else
121 : {
122 0 : if(do_progress_counter
123 0 : && do_stdout)
124 0 : fprintf(stdout, "%s", buf);
125 : }
126 0 : va_end(ap);
127 0 : }
128 :
129 80 : void logfmt(const char *fmt, ...)
130 : {
131 : #ifndef UTEST
132 : char buf[512]="";
133 : va_list ap;
134 : va_start(ap, fmt);
135 : vsnprintf(buf, sizeof(buf), fmt, ap);
136 : fprintf(stdout, "%s", buf);
137 : #endif
138 80 : }
139 :
140 91 : const char *progname(void)
141 : {
142 91 : return prog;
143 : }
144 :
145 14 : int log_fzp_set(const char *path, struct conf **confs)
146 : {
147 14 : fzp_close(&logfzp);
148 14 : if(path)
149 : {
150 : logp("Logging to %s\n", path);
151 7 : if(!(logfzp=fzp_open(path, "ab"))) return -1;
152 : }
153 14 : if(logfzp) fzp_setlinebuf(logfzp);
154 14 : do_syslog=get_int(confs[OPT_SYSLOG]);
155 14 : do_stdout=get_int(confs[OPT_STDOUT]);
156 14 : do_progress_counter=get_int(confs[OPT_PROGRESS_COUNTER]);
157 :
158 14 : if(syslog_opened)
159 : {
160 0 : closelog();
161 0 : syslog_opened=0;
162 : }
163 14 : if(do_syslog)
164 : {
165 0 : openlog(prog, LOG_PID, LOG_USER);
166 0 : syslog_opened++;
167 : }
168 : return 0;
169 : }
170 :
171 0 : void log_fzp_set_direct(struct fzp *fzp)
172 : {
173 0 : fzp_close(&logfzp);
174 0 : logfzp=fzp;
175 0 : }
176 :
177 1 : void log_out_of_memory(const char *function)
178 : {
179 : if(function) logp("out of memory in %s()\n", function);
180 : else logp("out of memory in unknown function\n");
181 1 : }
182 :
183 7 : void log_restore_settings(struct conf **cconfs, int srestore)
184 : {
185 : struct strlist *l;
186 : logp("Restore settings:\n");
187 7 : if(get_string(cconfs[OPT_ORIG_CLIENT]))
188 1 : logp("orig_client = '%s'\n",
189 : get_string(cconfs[OPT_ORIG_CLIENT]));
190 7 : if(get_string(cconfs[OPT_BACKUP]))
191 7 : logp("backup = '%s'\n",
192 : get_string(cconfs[OPT_BACKUP]));
193 7 : if(srestore)
194 : {
195 : // This are unknown unless doing a server initiated restore.
196 2 : logp("overwrite = %d\n", get_int(cconfs[OPT_OVERWRITE]));
197 2 : logp("strip = %d\n", get_int(cconfs[OPT_STRIP]));
198 : }
199 7 : if(get_string(cconfs[OPT_RESTOREPREFIX]))
200 0 : logp("restoreprefix = '%s'\n",
201 : get_string(cconfs[OPT_RESTOREPREFIX]));
202 7 : if(get_string(cconfs[OPT_REGEX]))
203 0 : logp("regex = '%s'\n", get_string(cconfs[OPT_REGEX]));
204 10 : for(l=get_strlist(cconfs[OPT_INCLUDE]); l; l=l->next)
205 3 : logp("include = '%s'\n", l->path);
206 7 : }
207 :
208 0 : int logm(struct asfd *asfd, struct conf **confs, const char *fmt, ...)
209 : {
210 0 : int r=0;
211 0 : char buf[512]="";
212 : va_list ap;
213 0 : va_start(ap, fmt);
214 : vsnprintf(buf, sizeof(buf), fmt, ap);
215 0 : if(asfd && asfd->as->doing_estimate) printf("\nMESSAGE: %s", buf);
216 : else
217 : {
218 0 : if(asfd
219 0 : && get_int(confs[OPT_MESSAGE])) // Backwards compatibility
220 0 : r=asfd->write_str(asfd, CMD_MESSAGE, buf);
221 : logp("MESSAGE: %s", buf);
222 : }
223 0 : va_end(ap);
224 0 : if(confs) cntr_add(get_cntr(confs), CMD_MESSAGE, 1);
225 0 : return r;
226 : }
227 :
228 13 : int logw(struct asfd *asfd, struct cntr *cntr, const char *fmt, ...)
229 : {
230 13 : int r=0;
231 13 : char buf[512]="";
232 : va_list ap;
233 13 : va_start(ap, fmt);
234 : vsnprintf(buf, sizeof(buf), fmt, ap);
235 13 : if(asfd
236 10 : && asfd->as
237 3 : && asfd->as->doing_estimate) printf("\nWARNING: %s", buf);
238 : else
239 : {
240 13 : if(asfd) r=asfd->write_str(asfd, CMD_WARNING, buf);
241 : logp("WARNING: %s", buf);
242 : }
243 13 : va_end(ap);
244 13 : cntr_add(cntr, CMD_WARNING, 1);
245 13 : return r;
246 : }
247 :
248 11 : void log_and_send(struct asfd *asfd, const char *msg)
249 : {
250 : logp("%s\n", msg);
251 11 : if(asfd)
252 11 : asfd->write_str(asfd, CMD_ERROR, msg);
253 11 : }
254 :
255 0 : void log_and_send_oom(struct asfd *asfd)
256 : {
257 0 : char m[256]="";
258 : snprintf(m, sizeof(m), "out of memory in %s()\n", __func__);
259 : logp("%s", m);
260 0 : if(asfd)
261 0 : asfd->write_str(asfd, CMD_ERROR, m);
262 0 : }
263 :
264 0 : void log_set_json(int value)
265 : {
266 0 : json=value;
267 0 : }
268 :
269 10 : void log_oom_w(const char *func, const char *orig_func)
270 : {
271 : logp("out of memory in %s, called from %s\n", func, orig_func);
272 10 : }
273 :
274 0 : int log_incexcs_buf(const char *incexc)
275 : {
276 0 : char *tok=NULL;
277 0 : char *copy=NULL;
278 0 : if(!incexc || !*incexc) return 0;
279 0 : if(!(copy=strdup_w(incexc, __func__)))
280 : return -1;
281 0 : if(!(tok=strtok(copy, "\n")))
282 : {
283 : logp("unable to parse server incexc\n");
284 0 : free_w(©);
285 0 : return -1;
286 : }
287 : do
288 : {
289 : logp("%s\n", tok);
290 0 : } while((tok=strtok(NULL, "\n")));
291 0 : free_w(©);
292 0 : return 0;
293 : }
294 :
295 8 : void log_recvd(struct iobuf *iobuf, struct cntr *cntr, int print)
296 : {
297 8 : const char *prefix="unset";
298 8 : switch(iobuf->cmd)
299 : {
300 : case CMD_MESSAGE: prefix="MESSAGE"; break;
301 : case CMD_WARNING: prefix="WARNING"; break;
302 : default: break;
303 : }
304 8 : logp("%s: %s", prefix, iobuf->buf);
305 8 : cntr_add(cntr, iobuf->cmd, print);
306 8 : }
|