/[svn]/vendor/pxys2-2.0.0/pxyscand/src/PXConfigLoader.cc
ViewVC logotype

Annotation of /vendor/pxys2-2.0.0/pxyscand/src/PXConfigLoader.cc

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3252 - (hide annotations)
Wed Apr 2 20:41:43 2014 UTC (9 years, 1 month ago) by michael
File MIME type: text/x-c++src
File size: 15180 byte(s)
- Imported pxys2-2.0.0

1 michael 3252 /* Copyright (C) 2003 Stephane Thiell
2     *
3     * This file is part of pxyservd (from pxys)
4     *
5     * This program is free software; you can redistribute it and/or
6     * modify it under the terms of the GNU General Public License
7     * as published by the Free Software Foundation; either version 2
8     * of the License, or (at your option) any later version.
9     *
10     * This program is distributed in the hope that it will be useful,
11     * but WITHOUT ANY WARRANTY; without even the implied warranty of
12     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13     * GNU General Public License for more details.
14     *
15     * You should have received a copy of the GNU General Public License
16     * along with this program; if not, write to the Free Software
17     * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18     *
19     */
20     #define RCSID "$Id: PXConfigLoader.cc,v 1.3 2004/01/02 00:33:03 mbuna Exp $"
21    
22     #ifdef HAVE_CONFIG_H
23     #include "config.h"
24     #endif
25    
26     #include "PXConfigLoader.h"
27     #include "PXConfig.h"
28    
29     #include <iostream>
30    
31     #include <arpa/inet.h>
32    
33     // XPaths...
34    
35     #define XP_OPAS "/pxyscand/opas"
36     #define XP_OPAS_PORT "port"
37     #define XP_OPAS_BIND_ADDRESS "bind-address"
38     #define XP_OPAS_PROTOCOL "protocol"
39     #define XP_OPAS_ALLOW "allow"
40     // TODO: deny
41     #define XP_OPAS_LIMIT "limit"
42    
43     #define XP_SCANNER "/pxyscand/scanner"
44     #define XP_SCANNER_MAXSCANS "maxscans"
45     #define XP_SCANNER_MODULE_TYPE_ATTR "module/@type"
46     #define XP_SCANNER_MODULE "module[@type]"
47     #define XP_SCANNER_SOURCE_POOL "source-pool"
48     #define XP_SCANNER_SOURCE_POOL_ADDRESS "address"
49     #define XP_SCANNER_TARGET "target"
50     #define XP_SCANNER_TARGET_ADDRESS "address"
51     #define XP_SCANNER_TARGET_PORT "port"
52     #define XP_SCANNER_TARGET_CHECK "target-check"
53     #define XP_SCANNER_LOG_AGENT "log-agent"
54     #define XP_SCANNER_TIMEOUT "timeout"
55     #define XP_SCANNER_STRING "string"
56    
57     #define XP_CACHE "/pxyscand/cache"
58     #define XP_CACHE_DIRECTORY "directory"
59     #define XP_CACHE_EXPIRE "expire"
60     #define XP_CACHE_PROXY_EXPIRE "proxy-expire"
61     #define XP_CACHE_MAXIPS "maxips"
62    
63     #define XP_NOSCAN "/pxyscand/noscan"
64     #define XP_NOSCAN_ADDRESS "address"
65    
66     using std::cout;
67     using std::endl;
68    
69     PXConfigLoader::PXConfigLoader(const char *inFile)
70     : PXXMLXPathLoaderImp(inFile)
71     {
72     }
73    
74     PXConfigLoader::~PXConfigLoader()
75     {
76     }
77    
78    
79     bool
80     PXConfigLoader::StringToNetworkNetmask(const char *str,
81     in_addr &oNet,
82     in_addr &oMask)
83     {
84     char ipbuf[16];
85     size_t len, j;
86     int k, dot = 0;
87     char *p;
88    
89     if ((p = strchr(str, '/')) == NULL)
90     oMask.s_addr = htonl(0xffffffff);
91     else
92     {
93     *p++ = '\0';
94     if (!strchr(p, '.'))
95     {
96     int nbits;
97    
98     if ((nbits = atoi(p)) > 0 && nbits <= 32)
99     oMask.s_addr = htonl(~(0xffffffff >> nbits));
100     }
101     else if (inet_pton(AF_INET, p, &oNet) == -1)
102     return false;
103     }
104    
105     len = strlen(str);
106     len = len < sizeof(ipbuf) ? len : sizeof(ipbuf) - 1;
107     for (j = 0; j < len; j++)
108     {
109     if (str[j] == '.')
110     dot++;
111     ipbuf[j] = str[j];
112     }
113     if (dot > 4 || len >= sizeof(ipbuf) - ((3 - dot) * 2))
114     return false;
115    
116     for (k = 0; k < 3 - dot; k++)
117     {
118     ipbuf[j++] = '.';
119     ipbuf[j++] = '0';
120     }
121    
122     assert(j < sizeof(ipbuf));
123     ipbuf[j] = '\0';
124    
125     if (inet_pton(AF_INET, ipbuf, &oNet) == -1)
126     return false;
127    
128     return true;
129     }
130    
131     PXConfig *
132     PXConfigLoader::Load()
133     {
134     PXConfig *cfg = new PXConfig;
135     try
136     {
137     this->DoLoad(cfg);
138     }
139     catch (...)
140     {
141     delete cfg;
142     throw;
143     }
144     return cfg;
145     }
146    
147     void
148     PXConfigLoader::DoLoad(PXConfig *cfg)
149     {
150     xmlXPathObjectPtr o, o2;
151    
152     if ((o = this->EvalUnique(XP_OPAS)))
153     {
154     StPXXPathContextNode cxNode(&mCx->node, o->nodesetval->nodeTab[0]);
155    
156     /* OPAS Port */
157     cfg->opas.port = this->GetInteger(XP_OPAS_PORT, 0, 1);
158    
159     /* OPAS local address (bind) */
160     this->GetAddress(XP_OPAS_BIND_ADDRESS, 0, 0, "opas/bind-address",
161     &cfg->opas.local_address);
162    
163     /* Protocol(s) to enable (tcp, udp) */
164     o2 = this->Eval(XP_OPAS_PROTOCOL);
165     if (!o2 || !o2->nodesetval->nodeNr)
166     PXXMLException::Throw("Missing parameter", "opas/protocol");
167     cfg->opas.proto.reserve(o2->nodesetval->nodeNr);
168     for (int i = 0; i < o2->nodesetval->nodeNr; i++)
169     {
170     xmlChar *s;
171     xmlNodePtr n;
172     n = o2->nodesetval->nodeTab[i]->xmlChildrenNode;
173     if (!(s = xmlNodeListGetString(mDoc, n, 1)))
174     PXXMLException::Throw("Empty protocol, use: tcp or udp",
175     "opas/protocol");
176     if (!strcmp((char *)s, "tcp"))
177     cfg->opas.proto.push_back(PXOPAS_PROTO_TCP);
178     else if (!strcmp((char *)s, "udp"))
179     cfg->opas.proto.push_back(PXOPAS_PROTO_UDP);
180     else
181     {
182     xmlFree(s);
183     PXXMLException::Throw("Unknown protocol (use: tcp or udp)",
184     "opas/protocol");
185     }
186     xmlFree(s);
187     }
188     xmlXPathFreeObject(o2);
189    
190     /* Allowed IPs */
191     o2 = this->Eval(XP_OPAS_ALLOW);
192     if (!o2 || !o2->nodesetval->nodeNr)
193     PXXMLException::Throw("Missing parameter", "opas/allow");
194     cfg->opas.allow.reserve(o2->nodesetval->nodeNr);
195     for (int i = 0; i < o2->nodesetval->nodeNr; i++)
196     {
197     xmlChar *s;
198     xmlNodePtr n;
199     in_addr addr;
200    
201     n = o2->nodesetval->nodeTab[i]->xmlChildrenNode;
202     if (!(s = xmlNodeListGetString(mDoc, n, 1)))
203     PXXMLException::Throw("Empty allow field", "opas/allow");
204     int res = inet_pton(AF_INET, (char *)s, &addr);
205     xmlFree(s);
206     if (res == -1)
207     PXXMLException::Throw("Bad IP address", "opas/allow");
208     cfg->opas.allow.push_back(addr);
209     }
210     xmlXPathFreeObject(o2);
211    
212     /* OPAS limit */
213     cfg->opas.limit = this->GetInteger(XP_OPAS_LIMIT, 0, 1);
214    
215     xmlXPathFreeObject(o);
216     }
217    
218     if ((o = this->EvalUnique(XP_SCANNER)))
219     {
220     StPXXPathContextNode cxNode(&mCx->node, o->nodesetval->nodeTab[0]);
221    
222     cfg->scanner.maxscans = this->GetInteger(XP_SCANNER_MAXSCANS, 0, 1);
223     if (cfg->scanner.maxscans <= 0)
224     cfg->scanner.maxscans = 100; // bah
225    
226     if (!(o2 = this->Eval(XP_SCANNER_MODULE_TYPE_ATTR)))
227     PXXMLException::Throw("Missing parameter", "scanner/module");
228     else
229     {
230     cfg->scanner.modules.reserve(o2->nodesetval->nodeNr);
231     for (int i = 0; i < o2->nodesetval->nodeNr; i++)
232     {
233     PXConfigModule m;
234     xmlChar *s;
235     xmlNodePtr n = o2->nodesetval->nodeTab[i]->xmlChildrenNode;
236    
237     if (!(s = xmlNodeListGetString(mDoc, n, 1)))
238     PXXMLException::Throw("Empty type attribute not allowed",
239     "scanner/module");
240    
241     m.port = 0; // only used for http scan module
242    
243     if (!xmlStrcasecmp(s, (xmlChar*)"wingate"))
244     m.id = CONFIG_MODULE_WINGATE;
245     else if (!xmlStrcasecmp(s, (xmlChar*)"socks"))
246     m.id = CONFIG_MODULE_SOCKS;
247     else if (!xmlStrcmp(s, (xmlChar*)"http"))
248     {
249     m.id = CONFIG_MODULE_HTTP;
250     m.port = this->GetInteger(XP_SCANNER_MODULE, i, 65536);
251     // Note: port 0 not allowed for convenience.
252     if (m.port <= 0 || m.port >= 65536)
253     PXXMLException::Throw("Bad proxy port number", "scanner/module");
254     }
255     else if (!xmlStrcasecmp(s, (xmlChar*)"crazybandit"))
256     m.id = CONFIG_MODULE_CRAZYBANDIT;
257    
258     /* Handle new module type here. */
259    
260     else
261     PXXMLException::Throw("Unknown scanner/module type attribute",
262     "scanner/module");
263    
264     cfg->scanner.modules.push_back(m);
265     }
266     xmlXPathFreeObject(o2);
267     }
268    
269    
270     if ((o2 = this->Eval(XP_SCANNER_SOURCE_POOL)))
271     {
272     StPXXPathContextNode cxNode(&mCx->node, o2->nodesetval->nodeTab[0]);
273    
274     xmlXPathObjectPtr o3 = this->Eval(XP_SCANNER_TARGET_ADDRESS);
275     if (o3)
276     {
277     int cnt = o3->nodesetval->nodeNr;
278     cfg->scanner.source_pool.reserve(cnt);
279     xmlXPathFreeObject(o3);
280     for (int i = 0; i < cnt; i++)
281     {
282     sockaddr_in sin;
283     memset(&sin, 0, sizeof(sin));
284     sin.sin_family = AF_INET;
285     sin.sin_port = htons(0);
286    
287     this->GetAddress(XP_SCANNER_TARGET_ADDRESS, i, 0,
288     "scanner/source-pool/address", &sin.sin_addr);
289    
290     // Test the local address now.
291     int testFD = socket(AF_INET, SOCK_STREAM, 0);
292     if (testFD == -1) // doh !
293     PXXMLException::Throw("Source pool address test failed",
294     "socket() failed!");
295     if (bind(testFD, (sockaddr *)&sin, sizeof(sin)) == -1)
296     PXXMLException::Throw("Source pool address test failed",
297     "bind() failed!");
298     close(testFD);
299     cfg->scanner.source_pool.push_back(sin.sin_addr);
300     }
301     }
302     xmlXPathFreeObject(o2);
303     }
304    
305     if (!(o2 = this->Eval(XP_SCANNER_TARGET)))
306     PXXMLException::Throw("Missing parameter", "scanner/target");
307    
308     cfg->scanner.targets.reserve(o2->nodesetval->nodeNr);
309     for (int i = 0; i < o2->nodesetval->nodeNr; i++)
310     {
311     StPXXPathContextNode cxNodeTarget(&mCx->node,
312     o2->nodesetval->nodeTab[i]);
313     PXConfigScannerTarget target;
314    
315     this->GetAddress(XP_SCANNER_TARGET_ADDRESS, 0, 1,
316     "scanner/target/address", &target.address);
317     target.port = this->GetInteger(XP_SCANNER_TARGET_PORT, 0, 1);
318    
319     cfg->scanner.targets.push_back(target);
320     }
321     xmlXPathFreeObject(o2);
322    
323     cfg->scanner.target_check = (time_t)this->GetInteger(
324     XP_SCANNER_TARGET_CHECK, 0, 1);
325     cfg->scanner.log_agent = (char *)this->CopyString(XP_SCANNER_LOG_AGENT,
326     0, 0);
327     cfg->scanner.timeout = (time_t)this->GetInteger(XP_SCANNER_TIMEOUT, 0, 1);
328     if (cfg->scanner.timeout <= 0)
329     cfg->scanner.timeout = 30;
330    
331     if (!(o2 = this->Eval(XP_SCANNER_STRING)))
332     PXXMLException::Throw("Missing parameter", "scanner/string");
333    
334     cfg->scanner.strings.reserve(o2->nodesetval->nodeNr);
335     for (int i = 0; i < o2->nodesetval->nodeNr; i++)
336     {
337     xmlChar *s;
338     xmlNodePtr n = o2->nodesetval->nodeTab[i]->xmlChildrenNode;
339     if (!(s = xmlNodeListGetString(mDoc, n, 1)))
340     PXXMLException::Throw("Empty string field", "scanner/string");
341     cfg->scanner.strings.push_back((char*)s);
342     }
343    
344     xmlXPathFreeObject(o2);
345     xmlXPathFreeObject(o);
346     }
347    
348     if ((o = this->EvalUnique(XP_CACHE)))
349     {
350     StPXXPathContextNode cxNode(&mCx->node, o->nodesetval->nodeTab[0]);
351    
352     // Cache directory
353     cfg->cache.dir = (char *)this->CopyString(XP_CACHE_DIRECTORY, 0, 1);
354     // Cache expire seconds
355     cfg->cache.expire = this->GetInteger(XP_CACHE_EXPIRE, 0, 1);
356     // Proxy cache expire seconds
357     cfg->cache.proxy_expire = this->GetInteger(XP_CACHE_PROXY_EXPIRE, 0, 1);
358     // Cache max IPs
359     cfg->cache.maxips = this->GetInteger(XP_CACHE_MAXIPS, 0, 1);
360    
361     xmlXPathFreeObject(o);
362     }
363    
364     if ((o = this->EvalUnique(XP_NOSCAN)))
365     {
366     StPXXPathContextNode cxNode(&mCx->node, o->nodesetval->nodeTab[0]);
367    
368     o2 = this->Eval(XP_NOSCAN_ADDRESS);
369     if (o2)
370     {
371     cfg->noscan.address.reserve(o2->nodesetval->nodeNr);
372     for (int i = 0; i < o2->nodesetval->nodeNr; i++)
373     {
374     xmlChar *s;
375     xmlNodePtr n;
376     n = o2->nodesetval->nodeTab[i]->xmlChildrenNode;
377     if (!(s = xmlNodeListGetString(mDoc, n, 1)))
378     PXXMLException::Throw("Empty allow field", "noscan/address");
379    
380     NetworkNetmask nwnm;
381     bool res = StringToNetworkNetmask((char *)s, nwnm.network,
382     nwnm.netmask);
383     xmlFree(s);
384     if (!res)
385     PXXMLException::Throw("Invalid address", "noscan/address");
386     cfg->noscan.address.push_back(nwnm);
387     }
388     xmlXPathFreeObject(o2);
389     }
390     xmlXPathFreeObject(o);
391     }
392     }
393    
394     void
395     PXConfigLoader::Dump(PXConfig *cfg)
396     {
397     size_t i;
398    
399     cout << "OPAS config" << endl;
400     cout << "port: " << cfg->opas.port << endl;
401     cout << "local_address: ";
402     if (cfg->opas.local_address.s_addr == INADDR_ANY)
403     cout << "default (any)";
404     else
405     cout << inet_ntoa(cfg->opas.local_address);
406     cout << endl;
407     cout << "proto: ";
408     for (i = 0; i < cfg->opas.proto.size(); i++)
409     if (cfg->opas.proto[i] == PXOPAS_PROTO_TCP)
410     cout << "tcp ";
411     else
412     cout << "udp";
413     cout << endl;
414    
415     cout << "allow: ";
416     for (size_t i = 0; i < cfg->opas.allow.size(); i++)
417     cout << inet_ntoa(cfg->opas.allow[i]) << " ";
418     cout << endl;
419    
420     cout << "limit: ";
421     if (cfg->opas.limit == 0)
422     cout << "unlimited";
423     else
424     cout << cfg->opas.limit;
425     cout << endl << endl;
426    
427     cout << "SCANNER config" << endl;
428     cout << "maxscans: " << cfg->scanner.maxscans << endl;
429     if (cfg->scanner.modules.size() == 0)
430     {
431     cout << "NO SCANNER MODULE ENABLED !!!" << endl;
432     exit(1);
433     }
434     else
435     {
436     cout << "Scanner modules (" << cfg->scanner.modules.size() << "):" << endl;
437     for (i = 0; i < cfg->scanner.modules.size(); i++)
438     {
439     cout << "id: " << cfg->scanner.modules[i].id << endl;
440     if (cfg->scanner.modules[i].port > 0 &&
441     cfg->scanner.modules[i].port < 65536)
442     cout << "port: " << cfg->scanner.modules[i].port << endl;
443     else
444     {
445     cout << "BAD PORT NUMBER: " << cfg->scanner.modules[i].port << endl;
446     exit(1);
447     }
448     }
449     }
450     if (cfg->scanner.source_pool.size() == 0)
451     cout << "No source pool." << endl;
452     else
453     {
454     cout << "Source pool (" << cfg->scanner.source_pool.size() << "):" << endl;
455     for (i = 0; i < cfg->scanner.source_pool.size(); i++)
456     cout << "address: " << inet_ntoa(cfg->scanner.source_pool[i]) << endl;
457     }
458     cout << "Targets (" << cfg->scanner.targets.size() << "):" << endl;
459     for (i = 0; i < cfg->scanner.targets.size(); i++)
460     {
461     cout << "address: " << inet_ntoa(cfg->scanner.targets[i].address);
462     cout << " port: " << cfg->scanner.targets[i].port;
463     cout << endl;
464     }
465     cout << "target_check: " << cfg->scanner.target_check << endl;
466     cout << "Strings..." << endl;
467     for (i = 0; i < cfg->scanner.strings.size(); i++)
468     cout << "string: " << cfg->scanner.strings[i] << endl;
469    
470     cout << endl;
471     cout << "CACHE config:" << endl;
472     cout << "expire: " << cfg->cache.expire << " (seconds)" << endl;
473     cout << "maxips: " << cfg->cache.maxips << endl << endl;
474    
475     cout << "NOSCAN config:" << endl;
476     for (i = 0; i < cfg->noscan.address.size(); i++)
477     {
478     cout << "noscan: " << inet_ntoa(cfg->noscan.address[i].network);
479     cout << "/" << inet_ntoa(cfg->noscan.address[i].netmask) << endl;
480     }
481     }

svnadmin@ircd-hybrid.org
ViewVC Help
Powered by ViewVC 1.1.30