#include #include #include #include "userfirewall.h" #include "userfirewall.m" #include #include static CONFIG_FILE f_route ("/proc/net/route",help_nil ,CONFIGF_OPTIONAL|CONFIGF_PROBED); class FWROUTE: public ARRAY_OBJ{ public: unsigned long network; unsigned long netmask; char device[20]; /*~PROTOBEG~ FWROUTE */ public: FWROUTE (const char *_device, unsigned long _network, unsigned long _netmask); /*~PROTOEND~ FWROUTE */ }; PUBLIC FWROUTE::FWROUTE( const char *_device, unsigned long _network, unsigned long _netmask) { strcpy (device,_device); network = _network; netmask = _netmask; } class FWROUTES: public ARRAY{ /*~PROTOBEG~ FWROUTES */ public: FWROUTE *getitem (int no)const; void load (void); /*~PROTOEND~ FWROUTES */ }; PUBLIC FWROUTE *FWROUTES::getitem(int no)const { return (FWROUTE*)ARRAY::getitem(no); } static int fwinfo_splitline (const char *line, SSTRINGS &tb) { int ret = 0; while (*line != '\0'){ SSTRING *s = new SSTRING; line = s->copyword (line); if (s->is_empty()){ delete s; break; }else{ tb.add (s); ret ++; } } return ret; } static unsigned long fwinfo_xtou (const char *s) { unsigned long val = 0; while (*s != '\0'){ if (isdigit(*s)){ val = (val<<4) + *s - '0'; }else{ val = (val<<4) + (*s & 0xf) + 9; } s++; } return ntohl (val); } PUBLIC void FWROUTES::load() { remove_all(); FILE_CFG *fin = f_route.fopen ("r"); if (fin != NULL){ char line[1000]; fgets(line,sizeof(line)-1,fin); // Skip the header while (fgets(line,sizeof(line)-1,fin) != NULL){ SSTRINGS tb; int nb = fwinfo_splitline (line,tb); if (nb >= 8){ const char *inter = tb.getitem(0)->get(); unsigned long network = fwinfo_xtou(tb.getitem(1)->get()); unsigned long netmask = fwinfo_xtou(tb.getitem(7)->get()); add (new FWROUTE(inter,network,netmask)); } } fclose (fin); } } class NAMEIP: public ARRAY_OBJ{ public: SSTRING name; SSTRING ip; /*~PROTOBEG~ NAMEIP */ public: NAMEIP (const char *_name, const char *_ip); /*~PROTOEND~ NAMEIP */ }; PUBLIC NAMEIP::NAMEIP(const char *_name, const char *_ip) { name.setfrom (_name); ip.setfrom (_ip); } class NAMEIPS: public ARRAY{ /*~PROTOBEG~ NAMEIPS */ public: void addgroups (const char *ip, SSTRINGS&tb, int start); NAMEIP *getitem (int no)const; void load (void); /*~PROTOEND~ NAMEIPS */ }; PUBLIC NAMEIP *NAMEIPS::getitem(int no) const { return (NAMEIP*)ARRAY::getitem(no); } PUBLIC void NAMEIPS::addgroups (const char *ip, SSTRINGS &tb, int start) { int nb = tb.getnb(); for (int i=start; iget(); int len = strlen(gr); char tmp[len+2]; tmp[0] = '@'; strcpy (tmp+1,gr); add (new NAMEIP(tmp,ip)); } } PUBLIC void NAMEIPS::load() { remove_all(); FILE *fin = fopen ("/var/run/userfirewall.state","r"); if (fin != NULL){ char line[10000]; while (fgets_strip(line,sizeof(line)-1,fin,NULL)!=NULL){ SSTRINGS tb; int nb = fwinfo_splitline (line,tb); if (nb >= 3){ const char *ip = tb.getitem(1)->get(); add (new NAMEIP(tb.getitem(0)->get(),ip)); // Add the groups addgroups (ip,tb,3); } } fclose (fin); } // Check permanent link FIREUSERS users; time_t now = time(NULL); for (int i=0; iuntil > now && u->source.is_filled()){ const char *ip = u->source.get(); add (new NAMEIP(u->id.get(),ip)); SSTRINGS tb; fwinfo_splitline (u->groups.get(),tb); addgroups (ip,tb,0); } } (*this); NAMEIP *i1 = (NAMEIP*)o1; NAMEIP *i2 = (NAMEIP*)o2; int ret = i1->name.cmp(i2->name); if (ret == 0) ret = i1->ip.cmp(i2->ip); return ret; } static NAMEIPS nameips; static FWROUTES routes; static int count = 0; static const char *fwinfo_pickhost (const char *s) { const char *ret = NULL; if (strncmp(s,"userfw/",7)==0){ ret = s + 7; } return ret; } /* Verify is a host is valid. It correspond to either a user or a group */ static bool fwinfo_hostexist (const char *host) { bool ret = false; const char *name = fwinfo_pickhost (host); if (name != NULL){ if (userfirewall_validhost()){ FIREUSERS users; for (int i=0; iid.cmp(name)==0){ ret = true; break; }else{ SSTRINGS tb; fwinfo_splitline (u->groups.get(),tb); if (tb.lookup(name)!=-1){ ret = true; break; } } } }else{ // No validation, we accept it ret = true; } } return ret; } static int fwinfo_gethostlist (SSTRINGS &hosts, SSTRINGS &descs) { SSTRINGS groups; FIREUSERS users; for (int i=0; isetfromf ("userfw/%s",u->id.get()); hosts.add (s); descs.add (new SSTRING (MSG_U(I_USERFIREWALL,"User assigned firewall"))); SSTRINGS grs; grs.neverdelete(); int n = fwinfo_splitline (u->groups.get(),grs); for (int j=0; jget(); SSTRING *s = new SSTRING; s->setfromf ("userfw/@%s",g); hosts.add (s); descs.add (new SSTRING (MSG_R(I_USERFIREWALL))); } return users.getnb() + groups.getnb(); } static int fwinfo_gethostinfo (const char *host, SSTRINGS &infos) { int ret = -1; const char *name = fwinfo_pickhost (host); if (name != NULL){ int n = nameips.getnb(); for (int i=0; iname.cmp(name)==0){ infos.add (new SSTRING(nip->ip)); ret = 0; } } } return ret; } static bool fwinfo_devexist (const char *devname) { return fwinfo_hostexist(devname); } static int fwinfo_getdevlist (SSTRINGS &devs, SSTRINGS &descs) { return fwinfo_gethostlist(devs,descs); } static int fwinfo_getdevinfo (const char *devname, SSTRINGS &kerneldevs) { int ret = fwinfo_gethostinfo (devname,kerneldevs); if (ret != -1){ // Transform host into interface // We have to locate on which interface a given host // is located. If we do not know, we return -1 if (routes.getnb()==0) routes.load(); int rnb = routes.getnb(); int devnb = kerneldevs.getnb(); for (int i=0; iget(); unsigned long ip = ipnum_aip2l (h); bool found = false; for (int j=0; jnetmask; if (ipm == r->network){ found = true; ss->setfrom (r->device); break; } } if (!found){ // Can't tell on which interface it is ret = -1; break; } } } return ret; } void *fwinfo_api_get() { count++; if (count == 1) nameips.load(); FWINFO_API *api = new FWINFO_API; api->devexist = fwinfo_devexist; api->getdevlist = fwinfo_getdevlist; api->getdevinfo = fwinfo_getdevinfo; api->hostexist = fwinfo_hostexist; api->gethostlist = fwinfo_gethostlist; api->gethostinfo = fwinfo_gethostinfo; return api; } void fwinfo_api_release(void *api) { count--; if (count == 0){ nameips.remove_all(); routes.remove_all(); } delete (FWINFO_API*)api; }