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