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

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

Parent Directory Parent Directory | Revision Log Revision Log


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

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