/* * Copyright (c) 2001-2007, OpenFWTK Development Group * All rights reserved. See LICENSE. */ /* * OpenFWTK project generation 2 API misc functions * * (C) Copyright 2001 ArkanoiD * */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "magic.h" #include "firewall.h" #include "firewall2.h" #include "fwfunc.h" static char* moduleId ATTR_UNUSED = "$Id: gen2api.c,v 1.29 2007/10/10 18:35:22 arkenoi Exp $"; #if defined(linux) || defined(SOLARIS) extern void initsetproctitle(int,char**); #endif #ifndef INT_MAX #define INT_MAX 2147483647 #endif #define DAEMON 1 #define FASTDAEMON 2 #define SAFEDAEMON 3 void proxy_update_status(); extern time_t sotimeout(int); extern void setproctitle(const char*,...); extern magic_t proxy_magic; Cfg* proxy_init(int ac,char *av[]) { int daemon = 0; int i; int port = 0; memset(proxy_chroot,0,sizeof(proxy_chroot)); strlcpy(proxy_name,basename(av[0]),sizeof(proxy_name)); for (i = 1; i < ac; i++) { if (!strcmp(av[i], "-daemon")) { daemon = DAEMON; if (++i >= ac) { fprintf(stderr,"-daemon requires port number"); exit(EX_USAGE); } port = str_to_port(av[i]); } if (!strcmp(av[i], "-fastdaemon")) { daemon = FASTDAEMON; if (++i >= ac) { fprintf(stderr,"-fastdaemon requires port number"); exit(EX_USAGE); } port = str_to_port(av[i]); } if (!strcmp(av[i], "-safedaemon")) { daemon = SAFEDAEMON; if (++i >= ac) { fprintf(stderr,"-safedaemon requires port number"); exit(EX_USAGE); } port = str_to_port(av[i]); } if (!strcmp(av[i], "-as")) { if (++i >= ac) { fprintf(stderr,"-as requires parameter"); exit(EX_USAGE); } strlcpy(proxy_name,av[i],sizeof(proxy_name)); } } #ifndef LOG_DAEMON openlog(proxy_name,LOG_PID); #else openlog(proxy_name,LOG_PID|LOG_NDELAY,LFAC); #endif #if defined(linux) || defined(SOLARIS) initsetproctitle(ac, av); #endif proxy_stats.inbytes = 0; proxy_stats.outbytes = 0; if ((proxy_confp = cfg_read(proxy_name)) == (Cfg *)-1) { syslog(LLEV,"fwtkcfgerr: no netperm-table records for %.128s",proxy_name); exit(1); } proxy_timeout = proxy_conf_int(proxy_confp,"timeout",1,INT_MAX,PROXY_TIMEOUT); proxy_nodns = (proxy_conf_string(proxy_confp,"nodns") != NULL); proxy_stats.child_limit = proxy_conf_int(proxy_confp,"maxchildren",1,4096,0); proxy_magic = magic_open(MAGIC_MIME); magic_load(proxy_magic,NULL); if (daemon) { syslog(LLEV,"Starting daemon mode on port %d",port); do_daemon(port); } if (daemon != FASTDAEMON) { /* * Not reloading magic here, too slow. Send -HUP if you really need to. */ cfg_free(proxy_confp); if ((proxy_confp = cfg_read(proxy_name)) == (Cfg *)-1) { syslog(LLEV,"fwtkcfgerr: no netperm-table records for %.128s",proxy_name); exit(1); } proxy_timeout = proxy_conf_int(proxy_confp,"timeout",1,INT_MAX,PROXY_TIMEOUT); proxy_stats.child_limit = proxy_conf_int(proxy_confp,"maxchildren",1,4096,0); } proxy_conf_groupid(proxy_confp); proxy_conf_userid(proxy_confp); proxy_conf_chroot(proxy_confp); sotimeout(proxy_timeout); time(&proxy_stats.start_time); if (peername(0,proxy_stats.rladdr,proxy_stats.riaddr,sizeof(proxy_stats.rladdr))) { if (errno==ENOTCONN) syslog (LLEV, "lost connection"); else syslog (LLEV, "fwtksyserr: cannot get peer name: %s", strerror(errno)); exit(1); } return(proxy_confp); } void proxy_setugid() { if(proxy_gid != -1 && setgid(proxy_gid)) { syslog(LLEV,"fwtksyserr: cannot set gid to %d: %s",proxy_gid, strerror(errno)); exit(1); } if(proxy_uid != -1 && setuid(proxy_uid)) { syslog(LLEV,"fwtksyserr: cannot set uid to %d: %s",proxy_uid, strerror(errno)); exit(1); } } void proxy_chroot_setugid() { if (proxy_chroot[0]) { chdir("/"); if(chdir(proxy_chroot) || chroot(proxy_chroot)) { syslog(LLEV,"fwtksyserr: cannot chroot %.128s %s",proxy_chroot, strerror(errno)); exit(1); } chdir("/"); } proxy_setugid(); } void proxy_exit() { time_t offtime; time(&offtime); syslog(LLEV,"exit host=%.512s/%.20s dest=%.128s in=%u out=%u user=%.64s duration=%u", proxy_stats.rladdr,proxy_stats.riaddr,proxy_stats.dst, proxy_stats.inbytes,proxy_stats.outbytes, proxy_stats.authuser, (unsigned int)(offtime-proxy_stats.start_time)); exit(0); } void proxy_update_status() { setproctitle("%.20s->%.20s %.64s in=%u out=%u %.32s",proxy_stats.rladdr, proxy_stats.dst,proxy_stats.operation, proxy_stats.inbytes,proxy_stats.outbytes,proxy_stats.authuser); } void proxy_update_operation(char *op) { strlcpy(proxy_stats.operation,op,sizeof(proxy_stats.operation)); proxy_update_status(); } void proxy_set_dscp(int sock, int dscp) { if (setsockopt(sock,IPPROTO_IP, IP_TOS, (void *) & dscp, sizeof(dscp)) < 0) { syslog(LLEV,"fwtksyserr: cannot set DSCP 0x%X on socket %d",dscp,sock); exit(1); } } int net_write(s, buf, len, flags) int s; char *buf; int len; int flags; { int nbytes = 0; int j; while (nbytes < len) { j = send(s, buf, len-nbytes, flags); if (j <= 0) return (nbytes ? nbytes : j); buf += j; nbytes += j; } return nbytes; }