9
#include <sys/socket.h>
12
#include <sys/types.h>
13
#include <sys/resource.h>
16
#include <netinet/in.h>
17
#include <arpa/inet.h>
21
#ifdef HAVE_CAPABILITIES
22
#include <sys/capability.h>
25
#ifdef HAVE_TCP_WRAPPERS
40
/* we avoid the more tedious sanity checks by assuming that since
41
we wrote the opcodes, they're going to be what we accept. dodgy. */
44
rl_warn("%s(%d) failed %s", (a), *op, strerror(errno))
46
#define RL_MIN(a, b) ((a) < (b) ? (a) : (b))
48
int allow_severity = LOG_INFO;
49
int deny_severity = LOG_WARNING;
52
static char * bytecode2string(rl_opcode_t op);
53
static char * bytecodeargs2string(rl_opcode_t* op);
56
void run_bytecode(rl_opcode_t *op, struct rl_instance *inst) {
60
fprintf(stderr, "sched(%d)\n", getpid());
64
fprintf(stderr, "%d: op %d: %s (%s)\n", getpid(), *op, bytecode2string(*op), bytecodeargs2string(op));
66
fprintf(stderr, "op %d\n", *op);
72
#ifdef HAVE_TCP_WRAPPERS
73
struct request_info *request;
77
struct semaphore *sem;
82
fcntl(inst->sock, F_SETFD, 0);
83
fcntl(inst->sock, F_SETFL, 0);
85
argv = argvtab_get(*++op);
86
argv_build(inst, argv);
87
str = (j != -1) ? stringtab_get(j) : argv->argv[0];
89
while ((ssid = setsid() < 0) && errno == EAGAIN)
93
rl_warn("setsid()) for %s: %s", str, strerror(errno));
96
for(i = 0; i < 3; i++)
101
if(execv(str, argv->argv)) {
102
rl_warn("execv(%s): %s", str, strerror(errno));
111
fprintf(stderr, "++setuid: %d\n", *(op + 1));
117
fprintf(stderr, "++setgid: %d\n", *(op + 1));
123
fprintf(stderr, "++nice: %d\n", *(op + 1));
124
if(setpriority(PRIO_PROCESS, 0, *++op))
125
rl_fail1("setpriority");
131
if(setrlimit(j, rlimittab_get(k)))
132
rl_fail1("setrlimit");
135
argv = argvtab_get(*++op);
136
string_build(inst, argv);
137
if(chroot(argv->str))
138
rl_fatal(EX_SOFTWARE, _("ABORT - chroot(\"%s\"): %s"), argv->str, strerror(errno));
140
rl_fatal(EX_SOFTWARE, _("ABORT - chdir(\"/\"): %s"), strerror(errno));
143
log = logtab_get(*++op);
144
argv = argvtab_get(log->argv);
146
string_build(inst, argv);
147
syslog(LOG_INFO, argv->str);
149
iov_build(inst, argv);
150
if(writev(log->fd, argv->iov, argv->argc) < 0)
151
rl_warn("writev() log: %s", strerror(errno));
162
inst->sin = (struct sockaddr *)malloc(i);
164
rl_fatal(EX_SOFTWARE, _("ABORT - Can't allocate memory"));
166
if((inst->sock = accept(inst->sock, inst->sin, &inst->sinlen)) < 0) {
167
rl_warn("accept(): %s", strerror(errno));
170
fcntl(inst->sock, F_SETFL, O_NDELAY); /* boggle */
171
if(fcntl(inst->sock, F_SETFD, 0) == -1) {
172
rl_warn("fcntl(%d, F_SETFD, 0): %s", inst->sock, strerror(errno));
181
rl_warn(_("fork() failed - %s"), strerror(errno));
186
rlstk_push(&inst->stk, 0);
187
run_bytecode(++op, inst);
188
exit(rlstk_pop(&inst->stk));
191
inst->start = time(NULL);
192
pidtab_add(j, i, inst);
194
return run_bytecode(oplisttab_get(k), inst);
198
str = stringtab_get(*++op);
200
#ifdef HAVE_TCP_WRAPPERS
201
request = (struct request_info *)malloc(sizeof(struct request_info));
203
rl_fatal(EX_SOFTWARE, _("ABORT - Can't allocate memory (OP: %d)"), *op);
205
request_init(request, RQ_FILE, inst->sock,
206
RQ_CLIENT_SIN, inst->sin,
209
/* undocumented tcp wrappers magic -
210
* does DNS lookup and possibly other stuff */
213
if(!hosts_access(request)) {
217
/* get address of client */
218
l.type = LOG_SOURCE_IP;
220
l.len = sizeof(l.arg);
221
loglist_build( inst, &l );
223
rl_warn(_("access for service %s from host %s denied by TCP wrappers"), str, host_ip);
225
run_bytecode(oplisttab_get(k), inst);
230
#ifdef HAVE_CAPABILITIES
231
if(cap_set_proc(captab_get(*++op)))
232
rl_warn("cap_set_proc(): %s", strerror(errno));
236
str = stringtab_get(*++op);
239
fprintf(stderr, "++initgr: %s, %d\n", str, gid);
240
if(initgroups(str, gid))
241
rl_warn("initgroups(%s, %d): %s", str, gid, strerror(errno));
248
if((inst->sock != -1) && close(inst->sock))
249
rl_warn("close(%d): %s", inst->sock, strerror(errno));
253
rlstk_push(&inst->stk, rlbuf_copy(inst->sock, inst->buf, rlstk_pop(&inst->stk)));
256
rlstk_push(&inst->stk, 0);
264
argv = argvtab_get(*++op);
266
iov_build(inst, argv);
267
if(writev(inst->sock, argv->iov, argv->argc) < 0)
268
rl_warn("writev(): %s", strerror(errno));
271
sem = semaphore_get(*++op);
272
if(sem->count-- == sem->limit)
273
run_bytecode(oplisttab_get(sem->under), inst);
276
sem = semaphore_get(*++op);
277
if(++sem->count == sem->limit)
278
run_bytecode(oplisttab_get(sem->match), inst);
284
listeners_set(*++op);
287
listeners_clear(*++op);
290
rlbuf_init(&inst->buf, *++op);
293
rlstk_push(&inst->stk, rlbuf_read(inst->sock, inst->buf));
296
rlstk_push(&inst->stk, rlbuf_write(inst->sock, inst->buf));
300
read_hook(inst->sock, op + 1 + *op, inst);
303
read_unhook(inst->sock);
307
write_hook(inst->sock, op + 1 + *op, inst);
310
write_unhook(inst->sock);
315
if(!rlstk_pop(&inst->stk))
321
return run_bytecode(oplisttab_get(j), inst);
325
if(rlstk_pop(&inst->stk) <= 0)
329
j = rlstk_peek(&inst->stk, 1);
331
rlstk_poke(&inst->stk, 0, rlstk_pop(&inst->stk) + j);
334
j = rlstk_peek(&inst->stk, 1);
336
rlstk_poke(&inst->stk, 0, j - rlstk_pop(&inst->stk));
339
rlstk_push(&inst->stk, rlstk_peek(&inst->stk, 0));
342
rlstk_pop(&inst->stk);
345
bt = buftab_get(*++op);
347
rlbuf_init(&inst->buf, 0);
348
inst->buf->data = bt->addr;
349
inst->buf->size = inst->buf->head = bt->len;
352
inst->buf->data = NULL;
356
/* should never happen */
357
rl_fatal(EX_SOFTWARE, _("ABORT - Unknown opcode (%d)"), *op);
363
#ifdef BYTECODE_DEBUG
364
static char * bytecode2string(rl_opcode_t op)
368
case OP_EXEC : return "OP_EXEC";
369
case OP_FISH : return "OP_FISH";
370
case OP_SUID : return "OP_SUID";
371
case OP_SGID : return "OP_SGID";
372
case OP_NICE : return "OP_NICE";
373
case OP_RLIMIT : return "OP_RLIMIT";
374
case OP_LOG : return "OP_LOG";
375
case OP_CHROOT : return "OP_CHROOT";
376
case OP_ACCEPT : return "OP_ACCEPT";
377
case OP_FORK : return "OP_FORK";
378
case OP_WRAP : return "OP_WRAP";
379
case OP_SETCAP : return "OP_SETCAP";
380
case OP_INITGR : return "OP_INITGR";
381
case OP_BRANCH : return "OP_BRANCH";
382
case OP_CLOSE : return "OP_CLOSE";
383
case OP_BUFCOPY : return "OP_BUFCOPY";
384
case OP_ZERO : return "OP_ZERO";
385
case OP_RET : return "OP_RET";
386
case OP_EXIT : return "OP_EXIT";
387
case OP_ECHO : return "OP_ECHO";
388
case OP_UP : return "OP_UP";
389
case OP_DOWN : return "OP_DOWN";
390
case OP_FROG : return "OP_FROG";
391
case OP_LSET : return "OP_LSET";
392
case OP_LCLR : return "OP_LCLR";
393
case OP_BUFINIT : return "OP_BUFINIT";
394
case OP_BUFREAD : return "OP_BUFREAD";
395
case OP_BUFWRITE: return "OP_BUFWRITE";
396
case OP_RHOOK : return "OP_RHOOK";
397
case OP_RUNHOOK : return "OP_RUNHOOK";
398
case OP_WHOOK : return "OP_WHOOK";
399
case OP_WUNHOOK : return "OP_WUNHOOK";
400
case OP_BZ : return "OP_BZ";
401
case OP_JUMP : return "OP_JUMP";
402
case OP_BZNEG : return "OP_BZNEG";
403
case OP_ADD : return "OP_ADD";
404
case OP_SUB : return "OP_SUB";
405
case OP_DUP : return "OP_DUP";
406
case OP_POP : return "OP_POP";
407
case OP_BUFCLONE: return "OP_BUFCLONE";
408
case OP_BUFFREE : return "OP_BUFFREE";
409
default : return "UNKNOWN";
413
bytecodeargs2string (rl_opcode_t * op)
455
static char buf[128];
459
for (i = 0; i < nargs; ++i)
461
sprintf (buf + strlen (buf), "%s%d", i ? ", " : "", *(op + i + 1));