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