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: 9861
Committed: Sat Jan 2 18:38:36 2021 UTC (3 years, 2 months ago) by michael
Content type: text/x-csrc
File size: 32632 byte(s)
Log Message:
- Use monotonic time whenever possible

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 <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.ss_family = res->ai_family;
430 scan->addr_len = res->ai_addrlen;
431
432 freeaddrinfo(res);
433
434 node = libopm_node_create(scan);
435 libopm_list_add(&scanner->queue, node);
436
437 return OPM_SUCCESS;
438 }
439
440 /* opm_end
441 *
442 * End a scan prematurely.
443 *
444 * Parameters:
445 * scanner: Scanner to end scan on
446 * remote: Pointer to remote struct to search for and end
447 *
448 * Return:
449 * No return. OPM_CALLBACK_END will still be called as normal.
450 */
451 void
452 opm_end(OPM_T *scanner, OPM_REMOTE_T *remote)
453 {
454 OPM_NODE_T *node1, *node2, *next1, *next2;
455 OPM_SCAN_T *scan;
456 OPM_CONNECTION_T *conn;
457
458 /* End active scans */
459 opm_endscan(scanner, remote);
460
461 /*
462 * Secondly remove all traces of it in the queue. Once removed we have to call
463 * OPM_CALLBACK_END
464 */
465 LIST_FOREACH_SAFE(node1, next1, scanner->queue.head)
466 {
467 scan = node1->data;
468
469 if (scan->remote == remote)
470 {
471 /* Free all connections */
472 LIST_FOREACH_SAFE(node2, next2, scan->connections.head)
473 {
474 conn = node2->data;
475
476 libopm_list_remove(&scan->connections, node2);
477 libopm_connection_free(conn);
478 libopm_node_free(node2);
479 continue;
480 }
481
482 /* OPM_CALLBACK_END because check_closed normally handles this */
483 libopm_do_callback(scanner, scan->remote, OPM_CALLBACK_END, 0);
484
485 /* Free up the scan */
486 libopm_list_remove(&scanner->queue, node1);
487 libopm_scan_free(scan);
488 libopm_node_free(node1);
489 }
490 }
491 }
492
493 /* opm_endscan
494 *
495 * End a scan prematurely. Only end non-queued scans. This is useful
496 * because it only checks the active scan list (saving time), where
497 * opm_end checks both the scan and the possibly large queue.
498 *
499 * Parameters:
500 * scanner: Scanner to end scan on
501 * remote: Pointer to remote struct to search for and end
502 *
503 * Return:
504 * No return. OPM_CALLBACK_END will still be called as normal.
505 */
506 void
507 opm_endscan(OPM_T *scanner, OPM_REMOTE_T *remote)
508 {
509 OPM_NODE_T *node1, *node2;
510 OPM_SCAN_T *scan;
511 OPM_CONNECTION_T *conn;
512
513 /*
514 * First check to see if it's in the queue, if it is set all connections closed
515 * Next cycle of libopm_check_closed will take care of the garbage and handle
516 * OPM_CALLBACK_END
517 */
518 LIST_FOREACH(node1, scanner->scans.head)
519 {
520 scan = node1->data;
521
522 if (scan->remote == remote)
523 {
524 LIST_FOREACH(node2, scan->connections.head)
525 {
526 conn = node2->data;
527 conn->state = OPM_STATE_CLOSED;
528 }
529 }
530 }
531 }
532
533 /* opm_active
534
535 Return number of scans in a scanner left.
536
537 Parameters:
538 scanner: Scanner to return active scans on
539
540 Return:
541 Number of active scans, both queued and active.
542 */
543 size_t
544 opm_active(OPM_T *scanner)
545 {
546 return LIST_SIZE(&scanner->queue) + LIST_SIZE(&scanner->scans);
547 }
548
549 /* scan_create
550 *
551 * Create new OPM_SCAN_T struct
552 *
553 * Parameters:
554 * scanner: Scanner the scan is being created for. This
555 * is needed to get information on currently set
556 * protocols/config.
557 *
558 * remote: Remote host this scan will be scanning
559 *
560 * Return
561 * Address of new struct
562 */
563 static OPM_SCAN_T *
564 libopm_scan_create(OPM_T *scanner, OPM_REMOTE_T *remote)
565 {
566 OPM_SCAN_T *ret;
567 OPM_CONNECTION_T *conn;
568 OPM_NODE_T *node, *p;
569 #ifdef HAVE_LIBCRYPTO
570 static int tls_init = 0;
571 static SSL_CTX *ctx_client;
572
573 if (!tls_init)
574 {
575 tls_init = 1;
576 SSLeay_add_ssl_algorithms();
577
578 ctx_client = SSL_CTX_new(SSLv23_client_method());
579 if (!ctx_client)
580 exit(EXIT_FAILURE);
581 }
582 #endif
583
584 ret = libopm_calloc(sizeof(*ret));
585 ret->remote = remote;
586
587 /* Setup list of connections, one for each protocol */
588 LIST_FOREACH(p, scanner->protocols.head)
589 {
590 conn = libopm_connection_create();
591
592 conn->protocol = ((OPM_PROTOCOL_CONFIG_T *)p->data)->type;
593 conn->port = ((OPM_PROTOCOL_CONFIG_T *)p->data)->port;
594
595 #ifdef HAVE_LIBCRYPTO
596 if (conn->protocol->use_tls)
597 /* SSL_new does only fail if OOM in which case HOPM exits anyway */
598 conn->tls_handle = SSL_new(ctx_client);
599 #endif
600
601 node = libopm_node_create(conn);
602 libopm_list_add(&ret->connections, node);
603 }
604
605 /*
606 * Do the same for any specific protocols the remote struct might be configured with
607 */
608 LIST_FOREACH(p, remote->protocols.head)
609 {
610 conn = libopm_connection_create();
611
612 conn->protocol = ((OPM_PROTOCOL_CONFIG_T *)p->data)->type;
613 conn->port = ((OPM_PROTOCOL_CONFIG_T *)p->data)->port;
614
615 #ifdef HAVE_LIBCRYPTO
616 if (conn->protocol->use_tls)
617 /* SSL_new does only fail if OOM in which case HOPM exits anyway */
618 conn->tls_handle = SSL_new(ctx_client);
619 #endif
620
621 node = libopm_node_create(conn);
622 libopm_list_add(&ret->connections, node);
623 }
624
625 return ret;
626 }
627
628 /* scan_free
629 *
630 * Free and cleanup OPM_SCAN_T struct
631 *
632 * Parametsr:
633 * scan: Scan struct to free
634 *
635 * Return:
636 * None
637 */
638 static void
639 libopm_scan_free(OPM_SCAN_T *scan)
640 {
641 OPM_NODE_T *p, *next;
642 OPM_CONNECTION_T *conn;
643
644 LIST_FOREACH_SAFE(p, next, scan->connections.head)
645 {
646 conn = p->data;
647
648 libopm_connection_free(conn);
649 libopm_list_remove(&scan->connections, p);
650 libopm_node_free(p);
651 }
652
653 libopm_free(scan);
654 }
655
656 /* connection_create
657 *
658 * Allocate new OPM_CONNECTION_T
659 *
660 * Parameters:
661 * None
662 *
663 * Return:
664 * Address of new OPM_CONNECTION_T
665 */
666 static OPM_CONNECTION_T *
667 libopm_connection_create(void)
668 {
669 OPM_CONNECTION_T *ret;
670
671 ret = libopm_calloc(sizeof(*ret));
672 ret->state = OPM_STATE_UNESTABLISHED;
673
674 return ret;
675 }
676
677 /* connection_free
678 *
679 * Free OPM_CONNECTION_T struct
680 *
681 * Parameters:
682 * conn: Address of struct to free
683 *
684 * Return:
685 * None
686 */
687 static void
688 libopm_connection_free(OPM_CONNECTION_T *conn)
689 {
690 libopm_free(conn);
691 }
692
693 /* opm_cycle
694 *
695 * Perform tasks (called by client's loop)
696 *
697 * Parameters:
698 * None
699 * Return:
700 * None
701 */
702 void
703 opm_cycle(OPM_T *scanner)
704 {
705 libopm_check_queue(scanner); /* Move scans from the queue to the live scan list */
706 libopm_check_establish(scanner); /* Make new connections if possible */
707 libopm_check_poll(scanner); /* Poll connections for IO and proxy test */
708 libopm_check_closed(scanner); /* Check for closed or timed out connections */
709 }
710
711 /* check_queue
712 *
713 * Move scans from the queue to the live scan list as long as there is
714 * room.
715 *
716 * Parameters:
717 * scanner: Scanner to check queue on
718 *
719 * Return:
720 * None
721 */
722 static void
723 libopm_check_queue(OPM_T *scanner)
724 {
725 OPM_NODE_T *node;
726 OPM_SCAN_T *scan;
727 unsigned int protocols, projected, fd_limit;
728
729 if (LIST_SIZE(&scanner->queue) == 0)
730 return;
731
732 fd_limit = *(int *)libopm_config(scanner->config, OPM_CONFIG_FD_LIMIT);
733 projected = scanner->fd_use;
734
735 /*
736 * We want to keep the live scan list as small as possible, so only move
737 * queued scans to the live list if they will not push above fd_limit
738 */
739 while (LIST_SIZE(&scanner->queue) > 0)
740 {
741 /* Grab the top scan */
742 scan = scanner->queue.head->data;
743 protocols = LIST_SIZE(&scan->connections);
744
745 /* Check if it will fit in the live scan list */
746 if ((protocols + projected) > fd_limit)
747 break;
748
749 /*
750 * Scans on the top of the queue were added first, swap the head off the
751 * top of the queue and add it to the tail of the live scan list
752 */
753 node = libopm_list_remove(&scanner->queue, scanner->queue.head);
754 libopm_list_add(&scanner->scans, node);
755 projected += protocols;
756 }
757 }
758
759 /* check_establish
760 *
761 * Make new connections if there are free file descriptors and connections
762 * to be made.
763 *
764 * Parameters:
765 * scanner: Scanner to check for establish on
766 * Return:
767 * None
768 */
769 static void
770 libopm_check_establish(OPM_T *scanner)
771 {
772 OPM_NODE_T *node1, *node2;
773 OPM_SCAN_T *scan;
774 OPM_CONNECTION_T *conn;
775 unsigned int fd_limit;
776
777 if (LIST_SIZE(&scanner->scans) == 0)
778 return;
779
780 fd_limit = *(int *)libopm_config(scanner->config, OPM_CONFIG_FD_LIMIT);
781
782 if (scanner->fd_use >= fd_limit)
783 return;
784
785 LIST_FOREACH(node1, scanner->scans.head)
786 {
787 scan = node1->data;
788
789 LIST_FOREACH(node2, scan->connections.head)
790 {
791 /* Only scan if we have free file descriptors */
792 if (scanner->fd_use >= fd_limit)
793 return;
794
795 conn = node2->data;
796
797 if (conn->state == OPM_STATE_UNESTABLISHED)
798 libopm_do_connect(scanner, scan, conn);
799 }
800 }
801 }
802
803 /* check_closed
804 *
805 * Check for connections which have timed out or are
806 * closed. Connections timed out still need to be closed.
807 *
808 * Remove the connection from the list of connections, free
809 * the connection struct and free the list node. Then if this is
810 * the last connection of the scan, consider the scan completed and
811 * free the scan aswell (and callback that the scan ended).
812 *
813 * Parameters:
814 * scanner: Scanner to check on
815 * Return:
816 * None
817 */
818 static void
819 libopm_check_closed(OPM_T *scanner)
820 {
821 time_t present;
822 int timeout;
823 OPM_NODE_T *node1, *node2, *next1, *next2;
824 OPM_SCAN_T *scan;
825 OPM_CONNECTION_T *conn;
826
827 if (LIST_SIZE(&scanner->scans) == 0)
828 return;
829
830 present = opm_gettime();
831 timeout = *(int *)libopm_config(scanner->config, OPM_CONFIG_TIMEOUT);
832
833 LIST_FOREACH_SAFE(node1, next1, scanner->scans.head)
834 {
835 scan = node1->data;
836
837 LIST_FOREACH_SAFE(node2, next2, scan->connections.head)
838 {
839 conn = node2->data;
840
841 if (conn->state == OPM_STATE_CLOSED)
842 {
843 #ifdef HAVE_LIBCRYPTO
844 if (conn->protocol->use_tls)
845 {
846 SSL_set_shutdown(conn->tls_handle, SSL_RECEIVED_SHUTDOWN);
847 if (!SSL_shutdown(conn->tls_handle))
848 SSL_shutdown(conn->tls_handle);
849 SSL_free(conn->tls_handle);
850 }
851 #endif
852 if (conn->fd > -1)
853 close(conn->fd);
854
855 scanner->fd_use--;
856
857 libopm_list_remove(&scan->connections, node2);
858 libopm_connection_free(conn);
859 libopm_node_free(node2);
860 continue;
861 }
862
863 if (((present - conn->creation) >= timeout) && conn->state != OPM_STATE_UNESTABLISHED)
864 {
865 #ifdef HAVE_LIBCRYPTO
866 if (conn->protocol->use_tls)
867 {
868 SSL_set_shutdown(conn->tls_handle, SSL_RECEIVED_SHUTDOWN);
869 if (!SSL_shutdown(conn->tls_handle))
870 SSL_shutdown(conn->tls_handle);
871 SSL_free(conn->tls_handle);
872 }
873 #endif
874 if (conn->fd > -1)
875 close(conn->fd);
876
877 scanner->fd_use--;
878
879 libopm_do_callback(scanner, libopm_setup_remote(scan->remote, conn), OPM_CALLBACK_TIMEOUT, 0);
880 libopm_list_remove(&scan->connections, node2);
881 libopm_connection_free(conn);
882 libopm_node_free(node2);
883 continue;
884 }
885 }
886
887 /*
888 * No more connections left in this scan, let the client know the scan has
889 * ended, then remove the scan from the scanner, and free it up.
890 */
891 if (LIST_SIZE(&scan->connections) == 0)
892 {
893 libopm_do_callback(scanner, scan->remote, OPM_CALLBACK_END, 0);
894 libopm_list_remove(&scanner->scans, node1);
895 libopm_scan_free(scan);
896 libopm_node_free(node1);
897 }
898 }
899 }
900
901 /* do_connect
902 *
903 * Call socket() and connect() to start a scan.
904 *
905 * Parametsr:
906 * scan: Scan struct containing the connection
907 * conn: Connection to establish
908 * Return:
909 * None
910 */
911 static void
912 libopm_do_connect(OPM_T * scanner, OPM_SCAN_T *scan, OPM_CONNECTION_T *conn)
913 {
914 assert(scan->addr.ss_family == AF_INET);
915
916 if (scan->addr.ss_family == AF_INET6)
917 ((struct sockaddr_in6 *)&scan->addr)->sin6_port = htons(conn->port);
918 else
919 ((struct sockaddr_in *)&scan->addr)->sin_port = htons(conn->port);
920
921 scanner->fd_use++; /* Increase file descriptor use */
922
923 conn->fd = socket(scan->addr.ss_family, SOCK_STREAM, 0);
924 if (conn->fd == -1)
925 {
926 libopm_do_callback(scanner, libopm_setup_remote(scan->remote, conn), OPM_CALLBACK_ERROR, OPM_ERR_NOFD);
927 conn->state = OPM_STATE_CLOSED;
928 return;
929 }
930
931 struct sockaddr_storage *bind_ip = libopm_config(scanner->config, OPM_CONFIG_BIND_IP);
932 if (bind_ip)
933 {
934 size_t addr_len;
935
936 if (bind_ip->ss_family == AF_INET6)
937 {
938 struct sockaddr_in6 *in = (struct sockaddr_in6 *)bind_ip;
939 in->sin6_port = htons(0);
940 addr_len = sizeof(*in);
941 }
942 else
943 {
944 struct sockaddr_in *in = (struct sockaddr_in *)bind_ip;
945 in->sin_port = htons(0);
946 addr_len = sizeof(*in);
947 }
948
949 if (bind(conn->fd, (const struct sockaddr *)bind_ip, addr_len) == -1)
950 {
951 libopm_do_callback(scanner, libopm_setup_remote(scan->remote, conn), OPM_CALLBACK_ERROR, OPM_ERR_BIND);
952 conn->state = OPM_STATE_CLOSED;
953 return;
954 }
955 }
956
957 /* Set socket non blocking */
958 fcntl(conn->fd, F_SETFL, O_NONBLOCK);
959
960 connect(conn->fd, (const struct sockaddr *)&scan->addr, scan->addr_len);
961
962 #ifdef HAVE_LIBCRYPTO
963 if (conn->protocol->use_tls)
964 SSL_set_fd(conn->tls_handle, conn->fd);
965 #endif
966
967 conn->state = OPM_STATE_ESTABLISHED;
968 conn->creation = opm_gettime(); /* Stamp creation time, for timeout */
969 }
970
971 /* check_poll
972 *
973 * Check sockets for ready read/write
974 *
975 * Parameters:
976 * scanner: Scanner to isolate check on
977 * Return:
978 * None
979 */
980 static void
981 libopm_check_poll(OPM_T *scanner)
982 {
983 OPM_NODE_T *node1, *node2;
984 OPM_SCAN_T *scan;
985 OPM_CONNECTION_T *conn;
986 unsigned int size = 0;
987 static unsigned int ufds_size;
988 static struct pollfd *ufds = NULL;
989
990 /* Grow pollfd array (ufds) as needed */
991 if (ufds_size < (*(unsigned int *)libopm_config(scanner->config, OPM_CONFIG_FD_LIMIT)))
992 {
993 libopm_free(ufds);
994
995 ufds = libopm_calloc((sizeof *ufds) * (*(unsigned int *)libopm_config(scanner->config, OPM_CONFIG_FD_LIMIT)));
996 ufds_size = (*(unsigned int *)libopm_config(scanner->config, OPM_CONFIG_FD_LIMIT));
997 }
998
999 if (LIST_SIZE(&scanner->scans) == 0)
1000 return;
1001
1002 LIST_FOREACH(node1, scanner->scans.head)
1003 {
1004 scan = node1->data;
1005
1006 LIST_FOREACH(node2, scan->connections.head)
1007 {
1008 if (size >= ufds_size)
1009 break;
1010
1011 conn = node2->data;
1012
1013 if (conn->state < OPM_STATE_ESTABLISHED ||
1014 conn->state == OPM_STATE_CLOSED)
1015 continue;
1016
1017 ufds[size].events = 0;
1018 ufds[size].revents = 0;
1019 ufds[size].fd = conn->fd;
1020
1021 /* Check for HUNG UP. */
1022 ufds[size].events |= POLLHUP;
1023 /* Check for INVALID FD */
1024 ufds[size].events |= POLLNVAL;
1025
1026 switch (conn->state)
1027 {
1028 case OPM_STATE_ESTABLISHED:
1029 ufds[size].events |= POLLOUT;
1030 break;
1031 case OPM_STATE_NEGSENT:
1032 ufds[size].events |= POLLIN;
1033 break;
1034 }
1035
1036 size++;
1037 }
1038 }
1039
1040 switch (poll(ufds, size, 0))
1041 {
1042 case -1:
1043 /* error in select/poll */
1044 return;
1045 case 0:
1046 /* Nothing to do */
1047 return;
1048
1049 /* Pass pointer to connection to handler. */
1050 }
1051
1052 LIST_FOREACH(node1, scanner->scans.head)
1053 {
1054 scan = node1->data;
1055
1056 LIST_FOREACH(node2, scan->connections.head)
1057 {
1058 conn = node2->data;
1059
1060 for (unsigned int i = 0; i < size; ++i)
1061 {
1062 if ((ufds[i].fd == conn->fd) && (conn->state != OPM_STATE_CLOSED))
1063 {
1064 if (ufds[i].revents & POLLIN)
1065 libopm_do_readready(scanner, scan, conn);
1066 if (ufds[i].revents & POLLOUT)
1067 libopm_do_writeready(scanner, scan, conn);
1068 if (ufds[i].revents & POLLHUP)
1069 libopm_do_hup(scanner, scan, conn);
1070 }
1071 }
1072 }
1073 }
1074 }
1075
1076 static int
1077 libopm_do_readready_tls(OPM_T *scanner, OPM_SCAN_T *scan, OPM_CONNECTION_T *conn)
1078 {
1079 #ifdef HAVE_LIBCRYPTO
1080 int max_read, length;
1081 char readbuf[LIBOPM_TLS_RECORD_SIZE];
1082
1083 if (!SSL_is_init_finished(conn->tls_handle))
1084 return 0;
1085
1086 if ((length = SSL_read(conn->tls_handle, readbuf, sizeof(readbuf))) <= 0)
1087 {
1088 switch (SSL_get_error(conn->tls_handle, length))
1089 {
1090 /* TBD: possibly could recover here from some errors */
1091 default:
1092 libopm_do_hup(scanner, scan, conn);
1093 return 0;
1094 }
1095 }
1096
1097 max_read = *(int *)libopm_config(scanner->config, OPM_CONFIG_MAX_READ);
1098
1099 for (const char *p = readbuf, *end = readbuf + length; p < end; ++p)
1100 {
1101 conn->bytes_read++;
1102
1103 if (conn->bytes_read >= max_read)
1104 {
1105 libopm_do_callback(scanner, libopm_setup_remote(scan->remote, conn), OPM_CALLBACK_ERROR, OPM_ERR_MAX_READ);
1106 conn->state = OPM_STATE_CLOSED;
1107 return 0;
1108 }
1109
1110 if (*p == '\0' || *p == '\r')
1111 continue;
1112
1113 if (*p == '\n')
1114 {
1115 conn->readbuf[conn->readlen] = '\0';
1116 conn->readlen = 0;
1117
1118 libopm_do_read(scanner, scan, conn);
1119
1120 if (conn->state == OPM_STATE_CLOSED)
1121 return 0;
1122
1123 continue;
1124 }
1125
1126 if (conn->readlen < READBUFLEN)
1127 conn->readbuf[++(conn->readlen) - 1] = *p; /* -1 to pad for null term */
1128 }
1129 #endif
1130 return 0;
1131 }
1132
1133 /* do_readready
1134 *
1135 * Remote connection is read ready, read the data into a buffer and check it against
1136 * the target_string if neccessary
1137 *
1138 * Parameters:
1139 * scanner: Scanner doing the scan
1140 * scan: Specific scan
1141 * conn: Specific connection in the scan
1142 *
1143 * Return:
1144 * None
1145 */
1146 static void
1147 libopm_do_readready(OPM_T *scanner, OPM_SCAN_T *scan, OPM_CONNECTION_T *conn)
1148 {
1149 int max_read;
1150 char c;
1151
1152 /*
1153 * If protocol has a specific read function, call that instead of
1154 * reading data from here.
1155 */
1156 if (conn->protocol->read_function)
1157 {
1158 conn->protocol->read_function(scanner, scan, conn);
1159 return;
1160 }
1161
1162 max_read = *(int *)libopm_config(scanner->config, OPM_CONFIG_MAX_READ);
1163
1164 while (1)
1165 {
1166 switch (read(conn->fd, &c, 1))
1167 {
1168 case 0:
1169 libopm_do_hup(scanner, scan, conn);
1170 return;
1171
1172 case -1:
1173 if (errno != EAGAIN)
1174 libopm_do_hup(scanner, scan, conn);
1175 return;
1176
1177 default:
1178 conn->bytes_read++;
1179
1180 if (conn->bytes_read >= max_read)
1181 {
1182 libopm_do_callback(scanner, libopm_setup_remote(scan->remote, conn), OPM_CALLBACK_ERROR, OPM_ERR_MAX_READ);
1183 conn->state = OPM_STATE_CLOSED;
1184 return;
1185 }
1186
1187 if (c == '\0' || c == '\r')
1188 continue;
1189
1190 if (c == '\n')
1191 {
1192 conn->readbuf[conn->readlen] = '\0';
1193 conn->readlen = 0;
1194
1195 libopm_do_read(scanner, scan, conn);
1196
1197 if (conn->state == OPM_STATE_CLOSED)
1198 return;
1199
1200 continue;
1201 }
1202
1203 if (conn->readlen < READBUFLEN)
1204 conn->readbuf[++(conn->readlen) - 1] = c; /* -1 to pad for null term */
1205 }
1206 }
1207 }
1208
1209 /* do_read
1210 *
1211 * A line of data has been read from the socket, check it against
1212 * target string.
1213 *
1214 *
1215 *
1216 * Parameters:
1217 * scanner: Scanner doing the scan
1218 * scan: Specific scan
1219 * conn: Specific connection in the scan
1220 *
1221 * Return:
1222 * None
1223 */
1224 static void
1225 libopm_do_read(OPM_T *scanner, OPM_SCAN_T *scan, OPM_CONNECTION_T *conn)
1226 {
1227 OPM_LIST_T *list;
1228 OPM_NODE_T *node;
1229
1230 /* Check readbuf against target strings */
1231 list = (OPM_LIST_T *)libopm_config(scanner->config, OPM_CONFIG_TARGET_STRING);
1232
1233 LIST_FOREACH(node, list->head)
1234 {
1235 const char *target_string = node->data;
1236
1237 if (strstr(conn->readbuf, target_string))
1238 {
1239 libopm_do_openproxy(scanner, scan, conn);
1240 break;
1241 }
1242 }
1243 }
1244
1245 /* do_openproxy
1246 *
1247 * An open proxy was found on connection conn. Cleanup the connection and
1248 * call the appropriate callback to let the client know the proxy was found.
1249 *
1250 * Parameters:
1251 * scanner: Scanner doing the scan
1252 * scan: Specific scan
1253 * conn: Specific connection in the scan
1254 *
1255 * Return:
1256 * None
1257 */
1258 static void
1259 libopm_do_openproxy(OPM_T *scanner, OPM_SCAN_T *scan, OPM_CONNECTION_T *conn)
1260 {
1261 /* Mark the connection for close */
1262 conn->state = OPM_STATE_CLOSED;
1263
1264 /* Call client's open proxy callback */
1265 libopm_do_callback(scanner, libopm_setup_remote(scan->remote, conn), OPM_CALLBACK_OPENPROXY, 0);
1266 }
1267
1268 /* do_writeready
1269 *
1270 * Remote connection is write ready, call the specific protocol
1271 * function for writing to this socket.
1272 *
1273 * Parameters:
1274 * scanner: Scanner doing the scan
1275 * scan: Specific scan
1276 * conn: Specific connection in the scan
1277 *
1278 * Return:
1279 * None
1280 */
1281 static void
1282 libopm_do_writeready(OPM_T *scanner, OPM_SCAN_T *scan, OPM_CONNECTION_T *conn)
1283 {
1284 OPM_PROTOCOL_T *protocol;
1285
1286 #ifdef HAVE_LIBCRYPTO
1287 if (conn->protocol->use_tls)
1288 {
1289 if (!SSL_is_init_finished(conn->tls_handle))
1290 {
1291 SSL_connect(conn->tls_handle);
1292 return;
1293 }
1294 }
1295 #endif
1296
1297 protocol = conn->protocol;
1298
1299 /* Call write function for specific protocol */
1300 if (protocol->write_function)
1301 protocol->write_function(scanner, scan, conn);
1302
1303 /* Flag as NEGSENT so we don't have to send data again*/
1304 conn->state = OPM_STATE_NEGSENT;
1305 }
1306
1307 /* do_hup
1308 *
1309 * Connection ended prematurely
1310 *
1311 * Parameters:
1312 * scanner: Scanner doing the scan
1313 * scan: Specific scan
1314 * conn: Specific connection in the scan
1315 * error: OPM_ERR_T containing the error type
1316 * Return:
1317 * None
1318 */
1319 static void
1320 libopm_do_hup(OPM_T *scanner, OPM_SCAN_T *scan, OPM_CONNECTION_T *conn)
1321 {
1322 /* Mark the connection for close */
1323 conn->state = OPM_STATE_CLOSED;
1324
1325 libopm_do_callback(scanner, libopm_setup_remote(scan->remote, conn), OPM_CALLBACK_NEGFAIL, 0);
1326 }
1327
1328 /* do_callback
1329 *
1330 * Call callback
1331 *
1332 * Parameters:
1333 * scanner: scanner remote is on
1334 * remote: remote callback is for
1335 * type: callback type
1336 * var: optional var passed back (error codes, etc )
1337 * Return:
1338 * None
1339 */
1340 static void
1341 libopm_do_callback(OPM_T *scanner, OPM_REMOTE_T *remote, int type, int var)
1342 {
1343 /* Callback is out of range */
1344 if (type < 0 || type >= CBLEN)
1345 return;
1346
1347 if (scanner->callbacks[type].func)
1348 (scanner->callbacks[type].func)(scanner, remote, var, scanner->callbacks[type].data);
1349 }
1350
1351 /* setup_remote
1352 *
1353 * Setup an OPM_REMOTE_T with information from an OPM_CONNECTION_T
1354 * for callback
1355 *
1356 * Parameters:
1357 * remote, conn
1358 *
1359 * Return:
1360 * remote
1361 */
1362 static OPM_REMOTE_T *
1363 libopm_setup_remote(OPM_REMOTE_T *remote, OPM_CONNECTION_T *conn)
1364 {
1365 remote->port = conn->port;
1366 remote->bytes_read = conn->bytes_read;
1367 remote->protocol = conn->protocol->type;
1368
1369 return remote;
1370 }

Properties

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