/[svn]/hopm/branches/1.1.x/src/libopm/src/libopm.c
ViewVC logotype

Contents of /hopm/branches/1.1.x/src/libopm/src/libopm.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 9996 - (show annotations)
Thu Jun 17 18:43:18 2021 UTC (5 weeks, 2 days ago) by michael
File MIME type: text/x-chdr
File size: 32591 byte(s)
- config.c, libopm.c: remove redundant 'p->addr.ss_family = res->ai_family' assignments

1 /*
2 * Copyright (C) 2002-2003 Erik Fears
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to
16 *
17 * The Free Software Foundation, Inc.
18 * 59 Temple Place - Suite 330
19 * Boston, MA 02111-1307, USA.
20 *
21 *
22 */
23
24 #include "setup.h"
25
26 #include <errno.h>
27 #include <time.h>
28 #include <unistd.h>
29 #include <fcntl.h>
30 #include <string.h>
31 #include <stdlib.h>
32 #include <assert.h>
33 #include <poll.h>
34 #ifdef HAVE_LIBCRYPTO
35 #include <openssl/ssl.h>
36 #endif
37 #include <sys/types.h>
38 #include <sys/socket.h>
39 #include <netdb.h>
40
41 #include "config.h"
42 #include "libopm.h"
43 #include "memory.h"
44 #include "opm_error.h"
45 #include "opm_types.h"
46 #include "opm_common.h"
47 #include "opm_gettime.h"
48 #include "list.h"
49 #include "proxy.h"
50
51
52 static OPM_PROTOCOL_CONFIG_T *libopm_protocol_config_create(void);
53 static void libopm_protocol_config_free(OPM_PROTOCOL_CONFIG_T *);
54
55 static OPM_SCAN_T *libopm_scan_create(OPM_T *, OPM_REMOTE_T *);
56 static void libopm_scan_free(OPM_SCAN_T *);
57
58 static OPM_CONNECTION_T *libopm_connection_create(void);
59 static void libopm_connection_free(OPM_CONNECTION_T *);
60
61 static void libopm_check_establish(OPM_T *);
62 static void libopm_check_poll(OPM_T *);
63 static void libopm_check_closed(OPM_T *);
64 static void libopm_check_queue(OPM_T *);
65
66 static void libopm_do_connect(OPM_T *, OPM_SCAN_T *, OPM_CONNECTION_T *);
67 static void libopm_do_readready(OPM_T *, OPM_SCAN_T *, OPM_CONNECTION_T *);
68 static int libopm_do_readready_tls(OPM_T *, OPM_SCAN_T *, OPM_CONNECTION_T *);
69 static void libopm_do_writeready(OPM_T *, OPM_SCAN_T *, OPM_CONNECTION_T *);
70 static void libopm_do_hup(OPM_T *, OPM_SCAN_T *, OPM_CONNECTION_T *);
71 static void libopm_do_read(OPM_T *, OPM_SCAN_T *, OPM_CONNECTION_T *);
72 static void libopm_do_openproxy(OPM_T *, OPM_SCAN_T *, OPM_CONNECTION_T *);
73 static void libopm_do_callback(OPM_T *, OPM_REMOTE_T *, int, int);
74
75 static OPM_REMOTE_T *libopm_setup_remote(OPM_REMOTE_T *, OPM_CONNECTION_T *);
76
77
78 /* OPM_PROTOCOLS hash
79 *
80 * OPM_PPROTOCOLS hashes the protocol types (int) to functions
81 * which handle the protocol (sending/receiving protocol specific
82 * data).
83 *
84 */
85 static OPM_PROTOCOL_T OPM_PROTOCOLS[] =
86 {
87 { OPM_TYPE_HTTP, libopm_proxy_http_write, NULL, 0 },
88 { OPM_TYPE_SOCKS4, libopm_proxy_socks4_write, NULL, 0 },
89 { OPM_TYPE_SOCKS5, libopm_proxy_socks5_write, NULL, 0 },
90 { OPM_TYPE_ROUTER, libopm_proxy_router_write, NULL, 0 },
91 { OPM_TYPE_WINGATE, libopm_proxy_wingate_write, NULL, 0 },
92 { OPM_TYPE_HTTPPOST, libopm_proxy_httppost_write, NULL, 0 },
93 { OPM_TYPE_DREAMBOX, libopm_proxy_dreambox_write, NULL, 0 },
94 { OPM_TYPE_HTTPS, libopm_proxy_https_write, libopm_do_readready_tls, 1 },
95 { OPM_TYPE_HTTPSPOST, libopm_proxy_httpspost_write, libopm_do_readready_tls, 1 },
96 { OPM_TYPE_SSH, NULL, NULL, 0 }
97 };
98
99 /* opm_create
100 *
101 * Initialize a new scanner and return a pointer to it.
102 *
103 * Parameters:
104 * None
105 *
106 * Return
107 * Pointer to new OPM_T (scanner)
108 */
109 OPM_T *
110 opm_create(void)
111 {
112 OPM_T *ret;
113
114 ret = libopm_calloc(sizeof(*ret));
115 ret->config = libopm_config_create();
116
117 /* Setup callbacks */
118 ret->callbacks = libopm_calloc(sizeof(OPM_CALLBACK_T) * CBLEN);
119
120 return ret;
121 }
122
123 /* opm_remote_create
124 *
125 * Create OPM_REMOTE_T struct, fill it with neccessary
126 * default values and return it to the client.
127 *
128 * Parameters:
129 * ip: IP of remote host
130 *
131 * Return:
132 * Address of OPM_REMOTE_T created
133 *
134 */
135 OPM_REMOTE_T *
136 opm_remote_create(const char *ip)
137 {
138 OPM_REMOTE_T *ret;
139
140 ret = libopm_calloc(sizeof(*ret));
141 ret->ip = libopm_strdup(ip);
142
143 return ret;
144 }
145
146 /* opm_remote_free
147 *
148 * Free OPM_REMOTE_T struct and cleanup
149 *
150 * Parameters:
151 * remote: Struct to free
152 *
153 * Return:
154 * None
155 */
156 void
157 opm_remote_free(OPM_REMOTE_T *remote)
158 {
159 OPM_NODE_T *p, *next;
160 OPM_PROTOCOL_CONFIG_T *ppc;
161
162 libopm_free(remote->ip);
163
164 LIST_FOREACH_SAFE(p, next, remote->protocols.head)
165 {
166 ppc = p->data;
167
168 libopm_protocol_config_free(ppc);
169 libopm_list_remove(&remote->protocols, p);
170 libopm_node_free(p);
171 }
172
173 libopm_free(remote);
174 }
175
176 /* opm_callback
177 * Register scanner level callback
178 *
179 * Parameters
180 * scanner: scanner struct
181 * type: callback type
182 * Return:
183 * Error code
184 */
185
186 OPM_ERR_T
187 opm_callback(OPM_T *scanner, int type, OPM_CALLBACK_FUNC *function, void *data)
188 {
189 if (type < 0 || type >= CBLEN)
190 return OPM_ERR_CBNOTFOUND;
191
192 scanner->callbacks[type].func = function;
193 scanner->callbacks[type].data = data;
194
195 return OPM_SUCCESS;
196 }
197
198 /* opm_free
199 *
200 * Free OPM_T (scanner) and cleanup
201 *
202 * Parameters:
203 * scanner: Address of OPM_T to cleanup
204 *
205 * Return:
206 * None
207 */
208 void
209 opm_free(OPM_T *scanner)
210 {
211 OPM_NODE_T *p, *next;
212 OPM_PROTOCOL_CONFIG_T *ppc;
213 OPM_SCAN_T *scan;
214
215 libopm_config_free(scanner->config);
216
217 LIST_FOREACH_SAFE(p, next, scanner->protocols.head)
218 {
219 ppc = p->data;
220
221 libopm_protocol_config_free(ppc);
222 libopm_list_remove(&scanner->protocols, p);
223 libopm_node_free(p);
224 }
225
226 LIST_FOREACH_SAFE(p, next, scanner->scans.head)
227 {
228 scan = p->data;
229
230 libopm_scan_free(scan);
231 libopm_list_remove(&scanner->scans, p);
232 libopm_node_free(p);
233 }
234
235 LIST_FOREACH_SAFE(p, next, scanner->queue.head)
236 {
237 scan = p->data;
238
239 libopm_scan_free(scan);
240 libopm_list_remove(&scanner->queue, p);
241 libopm_node_free(p);
242 }
243
244 libopm_free(scanner->callbacks);
245 libopm_free(scanner);
246 }
247
248 /* opm_config
249 *
250 * Wrapper to config_set. Set configuration variables
251 * on the config struct.
252 *
253 * Parameters:
254 * scanner: OPM_T struct the config struct resides in
255 * key: Variable within the config struct to set
256 * value: Address of value to set variable (key) to
257 *
258 * Return:
259 * OPM_ERR_T containing error code
260 */
261 OPM_ERR_T
262 opm_config(OPM_T *scanner, int key, const void *value)
263 {
264 return libopm_config_set(scanner->config, key, value);
265 }
266
267 /* opm_addtype
268 *
269 * Add a proxy type and port to the list of protocols
270 * a scanner will use.
271 *
272 * Parameters:
273 * scanner: pointer to scanner struct
274 * type: type of proxy to scan (used in hashing to the functions)
275 * port: port this specific type/protocol will scan on
276 * Return:
277 * OPM_SUCCESS: Successful protocol add
278 * OPM_ERR_BADPROTOCOL: Protocol is unknown
279 */
280 OPM_ERR_T
281 opm_addtype(OPM_T *scanner, int type, unsigned short int port)
282 {
283 OPM_NODE_T *node;
284 OPM_PROTOCOL_CONFIG_T *protocol_config;
285
286 for (unsigned int i = 0; i < sizeof(OPM_PROTOCOLS) / sizeof(OPM_PROTOCOL_T); ++i)
287 {
288 if (type == OPM_PROTOCOLS[i].type)
289 {
290 #ifndef HAVE_LIBCRYPTO
291 if (OPM_PROTOCOLS[i].use_tls)
292 return OPM_ERR_BADPROTOCOL;
293 #endif
294 protocol_config = libopm_protocol_config_create();
295 protocol_config->type = &OPM_PROTOCOLS[i];
296 protocol_config->port = port;
297
298 node = libopm_node_create(protocol_config);
299 libopm_list_add(&scanner->protocols, node);
300
301 return OPM_SUCCESS;
302 }
303 }
304
305 return OPM_ERR_BADPROTOCOL;
306 }
307
308 /* opm_remote_addtype
309 *
310 * Add a proxy type and port to the list of protocols
311 * a scanner will use.
312 *
313 * Parameters:
314 * remote: pointer to scanner struct
315 * type: type of proxy to scan (used in hashing to the functions)
316 * port: port this specific type/protocol will scan on
317 * Return:
318 * OPM_SUCCESS: Successful protocol add
319 * OPM_ERR_BADPROTOCOL: Protocol is unknown
320 */
321 OPM_ERR_T opm_remote_addtype(OPM_REMOTE_T *remote, int type, unsigned short int port)
322 {
323 OPM_NODE_T *node;
324 OPM_PROTOCOL_CONFIG_T *protocol_config;
325
326 for (unsigned int i = 0; i < sizeof(OPM_PROTOCOLS) / sizeof(OPM_PROTOCOL_T); ++i)
327 {
328 if (type == OPM_PROTOCOLS[i].type)
329 {
330 #ifndef HAVE_LIBCRYPTO
331 if (OPM_PROTOCOLS[i].use_tls)
332 return OPM_ERR_BADPROTOCOL;
333 #endif
334 protocol_config = libopm_protocol_config_create();
335 protocol_config->type = &OPM_PROTOCOLS[i];
336 protocol_config->port = port;
337
338 node = libopm_node_create(protocol_config);
339 libopm_list_add(&remote->protocols, node);
340
341 return OPM_SUCCESS;
342 }
343 }
344
345 return OPM_ERR_BADPROTOCOL;
346 }
347
348 /* libopm_protocol_config_create
349 *
350 * Allocate and return address of a new OPM_PROTOCOL_CONFIG_T
351 *
352 * Parameters:
353 * None
354 *
355 * Return:
356 * Address of new OPM_PROTOCOL_CONFIG_T
357 */
358 static OPM_PROTOCOL_CONFIG_T *
359 libopm_protocol_config_create(void)
360 {
361 OPM_PROTOCOL_CONFIG_T *ret;
362
363 ret = libopm_calloc(sizeof(*ret));
364
365 return ret;
366 }
367
368 /* protocol_config_free
369 *
370 * Free OPM_PROTOCOL_CONFIG_T struct
371 *
372 * Parameters:
373 * protocol: struct to free
374 *
375 * Return:
376 * None
377 */
378 static void
379 libopm_protocol_config_free(OPM_PROTOCOL_CONFIG_T *protocol)
380 {
381 libopm_free(protocol);
382 }
383
384 /* opm_scan
385 *
386 * Scan remote host. The opm_scan function takes an OPM_REMOTE_T
387 * struct, calculates the in_addr of the remote host, and creates
388 * a scan list based on protocols defined in the scanner.
389 *
390 * Parameters:
391 * scanner: Scanner to scan host on
392 * remote: OPM_REMOTE_T defining remote host
393 *
394 * Return:
395 * (to be written)
396 */
397 OPM_ERR_T
398 opm_scan(OPM_T *scanner, OPM_REMOTE_T *remote)
399 {
400 OPM_NODE_T *node; /* Node we'll add scan to when we link it to scans */
401 struct addrinfo hints, *res;
402
403 if (LIST_SIZE(&scanner->protocols) == 0 &&
404 LIST_SIZE(&remote->protocols) == 0)
405 return OPM_ERR_NOPROTOCOLS;
406
407 memset(&hints, 0, sizeof(hints));
408
409 hints.ai_family = AF_UNSPEC;
410 hints.ai_socktype = SOCK_STREAM;
411 hints.ai_flags = AI_NUMERICHOST;
412
413 /*
414 * XXX: libopm ideally shouldn't see an IP address in string representation.
415 * Could have been stuffed into the _OPM_REMOTE struct by the caller that
416 * already does getaddrinfo() anyway.
417 */
418 if (getaddrinfo(remote->ip, NULL, &hints, &res) || res->ai_family != AF_INET) /* XXX: only do v4 for now */
419 {
420 if (res)
421 freeaddrinfo(res);
422
423 return OPM_ERR_BADADDR;
424 }
425
426 OPM_SCAN_T *scan = libopm_scan_create(scanner, remote);
427
428 memcpy(&scan->addr, res->ai_addr, res->ai_addrlen);
429 scan->addr_len = res->ai_addrlen;
430
431 freeaddrinfo(res);
432
433 node = libopm_node_create(scan);
434 libopm_list_add(&scanner->queue, node);
435
436 return OPM_SUCCESS;
437 }
438
439 /* opm_end
440 *
441 * End a scan prematurely.
442 *
443 * Parameters:
444 * scanner: Scanner to end scan on
445 * remote: Pointer to remote struct to search for and end
446 *
447 * Return:
448 * No return. OPM_CALLBACK_END will still be called as normal.
449 */
450 void
451 opm_end(OPM_T *scanner, OPM_REMOTE_T *remote)
452 {
453 OPM_NODE_T *node1, *node2, *next1, *next2;
454 OPM_SCAN_T *scan;
455 OPM_CONNECTION_T *conn;
456
457 /* End active scans */
458 opm_endscan(scanner, remote);
459
460 /*
461 * Secondly remove all traces of it in the queue. Once removed we have to call
462 * OPM_CALLBACK_END
463 */
464 LIST_FOREACH_SAFE(node1, next1, scanner->queue.head)
465 {
466 scan = node1->data;
467
468 if (scan->remote == remote)
469 {
470 /* Free all connections */
471 LIST_FOREACH_SAFE(node2, next2, scan->connections.head)
472 {
473 conn = node2->data;
474
475 libopm_list_remove(&scan->connections, node2);
476 libopm_connection_free(conn);
477 libopm_node_free(node2);
478 continue;
479 }
480
481 /* OPM_CALLBACK_END because check_closed normally handles this */
482 libopm_do_callback(scanner, scan->remote, OPM_CALLBACK_END, 0);
483
484 /* Free up the scan */
485 libopm_list_remove(&scanner->queue, node1);
486 libopm_scan_free(scan);
487 libopm_node_free(node1);
488 }
489 }
490 }
491
492 /* opm_endscan
493 *
494 * End a scan prematurely. Only end non-queued scans. This is useful
495 * because it only checks the active scan list (saving time), where
496 * opm_end checks both the scan and the possibly large queue.
497 *
498 * Parameters:
499 * scanner: Scanner to end scan on
500 * remote: Pointer to remote struct to search for and end
501 *
502 * Return:
503 * No return. OPM_CALLBACK_END will still be called as normal.
504 */
505 void
506 opm_endscan(OPM_T *scanner, OPM_REMOTE_T *remote)
507 {
508 OPM_NODE_T *node1, *node2;
509 OPM_SCAN_T *scan;
510 OPM_CONNECTION_T *conn;
511
512 /*
513 * First check to see if it's in the queue, if it is set all connections closed
514 * Next cycle of libopm_check_closed will take care of the garbage and handle
515 * OPM_CALLBACK_END
516 */
517 LIST_FOREACH(node1, scanner->scans.head)
518 {
519 scan = node1->data;
520
521 if (scan->remote == remote)
522 {
523 LIST_FOREACH(node2, scan->connections.head)
524 {
525 conn = node2->data;
526 conn->state = OPM_STATE_CLOSED;
527 }
528 }
529 }
530 }
531
532 /* opm_active
533
534 Return number of scans in a scanner left.
535
536 Parameters:
537 scanner: Scanner to return active scans on
538
539 Return:
540 Number of active scans, both queued and active.
541 */
542 size_t
543 opm_active(OPM_T *scanner)
544 {
545 return LIST_SIZE(&scanner->queue) + LIST_SIZE(&scanner->scans);
546 }
547
548 /* scan_create
549 *
550 * Create new OPM_SCAN_T struct
551 *
552 * Parameters:
553 * scanner: Scanner the scan is being created for. This
554 * is needed to get information on currently set
555 * protocols/config.
556 *
557 * remote: Remote host this scan will be scanning
558 *
559 * Return
560 * Address of new struct
561 */
562 static OPM_SCAN_T *
563 libopm_scan_create(OPM_T *scanner, OPM_REMOTE_T *remote)
564 {
565 OPM_SCAN_T *ret;
566 OPM_CONNECTION_T *conn;
567 OPM_NODE_T *node, *p;
568 #ifdef HAVE_LIBCRYPTO
569 static int tls_init = 0;
570 static SSL_CTX *ctx_client;
571
572 if (!tls_init)
573 {
574 tls_init = 1;
575 SSLeay_add_ssl_algorithms();
576
577 ctx_client = SSL_CTX_new(SSLv23_client_method());
578 if (!ctx_client)
579 exit(EXIT_FAILURE);
580 }
581 #endif
582
583 ret = libopm_calloc(sizeof(*ret));
584 ret->remote = remote;
585
586 /* Setup list of connections, one for each protocol */
587 LIST_FOREACH(p, scanner->protocols.head)
588 {
589 conn = libopm_connection_create();
590
591 conn->protocol = ((OPM_PROTOCOL_CONFIG_T *)p->data)->type;
592 conn->port = ((OPM_PROTOCOL_CONFIG_T *)p->data)->port;
593
594 #ifdef HAVE_LIBCRYPTO
595 if (conn->protocol->use_tls)
596 /* SSL_new does only fail if OOM in which case HOPM exits anyway */
597 conn->tls_handle = SSL_new(ctx_client);
598 #endif
599
600 node = libopm_node_create(conn);
601 libopm_list_add(&ret->connections, node);
602 }
603
604 /*
605 * Do the same for any specific protocols the remote struct might be configured with
606 */
607 LIST_FOREACH(p, remote->protocols.head)
608 {
609 conn = libopm_connection_create();
610
611 conn->protocol = ((OPM_PROTOCOL_CONFIG_T *)p->data)->type;
612 conn->port = ((OPM_PROTOCOL_CONFIG_T *)p->data)->port;
613
614 #ifdef HAVE_LIBCRYPTO
615 if (conn->protocol->use_tls)
616 /* SSL_new does only fail if OOM in which case HOPM exits anyway */
617 conn->tls_handle = SSL_new(ctx_client);
618 #endif
619
620 node = libopm_node_create(conn);
621 libopm_list_add(&ret->connections, node);
622 }
623
624 return ret;
625 }
626
627 /* scan_free
628 *
629 * Free and cleanup OPM_SCAN_T struct
630 *
631 * Parametsr:
632 * scan: Scan struct to free
633 *
634 * Return:
635 * None
636 */
637 static void
638 libopm_scan_free(OPM_SCAN_T *scan)
639 {
640 OPM_NODE_T *p, *next;
641 OPM_CONNECTION_T *conn;
642
643 LIST_FOREACH_SAFE(p, next, scan->connections.head)
644 {
645 conn = p->data;
646
647 libopm_connection_free(conn);
648 libopm_list_remove(&scan->connections, p);
649 libopm_node_free(p);
650 }
651
652 libopm_free(scan);
653 }
654
655 /* connection_create
656 *
657 * Allocate new OPM_CONNECTION_T
658 *
659 * Parameters:
660 * None
661 *
662 * Return:
663 * Address of new OPM_CONNECTION_T
664 */
665 static OPM_CONNECTION_T *
666 libopm_connection_create(void)
667 {
668 OPM_CONNECTION_T *ret;
669
670 ret = libopm_calloc(sizeof(*ret));
671 ret->state = OPM_STATE_UNESTABLISHED;
672
673 return ret;
674 }
675
676 /* connection_free
677 *
678 * Free OPM_CONNECTION_T struct
679 *
680 * Parameters:
681 * conn: Address of struct to free
682 *
683 * Return:
684 * None
685 */
686 static void
687 libopm_connection_free(OPM_CONNECTION_T *conn)
688 {
689 libopm_free(conn);
690 }
691
692 /* opm_cycle
693 *
694 * Perform tasks (called by client's loop)
695 *
696 * Parameters:
697 * None
698 * Return:
699 * None
700 */
701 void
702 opm_cycle(OPM_T *scanner)
703 {
704 libopm_check_queue(scanner); /* Move scans from the queue to the live scan list */
705 libopm_check_establish(scanner); /* Make new connections if possible */
706 libopm_check_poll(scanner); /* Poll connections for IO and proxy test */
707 libopm_check_closed(scanner); /* Check for closed or timed out connections */
708 }
709
710 /* check_queue
711 *
712 * Move scans from the queue to the live scan list as long as there is
713 * room.
714 *
715 * Parameters:
716 * scanner: Scanner to check queue on
717 *
718 * Return:
719 * None
720 */
721 static void
722 libopm_check_queue(OPM_T *scanner)
723 {
724 OPM_NODE_T *node;
725 OPM_SCAN_T *scan;
726 unsigned int protocols, projected, fd_limit;
727
728 if (LIST_SIZE(&scanner->queue) == 0)
729 return;
730
731 fd_limit = *(int *)libopm_config(scanner->config, OPM_CONFIG_FD_LIMIT);
732 projected = scanner->fd_use;
733
734 /*
735 * We want to keep the live scan list as small as possible, so only move
736 * queued scans to the live list if they will not push above fd_limit
737 */
738 while (LIST_SIZE(&scanner->queue) > 0)
739 {
740 /* Grab the top scan */
741 scan = scanner->queue.head->data;
742 protocols = LIST_SIZE(&scan->connections);
743
744 /* Check if it will fit in the live scan list */
745 if ((protocols + projected) > fd_limit)
746 break;
747
748 /*
749 * Scans on the top of the queue were added first, swap the head off the
750 * top of the queue and add it to the tail of the live scan list
751 */
752 node = libopm_list_remove(&scanner->queue, scanner->queue.head);
753 libopm_list_add(&scanner->scans, node);
754 projected += protocols;
755 }
756 }
757
758 /* check_establish
759 *
760 * Make new connections if there are free file descriptors and connections
761 * to be made.
762 *
763 * Parameters:
764 * scanner: Scanner to check for establish on
765 * Return:
766 * None
767 */
768 static void
769 libopm_check_establish(OPM_T *scanner)
770 {
771 OPM_NODE_T *node1, *node2;
772 OPM_SCAN_T *scan;
773 OPM_CONNECTION_T *conn;
774 unsigned int fd_limit;
775
776 if (LIST_SIZE(&scanner->scans) == 0)
777 return;
778
779 fd_limit = *(int *)libopm_config(scanner->config, OPM_CONFIG_FD_LIMIT);
780
781 if (scanner->fd_use >= fd_limit)
782 return;
783
784 LIST_FOREACH(node1, scanner->scans.head)
785 {
786 scan = node1->data;
787
788 LIST_FOREACH(node2, scan->connections.head)
789 {
790 /* Only scan if we have free file descriptors */
791 if (scanner->fd_use >= fd_limit)
792 return;
793
794 conn = node2->data;
795
796 if (conn->state == OPM_STATE_UNESTABLISHED)
797 libopm_do_connect(scanner, scan, conn);
798 }
799 }
800 }
801
802 /* check_closed
803 *
804 * Check for connections which have timed out or are
805 * closed. Connections timed out still need to be closed.
806 *
807 * Remove the connection from the list of connections, free
808 * the connection struct and free the list node. Then if this is
809 * the last connection of the scan, consider the scan completed and
810 * free the scan aswell (and callback that the scan ended).
811 *
812 * Parameters:
813 * scanner: Scanner to check on
814 * Return:
815 * None
816 */
817 static void
818 libopm_check_closed(OPM_T *scanner)
819 {
820 time_t present;
821 int timeout;
822 OPM_NODE_T *node1, *node2, *next1, *next2;
823 OPM_SCAN_T *scan;
824 OPM_CONNECTION_T *conn;
825
826 if (LIST_SIZE(&scanner->scans) == 0)
827 return;
828
829 present = opm_gettime();
830 timeout = *(int *)libopm_config(scanner->config, OPM_CONFIG_TIMEOUT);
831
832 LIST_FOREACH_SAFE(node1, next1, scanner->scans.head)
833 {
834 scan = node1->data;
835
836 LIST_FOREACH_SAFE(node2, next2, scan->connections.head)
837 {
838 conn = node2->data;
839
840 if (conn->state == OPM_STATE_CLOSED)
841 {
842 #ifdef HAVE_LIBCRYPTO
843 if (conn->protocol->use_tls)
844 {
845 SSL_set_shutdown(conn->tls_handle, SSL_RECEIVED_SHUTDOWN);
846 if (!SSL_shutdown(conn->tls_handle))
847 SSL_shutdown(conn->tls_handle);
848 SSL_free(conn->tls_handle);
849 }
850 #endif
851 if (conn->fd > -1)
852 close(conn->fd);
853
854 scanner->fd_use--;
855
856 libopm_list_remove(&scan->connections, node2);
857 libopm_connection_free(conn);
858 libopm_node_free(node2);
859 continue;
860 }
861
862 if (((present - conn->creation) >= timeout) && conn->state != OPM_STATE_UNESTABLISHED)
863 {
864 #ifdef HAVE_LIBCRYPTO
865 if (conn->protocol->use_tls)
866 {
867 SSL_set_shutdown(conn->tls_handle, SSL_RECEIVED_SHUTDOWN);
868 if (!SSL_shutdown(conn->tls_handle))
869 SSL_shutdown(conn->tls_handle);
870 SSL_free(conn->tls_handle);
871 }
872 #endif
873 if (conn->fd > -1)
874 close(conn->fd);
875
876 scanner->fd_use--;
877
878 libopm_do_callback(scanner, libopm_setup_remote(scan->remote, conn), OPM_CALLBACK_TIMEOUT, 0);
879 libopm_list_remove(&scan->connections, node2);
880 libopm_connection_free(conn);
881 libopm_node_free(node2);
882 continue;
883 }
884 }
885
886 /*
887 * No more connections left in this scan, let the client know the scan has
888 * ended, then remove the scan from the scanner, and free it up.
889 */
890 if (LIST_SIZE(&scan->connections) == 0)
891 {
892 libopm_do_callback(scanner, scan->remote, OPM_CALLBACK_END, 0);
893 libopm_list_remove(&scanner->scans, node1);
894 libopm_scan_free(scan);
895 libopm_node_free(node1);
896 }
897 }
898 }
899
900 /* do_connect
901 *
902 * Call socket() and connect() to start a scan.
903 *
904 * Parametsr:
905 * scan: Scan struct containing the connection
906 * conn: Connection to establish
907 * Return:
908 * None
909 */
910 static void
911 libopm_do_connect(OPM_T * scanner, OPM_SCAN_T *scan, OPM_CONNECTION_T *conn)
912 {
913 assert(scan->addr.ss_family == AF_INET);
914
915 if (scan->addr.ss_family == AF_INET6)
916 ((struct sockaddr_in6 *)&scan->addr)->sin6_port = htons(conn->port);
917 else
918 ((struct sockaddr_in *)&scan->addr)->sin_port = htons(conn->port);
919
920 scanner->fd_use++; /* Increase file descriptor use */
921
922 conn->fd = socket(scan->addr.ss_family, SOCK_STREAM, 0);
923 if (conn->fd == -1)
924 {
925 libopm_do_callback(scanner, libopm_setup_remote(scan->remote, conn), OPM_CALLBACK_ERROR, OPM_ERR_NOFD);
926 conn->state = OPM_STATE_CLOSED;
927 return;
928 }
929
930 struct sockaddr_storage *bind_ip = libopm_config(scanner->config, OPM_CONFIG_BIND_IP);
931 if (bind_ip)
932 {
933 size_t addr_len;
934
935 if (bind_ip->ss_family == AF_INET6)
936 {
937 struct sockaddr_in6 *in = (struct sockaddr_in6 *)bind_ip;
938 in->sin6_port = htons(0);
939 addr_len = sizeof(*in);
940 }
941 else
942 {
943 struct sockaddr_in *in = (struct sockaddr_in *)bind_ip;
944 in->sin_port = htons(0);
945 addr_len = sizeof(*in);
946 }
947
948 if (bind(conn->fd, (const struct sockaddr *)bind_ip, addr_len) == -1)
949 {
950 libopm_do_callback(scanner, libopm_setup_remote(scan->remote, conn), OPM_CALLBACK_ERROR, OPM_ERR_BIND);
951 conn->state = OPM_STATE_CLOSED;
952 return;
953 }
954 }
955
956 /* Set socket non blocking */
957 fcntl(conn->fd, F_SETFL, O_NONBLOCK);
958
959 connect(conn->fd, (const struct sockaddr *)&scan->addr, scan->addr_len);
960
961 #ifdef HAVE_LIBCRYPTO
962 if (conn->protocol->use_tls)
963 SSL_set_fd(conn->tls_handle, conn->fd);
964 #endif
965
966 conn->state = OPM_STATE_ESTABLISHED;
967 conn->creation = opm_gettime(); /* Stamp creation time, for timeout */
968 }
969
970 /* check_poll
971 *
972 * Check sockets for ready read/write
973 *
974 * Parameters:
975 * scanner: Scanner to isolate check on
976 * Return:
977 * None
978 */
979 static void
980 libopm_check_poll(OPM_T *scanner)
981 {
982 OPM_NODE_T *node1, *node2;
983 OPM_SCAN_T *scan;
984 OPM_CONNECTION_T *conn;
985 unsigned int size = 0;
986 static unsigned int ufds_size;
987 static struct pollfd *ufds = NULL;
988
989 /* Grow pollfd array (ufds) as needed */
990 if (ufds_size < (*(unsigned int *)libopm_config(scanner->config, OPM_CONFIG_FD_LIMIT)))
991 {
992 libopm_free(ufds);
993
994 ufds = libopm_calloc((sizeof *ufds) * (*(unsigned int *)libopm_config(scanner->config, OPM_CONFIG_FD_LIMIT)));
995 ufds_size = (*(unsigned int *)libopm_config(scanner->config, OPM_CONFIG_FD_LIMIT));
996 }
997
998 if (LIST_SIZE(&scanner->scans) == 0)
999 return;
1000
1001 LIST_FOREACH(node1, scanner->scans.head)
1002 {
1003 scan = node1->data;
1004
1005 LIST_FOREACH(node2, scan->connections.head)
1006 {
1007 if (size >= ufds_size)
1008 break;
1009
1010 conn = node2->data;
1011
1012 if (conn->state < OPM_STATE_ESTABLISHED ||
1013 conn->state == OPM_STATE_CLOSED)
1014 continue;
1015
1016 ufds[size].events = 0;
1017 ufds[size].revents = 0;
1018 ufds[size].fd = conn->fd;
1019
1020 /* Check for HUNG UP. */
1021 ufds[size].events |= POLLHUP;
1022 /* Check for INVALID FD */
1023 ufds[size].events |= POLLNVAL;
1024
1025 switch (conn->state)
1026 {
1027 case OPM_STATE_ESTABLISHED:
1028 ufds[size].events |= POLLOUT;
1029 break;
1030 case OPM_STATE_NEGSENT:
1031 ufds[size].events |= POLLIN;
1032 break;
1033 }
1034
1035 size++;
1036 }
1037 }
1038
1039 switch (poll(ufds, size, 0))
1040 {
1041 case -1:
1042 /* error in select/poll */
1043 return;
1044 case 0:
1045 /* Nothing to do */
1046 return;
1047
1048 /* Pass pointer to connection to handler. */
1049 }
1050
1051 LIST_FOREACH(node1, scanner->scans.head)
1052 {
1053 scan = node1->data;
1054
1055 LIST_FOREACH(node2, scan->connections.head)
1056 {
1057 conn = node2->data;
1058
1059 for (unsigned int i = 0; i < size; ++i)
1060 {
1061 if ((ufds[i].fd == conn->fd) && (conn->state != OPM_STATE_CLOSED))
1062 {
1063 if (ufds[i].revents & POLLIN)
1064 libopm_do_readready(scanner, scan, conn);
1065 if (ufds[i].revents & POLLOUT)
1066 libopm_do_writeready(scanner, scan, conn);
1067 if (ufds[i].revents & POLLHUP)
1068 libopm_do_hup(scanner, scan, conn);
1069 }
1070 }
1071 }
1072 }
1073 }
1074
1075 static int
1076 libopm_do_readready_tls(OPM_T *scanner, OPM_SCAN_T *scan, OPM_CONNECTION_T *conn)
1077 {
1078 #ifdef HAVE_LIBCRYPTO
1079 int max_read, length;
1080 char readbuf[LIBOPM_TLS_RECORD_SIZE];
1081
1082 if (!SSL_is_init_finished(conn->tls_handle))
1083 return 0;
1084
1085 if ((length = SSL_read(conn->tls_handle, readbuf, sizeof(readbuf))) <= 0)
1086 {
1087 switch (SSL_get_error(conn->tls_handle, length))
1088 {
1089 /* TBD: possibly could recover here from some errors */
1090 default:
1091 libopm_do_hup(scanner, scan, conn);
1092 return 0;
1093 }
1094 }
1095
1096 max_read = *(int *)libopm_config(scanner->config, OPM_CONFIG_MAX_READ);
1097
1098 for (const char *p = readbuf, *end = readbuf + length; p < end; ++p)
1099 {
1100 conn->bytes_read++;
1101
1102 if (conn->bytes_read >= max_read)
1103 {
1104 libopm_do_callback(scanner, libopm_setup_remote(scan->remote, conn), OPM_CALLBACK_ERROR, OPM_ERR_MAX_READ);
1105 conn->state = OPM_STATE_CLOSED;
1106 return 0;
1107 }
1108
1109 if (*p == '\0' || *p == '\r')
1110 continue;
1111
1112 if (*p == '\n')
1113 {
1114 conn->readbuf[conn->readlen] = '\0';
1115 conn->readlen = 0;
1116
1117 libopm_do_read(scanner, scan, conn);
1118
1119 if (conn->state == OPM_STATE_CLOSED)
1120 return 0;
1121
1122 continue;
1123 }
1124
1125 if (conn->readlen < READBUFLEN)
1126 conn->readbuf[++(conn->readlen) - 1] = *p; /* -1 to pad for null term */
1127 }
1128 #endif
1129 return 0;
1130 }
1131
1132 /* do_readready
1133 *
1134 * Remote connection is read ready, read the data into a buffer and check it against
1135 * the target_string if neccessary
1136 *
1137 * Parameters:
1138 * scanner: Scanner doing the scan
1139 * scan: Specific scan
1140 * conn: Specific connection in the scan
1141 *
1142 * Return:
1143 * None
1144 */
1145 static void
1146 libopm_do_readready(OPM_T *scanner, OPM_SCAN_T *scan, OPM_CONNECTION_T *conn)
1147 {
1148 int max_read;
1149 char c;
1150
1151 /*
1152 * If protocol has a specific read function, call that instead of
1153 * reading data from here.
1154 */
1155 if (conn->protocol->read_function)
1156 {
1157 conn->protocol->read_function(scanner, scan, conn);
1158 return;
1159 }
1160
1161 max_read = *(int *)libopm_config(scanner->config, OPM_CONFIG_MAX_READ);
1162
1163 while (1)
1164 {
1165 switch (read(conn->fd, &c, 1))
1166 {
1167 case 0:
1168 libopm_do_hup(scanner, scan, conn);
1169 return;
1170
1171 case -1:
1172 if (errno != EAGAIN)
1173 libopm_do_hup(scanner, scan, conn);
1174 return;
1175
1176 default:
1177 conn->bytes_read++;
1178
1179 if (conn->bytes_read >= max_read)
1180 {
1181 libopm_do_callback(scanner, libopm_setup_remote(scan->remote, conn), OPM_CALLBACK_ERROR, OPM_ERR_MAX_READ);
1182 conn->state = OPM_STATE_CLOSED;
1183 return;
1184 }
1185
1186 if (c == '\0' || c == '\r')
1187 continue;
1188
1189 if (c == '\n')
1190 {
1191 conn->readbuf[conn->readlen] = '\0';
1192 conn->readlen = 0;
1193
1194 libopm_do_read(scanner, scan, conn);
1195
1196 if (conn->state == OPM_STATE_CLOSED)
1197 return;
1198
1199 continue;
1200 }
1201
1202 if (conn->readlen < READBUFLEN)
1203 conn->readbuf[++(conn->readlen) - 1] = c; /* -1 to pad for null term */
1204 }
1205 }
1206 }
1207
1208 /* do_read
1209 *
1210 * A line of data has been read from the socket, check it against
1211 * target string.
1212 *
1213 *
1214 *
1215 * Parameters:
1216 * scanner: Scanner doing the scan
1217 * scan: Specific scan
1218 * conn: Specific connection in the scan
1219 *
1220 * Return:
1221 * None
1222 */
1223 static void
1224 libopm_do_read(OPM_T *scanner, OPM_SCAN_T *scan, OPM_CONNECTION_T *conn)
1225 {
1226 OPM_LIST_T *list;
1227 OPM_NODE_T *node;
1228
1229 /* Check readbuf against target strings */
1230 list = (OPM_LIST_T *)libopm_config(scanner->config, OPM_CONFIG_TARGET_STRING);
1231
1232 LIST_FOREACH(node, list->head)
1233 {
1234 const char *target_string = node->data;
1235
1236 if (strstr(conn->readbuf, target_string))
1237 {
1238 libopm_do_openproxy(scanner, scan, conn);
1239 break;
1240 }
1241 }
1242 }
1243
1244 /* do_openproxy
1245 *
1246 * An open proxy was found on connection conn. Cleanup the connection and
1247 * call the appropriate callback to let the client know the proxy was found.
1248 *
1249 * Parameters:
1250 * scanner: Scanner doing the scan
1251 * scan: Specific scan
1252 * conn: Specific connection in the scan
1253 *
1254 * Return:
1255 * None
1256 */
1257 static void
1258 libopm_do_openproxy(OPM_T *scanner, OPM_SCAN_T *scan, OPM_CONNECTION_T *conn)
1259 {
1260 /* Mark the connection for close */
1261 conn->state = OPM_STATE_CLOSED;
1262
1263 /* Call client's open proxy callback */
1264 libopm_do_callback(scanner, libopm_setup_remote(scan->remote, conn), OPM_CALLBACK_OPENPROXY, 0);
1265 }
1266
1267 /* do_writeready
1268 *
1269 * Remote connection is write ready, call the specific protocol
1270 * function for writing to this socket.
1271 *
1272 * Parameters:
1273 * scanner: Scanner doing the scan
1274 * scan: Specific scan
1275 * conn: Specific connection in the scan
1276 *
1277 * Return:
1278 * None
1279 */
1280 static void
1281 libopm_do_writeready(OPM_T *scanner, OPM_SCAN_T *scan, OPM_CONNECTION_T *conn)
1282 {
1283 OPM_PROTOCOL_T *protocol;
1284
1285 #ifdef HAVE_LIBCRYPTO
1286 if (conn->protocol->use_tls)
1287 {
1288 if (!SSL_is_init_finished(conn->tls_handle))
1289 {
1290 SSL_connect(conn->tls_handle);
1291 return;
1292 }
1293 }
1294 #endif
1295
1296 protocol = conn->protocol;
1297
1298 /* Call write function for specific protocol */
1299 if (protocol->write_function)
1300 protocol->write_function(scanner, scan, conn);
1301
1302 /* Flag as NEGSENT so we don't have to send data again*/
1303 conn->state = OPM_STATE_NEGSENT;
1304 }
1305
1306 /* do_hup
1307 *
1308 * Connection ended prematurely
1309 *
1310 * Parameters:
1311 * scanner: Scanner doing the scan
1312 * scan: Specific scan
1313 * conn: Specific connection in the scan
1314 * error: OPM_ERR_T containing the error type
1315 * Return:
1316 * None
1317 */
1318 static void
1319 libopm_do_hup(OPM_T *scanner, OPM_SCAN_T *scan, OPM_CONNECTION_T *conn)
1320 {
1321 /* Mark the connection for close */
1322 conn->state = OPM_STATE_CLOSED;
1323
1324 libopm_do_callback(scanner, libopm_setup_remote(scan->remote, conn), OPM_CALLBACK_NEGFAIL, 0);
1325 }
1326
1327 /* do_callback
1328 *
1329 * Call callback
1330 *
1331 * Parameters:
1332 * scanner: scanner remote is on
1333 * remote: remote callback is for
1334 * type: callback type
1335 * var: optional var passed back (error codes, etc )
1336 * Return:
1337 * None
1338 */
1339 static void
1340 libopm_do_callback(OPM_T *scanner, OPM_REMOTE_T *remote, int type, int var)
1341 {
1342 /* Callback is out of range */
1343 if (type < 0 || type >= CBLEN)
1344 return;
1345
1346 if (scanner->callbacks[type].func)
1347 (scanner->callbacks[type].func)(scanner, remote, var, scanner->callbacks[type].data);
1348 }
1349
1350 /* setup_remote
1351 *
1352 * Setup an OPM_REMOTE_T with information from an OPM_CONNECTION_T
1353 * for callback
1354 *
1355 * Parameters:
1356 * remote, conn
1357 *
1358 * Return:
1359 * remote
1360 */
1361 static OPM_REMOTE_T *
1362 libopm_setup_remote(OPM_REMOTE_T *remote, OPM_CONNECTION_T *conn)
1363 {
1364 remote->port = conn->port;
1365 remote->bytes_read = conn->bytes_read;
1366 remote->protocol = conn->protocol->type;
1367
1368 return remote;
1369 }

Properties

Name Value
svn:eol-style native
svn:keywords Id

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