/* * Copyright (c) 2000-2007, OpenFWTK Development Group * All rights reserved. See LICENSE. */ /* * OpenFWTK project generation 2 API configuration functions * * (C) Copyright 2001,2002 ArkanoiD * (C) Copyright 2000 Eberhard Mattes */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "firewall.h" #include "firewall2.h" #include "fwfunc.h" #include "auth.h" static char* moduleId ATTR_UNUSED = "$Id: cfg2.c,v 1.21 2007/09/10 02:49:13 arkenoi Exp $"; int auth_perm(Cfg*,char*,char*,char*,char**); /* * proxy_conf_* functions are taken from Eberhard Mattes' libemfw * function names are changed to avoid conflicts because functions * are not always exactly same. Say, config_uid etc do not have * things required by other libem functions like fastdaemon. */ /* Copyright 2000 by Eberhard Mattes Donated to the public domain. No warranty. */ void proxy_conf_arg_count (Cfg *cf, int n) { if (cf->argc == n) return; syslog (LLEV, "fwtkcfgerr: %s must have %d parameter%s, line %d", cf->op, n, (n == 1 ? "" : "s"), cf->ln); exit (1); } int proxy_conf_int (Cfg *confp, const char *name, int lo, int hi, int def) { char *end; Cfg *cf; long n; cf = cfg_get (name, confp); if (cf == (Cfg *)0) return def; proxy_conf_arg_count (cf, 1); errno = 0; n = strtol (cf->argv[0], &end, 10); if (end == cf->argv[0] || *end != 0 || errno != 0 || n < lo || n > hi) { syslog (LLEV, "fwtkcfgerr: bad value for %s, line %d", name, cf->ln); exit (1); } return (int)n; } char* proxy_conf_string (Cfg *confp, const char *name) { Cfg *cf = cfg_get (name, confp); if (cf == (Cfg *)0) return NULL; proxy_conf_arg_count (cf, 1); return cf->argv[0]; } int proxy_conf_userid (Cfg *confp) { Cfg *cf; int uid; if ((cf = cfg_get ("userid", confp)) == (Cfg *)0) return -1; proxy_conf_arg_count (cf, 1); if ((uid = mapuid (cf->argv[0])) == -1) { syslog (LLEV, "fwtkcfgerr: cannot map %s to uid", cf->argv[0]); exit (1); } proxy_uid = uid; return uid; } int proxy_conf_groupid (Cfg *confp) { Cfg *cf; int gid; if ((cf = cfg_get ("groupid", confp)) == (Cfg *)0) return -1; proxy_conf_arg_count (cf, 1); if ((gid = mapgid (cf->argv[0])) == -1) { syslog (LLEV, "fwtkcfgerr: cannot map %s to gid", cf->argv[0]); exit(1); } proxy_gid = gid; return gid; } char* proxy_conf_chroot (Cfg *confp) { char *s; if ((s = proxy_conf_string(proxy_confp,"directory"))) strlcpy(proxy_chroot,s,sizeof(proxy_chroot)); return s; } int proxy_conf_timeout (Cfg *confp) { return(proxy_timeout = proxy_conf_int(confp,"timeout",1,1440,PROXY_TIMEOUT)); } Cfg* proxy_conf_hosts (Cfg *confp, char *rladdr, char *riaddr) { Cfg *cf = cfg_get ("hosts", confp); int i; while (cf != (Cfg *)0) { for (i = 0; i < cf->argc && cf->argv[i][0] != '-'; ++i) { if (hostmatch (cf->argv[i], riaddr)) { if (cf->flags & PERM_DENY) goto deny; syslog (LLEV, "permit host=%s/%s use of gateway", rladdr, riaddr); return cf; } } cf = cfg_get ("hosts", (Cfg *)0); } deny: syslog (LLEV, "deny host=%s/%s use of gateway", rladdr, riaddr); return (Cfg *)0; } int proxy_conf_diffserv_codepoint(Cfg *confp, char* policy) { char *p; long l; if (((l=strtol(policy,&p,0)) >= 0) && (l<=0xff) && (!(*p))) return((int)l); else { Cfg* cfp; cfp = cfg_get("diffserv-codepoint",confp); while (cfp) { if((cfp->argc<1)||(cfp->argv[0][0]=='-')) { syslog(LLEV,"fwtkcfgerr: diffserv-codepoint needs an argument, line %d",cfp->ln); exit(1); } if (!(strcmp(cfp->argv[0],policy))) { if (((l=strtol(cfp->argv[1],&p,0)) >= 0) && (l<=0xff) && (!(*p))) return((int)l); else { syslog(LLEV,"fwtkcfgerr: invalid diffserv-codepoint value, line %d",cfp->ln); exit(1); } } cfp = cfg_get("diffserv-codepoint",NULL); } syslog(LLEV,"fwtkcfgerr: invalid diffserv-codepoint %.128s",policy); exit(1); } } int proxy_check_dest(list,xtnd) char **list; int xtnd; { if(searchlisth(proxy_stats.dst,list)) { syslog(LLEV,"deny host %.256s/%.20s connect to %.256s", proxy_stats.rladdr,proxy_stats.riaddr,proxy_stats.dst); return(1); } if (xtnd) { switch (auth_perm(proxy_confp,proxy_stats.authuser,proxy_name, proxy_stats.dst,NULL)) { case -1: syslog(LLEV,"no match for %.256s user=%.100s in netperm-table",proxy_name,proxy_stats.authuser); return(1); case 1: syslog(LLEV,"deny host=%.512s/%.20s connect to %.512s user=%.100s",proxy_stats.rladdr,proxy_stats.riaddr,proxy_stats.dst,proxy_stats.authuser); return(1); } } syslog(LLEV,"permit host=%.512s/%.20s connect to %.512s:%d", proxy_stats.rladdr,proxy_stats.riaddr,proxy_stats.dst, proxy_stats.port); return(0); } void proxy_parse_options(Cfg *cf,fwparm options[]) { int x; fwparm* option; for (x=1; x < cf->argc; x++) { if (cf->argv[x][0] != '-') continue; for (option = options; option->type ; option++) { if (!strcmp(cf->argv[x],option->name)) { switch (option->type) { case FWPARM_BOOL: *((int*)(option->value)) = (int) 1; break; case FWPARM_INT: if (++x >= cf->argc) { syslog(LLEV,"fwtkcfgerr: %s needs an argument, line %d",option->name,cf->ln); exit(1); } *((int*) option->value) = atoi(cf->argv[x]); break; case FWPARM_STRING: if (++x >= cf->argc) { syslog(LLEV,"fwtkcfgerr: %s needs an argument, line %d",option->name,cf->ln); exit(1); } strlcpy((char*)option->value,cf->argv[x],MAX_STR); break; case FWPARM_CHAR: if (++x >= cf->argc) { syslog(LLEV,"fwtkcfgerr: %s needs an argument, line %d",option->name,cf->ln); exit(1); } if (strlen(cf->argv[x]) == 1) *((char*)option->value) = cf->argv[x][0]; else { syslog(LLEV,"fwtkcfgerr: %s can be one character only, line %d",option->name,cf->ln); exit(1); } break; case FWPARM_LIST: if(++x >= cf->argc) { syslog(LLEV,"fwtkcfgerr: malformed line %d: missing option",cf->ln); exit(1); } freelist((char***) option->value); if(!strcmp(cf->argv[x],"{")) { while(1) { if(++x >= cf->argc) { syslog(LLEV,"fwtkcfgerr: malformed line %d: missing option",cf->ln); exit(1); } if(!strcmp(cf->argv[x],"}")) break; addlist(cf->argv[x],(char***) option->value); } } else addlist(cf->argv[x],(char***) option->value); break; case FWPARM_PORT: if (++x >= cf->argc) { syslog(LLEV,"fwtkcfgerr: %s needs an argument, line %d",option->name,cf->ln); exit(1); } *((int*) option->value) = str_to_port(cf->argv[x]); break; case FWPARM_DSCP: if (++x >= cf->argc) { syslog(LLEV,"fwtkcfgerr: %s needs an argument, line %d",option->name,cf->ln); exit(1); } *((int*) option->value) = (int) proxy_conf_diffserv_codepoint(proxy_confp,cf->argv[x]); break; case FWPARM_OPPERMIT: case FWPARM_OPLOG: case FWPARM_OPDENY: case FWPARM_OPAUTH: case FWPARM_OPXTND: if(++x >= cf->argc) { syslog(LLEV,"fwtkcfgerr: malformed line %d: missing option",cf->ln); exit(1); } if(!strcmp(cf->argv[x],"{")) { while(1) { int flag; struct hash_entry *he; if(++x >= cf->argc) { syslog(LLEV,"fwtkcfgerr: malformed line %d: missing option",cf->ln); exit(1); } if(!strcmp(cf->argv[x],"}")) break; flag = 077 & option->type; if ((he=find_vhe2((struct hash_descr*) option->value,cf->argv[x], strlen(cf->argv[x])))) he->flags = flag ? he->flags | flag : 0; else { syslog(LLEV,"fwtkcfgerr: unknown operation %s,line %d", cf->argv[x],cf->ln); exit(1); } } break; } else { /* ugly */ int flag; struct hash_entry *he; flag = 077 & option->type; if ((he=find_vhe2((struct hash_descr*) option->value,cf->argv[x], strlen(cf->argv[x])))) he->flags = flag ? he->flags | flag : 0; else { syslog(LLEV,"fwtkcfgerr: unknown operation %s,line %d", cf->argv[x],cf->ln); exit(1); } break; } default: syslog(LLEV,"fwtkcfgerr: unknown parameter type"); exit(1); } break; } } if (!option->type) { syslog(LLEV,"fwtkcfgerr: unknown option %s,line %d", cf->argv[x],cf->ln); exit(1); } } }