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: 9530
Committed: Mon Jul 13 10:08:29 2020 UTC (3 years, 9 months ago) by michael
Content type: text/x-csrc
File size: 32945 byte(s)
Log Message:
- libopm: work towards ipv6 support; use sockaddr_storage; replace inet_pton() with getaddrinfo()

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

Properties

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