]> jfr.im git - irc/ircd-hybrid/bopm.git/blame - src/scan.c
Merged in TimeMr14C's IPv6 stuff to main branch.
[irc/ircd-hybrid/bopm.git] / src / scan.c
CommitLineData
7cdaaf39 1/*
2Copyright (C) 2002 Erik Fears
3
4This program is free software; you can redistribute it and/or
5modify it under the terms of the GNU General Public License
6as published by the Free Software Foundation; either version 2
7of the License, or (at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along with this program; if not, write to the Free Software
16
17 Foundation, Inc.
18 59 Temple Place - Suite 330
19 Boston, MA 02111-1307, USA.
20
21*/
22
23#include "setup.h"
24
25#include <stdio.h>
26#include <unistd.h>
27
28#ifdef STDC_HEADERS
29# include <stdlib.h>
30# include <string.h>
31#endif
32
7cdaaf39 33#ifdef TIME_WITH_SYS_TIME
34# include <sys/time.h>
35# include <time.h>
36#else
37# ifdef HAVE_SYS_TIME_H
38# include <sys/time.h>
39# else
40# include <time.h>
41# endif
42#endif
43
44#include <errno.h>
45#include <fcntl.h>
46
47#ifdef HAVE_SYS_POLL_H
48# include <sys/poll.h>
49#endif
50
51#include "config.h"
52#include "irc.h"
53#include "log.h"
54#include "opercmd.h"
55#include "scan.h"
56#include "stats.h"
57#include "dnsbl.h"
58#include "extern.h"
59#include "options.h"
60
61static void scan_memfail(void);
62static void scan_establish(scan_struct *conn);
63static void scan_check(void);
64static void scan_negfail(scan_struct *conn);
65static void scan_readready(scan_struct *conn);
66static void scan_read(scan_struct *conn);
67static void scan_openproxy(scan_struct *conn);
68static void scan_writeready(scan_struct *conn);
69static void scan_add(scan_struct *newconn);
70static void scan_del(scan_struct *delconn);
71static int scan_w_squid(struct scan_struct *conn);
72static int scan_w_socks4(struct scan_struct *conn);
73static int scan_w_socks5(struct scan_struct *conn);
74static int scan_w_cisco(struct scan_struct *conn);
75static int scan_w_wingate(struct scan_struct *conn);
76
77/* Linked list head for connections. */
78struct scan_struct *CONNECTIONS = 0;
79
80char SENDBUFF[513];
81
82/* Keep track of numbers of open FD's, for use with FDLIMIT. */
83unsigned int FD_USE = 0;
84
85
86/*
87 * Protocol Name, Port, Write Handler, Read Handler
88 *
89 * Always scan Cisco before Wingate, because cisco routers only allow 4
90 * connects at once.
91 */
92
93protocol_hash SCAN_PROTOCOLS[] = {
94
95 {"HTTP" , 8080, &(scan_w_squid), 0 ,0 },
96/* {"HTTP" , 8001, &(scan_w_squid), 0 ,0 }, */
97/* {"HTTP" , 8000, &(scan_w_squid), 0 ,0 }, */
98 {"HTTP" , 3128, &(scan_w_squid), 0 ,0 },
99 {"HTTP" , 80, &(scan_w_squid), 0 ,0 },
100 {"Socks4" , 1080, &(scan_w_socks4), 0 ,0 },
101 {"Socks5" , 1080, &(scan_w_socks5), 0 ,0 },
102 {"Cisco" , 23, &(scan_w_cisco), 0 ,0 },
103 {"Wingate" , 23, &(scan_w_wingate), 0 ,0 },
104};
105
106size_t SCAN_NUMPROTOCOLS;
107
108void do_scan_init(void)
109{
110 SCAN_NUMPROTOCOLS = sizeof(SCAN_PROTOCOLS) / sizeof(protocol_hash);
111}
112
113
114static void scan_memfail(void)
115{
116 log("SCAN -> Error allocating memory.");
117 exit(EXIT_FAILURE);
118}
119
120
121
122/*
123 * IRC client has receieved a +c notice from the remote server. scan_connect
124 * is called with the connecting IP, where we will begin to establish the
125 * proxy testing.
126 */
127
128void scan_connect(char *addr, char *irc_addr, char *irc_nick,
c185a5dd 129 char *irc_user, int verbose, int aftype, char *conn_notice)
7cdaaf39 130{
131 size_t i;
132 scan_struct *newconn;
133
134 if (OPT_DEBUG) {
135 log("SCAN -> checking user %s!%s@%s", irc_nick, irc_user,
136 irc_addr);
137 }
138
139 /*
140 * Loop through the protocols creating a seperate connection struct
141 * for each port/protocol.
142 */
143
144 for (i = 0; i < SCAN_NUMPROTOCOLS; i++) {
145 newconn = malloc(sizeof(*newconn));
146
147 if (!newconn)
148 scan_memfail();
149
150 newconn->addr = strdup(addr);
151 newconn->irc_addr = strdup(irc_addr);
152 newconn->irc_nick = strdup(irc_nick);
153 newconn->irc_user = strdup(irc_user);
154 /* This is allocated later on in scan_establish to save on
155 * memory.
156 */
157 newconn->data = 0;
158 newconn->verbose = verbose;
159 newconn->bytes_read = 0;
160 newconn->fd = 0;
c185a5dd 161 newconn->aftype = aftype;
7cdaaf39 162 if (conn_notice)
163 newconn->conn_notice = strdup(conn_notice);
164 else
165 newconn->conn_notice = 0;
166
167 /*
168 * Give struct a link to information about the protocol it
169 * will be handling.
170 */
171 newconn->protocol = &(SCAN_PROTOCOLS[i]);
172
c185a5dd 173 memset(&(newconn->sockaddr), 0, sizeof(struct bopm_sockaddr));
174
175#ifdef IPV6
176 if (aftype == AF_INET6) {
177 newconn->sockaddr.sas.sa6.sin6_family = AF_INET6; /* Fill in sockaddr with information about remote host */
178 newconn->sockaddr.sas.sa6.sin6_port = htons(newconn->protocol->port);
179 newconn->sockaddr.sas.sa6.sin6_addr = *((struct in6_addr *) addr);
180 } else {
181#endif
182 newconn->sockaddr.sas.sa4.sin_family = AF_INET; /* Fill in sockaddr with information about remote host */
183 newconn->sockaddr.sas.sa4.sin_port = htons(newconn->protocol->port);
184 newconn->sockaddr.sas.sa4.sin_addr = *((struct in_addr *) addr);
185#ifdef IPV6
186 }
187#endif
7cdaaf39 188 newconn->state = STATE_UNESTABLISHED;
189
190 /* Add struct to list of connections. */
191 scan_add(newconn);
192
193 /* If we have available FD's, overide queue. */
194 if (FD_USE < CONF_FDLIMIT)
195 scan_establish(newconn);
196 else if (OPT_DEBUG >= 3) {
197 log("SCAN -> File Descriptor limit (%d) reached, "
198 "queuing scan for %s", CONF_FDLIMIT,
199 newconn->addr);
200 }
201 }
202}
203
204/*
205 * Get FD for new socket, bind to interface and connect() (non blocking) then
206 * set conn to ESTABLISHED for write check.
207 */
208static void scan_establish(scan_struct *conn)
209{
210 /* For local bind() */
c185a5dd 211 struct bopm_ircaddr SCAN_LOCAL;
212 struct bopm_sockaddr bsadr;
7cdaaf39 213
214 memset(&SCAN_LOCAL, 0, sizeof(struct sockaddr_in));
c185a5dd 215 memset(&bsadr, 0, sizeof(struct bopm_sockaddr));
7cdaaf39 216
217 /* Setup SCAN_LOCAL for local bind() */
218 if (CONF_BINDSCAN) {
c185a5dd 219 if (bindto_ipv6) {
220 if (!inetpton(AF_INET6, CONF_BINDSCAN, &(SCAN_LOCAL.ins.in6.s6_addr))) {
221 log("IRC -> bind(): %s is an invalid address", CONF_BINDIRC);
222 exit(1);
223 }
224 } else {
225 if (!inetpton(AF_INET, CONF_BINDSCAN, &(SCAN_LOCAL.ins.in4.s_addr))) {
226 log("IRC -> bind(): %s is an invalid address", CONF_BINDIRC);
227 exit(1);
228 }
229 }
7cdaaf39 230 }
231
232 /* Request file descriptor for socket. */
c185a5dd 233 conn->fd = socket(conn->aftype, SOCK_STREAM, 0);
7cdaaf39 234
235 /* Increase global FD Use counter. */
236 FD_USE++;
237
238 /* If error, mark connection for close. */
239 if (conn->fd == -1) {
240 log("SCAN -> Error allocating file descriptor.");
241 conn->state = STATE_CLOSED;
242 return;
243 }
244
245 /* Bind to specific interface designated in conf file. */
246 if (CONF_BINDSCAN) {
c185a5dd 247 copy_s_addr(bsadr.sas.sa6.sin6_addr.s6_addr, SCAN_LOCAL.ins.in6.s6_addr);
248 if (bind(conn->fd, (struct sockaddr *)&bsadr, sizeof(bsadr)) == -1) {
7cdaaf39 249 switch (errno) {
250 case EACCES:
251 log("SCAN -> bind(): No access to bind to %s",
252 CONF_BINDSCAN);
253 break;
254 default:
255 log("SCAN -> bind(): Error binding to %s",
256 CONF_BINDSCAN);
257 break;
258
259 }
260 exit(EXIT_FAILURE);
261 }
262 }
263
264 /* Log create time of connection for timeouts. */
265 time(&(conn->create_time));
266 /* Flag conn established (for write). */
267 conn->state = STATE_ESTABLISHED;
268 /* Set socket non blocking. */
269 fcntl(conn->fd, F_SETFL, O_NONBLOCK);
270 /* Connect! */
271 connect(conn->fd, (struct sockaddr *) &(conn->sockaddr),
272 sizeof(conn->sockaddr));
273
274 /* Allocate memory for the scan buffer. */
275 conn->data = malloc((SCANBUFFER + 1) * sizeof(char));
276 conn->datasize = 0;
277
278}
279
280
281/*
282 * Pass one cycle to the proxy scanner so it can do neccessary functions like
283 * testing for sockets to be written to and read from.
284 */
285
286void scan_cycle(void)
287{
288 scan_check();
289}
290
291
292/*
293 * Test for sockets to be written/read to.
294 */
295
296static void scan_check(void)
297{
298#ifdef HAVE_SYS_POLL_H
299 /* MAX_POLL is defined in options.h */
300 static struct pollfd ufds[MAX_POLL];
301 unsigned long size, i;
302#else /* select() */
303 fd_set w_fdset;
304 fd_set r_fdset;
305 struct timeval scan_timeout;
306 int highfd;
307#endif /* HAVE_SYS_POLL_H */
308
309 struct scan_struct *ss;
310
311 if (!CONNECTIONS)
312 return;
313
314#ifdef HAVE_SYS_POLL_H
315 size = 0;
316
317 /* Get size of list we're interested in. */
318 for (ss = CONNECTIONS; ss; ss = ss->next) {
319 if (ss->state != STATE_CLOSED &&
320 ss->state != STATE_UNESTABLISHED)
321 size++;
322 }
323
324 i = 0;
325
326 /* Setup each element now. */
327 for (ss = CONNECTIONS; ss; ss = ss->next) {
328 if (ss->state == STATE_CLOSED ||
329 ss->state == STATE_UNESTABLISHED)
330 continue;
331
332 ufds[i].events = 0;
333 ufds[i].revents = 0;
334 ufds[i].fd = ss->fd;
335
336 /* Check for HUNG UP. */
337 ufds[i].events |= POLLHUP;
338 /* Check for INVALID FD */
339 ufds[i].events |= POLLNVAL;
340
341 switch (ss->state) {
342 case STATE_ESTABLISHED:
343 /* Check for NO BLOCK ON WRITE. */
344 ufds[i].events |= POLLOUT;
345 break;
346 case STATE_SENT:
347 /* Check for data to be read. */
348 ufds[i].events |= POLLIN;
349 break;
350 }
351
352 if (++i >= MAX_POLL)
353 break;
354 }
355
356#else /* select() */
357 FD_ZERO(&w_fdset);
358 FD_ZERO(&r_fdset);
359 highfd = 0;
360
361 /* Add connections to appropriate sets. */
362
363 for (ss = CONNECTIONS; ss; ss = ss->next) {
364 if (ss->state == STATE_ESTABLISHED) {
365 if(ss->fd > highfd)
366 highfd = ss->fd;
367
368 FD_SET(ss->fd, &w_fdset);
369 continue;
370 }
371
372 if (ss->state == STATE_SENT) {
373 if (ss->fd > highfd)
374 highfd = ss->fd;
375
376 FD_SET(ss->fd, &r_fdset);
377 }
378 }
379
380 /* No timeout. */
381 scan_timeout.tv_sec = 0;
382 scan_timeout.tv_usec= 0;
383
384#endif /* HAVE_SYS_POLL_H */
385
386
387#ifdef HAVE_SYS_POLL_H
388 switch (poll(ufds, size, 0)) {
389#else /* select() */
390 switch (select((highfd + 1), &r_fdset, &w_fdset, 0, &scan_timeout)) {
391#endif /* HAVE_SYS_POLL_H */
392 case -1:
393 /* error in select/poll */
394 return;
395 case 0:
396 break;
397 default:
398 /* Pass pointer to connection to handler. */
399
400#ifdef HAVE_SYS_POLL_H
401 for (ss = CONNECTIONS; ss; ss = ss->next) {
402 for (i = 0; i < size; i++) {
403 if (ufds[i].fd == ss->fd) {
404 if (ufds[i].revents & POLLIN)
405 scan_readready(ss);
406
407 if (ufds[i].revents & POLLOUT)
408 scan_writeready(ss);
409
410 if (ufds[i].revents & POLLHUP)
411 scan_negfail(ss);
412
413 break;
414 }
415 }
416 }
417#else
418
419 for (ss = CONNECTIONS; ss; ss = ss->next) {
420 if ((ss->state == STATE_ESTABLISHED) &&
421 FD_ISSET(ss->fd, &w_fdset))
422 scan_writeready(ss);
423
424 if ((ss->state == STATE_SENT) &&
425 FD_ISSET(ss->fd, &r_fdset))
426 scan_readready(ss);
427 }
428#endif /* HAVE_SYS_POLL_H */
429 }
430}
431
432
433/*
434 * Negotiation failed - Read returned false, we discard the connection as a
435 * closed proxy to save CPU.
436 */
437static void scan_negfail(scan_struct *conn)
438{
439 if (conn->verbose) {
440 irc_send("PRIVMSG %s :%s (%d): Connection to %s closed, "
441 "negotiation failed (%d bytes read)", CONF_CHANNELS,
442 conn->protocol->type, conn->protocol->port,
443 conn->irc_addr, conn->bytes_read);
444 }
445 conn->state = STATE_CLOSED;
446}
447
448/*
449 * Poll or select returned back that this connection is ready for read.
450 */
451static void scan_readready(scan_struct *conn)
452{
453 char c;
454
455 while(1) {
456 switch (read(conn->fd, &c, 1)) {
457 case 0:
458 case -1:
459 return;
460
461 default:
462 conn->bytes_read++;
463 if (c == 0 || c == '\r')
464 continue;
465
466 if(c == '\n') {
467 conn->data[conn->datasize] = 0;
468 conn->datasize = 0;
469 scan_read(conn);
470 continue;
471 }
472
473 /* Avoid freezing from reading endless data. */
474 if (conn->bytes_read >= MAXREAD) {
475 conn->state = STATE_CLOSED;
476 return;
477 }
478
479 if (conn->datasize < SCANBUFFER) {
480 /* -1 to pad for null term. */
481 conn->data[(++conn->datasize) - 1] = c;
482 }
483 }
484 }
485}
486
487/*
488 * Read one line in from remote, check line against target line.
489 */
490static void scan_read(scan_struct *conn)
491{
492 if (OPT_DEBUG >= 3)
493 log("SCAN -> Checking data from %s [%s:%d] against "
494 "TARGET_STRING: %s", conn->addr, conn->protocol->type,
495 conn->protocol->port, conn->data);
496 if (strstr(conn->data, CONF_TARGET_STRING))
497 scan_openproxy(conn);
498}
499
500/*
501 * Test proved positive for open proxy.
502 */
503static void scan_openproxy(scan_struct *conn)
504{
505 scan_struct *ss;
506
507 irc_kline(conn->irc_addr, conn->addr);
508
509 if (CONF_DNSBL_FROM && CONF_DNSBL_TO && CONF_SENDMAIL &&
510 !conn->verbose)
511 dnsbl_report(conn);
512
513 log("OPEN PROXY -> %s: %s!%s@%s (%d)", conn->protocol->type,
514 conn->irc_nick, conn->irc_user, conn->irc_addr,
515 conn->protocol->port);
516
517 irc_send("PRIVMSG %s :%s (%d): OPEN PROXY -> %s!%s@%s",
518 CONF_CHANNELS, conn->protocol->type, conn->protocol->port,
519 conn->irc_nick, conn->irc_user, conn->irc_addr);
520
521 /* Increase number OPEN (insecure) of this type. */
522 conn->protocol->stat_numopen++;
523
524 conn->state = STATE_CLOSED;
525
526 /*
527 * Flag connections with the same addr CLOSED aswell, but only if this
528 * is not a verbose check. When it is verbose/manual, we care about
529 * all types of proxy. When it is automatic (i.e. when a user
530 * connects) we want them killed quickly sow e can move on.
531 */
c185a5dd 532#if 0
7cdaaf39 533 if (!conn->verbose) {
534 for (ss = CONNECTIONS;ss;ss = ss->next) {
c185a5dd 535 if (!strcmp(conn->irc_addr, ss->irc_addr)) /* TimeMr14C */
7cdaaf39 536 ss->state = STATE_CLOSED;
537 }
538 }
c185a5dd 539#endif
7cdaaf39 540}
541
542/*
543 * Poll or select returned back that this connect is ready for write.
544 */
545static void scan_writeready(scan_struct *conn)
546{
547 /* If write returns true, flag STATE_SENT. */
548 if ((*conn->protocol->w_handler)(conn))
549 conn->state = STATE_SENT;
550
551 /* Increase number attempted negotiated of this type. */
552 conn->protocol->stat_num++;
553}
554
555/*
556 * Link struct to connection list.
557 */
558static void scan_add(scan_struct *newconn)
559{
560 scan_struct *ss;
561
562 /* Only item in list. */
563
564 if (!CONNECTIONS) {
565 newconn->next = 0;
566 CONNECTIONS = newconn;
567 } else {
568 /* Link to end of list. */
569 for(ss = CONNECTIONS; ss; ss = ss->next) {
570 if (!ss->next) {
571 newconn->next = 0;
572 ss->next = newconn;
573 break;
574 }
575 }
576 }
577}
578
579
580/*
581 * Unlink struct from connection list and free its memory.
582 */
583static void scan_del(scan_struct *delconn)
584{
585 scan_struct *ss;
586 scan_struct *lastss;
587
588 if (delconn->fd > 0)
589 close(delconn->fd);
590
591 /* 1 file descriptor freed up for use. */
592 if(delconn->fd)
593 FD_USE--;
594
595 lastss = 0;
596
597 for(ss = CONNECTIONS; ss; ss = ss->next) {
598 if (ss == delconn) {
599 /* Link around deleted node */
600 if (lastss == 0)
601 CONNECTIONS = ss->next;
602 else
603 lastss->next = ss->next;
604
605 free(ss->addr);
606 free(ss->irc_addr);
607 free(ss->irc_nick);
608 free(ss->irc_user);
609
610 if (ss->conn_notice)
611 free(ss->conn_notice);
612
613 /* If it's established, free the scan buffer. */
614 if (delconn->data)
615 free(delconn->data);
616
617 free(ss);
618
619 break;
620 }
621
622 lastss = ss;
623 }
624
625}
626
627/*
628 * Alarm signaled, loop through connections and remove any we don't need
629 * anymore.
630 */
631void scan_timer()
632{
633 scan_struct *ss;
634 scan_struct *nextss;
635
636 time_t present;
637 time(&present);
638
639 /*
640 * Check for timed out connections and also check if queued
641 * (UNESTABLISHED) connections can be established now.
642 */
643
644 for (ss = CONNECTIONS; ss;) {
645 if (ss->state == STATE_UNESTABLISHED) {
646 if (FD_USE < CONF_FDLIMIT) {
647 scan_establish(ss);
648 if (OPT_DEBUG >= 3) {
649 log("SCAN -> File descriptor free, "
650 "continuing queued scan on %s",
651 ss->addr);
652 }
653 } else {
654 ss = ss->next;
655
656 /*
657 * Continue to avoid timeout checks on an
658 * unestablished connection.
659 */
660 continue;
661 }
662 }
663
664 if (((present - ss->create_time) >= CONF_TIMEOUT) ||
665 (ss->state == STATE_CLOSED)) {
666 /* State closed or timed out, remove */
667 if (ss->verbose && (ss->state != STATE_CLOSED)) {
668 if (ss->bytes_read) {
669 irc_send("PRIVMSG %s :%s (%d): "
670 "Negotiation to %s timed out "
671 "(%d bytes read).",
672 CONF_CHANNELS,
673 ss->protocol->type,
674 ss->protocol->port,
675 ss->irc_addr, ss->bytes_read);
676 } else {
677 irc_send("PRIVMSG %s :%s (%d): "
678 "Negotiation to %s timed out "
679 "(No response).",
680 CONF_CHANNELS,
681 ss->protocol->type,
682 ss->protocol->port,
683 ss->irc_addr);
684 }
685 }
686
687 nextss = ss->next;
688 scan_del(ss);
689 ss = nextss;
690 continue;
691 }
692 ss = ss->next;
693 }
694}
695
696
697
698/*
699 * Function for handling open HTTP data.
700 *
701 * Return 1 on success.
702 */
703static int scan_w_squid(struct scan_struct *conn)
704{
705 snprintf(SENDBUFF, 128, "CONNECT %s:%d HTTP/1.0\r\n\r\n",
706 CONF_SCANIP, CONF_SCANPORT);
707 send(conn->fd, SENDBUFF, strlen(SENDBUFF), 0);
708
709 return(1);
710}
711
712
713/*
714 * CONNECT request byte order for socks4
715 *
716 * +----+----+----+----+----+----+----+----+----+----+....+----+
717 * | VN | CD | DSTPORT | DSTIP | USERID |NULL|
718 * +----+----+----+----+----+----+----+----+----+----+....+----+
719 * # of bytes: 1 1 2 4 variable 1
720 *
721 * VN = Version, CD = Command Code (1 is connect request)
722 */
723static int scan_w_socks4(struct scan_struct *conn)
724{
725 struct in_addr addr;
726 unsigned long laddr;
727 int len;
728
729 if (inet_aton(CONF_SCANIP, &addr) == 0) {
730 log("SCAN -> scan_w_socks4 : %s is not a valid IP",
731 CONF_SCANIP);
732 }
733
734 laddr = htonl(addr.s_addr);
735
736 len = snprintf(SENDBUFF, 512, "%c%c%c%c%c%c%c%c%c", 4, 1,
737 (((unsigned short) CONF_SCANPORT) >> 8) & 0xFF,
109ebed4 738 (((unsigned short) CONF_SCANPORT) & 0xFF),
7cdaaf39 739 (char) (laddr >> 24) & 0xFF, (char) (laddr >> 16) & 0xFF,
740 (char) (laddr >> 8) & 0xFF, (char) laddr & 0xFF, 0);
741
742 send(conn->fd, SENDBUFF, len, 0);
743 return(1);
744}
745
746/*
747 * Send version authentication selection message to socks5
748 *
109ebed4 749 * +----+----------+----------+
750 * |VER | NMETHODS | METHODS |
751 * +----+----------+----------+
752 * | 1 | 1 | 1 to 255 |
753 * +----+----------+----------+
7cdaaf39 754 *
755 * VER always contains 5, for socks version 5
756 * Method 0 is 'No authentication required'
109ebed4 757 *
758 *
759 *
760 * The SOCKS request is formed as follows:
761 *
762 * +----+-----+-------+------+----------+----------+
763 * |VER | CMD | RSV | ATYP | DST.ADDR | DST.PORT |
764 * +----+-----+-------+------+----------+----------+
765 * | 1 | 1 | X'00' | 1 | Variable | 2 |
766 * +----+-----+-------+------+----------+----------+
767 *
768 * Where:
769 *
770 * o VER protocol version: X'05'
771 * o CMD
772 * o CONNECT X'01'
773 * o BIND X'02'
774 * o UDP ASSOCIATE X'03'
775 * o RSV RESERVED
776 * o ATYP address type of following address
777 * o IP V4 address: X'01'
778 * o DOMAINNAME: X'03'
779 * o IP V6 address: X'04'
780 * o DST.ADDR desired destination address
781 * o DST.PORT desired destination port in network octet
782 * order
783 *
784 *
7cdaaf39 785 */
109ebed4 786
7cdaaf39 787static int scan_w_socks5(struct scan_struct *conn)
788{
109ebed4 789
790 struct in_addr addr;
791 unsigned long laddr;
792 int len;
793
794 if (inet_aton(CONF_SCANIP, &addr) == 0) {
795 log("SCAN -> scan_w_socks4 : %s is not a valid IP",
796 CONF_SCANIP);
797 }
798
799 laddr = htonl(addr.s_addr);
7cdaaf39 800
109ebed4 801 /* Form authentication string */
7cdaaf39 802 /* Version 5, 1 number of methods, 0 method (no auth). */
803 len = snprintf(SENDBUFF, 512, "%c%c%c", 5, 1, 0);
804 send(conn->fd, SENDBUFF, len, 0);
109ebed4 805
806 /* Form request string */
807
808 /* Will need to write ipv6 support here in future
809 * as socks5 is ipv6 compatible
810 */
811
812 len = snprintf(SENDBUFF, 512, "%c%c%c%c%c%c%c%c%c%c", 5, 1, 0, 1,
813 (char) (laddr >> 24) & 0xFF, (char) (laddr >> 16) & 0xFF,
814 (char) (laddr >> 8) & 0xFF, (char) laddr & 0xFF,
815 (((unsigned short) CONF_SCANPORT) >> 8) & 0xFF,
816 (((unsigned short) CONF_SCANPORT) & 0xFF)
817 );
7cdaaf39 818
109ebed4 819 send(conn->fd, SENDBUFF, len, 0);
7cdaaf39 820 return(1);
821}
822
823/*
824 * Cisco scanning
825 *
826 * Some cisco routers have 'cisco' set as password which allow open telnet
827 * relay. Attempt to connect using cisco as a password, then give command for
828 * telnet to the scanip/scanport
829 */
830static int scan_w_cisco(struct scan_struct *conn)
831{
832 int len;
833
834 len = snprintf(SENDBUFF, 512, "cisco\r\n");
835 send(conn->fd, SENDBUFF, len, 0);
836
837 len = snprintf(SENDBUFF, 512, "telnet %s %d\r\n", CONF_SCANIP,
838 CONF_SCANPORT);
839 send(conn->fd, SENDBUFF, len, 0);
840
841 return(1);
842}
843
844
845/*
846 * Open wingates require no authentication, they will send a prompt when
847 * connect. No need to send any data.
848 */
849static int scan_w_wingate(struct scan_struct *conn)
850{
851 int len;
852
853 len = snprintf(SENDBUFF, 512, "%s:%d\r\n", CONF_SCANIP,
854 CONF_SCANPORT);
855 send(conn->fd, SENDBUFF, len, 0);
856
857 return(1);
858}
859
860
861/*
862 * Manually check a host for proxies.
863 */
864void do_manual_check(struct command *c)
865{
866 struct hostent *he;
867 char *ip;
868
869 if (!(he = gethostbyname(c->param))) {
870 switch (h_errno) {
871 case HOST_NOT_FOUND:
872 irc_send("PRIVMSG %s :Host '%s' is unknown, dummy.",
873 c->target, c->param);
874 return;
875 case NO_ADDRESS:
876 irc_send("PRIVMSG %s :The specified name '%s' "
877 "exists, but has no address.", c->target,
878 c->param);
879 return;
880 case NO_RECOVERY:
881 irc_send("PRIVMSG %s :An unrecoverable error "
882 "occured whilst resolving '%s'.", c->target,
883 c->param);
884 return;
885 case TRY_AGAIN:
886 irc_send("PRIVMSG %s :A temporary nameserver "
887 "error occurred.", c->target);
888 return;
889 default:
890 irc_send("PRIVMSG %s :Unknown error resolving "
891 "'%s' (sorry!)", c->target, c->param);
892 return;
893 }
894 }
895
896 ip = inet_ntoa(*((struct in_addr *) he->h_addr));
897
898 irc_send("PRIVMSG %s :Checking %s [%s] for open proxies at "
899 "request of %s...", CONF_CHANNELS, c->param, ip, c->nick);
900
c185a5dd 901 if (CONF_DNSBL_ZONE && he->h_addrtype != AF_INET6)
902 dnsbl_check(ip, "*", "*", c->param);
7cdaaf39 903
904 /* Scan using verbose. */
c185a5dd 905 scan_connect(ip, c->param, "*", "*", 1, he->h_addrtype, 0);
7cdaaf39 906}
907