ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/hopm/branches/1.1.x/src/libopm/src/libopm.c
Revision: 6224
Committed: Thu Jul 2 08:01:14 2015 UTC (8 years, 8 months ago) by michael
Content type: text/x-csrc
Original Path: hopm/trunk/src/libopm/src/libopm.c
File size: 33114 byte(s)
Log Message:
- libopm.c:libopm_check_closed(): improve sanity test on conn->fd

File Contents

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

Properties

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