2004-01-14 11:40:16 +00:00
/* NeoStats - IRC Statistical Services Copyright (c) 1999-2004 NeoStats Group Inc.
* * Copyright ( c ) 1999 - 2004 Adam Rutter , Justin Hammond
2002-09-04 08:52:34 +00:00
* * http : //www.neostats.net/
* *
2004-01-14 11:40:16 +00:00
* * Portions Copyright ( c ) 2004 Erik Fears
2002-09-04 08:52:34 +00:00
* *
* * This program is free software ; you can redistribute it and / or modify
* * it under the terms of the GNU General Public License as published by
* * the Free Software Foundation ; either version 2 of the License , or
* * ( at your option ) any later version .
* *
* * This program is distributed in the hope that it will be useful ,
* * but WITHOUT ANY WARRANTY ; without even the implied warranty of
* * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* * GNU General Public License for more details .
* *
* * You should have received a copy of the GNU General Public License
* * along with this program ; if not , write to the Free Software
* * Foundation , Inc . , 59 Temple Place , Suite 330 , Boston , MA 02111 - 1307
* * USA
* *
* * NeoStats CVS Identification
2003-09-22 15:14:02 +00:00
* * $ Id $
2002-08-31 09:28:34 +00:00
*/
# include <stdio.h>
# include <sys/types.h>
# include <sys/socket.h>
# include <netinet/in.h>
# include <arpa/inet.h>
# include <arpa/nameser.h>
2004-03-08 22:17:03 +00:00
# include "neostats.h"
2002-08-31 09:28:34 +00:00
# include "opsb.h"
2003-10-24 14:12:17 +00:00
# include "opm.h"
# include "opm_types.h"
2003-10-28 11:49:35 +00:00
# include "opm_error.h"
2002-08-31 09:28:34 +00:00
int proxy_connect ( unsigned long ipaddr , int port , char * who ) ;
2003-10-24 14:12:17 +00:00
void open_proxy ( OPM_T * scanner , OPM_REMOTE_T * remote , int notused , void * unused ) ;
void negfailed ( OPM_T * scanner , OPM_REMOTE_T * remote , int notused , void * unused ) ;
void timeout ( OPM_T * scanner , OPM_REMOTE_T * remote , int notused , void * unused ) ;
void scan_end ( OPM_T * scanner , OPM_REMOTE_T * remote , int notused , void * unused ) ;
void scan_error ( OPM_T * scanner , OPM_REMOTE_T * remote , int opmerr , void * unused ) ;
2002-08-31 09:28:34 +00:00
# ifndef MSG_NOSIGNAL
# define MSG_NOSIGNAL 0
# endif
2003-10-24 14:12:17 +00:00
OPM_T * scanner ;
2003-10-29 11:07:23 +00:00
proxy_type proxy_list [ ] = {
{ OPM_TYPE_HTTP , " HTTP " } ,
{ OPM_TYPE_SOCKS4 , " SOCKS4 " } ,
{ OPM_TYPE_SOCKS5 , " SOCKS5 " } ,
{ OPM_TYPE_WINGATE , " WINGATE " } ,
{ OPM_TYPE_ROUTER , " ROUTER " } ,
{ OPM_TYPE_HTTPPOST , " HTTPPOST " } ,
{ 0 , " " }
} ;
char * type_of_proxy ( int type ) {
return proxy_list [ type - 1 ] . name ;
}
int get_proxy_by_name ( const char * name ) {
int i ;
for ( i = 0 ; proxy_list [ i ] . type ! = 0 ; i + + ) {
if ( ! strcasecmp ( proxy_list [ i ] . name , name ) ) {
return proxy_list [ i ] . type ;
}
}
return 0 ;
}
void add_port ( int type , int port ) {
opm_addtype ( scanner , type , port ) ;
}
2003-10-24 14:12:17 +00:00
2003-10-29 11:07:23 +00:00
int load_ports ( ) {
char * portname , * * av ;
int i , j , ac , ok ;
port_list * prtlst ;
lnode_t * pn ;
ok = 0 ;
for ( i = 0 ; proxy_list [ i ] . type ! = 0 ; i + + ) {
if ( GetConf ( ( void * ) & portname , CFGSTR , proxy_list [ i ] . name ) < = 0 ) {
nlog ( LOG_WARNING , LOG_MOD , " Warning, No Ports defined for Protocol %s " , proxy_list [ i ] . name ) ;
} else {
ac = split_buf ( portname , & av , 0 ) ;
for ( j = 0 ; j < ac ; j + + ) {
if ( atoi ( av [ j ] ) = = 0 ) {
nlog ( LOG_WARNING , LOG_MOD , " Invalid Port %s for Proxy Type %s " , av [ j ] , proxy_list [ i ] . name ) ;
continue ;
}
if ( list_isfull ( opsb . ports ) ) {
nlog ( LOG_MOD , LOG_WARNING , " Ports List is Full. " ) ;
break ;
}
prtlst = malloc ( sizeof ( port_list ) ) ;
prtlst - > type = proxy_list [ i ] . type ;
prtlst - > port = atoi ( av [ j ] ) ;
prtlst - > noopen = 0 ;
pn = lnode_create ( prtlst ) ;
list_append ( opsb . ports , pn ) ;
nlog ( LOG_DEBUG1 , LOG_MOD , " Added Port %d for Protocol %s " , prtlst - > port , proxy_list [ i ] . name ) ;
ok = 1 ;
}
2003-11-07 13:11:18 +00:00
free ( av ) ;
free ( portname ) ;
2003-10-29 11:07:23 +00:00
}
}
return ok ;
}
2003-10-24 14:12:17 +00:00
int init_libopm ( ) {
2003-10-29 11:07:23 +00:00
lnode_t * pn ;
port_list * pl ;
2004-10-19 06:31:55 +00:00
struct hostent * hp ;
2003-10-24 14:12:17 +00:00
scanner = opm_create ( ) ;
/* setup the callbacks to our code */
opm_callback ( scanner , OPM_CALLBACK_OPENPROXY , & open_proxy , NULL ) ;
opm_callback ( scanner , OPM_CALLBACK_NEGFAIL , & negfailed , NULL ) ;
opm_callback ( scanner , OPM_CALLBACK_TIMEOUT , & timeout , NULL ) ;
opm_callback ( scanner , OPM_CALLBACK_END , & scan_end , NULL ) ;
opm_callback ( scanner , OPM_CALLBACK_ERROR , & scan_error , NULL ) ;
2003-10-28 11:49:35 +00:00
2004-10-19 06:31:55 +00:00
/* configure opm to bind to a IP address */
if ( me . local [ 0 ] ! = 0 ) {
if ( ( hp = gethostbyname ( me . local ) ) = = NULL ) {
nlog ( LOG_WARNING , LOG_MOD , " Warning, Couldn't bind OPSB ports to IP address: %s " , me . local ) ;
} else {
if ( opm_config ( scanner , OPM_CONFIG_BIND_IP , & me . local ) ! = OPM_SUCCESS ) {
nlog ( LOG_WARNING , LOG_MOD , " LIBOPM couldn't bind to a IP address " ) ;
}
}
}
2003-10-28 11:49:35 +00:00
/* max number of socks we allow */
opm_config ( scanner , OPM_CONFIG_FD_LIMIT , & opsb . socks ) ;
/* host to try to connect to */
opm_config ( scanner , OPM_CONFIG_SCAN_IP , opsb . targethost ) ;
/* port to try to connect to */
opm_config ( scanner , OPM_CONFIG_SCAN_PORT , & opsb . targetport ) ;
/* string to look for */
opm_config ( scanner , OPM_CONFIG_TARGET_STRING , opsb . lookforstring ) ;
/* also look for throttle messages */
opm_config ( scanner , OPM_CONFIG_TARGET_STRING , " ERROR :Trying to reconnect too fast " ) ;
/* timeout */
opm_config ( scanner , OPM_CONFIG_TIMEOUT , & opsb . timeout ) ;
/* max bytes read */
opm_config ( scanner , OPM_CONFIG_MAX_READ , & opsb . maxbytes ) ;
2003-10-29 11:07:23 +00:00
/* read the proxy types directly from keeper :) */
pn = list_first ( opsb . ports ) ;
while ( pn ) {
pl = lnode_get ( pn ) ;
opm_addtype ( scanner , pl - > type , pl - > port ) ;
pn = list_next ( opsb . ports , pn ) ;
}
2003-10-28 12:45:28 +00:00
2003-10-28 11:49:35 +00:00
/* add the sock poll interface into neo */
add_sockpoll ( " libopm_before_poll " , " libopm_after_poll " , " opsb " , " opsb " , scanner ) ;
2003-10-24 14:12:17 +00:00
return 1 ;
}
void open_proxy ( OPM_T * scanner , OPM_REMOTE_T * remote , int notused , void * unused )
{
2003-10-29 12:11:16 +00:00
#if 0
2002-08-31 09:28:34 +00:00
FILE * fp ;
2003-10-29 12:11:16 +00:00
# endif
2003-10-24 14:12:17 +00:00
scaninfo * scandata ;
2002-08-31 09:28:34 +00:00
2003-09-29 12:59:07 +00:00
SET_SEGV_LOCATION ( ) ;
2002-09-04 08:52:34 +00:00
2003-10-24 14:12:17 +00:00
scandata = remote - > data ;
2002-09-04 08:52:34 +00:00
if ( scandata - > doneban = = 1 )
return ;
2002-08-31 09:28:34 +00:00
+ + opsb . open ;
2003-10-29 11:07:23 +00:00
nlog ( LOG_CRITICAL , LOG_MOD , " OPSB: Banning %s (%s) for Open Proxy - %s(%d) " , scandata - > who , remote - > ip , type_of_proxy ( remote - > protocol ) , remote - > port ) ;
chanalert ( s_opsb , " Banning %s (%s) for Open Proxy - %s(%d) " , scandata - > who , remote - > ip , type_of_proxy ( remote - > protocol ) , remote - > port ) ;
globops ( s_opsb , " Banning %s (%s) for Open Proxy - %s(%d) " , scandata - > who , remote - > ip , type_of_proxy ( remote - > protocol ) , remote - > port ) ;
if ( scandata - > u ) prefmsg ( scandata - > u - > nick , s_opsb , " Banning %s (%s) for Open Proxy - %s(%d) " , scandata - > who , remote - > ip , type_of_proxy ( remote - > protocol ) , remote - > port ) ;
2003-11-05 12:31:21 +00:00
if ( opsb . doban ) sakill_cmd ( remote - > ip , " * " , s_opsb , opsb . bantime , " Open Proxy found on your host. %s(%d) " , type_of_proxy ( remote - > protocol ) , remote - > port ) ;
2003-10-24 14:12:17 +00:00
#if 0
/* write out to a logfile */
if ( ( fp = fopen ( " logs/openproxies.log " , " a " ) ) = = NULL ) return ;
fprintf ( fp , " %d:%s:%s \n " , remote - > protocol , remote - > ip , " empty " ) ;
fclose ( fp ) ;
2003-10-28 11:49:35 +00:00
# endif
2003-10-24 14:12:17 +00:00
/* no point continuing the scan if they are found open */
2003-10-28 12:45:28 +00:00
scandata - > state = GOTOPENPROXY ;
2003-10-24 14:12:17 +00:00
opm_end ( scanner , remote ) ;
#if 0
2002-08-31 09:28:34 +00:00
if ( scandata - > dnsstate = = OPMLIST ) {
2002-09-04 08:52:34 +00:00
scandata - > doneban = 1 ;
2003-04-17 15:55:47 +00:00
nlog ( LOG_CRITICAL , LOG_MOD , " OPSB: Banning %s (%s) as its listed in %s " , scandata - > who , inet_ntoa ( scandata - > ipaddr ) , opsb . opmdomain ) ;
2002-08-31 09:28:34 +00:00
chanalert ( s_opsb , " Banning %s (%s) as its listed in %s " , scandata - > who , inet_ntoa ( scandata - > ipaddr ) , opsb . opmdomain ) ;
globops ( s_opsb , " Banning %s (%s) as its listed in %s " , scandata - > who , inet_ntoa ( scandata - > ipaddr ) , opsb . opmdomain ) ;
if ( scandata - > u ) prefmsg ( scandata - > u - > nick , s_opsb , " Banning %s (%s) as its listed in %s " , scandata - > who , inet_ntoa ( scandata - > ipaddr ) , opsb . opmdomain ) ;
2003-10-07 14:00:31 +00:00
sakill_cmd ( inet_ntoa ( scandata - > ipaddr ) , " * " , s_opsb , opsb . bantime , " Your host is listed as an Open Proxy. Please visit the following website for more info: www.blitzed.org/proxy?ip=%s " , inet_ntoa ( scandata - > ipaddr ) ) ;
2002-08-31 09:28:34 +00:00
}
2003-10-24 14:12:17 +00:00
# endif
2002-08-31 09:28:34 +00:00
}
2003-10-24 14:12:17 +00:00
void negfailed ( OPM_T * scanner , OPM_REMOTE_T * remote , int notused , void * unused ) {
scaninfo * scandata ;
2002-08-31 09:28:34 +00:00
2003-10-24 14:12:17 +00:00
SET_SEGV_LOCATION ( ) ;
2002-08-31 09:28:34 +00:00
2003-10-24 14:12:17 +00:00
scandata = remote - > data ;
if ( scandata - > u ) {
2003-10-29 11:07:23 +00:00
prefmsg ( scandata - > u - > nick , s_opsb , " Negitiation failed for protocol %s(%d) " , type_of_proxy ( remote - > protocol ) , remote - > port ) ;
2003-10-24 14:12:17 +00:00
}
}
2002-08-31 09:28:34 +00:00
2003-10-24 14:12:17 +00:00
void timeout ( OPM_T * scanner , OPM_REMOTE_T * remote , int notused , void * unused ) {
scaninfo * scandata ;
2002-08-31 09:28:34 +00:00
2003-10-24 14:12:17 +00:00
SET_SEGV_LOCATION ( ) ;
2002-08-31 09:28:34 +00:00
2003-10-24 14:12:17 +00:00
scandata = remote - > data ;
if ( scandata - > u ) {
2003-10-29 11:07:23 +00:00
prefmsg ( scandata - > u - > nick , s_opsb , " Timeout on Protocol %s(%d) " , type_of_proxy ( remote - > protocol ) , remote - > port ) ;
2003-10-24 14:12:17 +00:00
}
2002-08-31 09:28:34 +00:00
}
2003-10-24 14:12:17 +00:00
void scan_end ( OPM_T * scanner , OPM_REMOTE_T * remote , int notused , void * unused ) {
2002-08-31 09:28:34 +00:00
scaninfo * scandata ;
2003-09-29 12:59:07 +00:00
SET_SEGV_LOCATION ( ) ;
2002-09-04 08:52:34 +00:00
2003-10-24 14:12:17 +00:00
scandata = remote - > data ;
if ( scandata - > u ) {
2003-10-29 11:07:23 +00:00
prefmsg ( scandata - > u - > nick , s_opsb , " scan finished on %s " , scandata - > who ) ;
2003-10-24 14:12:17 +00:00
}
2003-11-07 13:11:18 +00:00
opm_remote_free ( remote ) ;
2003-10-28 12:45:28 +00:00
if ( scandata - > state ! = GOTOPENPROXY ) scandata - > state = FIN_SCAN ;
check_scan_free ( scandata ) ;
2003-10-24 14:12:17 +00:00
}
2002-08-31 09:28:34 +00:00
2003-10-24 14:12:17 +00:00
void scan_error ( OPM_T * scanner , OPM_REMOTE_T * remote , int opmerr , void * unused ) {
scaninfo * scandata ;
2002-11-05 13:31:59 +00:00
2003-10-24 14:12:17 +00:00
SET_SEGV_LOCATION ( ) ;
scandata = remote - > data ;
if ( scandata - > u ) {
2003-10-29 12:23:17 +00:00
if ( opmerr = = 5 ) {
prefmsg ( scandata - > u - > nick , s_opsb , " Closed Proxy on Protocol %s (%d) " , type_of_proxy ( remote - > protocol ) , remote - > port ) ;
} else {
prefmsg ( scandata - > u - > nick , s_opsb , " scan error on Protocol %s (%d) - %d " , type_of_proxy ( remote - > protocol ) , remote - > port , opmerr ) ;
}
2002-08-31 09:28:34 +00:00
}
2003-10-24 14:12:17 +00:00
2002-08-31 09:28:34 +00:00
}
2003-10-24 14:12:17 +00:00
2004-02-26 19:49:27 +00:00
int do_status ( User * u , char * * av , int ac )
{
2003-10-24 14:12:17 +00:00
lnode_t * node ;
2002-08-31 09:28:34 +00:00
scaninfo * scandata ;
2002-09-04 08:52:34 +00:00
2003-09-29 12:59:07 +00:00
SET_SEGV_LOCATION ( ) ;
2002-09-04 08:52:34 +00:00
2002-08-31 09:28:34 +00:00
prefmsg ( u - > nick , s_opsb , " Proxy Results: " ) ;
2003-12-02 20:24:02 +00:00
prefmsg ( u - > nick , s_opsb , " Hosts Scanned: %d Hosts found Open: %d Exceptions %d " , opsb . scanned , opsb . open , ( int ) list_count ( exempt ) ) ;
prefmsg ( u - > nick , s_opsb , " Cache Entries: %d " , ( int ) list_count ( cache ) ) ;
2003-01-30 11:29:25 +00:00
prefmsg ( u - > nick , s_opsb , " Cache Hits: %d " , opsb . cachehits ) ;
prefmsg ( u - > nick , s_opsb , " Blacklist Hits: %d " , opsb . opmhits ) ;
2003-10-24 14:12:17 +00:00
#if 0
2002-08-31 09:28:34 +00:00
for ( i = 0 ; i < NUM_PROXIES ; i + + ) {
prefmsg ( u - > nick , s_opsb , " Proxy %s (%d) Found %d Open %d " , proxy_list [ i ] . type , proxy_list [ i ] . port , proxy_list [ i ] . nofound , proxy_list [ i ] . noopen ) ;
}
2003-10-24 14:12:17 +00:00
# endif
2003-12-02 20:24:02 +00:00
prefmsg ( u - > nick , s_opsb , " Currently Scanning %d Proxies (%d in queue): " , ( int ) list_count ( opsbl ) , ( int ) list_count ( opsbq ) ) ;
2002-08-31 09:28:34 +00:00
node = list_first ( opsbl ) ;
while ( node ) {
scandata = lnode_get ( node ) ;
if ( scandata - > u )
prefmsg ( u - > nick , s_opsb , " Scanning %s by request of %s " , scandata - > lookup , scandata - > u - > nick ) ;
else
2003-01-30 11:29:25 +00:00
prefmsg ( u - > nick , s_opsb , " Scanning %s (%s) - %s " , scandata - > lookup , inet_ntoa ( scandata - > ipaddr ) , scandata - > who ) ;
2002-08-31 09:28:34 +00:00
switch ( scandata - > dnsstate ) {
case REPORT_DNS :
prefmsg ( u - > nick , s_opsb , " Looking up IP Address " ) ;
break ;
2004-07-06 12:10:07 +00:00
case DO_DNS_HOST_LOOKUP :
2002-08-31 09:28:34 +00:00
prefmsg ( u - > nick , s_opsb , " Looking up IP address for Scan " ) ;
break ;
case DO_OPM_LOOKUP :
prefmsg ( u - > nick , s_opsb , " Looking up DNS blacklist " ) ;
break ;
2002-09-06 04:33:28 +00:00
case OPMLIST :
prefmsg ( u - > nick , s_opsb , " Host is listed in %s " , opsb . opmdomain ) ;
break ;
case NOOPMLIST :
prefmsg ( u - > nick , s_opsb , " Host is Not listed in %s " , opsb . opmdomain ) ;
break ;
2002-08-31 09:28:34 +00:00
default :
prefmsg ( u - > nick , s_opsb , " Unknown State (DNS) " ) ;
}
switch ( scandata - > state ) {
case DOING_SCAN :
prefmsg ( u - > nick , s_opsb , " Scanning for Open Proxies " ) ;
break ;
case GOTOPENPROXY :
2003-10-07 14:00:31 +00:00
prefmsg ( u - > nick , s_opsb , " Contains an Open Proxy " ) ;
2002-08-31 09:28:34 +00:00
break ;
default :
prefmsg ( u - > nick , s_opsb , " Unknown State (Scan) " ) ;
}
node = list_next ( opsbl , node ) ;
}
2004-02-26 19:49:27 +00:00
return 0 ;
2002-08-31 09:28:34 +00:00
}
void start_proxy_scan ( lnode_t * scannode ) {
scaninfo * scandata ;
2003-10-24 14:12:17 +00:00
OPM_REMOTE_T * remote ;
2003-10-28 11:49:35 +00:00
int i ;
2002-08-31 09:28:34 +00:00
2003-09-29 12:59:07 +00:00
SET_SEGV_LOCATION ( ) ;
2002-09-04 08:52:34 +00:00
2002-08-31 09:28:34 +00:00
scandata = lnode_get ( scannode ) ;
2004-07-06 12:10:07 +00:00
/* if we are configured not to scan, and its not a request, bail out */
if ( ( opsb . doscan = = 0 ) & & ( ! scandata - > u ) ) {
scandata - > state = FIN_SCAN ;
check_scan_free ( scandata ) ;
return ;
}
2002-08-31 09:28:34 +00:00
if ( scandata - > u ) chanalert ( s_opsb , " Starting proxy scan on %s (%s) by Request of %s " , scandata - > who , scandata - > lookup , scandata - > u - > nick ) ;
scandata - > state = DOING_SCAN ;
2002-10-27 10:28:47 +00:00
/* this is so we can timeout scans */
scandata - > started = time ( NULL ) ;
2002-10-24 09:27:58 +00:00
if ( ( opsb . doscan = = 1 ) | | ( scandata - > u ) ) {
2003-10-24 14:12:17 +00:00
remote = opm_remote_create ( inet_ntoa ( scandata - > ipaddr ) ) ;
remote - > data = scandata ;
2003-10-28 11:49:35 +00:00
switch ( i = opm_scan ( scanner , remote ) )
{
case OPM_SUCCESS :
2003-10-28 12:45:28 +00:00
nlog ( LOG_DEBUG2 , LOG_MOD , " Starting Scan on %s " , inet_ntoa ( scandata - > ipaddr ) ) ;
2003-10-28 11:49:35 +00:00
break ;
case OPM_ERR_BADADDR :
2003-10-28 12:45:28 +00:00
nlog ( LOG_WARNING , LOG_MOD , " Scan of %s %s Failed. Bad Address? " , scandata - > who , inet_ntoa ( scandata - > ipaddr ) ) ;
2003-10-28 11:49:35 +00:00
opm_remote_free ( remote ) ;
2003-10-28 12:45:28 +00:00
scandata - > state = FIN_SCAN ;
check_scan_free ( scandata ) ;
2003-10-28 11:49:35 +00:00
}
2002-08-31 09:28:34 +00:00
}
}
2003-10-28 12:45:28 +00:00
void check_scan_free ( scaninfo * scandata ) {
lnode_t * scannode ;
2004-07-06 12:10:07 +00:00
if ( ( scandata - > dnsstate = = DO_OPM_LOOKUP ) | | ( scandata - > dnsstate = = DO_DNS_HOST_LOOKUP ) | | ( scandata - > state = = DOING_SCAN ) ) {
2003-10-28 12:45:28 +00:00
nlog ( LOG_DEBUG2 , LOG_MOD , " Not Cleaning up Scaninfo for %s yet. Scan hasn't completed " , scandata - > who ) ;
return ;
}
if ( ( scandata - > dnsstate ! = OPMLIST ) & & ( scandata - > state ! = GOTOPENPROXY ) ) {
addtocache ( scandata - > ipaddr . s_addr ) ;
nlog ( LOG_DEBUG1 , LOG_MOD , " %s's Host is clean. Adding to Cache " , scandata - > who ) ;
}
scannode = list_find ( opsbl , scandata - > who , findscan ) ;
if ( scannode ) {
nlog ( LOG_DEBUG1 , LOG_MOD , " %s scan finished. Cleaning up " , scandata - > who ) ;
list_delete ( opsbl , scannode ) ;
lnode_destroy ( scannode ) ;
scandata - > u = NULL ;
free ( scandata ) ;
} else {
nlog ( LOG_WARNING , LOG_MOD , " Damn, Can't find ScanNode %s. Something is fubar " , scandata - > who ) ;
}
checkqueue ( ) ;
2003-10-29 11:07:23 +00:00
}