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

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

Parent Directory Parent Directory | Revision Log Revision Log


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

1 /* 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.28