debug() send_uptime() urcapture is_safepath

This commit is contained in:
joonicks
2018-03-14 03:02:30 +01:00
parent 2d7d789621
commit fb70029b56
29 changed files with 575 additions and 164 deletions

2
.gitignore vendored
View File

@@ -9,6 +9,8 @@ src/energymech
src/gencmd src/gencmd
src/mcmd.h src/mcmd.h
src/usercombo.h src/usercombo.h
src/aliastest
src/safepathtest
*~ *~
*.bak *.bak

View File

@@ -92,6 +92,14 @@ mega: FORCE
mega-install: FORCE mega-install: FORCE
$(MAKE) -C src mega-install $(MAKE) -C src mega-install
#
# code validation tests
#
test: FORCE
$(MAKE) -C src test
# #
# packing things up for distribution # packing things up for distribution
# #

2
README
View File

@@ -135,4 +135,4 @@ IT COMES TO CONFIGURING AND USING IT.
---*--- ---*---
joonicks, March 10th, 2018. proton, March 13th, 2018.

View File

@@ -1,5 +1,10 @@
3.0.99p4 -- WORK IN PROGRESS (~March, 2018) 3.0.99p4 -- WORK IN PROGRESS (~March, 2018)
* Added: URL capturing with command to display recent URLs seen
by the bot. Also spy source "URL" for spy channels.
* Fixed: Rewrite of is_safepath() to conform with standard C
* Fixed: Potential crash bug in send_uptime()
* Fixed: Potential crash bug in debug()
* Added: New host information commands: HOSTINFO, MEMINFO, CPUINFO. * Added: New host information commands: HOSTINFO, MEMINFO, CPUINFO.
* Added: New configuration option: hostinfo * Added: New configuration option: hostinfo
* Fixed: Custom ld script fintuning the core order. * Fixed: Custom ld script fintuning the core order.

19
configure vendored
View File

@@ -79,6 +79,7 @@ do
toybox ) ft_toybox=$yesno ;; toybox ) ft_toybox=$yesno ;;
trivia ) ft_trivia=$yesno ;; trivia ) ft_trivia=$yesno ;;
uptime ) ft_uptime=$yesno ;; uptime ) ft_uptime=$yesno ;;
urlcapture ) ft_urlcapture=$yesno ;;
web ) ft_web=$yesno ;; web ) ft_web=$yesno ;;
wingate ) ft_wingate=$yesno ;; wingate ) ft_wingate=$yesno ;;
esac esac
@@ -109,7 +110,7 @@ do
case "$feature" in case "$feature" in
debug | botnet | telnet | alias | seen | session | dyncmd | newbie | wingate | md5 | sha \ debug | botnet | telnet | alias | seen | session | dyncmd | newbie | wingate | md5 | sha \
| ctcp | dccfile | uptime | redirect | greet | perl | profiling | tcl | dynamode | web | hostinfo \ | ctcp | dccfile | uptime | redirect | greet | perl | profiling | tcl | dynamode | web | hostinfo \
| note | notify | trivia | toybox | bounce | stats | rawdns | ircd_ext | idwrap | chanban | python ) | note | notify | trivia | toybox | bounce | stats | rawdns | ircd_ext | idwrap | chanban | python | urlcapture )
case _"$optarg"_ in case _"$optarg"_ in
_yes_ | _no_ | __ ) _yes_ | _no_ | __ )
;; ;;
@@ -193,6 +194,8 @@ do
trivia_no ) ft_trivia=no ;; trivia_no ) ft_trivia=no ;;
uptime_yes | uptime_ ) ft_uptime=yes ;; uptime_yes | uptime_ ) ft_uptime=yes ;;
uptime_no ) ft_uptime=no ;; uptime_no ) ft_uptime=no ;;
urlcapture_yes | urlcapture_ ) ft_urlcapture=yes ;;
urlcapture_no ) ft_urlcapture=no ;;
web_yes | web_ ) ft_web=yes ;; web_yes | web_ ) ft_web=yes ;;
web_no ) ft_web=no ;; web_no ) ft_web=no ;;
wingate_yes | wingate_ ) ft_wingate=yes ;; wingate_yes | wingate_ ) ft_wingate=yes ;;
@@ -234,6 +237,7 @@ do
toybox ) ft_toybox=no ;; toybox ) ft_toybox=no ;;
trivia ) ft_trivia=no ;; trivia ) ft_trivia=no ;;
uptime ) ft_uptime=no ;; uptime ) ft_uptime=no ;;
urlcapture ) ft_urlcapture=no ;;
web ) ft_web=no ;; web ) ft_web=no ;;
wingate ) ft_wingate=no ;; wingate ) ft_wingate=no ;;
esac esac
@@ -280,6 +284,7 @@ do
ft_toybox=yes ft_toybox=yes
ft_trivia=yes ft_trivia=yes
ft_uptime=yes ft_uptime=yes
ft_urlcapture=yes
ft_web=yes ft_web=yes
ft_wingate=yes ft_wingate=yes
;; ;;
@@ -302,13 +307,15 @@ Features and packages:
--with-debug Debug support --with-debug Debug support
--with-dyncmd Dynamic command levels support --with-dyncmd Dynamic command levels support
--with-hostinfo Support for code that reveals/displays/shares information about the host --with-hostinfo Support for code that reveals/displays/shares information about the host
that the bot is running on. that the bot is running on
--with-newbie Newbie support --with-newbie Newbie support
--with-profiling Profiling (gcc+gprof) --with-profiling Profiling (gcc+gprof)
--with-seen SEEN support --with-seen SEEN support
--with-session Session support --with-session Session support
--with-tcl Tcl support --with-tcl Tcl support
--with-telnet Telnet support --with-telnet Telnet support
--with-uptime Include code that sends uptime reports to the IRC bot uptime contest server
--with-urlcapture URL capture support
--with-wingate Wingate support --with-wingate Wingate support
__EOT__ __EOT__
exit 0 exit 0
@@ -1186,6 +1193,13 @@ test "$ft_uptime" && echo "$ft_uptime" && ans=$ft_uptime
test -z "$ft_uptime" && read ans test -z "$ft_uptime" && read ans
test -z "$ans" -o "$ans" = y -o "$ans" = Y -o "$ans" = yes -o "$ans" = YES -o "$ans" = Yes && def_uptime='#define UPTIME' test -z "$ans" -o "$ans" = y -o "$ans" = Y -o "$ans" = yes -o "$ans" = YES -o "$ans" = Yes && def_uptime='#define UPTIME'
def_urlcapture='#undef URLCAPTURE'
unset ans
echo $ac_n "URL capture support? ....................... [Y/n] "$ac_c
test "$ft_urlcapture" && echo "$ft_urlcapture" && ans=$ft_urlcapture
test -z "$ft_urlcapture" && read ans
test -z "$ans" -o "$ans" = y -o "$ans" = Y -o "$ans" = yes -o "$ans" = YES -o "$ans" = Yes && def_urlcapture='#define URLCAPTURE'
def_wingate='#undef WINGATE' def_wingate='#undef WINGATE'
unset ans unset ans
echo $ac_n "WinGate support? ........................... [Y/n] "$ac_c echo $ac_n "WinGate support? ........................... [Y/n] "$ac_c
@@ -1265,6 +1279,7 @@ s|@DEF_REDIRECT@|$def_redirect|;
s|@DEF_TOYBOX@|$def_toybox|; s|@DEF_TOYBOX@|$def_toybox|;
s|@DEF_TRIVIA@|$def_trivia|; s|@DEF_TRIVIA@|$def_trivia|;
s|@DEF_UPTIME@|$def_uptime|; s|@DEF_UPTIME@|$def_uptime|;
s|@DEF_URLCAPTURE@|$def_urlcapture|;
s|@DEF_WEB@|$def_web|; s|@DEF_WEB@|$def_web|;
s|@DEF_WINGATE@|$def_wingate|; s|@DEF_WINGATE@|$def_wingate|;

View File

@@ -42,18 +42,20 @@ CHMOD = chmod
INCS = config.h mcmd.h defines.h global.h h.h structs.h text.h INCS = config.h mcmd.h defines.h global.h h.h structs.h text.h
TESTFILES = aliastest safepathtest
OFILES = alias.o auth.o bounce.o chanban.o channel.o core.o \ OFILES = alias.o auth.o bounce.o chanban.o channel.o core.o \
ctcp.o debug.o dns.o dynamode.o function.o greet.o help.o hostinfo.o irc.o \ ctcp.o debug.o dns.o dynamode.o function.o greet.o help.o hostinfo.o irc.o \
kicksay.o main.o net.o net_chan.o note.o notify.o ons.o parse.o \ kicksay.o main.o net.o net_chan.o note.o notify.o ons.o parse.o \
perl.o prot.o python.o redirect.o reset.o seen.o shit.o socket.o \ perl.o prot.o python.o redirect.o reset.o seen.o shit.o socket.o \
spy.o stats.o tcl.o telnet.o toybox.o trivia.o uptime.o \ spy.o stats.o tcl.o telnet.o toybox.o trivia.o uptime.o urlcap.o \
user.o vars.o web.o @MD5_O@ @SHA_O@ user.o vars.o web.o @MD5_O@ @SHA_O@
SRCFILES = alias.c auth.c bounce.c chanban.c channel.c core.c \ SRCFILES = alias.c auth.c bounce.c chanban.c channel.c core.c \
ctcp.c debug.c dns.c dynamode.c function.c greet.c help.c hostinfo.c irc.c \ ctcp.c debug.c dns.c dynamode.c function.c greet.c help.c hostinfo.c irc.c \
kicksay.c main.c net.c net_chan.c note.c notify.c ons.c parse.c \ kicksay.c main.c net.c net_chan.c note.c notify.c ons.c parse.c \
perl.c prot.c python.c redirect.c reset.c seen.c shit.c socket.c \ perl.c prot.c python.c redirect.c reset.c seen.c shit.c socket.c \
spy.c stats.c tcl.c telnet.c toybox.c trivia.c uptime.c \ spy.c stats.c tcl.c telnet.c toybox.c trivia.c uptime.c urlcap.c \
user.c vars.c web.c user.c vars.c web.c
all: $(INSTALLNAME) all: $(INSTALLNAME)
@@ -72,7 +74,7 @@ install: $(INSTALLNAME)
$(MV) $(INSTALLNAME) $(INSTALLDIR) $(MV) $(INSTALLNAME) $(INSTALLDIR)
clean: FORCE clean: FORCE
$(RM) $(INSTALLNAME) gencmd mcmd.h core aliastest $(OFILES) $(RM) $(INSTALLNAME) gencmd mcmd.h core $(TESTFILES) $(OFILES)
$(INSTALLNAME): $(OFILES) $(INSTALLNAME): $(OFILES)
$(CROSS_COMPILE)$(CC) $(LFLAGS) -o $(INSTALLNAME) $(OFILES) $(LPROF) $(LIBS) $(LDSCRIPT) $(CROSS_COMPILE)$(CC) $(LFLAGS) -o $(INSTALLNAME) $(OFILES) $(LPROF) $(LIBS) $(LDSCRIPT)
@@ -109,8 +111,15 @@ mega-static: $(SRCFILES) $(INCS) usage.h
# testing stuff # testing stuff
# #
test: $(TESTFILES)
./aliastest
./safepathtest
aliastest: alias.c aliastest: alias.c
$(CROSS_COMPILE)$(CC) $(CFLAGS) -o aliastest $< $(LPROF) $(LIBS) $(LDSCRIPT) -DALIASTEST $(CROSS_COMPILE)$(CC) $(CFLAGS) -o aliastest $< $(LPROF) $(LIBS) $(LDSCRIPT) -DTEST
safepathtest: function.c
$(CROSS_COMPILE)$(CC) $(CFLAGS) -o safepathtest $< $(LPROF) $(LIBS) $(LDSCRIPT) -DTEST
# #
# #
@@ -230,6 +239,9 @@ trivia.o: trivia.c $(INCS)
uptime.o: uptime.c $(INCS) uptime.o: uptime.c $(INCS)
$(CROSS_COMPILE)$(CC) $(CFLAGS) -c $< $(CPROF) $(CROSS_COMPILE)$(CC) $(CFLAGS) -c $< $(CPROF)
urlcap.o: urlcap.c $(INCS)
$(CROSS_COMPILE)$(CC) $(CFLAGS) -c $< $(CPROF)
user.o: user.c $(INCS) user.o: user.c $(INCS)
$(CROSS_COMPILE)$(CC) $(CFLAGS) -c $< $(CPROF) $(CROSS_COMPILE)$(CC) $(CFLAGS) -c $< $(CPROF)

View File

@@ -23,29 +23,17 @@
#ifdef ALIAS #ifdef ALIAS
#include "defines.h" #include "defines.h"
#include "structs.h" #include "structs.h"
#ifdef ALIASTEST #ifdef TEST
#define MAIN_C #define MAIN_C
#endif #endif
#include "global.h" #include "global.h"
#ifndef ALIASTEST
#include "h.h" #include "h.h"
#include "text.h" #include "text.h"
#include "mcmd.h" #include "mcmd.h"
#else /* ALIASTEST */
void afmt(char *, const char *, const char *); #ifdef TEST
void debug(char *format, ...) #include "debug.c"
{
va_list msg;
va_start(msg,format);
vsprintf(debugbuf,format,msg);
va_end(msg);
write(1,debugbuf,strlen(debugbuf));
}
char result[MSGLEN]; char result[MSGLEN];
char *input = "alias one two three four five six seven eight nine ten"; char *input = "alias one two three four five six seven eight nine ten";
@@ -60,6 +48,8 @@ void testcase(const char *test, const char *expect)
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
char *format = argv[1]; char *format = argv[1];
dodebug = 1;
strcpy(CurrentNick,"noob"); strcpy(CurrentNick,"noob");
if (format == NULL) if (format == NULL)
{ {
@@ -89,7 +79,7 @@ int main(int argc, char **argv)
exit(0); exit(0);
} }
#endif /* ALIASTEST */ #endif /* TEST */
/* /*
* copy_to = buffer to put resulting new command into * copy_to = buffer to put resulting new command into
@@ -160,7 +150,9 @@ void afmt(char *copy_to, const char *src, const char *input)
} }
} }
#ifdef DEBUG #ifdef DEBUG
#ifndef TEST
debug("(afmt) args #%i-#%i, characters %i-%i\n",startnum,endnum,argstart-input,argend-input); debug("(afmt) args #%i-#%i, characters %i-%i\n",startnum,endnum,argstart-input,argend-input);
#endif /* ifndef TEST */
#endif /* DEBUG */ #endif /* DEBUG */
while(*argstart && argstart < argend && dest <= BUFTAIL) while(*argstart && argstart < argend && dest <= BUFTAIL)
*(dest++) = *(argstart++); *(dest++) = *(argstart++);
@@ -172,11 +164,13 @@ void afmt(char *copy_to, const char *src, const char *input)
} }
*dest = 0; *dest = 0;
#ifdef DEBUG #ifdef DEBUG
#ifndef TEST
debug("(afmt) start %i end %i spc %i\n",startnum,endnum,spc); debug("(afmt) start %i end %i spc %i\n",startnum,endnum,spc);
#endif /* ifndef TEST */
#endif /* DEBUG */ #endif /* DEBUG */
} }
#ifndef ALIASTEST #ifndef TEST
/* /*
* *
@@ -290,6 +284,6 @@ void do_unalias(COMMAND_ARGS)
to_user(from,"Couldnt find matching alias"); to_user(from,"Couldnt find matching alias");
} }
#endif /* not ALIASTEST */ #endif /* not TEST */
#endif /* ALIAS */ #endif /* ALIAS */

View File

@@ -1,7 +1,7 @@
/* /*
EnergyMech, IRC bot software EnergyMech, IRC bot software
Parts Copyright (c) 1997-2009 proton Parts Copyright (c) 1997-2018 proton
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@@ -59,7 +59,7 @@ void check_idlekick(void)
} }
__attr (CORE_SEG, regparm(2)) __attr (CORE_SEG, regparm(2))
Chan *find_channel(char *name, int anychannel) Chan *find_channel(const char *name, int anychannel)
{ {
Chan *chan; Chan *chan;
uchar ni; uchar ni;
@@ -79,13 +79,13 @@ Chan *find_channel(char *name, int anychannel)
} }
__attr(CORE_SEG, __regparm (1)) __attr(CORE_SEG, __regparm (1))
Chan *find_channel_ac(char *name) Chan *find_channel_ac(const char *name)
{ {
return(find_channel(name,CHAN_ACTIVE)); return(find_channel(name,CHAN_ACTIVE));
} }
__attr(CORE_SEG, __regparm (1)) __attr(CORE_SEG, __regparm (1))
Chan *find_channel_ny(char *name) Chan *find_channel_ny(const char *name)
{ {
return(find_channel(name,CHAN_ANY)); return(find_channel(name,CHAN_ANY));
} }

View File

@@ -192,6 +192,11 @@
*/ */
@DEF_HOSTINFO@ @DEF_HOSTINFO@
/*
* URLCAPTURE: capture url's mentioned
*/
@DEF_URLCAPTURE@
/* /*
* FASTNICK: faster nick regain if the nick is seen when released * FASTNICK: faster nick regain if the nick is seen when released
* Enables code that is potentially dangerous if an attacker aquires * Enables code that is potentially dangerous if an attacker aquires

View File

@@ -551,7 +551,7 @@ void ctcp_dcc(char *from, char *to, char *rest)
debug("(ctcp_dcc) rest: `%s'\n",nullstr(rest)); debug("(ctcp_dcc) rest: `%s'\n",nullstr(rest));
#endif /* DEBUG */ #endif /* DEBUG */
filename = chop(&rest); filename = chop(&rest);
if (!is_safepath(filename)) if (is_safepath(filename,FILE_MUST_EXIST) != FILE_IS_SAFE)
{ {
#ifdef DEBUG #ifdef DEBUG
debug("(ctcp_dcc) filename `%s' is not safe\n",filename); debug("(ctcp_dcc) filename `%s' is not safe\n",filename);

View File

@@ -29,6 +29,8 @@
#include "h.h" #include "h.h"
#include "settings.h" #include "settings.h"
#ifndef TEST
#define boolstr(x) (x) ? "TRUE" : "FALSE" #define boolstr(x) (x) ? "TRUE" : "FALSE"
LS const char tabs[20] = "\t\t\t\t\t\t\t\t\t\t"; LS const char tabs[20] = "\t\t\t\t\t\t\t\t\t\t";
@@ -184,6 +186,9 @@ LS struct
{ init_uptime, "init_uptime" }, { init_uptime, "init_uptime" },
{ send_uptime, "send_uptime" }, { send_uptime, "send_uptime" },
#endif /* UPTIME */ #endif /* UPTIME */
#ifdef URLCAPTURE
{ urlcapture, "urlcapture" },
#endif /* URLCAPTURE */
{ 0, "(unknown)" }, { 0, "(unknown)" },
{ NULL, }}; { NULL, }};
@@ -1300,7 +1305,7 @@ int wrap_debug(void)
close(fd); close(fd);
debug_fd = backup_fd; debug_fd = backup_fd;
dodebug = backup_dodebug; dodebug = backup_dodebug;
debug("(wrap_debug) all done.\n"); debug("(wrap_debug) all done.\n");
return(1); return(1);
@@ -1314,6 +1319,8 @@ void do_debug(COMMAND_ARGS)
to_user(from,"Unable to write debug information to file"); to_user(from,"Unable to write debug information to file");
} }
#endif /* ifndef TEST */
void debug(char *format, ...) void debug(char *format, ...)
{ {
va_list msg; va_list msg;
@@ -1339,7 +1346,7 @@ void debug(char *format, ...)
} }
va_start(msg,format); va_start(msg,format);
vsprintf(debugbuf,format,msg); vsnprintf(debugbuf,sizeof(debugbuf),format,msg);
va_end(msg); va_end(msg);
if ((write(debug_fd,debugbuf,strlen(debugbuf))) < 0) if ((write(debug_fd,debugbuf,strlen(debugbuf))) < 0)

View File

@@ -1,7 +1,7 @@
/* /*
EnergyMech, IRC bot software EnergyMech, IRC bot software
Parts Copyright (c) 1997-2009 proton Parts Copyright (c) 1997-2018 proton
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@@ -161,6 +161,14 @@
#define IsChar(x) ((VarName[x].type & CHR_VAR) == CHR_VAR) #define IsChar(x) ((VarName[x].type & CHR_VAR) == CHR_VAR)
#define IsProc(x) (VarName[x].type & PROC_VAR) #define IsProc(x) (VarName[x].type & PROC_VAR)
/*
* is_safepath
*/
#define FILE_IS_SAFE 1
#define FILE_MUST_EXIST 1
#define FILE_MAY_EXIST 2
#define FILE_MUST_NOTEXIST 3
/* /*
* see settings.h for the actual setting struct * see settings.h for the actual setting struct
*/ */
@@ -264,6 +272,9 @@ enum {
STR_UPNICK, STR_UPNICK,
INT_UPPORT, INT_UPPORT,
#endif /* UPTIME */ #endif /* UPTIME */
#ifdef URLCAPTURE
INT_URLHISTMAX,
#endif /* URLCAPTURE */
STR_USERFILE, STR_USERFILE,
STR_VIRTUAL, STR_VIRTUAL,
#ifdef WEB #ifdef WEB
@@ -381,6 +392,9 @@ enum {
#define SPY_MESSAGE 5 #define SPY_MESSAGE 5
#define SPY_RAWIRC 6 #define SPY_RAWIRC 6
#define SPY_BOTNET 7 #define SPY_BOTNET 7
#ifdef URLCAPTURE
#define SPY_URL 8
#endif /* URLCAPTURE */
#define SPYF_ANY 1 #define SPYF_ANY 1
#define SPYF_CHANNEL (1 << SPY_CHANNEL) #define SPYF_CHANNEL (1 << SPY_CHANNEL)
@@ -388,6 +402,7 @@ enum {
#define SPYF_MESSAGE (1 << SPY_MESSAGE) #define SPYF_MESSAGE (1 << SPY_MESSAGE)
#define SPYF_RAWIRC (1 << SPY_RAWIRC) #define SPYF_RAWIRC (1 << SPY_RAWIRC)
#define SPYF_BOTNET (1 << SPY_BOTNET) #define SPYF_BOTNET (1 << SPY_BOTNET)
#define SPYF_URL (1 << SPY_URL)
/* /*
* notify defines * notify defines

View File

@@ -1,7 +1,7 @@
/* /*
EnergyMech, IRC bot software EnergyMech, IRC bot software
Parts Copyright (c) 1997-2009 proton Parts Copyright (c) 1997-2018 proton
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@@ -23,25 +23,19 @@
#include "defines.h" #include "defines.h"
#include "structs.h" #include "structs.h"
#ifdef TEST
#define MAIN_C
#endif
#include "global.h" #include "global.h"
#include "h.h" #include "h.h"
#include "text.h" #include "text.h"
#ifndef TEST
LS char timebuf[24]; /* max format lentgh == 20+1, round up to nearest longword -> 24 */ LS char timebuf[24]; /* max format lentgh == 20+1, round up to nearest longword -> 24 */
LS char idlestr[36]; /* max format lentgh == 24+1, round up to nearest longword -> 28 */ LS char idlestr[36]; /* max format lentgh == 24+1, round up to nearest longword -> 28 */
LS const char monlist[12][4] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
LS const char monlist[12][4] = LS const char daylist[7][4] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
{
"Jan", "Feb", "Mar", "Apr",
"May", "Jun", "Jul", "Aug",
"Sep", "Oct", "Nov", "Dec"
};
LS const char daylist[7][4] =
{
"Sun", "Mon", "Tue", "Wed",
"Thu", "Fri", "Sat"
};
/* /*
* memory allocation routines * memory allocation routines
@@ -493,7 +487,7 @@ char *cluster(char *hostname)
} }
else else
{ {
/* /*
* its not a numeric mask * its not a numeric mask
*/ */
p = mask; p = mask;
@@ -841,7 +835,8 @@ char *Strchr(const char *t, int c)
return((*t == ch) ? (char*)t : NULL); return((*t == ch) ? (char*)t : NULL);
} }
char *Strdup(char *src) __attr(CORE_SEG,__regparm(1))
char *Strdup(const char *src)
{ {
char *dest; char *dest;
@@ -1064,6 +1059,8 @@ void table_send(const char *from, const int space)
e_table = NULL; e_table = NULL;
} }
#ifdef OLDCODE
int is_safepath(const char *path) int is_safepath(const char *path)
{ {
struct stat st; struct stat st;
@@ -1097,3 +1094,125 @@ int is_safepath(const char *path)
} }
return(path_token_check() == 1 ? TRUE : FALSE); return(path_token_check() == 1 ? TRUE : FALSE);
} }
#endif
#endif /* ifndef TEST at the beginning of file */
#define FILE_MUST_EXIST 1
#define FILE_MAY_EXIST 2
#define FILE_MUST_NOTEXIST 3
__attr(CORE_SEG,__regparm(2))
int is_safepath(const char *path, int filemustexist)
{
struct stat st;
ino_t ino;
char tmp[PATH_MAX];
const char *src;
char *dst;
int r,mo,dir_r,orr,oerrno;
#ifdef TEST
memset(&st,0,sizeof(st));
#endif
if (*(src = path) == '/') // dont allow starting at root, only allow relative paths
return(-1);//(FALSE);
if (strlen(path) >= PATH_MAX)
return(-6);
orr = lstat(path,&st);
oerrno = errno;
if (filemustexist == FILE_MUST_EXIST && orr == -1 && errno == ENOENT)
return(-2);
if (filemustexist == FILE_MUST_NOTEXIST && orr == 0)
return(-3);
mo = st.st_mode; // save mode for later
dir_r = -1;
for(dst=tmp;*src;)
{
if (*src == '/')
{
*dst = 0;
if ((dir_r = lstat(tmp,&st)) == -1 && errno == ENOENT)
return(-7);
if (!(S_ISREG(st.st_mode) || S_ISDIR(st.st_mode))) // disallow all except regular files and directories
return(-4);
if (st.st_ino == parent_inode) // disallow traversing below bots homedir
return(-5);
}
if (dst == tmp + PATH_MAX-1)
return(-6);
*dst++ = *src++;
}
if (filemustexist != FILE_MUST_EXIST && orr == -1 && oerrno == ENOENT)
return(TRUE);
return (S_ISREG(mo)) ? TRUE : FALSE;
}
#ifdef TEST
#include "debug.c"
#define P0 "verylongexcessivelengthfilenamegibberish"
#define P1 P0 "/" P0 "/" P0 "/" P0 "/" P0 "/" P0 "/" P0 "/" P0 "/" P0 "/" P0 "/"
#define P2 P1 P1 P1 P1 P1 P1 P1 P1 P1 P1 P1 P1 P1 P1 P1 P1 P1 P1 P1 P1 P1 P1 P0
char *tostr[] = { "ZERO", "FILE_MUST_EXIST", "FILE_MAY_EXIST", "FILE_MUST_NOTEXIST" };
void testcase(const char *str, int expected, int filemustexist)
{
int r;
r = is_safepath(str,filemustexist);
if (r == expected)
{
debug("testcase SUCCESS: testpath %s %s -> result %i\n",
(strlen(str)>50) ? "(very long string)" : str,tostr[filemustexist],r);
}
else
{
debug("testcase FAIL: testpath %s(%i) %s -> result %i, expected %i\n",
(strlen(str)>50) ? "(very long string)" : str,
strlen(str),tostr[filemustexist],r,expected);//(r) ? "TRUE" : "FALSE",(expected) ? "TRUE" : "FALSE");
}
}
int main(int argc, char **argv)
{
struct stat st;
int r;
dodebug = 1;
stat("../..",&st);
parent_inode = st.st_ino; // used for is_safepath()
debug("PATH_MAX = %i\n",PATH_MAX);
if (argv[1] == NULL)
{
testcase("/etc/passwd",-1,FILE_MAY_EXIST);
testcase("../../../../../../../../../../../etc/passwd",-5,FILE_MAY_EXIST);
testcase("../anyparentfile",1,FILE_MAY_EXIST);
testcase("../../anyparentparentfile",-5,FILE_MAY_EXIST);
testcase("function.c",TRUE,FILE_MUST_EXIST);
testcase("./function.c",TRUE,FILE_MUST_EXIST);
testcase("function.c",-3,FILE_MUST_NOTEXIST);
testcase("./function.c",-3,FILE_MUST_NOTEXIST);
testcase("nosuchfile",1,FILE_MAY_EXIST);
testcase("nosuchfile",1,FILE_MUST_NOTEXIST);
testcase("./nosuchfile",1,FILE_MUST_NOTEXIST);
testcase("../../nosuchfile",-5,FILE_MUST_NOTEXIST);
testcase(P2,-6,FILE_MAY_EXIST);
exit(0);
}
r = is_safepath(argv[1],FILE_MAY_EXIST);
debug("testpath %s -> result %s\n",argv[1],(r) ? "TRUE" : "FALSE");
}
#endif /* TEST */

View File

@@ -91,6 +91,9 @@ struct
#ifdef SEEN #ifdef SEEN
{ 0, "SEEN", "do_seen", 20 | CCPW | CBANG }, { 0, "SEEN", "do_seen", 20 | CCPW | CBANG },
#endif /* SEEN */ #endif /* SEEN */
#ifdef URLCAPTURE
{ 0, "URLHIST", "do_urlhist", 20 | CCPW | REDIR | LBUF },
#endif /* ifdef URLCAPTURE */
/* /*
* Level 40 * Level 40
@@ -276,7 +279,7 @@ int main(int argc, char **argv)
ct = 0; ct = 0;
printf("/""* This file is automatically generated from gencmd.c *""/\n"); printf("/""* This file is automatically generated from gencmd.c *""/\n");
printf("#ifndef MCMD_H\n#define MCMD_H 1\n\n"); printf("#ifndef TEST\n#ifndef MCMD_H\n#define MCMD_H 1\n\n");
while(pass) while(pass)
{ {
@@ -401,6 +404,7 @@ int main(int argc, char **argv)
printf("extern OnMsg_access acmd[];\n\n"); printf("extern OnMsg_access acmd[];\n\n");
printf("#endif /""* MAIN_C *""/\n\n"); printf("#endif /""* MAIN_C *""/\n\n");
printf("#endif /""* MCMD_H *""/\n\n"); printf("#endif /""* MCMD_H *""/\n\n");
printf("#endif /""* TEST *""/\n\n");
unlink("usercombo.h"); unlink("usercombo.h");
of = fopen("usercombo.h","w"); of = fopen("usercombo.h","w");

View File

@@ -41,7 +41,7 @@
#define MECHUSERLOGIN "v3.energymech.net" #define MECHUSERLOGIN "v3.energymech.net"
BEG const char VERSION[] MDEF("3.0.99p4"); BEG const char VERSION[] MDEF("3.0.99p4");
BEG const char SRCDATE[] MDEF("March 9th, 2018"); BEG const char SRCDATE[] MDEF("March 13th, 2018");
#ifdef __CYGWIN__ #ifdef __CYGWIN__
BEG const char BOTCLASS[] MDEF("WinMech"); BEG const char BOTCLASS[] MDEF("WinMech");
#else /* ! CYGWIN */ #else /* ! CYGWIN */
@@ -63,10 +63,15 @@ BEG const char __SPYSTR_RAWIRC[] MDEF("rawirc");
BEG const char __SPYSTR_MESSAGE[] MDEF("message"); BEG const char __SPYSTR_MESSAGE[] MDEF("message");
BEG const char __SPYSTR_STATUS[] MDEF("status"); BEG const char __SPYSTR_STATUS[] MDEF("status");
BEG const char __SPYSTR_BOTNET[] MDEF("botnet"); BEG const char __SPYSTR_BOTNET[] MDEF("botnet");
#define SPYSTR_RAWIRC (char*)__SPYSTR_RAWIRC #define SPYSTR_RAWIRC __SPYSTR_RAWIRC
#define SPYSTR_MESSAGE (char*)__SPYSTR_MESSAGE #define SPYSTR_MESSAGE __SPYSTR_MESSAGE
#define SPYSTR_STATUS (char*)__SPYSTR_STATUS #define SPYSTR_STATUS __SPYSTR_STATUS
#define SPYSTR_BOTNET (char*)__SPYSTR_BOTNET #define SPYSTR_BOTNET __SPYSTR_BOTNET
#ifdef URLCAPTURE
BEG const char __SPYSTR_URL[] MDEF("url");
#define SPYSTR_URL __SPYSTR_URL
#endif /* URLCAPTURE */
BEG const char STR_MECHRESET[] MDEF("MECHRESET="); BEG const char STR_MECHRESET[] MDEF("MECHRESET=");
@@ -110,7 +115,6 @@ BEG User __internal_users[2];
* (functions that do not call any other non-trivial functions) * (functions that do not call any other non-trivial functions)
*/ */
BEG char gsockdata[MAXLEN]; BEG char gsockdata[MAXLEN];
BEG char nick_buf[MAXHOSTLEN]; BEG char nick_buf[MAXHOSTLEN];
BEG char nuh_buf[NUHLEN]; BEG char nuh_buf[NUHLEN];
@@ -139,10 +143,6 @@ BEG Alias *aliaslist MDEF(NULL);
#endif /* ALIAS */ #endif /* ALIAS */
#ifdef UPTIME
BEG char *defaultuptimehost MDEF("uptime.energymech.net");
#endif /* UPTIME */
#ifdef BOTNET #ifdef BOTNET
BEG const char UNKNOWNATUNKNOWN[] MDEF("unknown@unknown"); BEG const char UNKNOWNATUNKNOWN[] MDEF("unknown@unknown");
@@ -191,11 +191,17 @@ BEG Note *notelist MDEF(NULL);
#endif /* NOTE */ #endif /* NOTE */
#ifdef SCRIPTING #ifdef RAWDNS
BEG Hook *hooklist MDEF(NULL); BEG dnsList *dnslist MDEF(NULL);
BEG dnsAuthority *dnsroot MDEF(NULL);
BEG struct in_addr ia_ns[MAX_NAMESERVERS];
BEG struct in_addr ia_default;
#endif /* SCRIPTING */ #ifdef SESSION
BEG Strp *dnsrootfiles MDEF(NULL);
#endif /* SESSION */
#endif /* RAWDNS */
#ifdef REDIRECT #ifdef REDIRECT
@@ -211,6 +217,12 @@ LS struct
#endif /* REDIRECT */ #endif /* REDIRECT */
#ifdef SCRIPTING
BEG Hook *hooklist MDEF(NULL);
#endif /* SCRIPTING */
#ifdef SEEN #ifdef SEEN
BEG char *seenfile MDEF(NULL); /* proc var */ BEG char *seenfile MDEF(NULL); /* proc var */
@@ -237,9 +249,17 @@ BEG ulong uptimeip MDEF((ulong)-1);
BEG ulong uptimecookie; BEG ulong uptimecookie;
BEG ulong uptimeregnr MDEF(0); BEG ulong uptimeregnr MDEF(0);
BEG time_t uptimelast MDEF(0); BEG time_t uptimelast MDEF(0);
BEG const char *defaultuptimehost MDEF("uptime.energymech.net");
#endif /* UPTIME */ #endif /* UPTIME */
#ifdef URLCAPTURE
BEG int urlhistmax MDEF(20); /* proc var */
BEG Strp *urlhistory MDEF(NULL);
#endif /* URLCAPTURE */
#ifdef WEB #ifdef WEB
BEG int websock MDEF(-1); BEG int websock MDEF(-1);
@@ -247,17 +267,6 @@ BEG int webport MDEF(0);
#endif /* WEB */ #endif /* WEB */
#ifdef RAWDNS
BEG dnsList *dnslist MDEF(NULL);
BEG dnsAuthority *dnsroot MDEF(NULL);
BEG struct in_addr ia_ns[MAX_NAMESERVERS];
BEG struct in_addr ia_default;
#ifdef SESSION
BEG Strp *dnsrootfiles MDEF(NULL);
#endif /* SESSION */
#endif /* RAWDNS */
#ifndef I_HAVE_A_LEGITIMATE_NEED_FOR_MORE_THAN_4_BOTS #ifndef I_HAVE_A_LEGITIMATE_NEED_FOR_MORE_THAN_4_BOTS

View File

@@ -130,7 +130,7 @@ void do_greet(COMMAND_ARGS)
{ {
if (isfile) if (isfile)
{ {
if (!is_safepath(rest)) if (is_safepath(rest,FILE_MUST_EXIST) != FILE_IS_SAFE)
goto usage; goto usage;
} }

26
src/h.h
View File

@@ -1,7 +1,7 @@
/* /*
EnergyMech, IRC bot software EnergyMech, IRC bot software
Copyright (c) 1997-2009 proton Copyright (c) 1997-2018 proton
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@@ -107,9 +107,9 @@
#endif /* DEBUG */ #endif /* DEBUG */
LS Chan *find_channel(char *, int) __attr(CORE_SEG, __regparm (2) ); LS Chan *find_channel(const char *, int) __attr(CORE_SEG, __regparm (2) );
LS Chan *find_channel_ac(char *) __attr(CORE_SEG, __regparm (1) ); LS Chan *find_channel_ac(const char *) __attr(CORE_SEG, __regparm (1) );
LS Chan *find_channel_ny(char *) __attr(CORE_SEG, __regparm (1) ); LS Chan *find_channel_ny(const char *) __attr(CORE_SEG, __regparm (1) );
LS ChanUser *find_chanuser(Chan *, const char *) __attr(CORE_SEG, __regparm (2) ); LS ChanUser *find_chanuser(Chan *, const char *) __attr(CORE_SEG, __regparm (2) );
LS Client *find_client(const char *) __page(CORE_SEG); LS Client *find_client(const char *) __page(CORE_SEG);
LS Mech *add_bot(int, char *) __page(CORE_SEG); LS Mech *add_bot(int, char *) __page(CORE_SEG);
@@ -121,13 +121,13 @@ LS Shit *add_shit(char *, char *, char *, char *, int, int) __page(CMD1_SEG);
LS Shit *find_shit(const char *, const char *) __page(CORE_SEG); LS Shit *find_shit(const char *, const char *) __page(CORE_SEG);
LS Shit *get_shituser(char *, char *) __page(CORE_SEG); LS Shit *get_shituser(char *, char *) __page(CORE_SEG);
LS User *add_user(char *, char *, int) __page(CFG1_SEG); LS User *add_user(char *, char *, int) __page(CFG1_SEG);
LS User *find_handle(char *) __page(CORE_SEG); LS User *find_handle(const char *) __page(CORE_SEG);
LS User *get_authuser(char *, char *) __page(CORE_SEG); LS User *get_authuser(char *, char *) __page(CORE_SEG);
LS User *get_user(const char *, const char *) __page(CORE_SEG); LS User *get_user(const char *, const char *) __page(CORE_SEG);
LS int get_authaccess(char *, char *) __page(CORE_SEG); LS int get_authaccess(char *, char *) __page(CORE_SEG);
LS int get_protaction(Chan *, char *) __page(CORE_SEG); LS int get_protaction(Chan *, char *) __page(CORE_SEG);
LS int get_shitaction(const char *, const char *) __page(CORE_SEG); LS int get_shitaction(const char *, const char *) __page(CORE_SEG);
LS int get_useraccess(char *, char *) __page(CORE_SEG); LS int get_useraccess(const char *, const char *) __page(CORE_SEG);
LS int get_maxaccess(const char *) __page(CORE_SEG); LS int get_maxaccess(const char *) __page(CORE_SEG);
LS int Strcasecmp(const char *, const char *) __att2(CORE_SEG, const, __regparm (2) ); LS int Strcasecmp(const char *, const char *) __att2(CORE_SEG, const, __regparm (2) );
@@ -135,7 +135,7 @@ LS int Strcmp(const char *, const char *) __att2(CORE_SEG, const, __regparm (2
LS char *Strcat(char *, const char *) __attr(CORE_SEG, __regparm (2) ); LS char *Strcat(char *, const char *) __attr(CORE_SEG, __regparm (2) );
LS char *Strchr(const char *, int) __att2(CORE_SEG, const, __regparm (2) ); LS char *Strchr(const char *, int) __att2(CORE_SEG, const, __regparm (2) );
LS char *Strcpy(char *, const char *) __attr(CORE_SEG, __regparm (2) ); LS char *Strcpy(char *, const char *) __attr(CORE_SEG, __regparm (2) );
LS char *Strdup(char *) __page(CORE_SEG); LS char *Strdup(const char *) __attr(CORE_SEG, __regparm (1) );
LS void Strncpy(char *, const char *, int) __attr(CORE_SEG, __regparm (3) ); LS void Strncpy(char *, const char *, int) __attr(CORE_SEG, __regparm (3) );
LS char *chop(char **) __attr(CORE_SEG, __regparm (1) ); LS char *chop(char **) __attr(CORE_SEG, __regparm (1) );
LS int get_number(const char *) __page(CORE_SEG); LS int get_number(const char *) __page(CORE_SEG);
@@ -214,7 +214,7 @@ LS const int Strlen2(const char *, const char *) __attr(CORE_SEG, __regparm (2)
LS int matches(const char *, const char *) __att2(CORE_SEG, const, __regparm (2) ); LS int matches(const char *, const char *) __att2(CORE_SEG, const, __regparm (2) );
LS int num_matches(const char *, const char *) __att2(CORE_SEG, const, __regparm (2) ); LS int num_matches(const char *, const char *) __att2(CORE_SEG, const, __regparm (2) );
LS int a2i(char *) __attr(CORE_SEG, __regparm (1) ); LS int a2i(char *) __attr(CORE_SEG, __regparm (1) );
LS int is_safepath(const char *) __page(CORE_SEG); LS int is_safepath(const char *, int) __attr(CORE_SEG, __regparm (2) );
LS void afmt(char *, const char *, const char *) __page(CMD1_SEG); LS void afmt(char *, const char *, const char *) __page(CMD1_SEG);
LS void aucheck(User *) __attr(CORE_SEG, __regparm (1) ); LS void aucheck(User *) __attr(CORE_SEG, __regparm (1) );
@@ -398,6 +398,9 @@ LS void parse_mode(char *, char *) __page(CORE_SEG);
LS void parse_notice(char *, char *) __page(CORE_SEG); LS void parse_notice(char *, char *) __page(CORE_SEG);
LS void parse_part(char *, char *) __page(CORE_SEG); LS void parse_part(char *, char *) __page(CORE_SEG);
LS void parse_ping(char *, char *) __page(CORE_SEG); LS void parse_ping(char *, char *) __page(CORE_SEG);
#ifdef URLCAPTURE
LS void urlcapture(const char *) __page(CORE_SEG);
#endif /* URLCAPTURE */
LS void parse_privmsg(char *, char *) __page(CORE_SEG); LS void parse_privmsg(char *, char *) __page(CORE_SEG);
LS void parse_quit(char *, char *) __page(CORE_SEG); LS void parse_quit(char *, char *) __page(CORE_SEG);
LS void parse_topic(char *, char *) __page(CMD1_SEG); LS void parse_topic(char *, char *) __page(CMD1_SEG);
@@ -772,6 +775,13 @@ LS void uptime_death(int) __page(RARE_SEG); /* rare */
#endif /* UPTIME */ #endif /* UPTIME */
#ifdef URLCAPTURE
LS void urlcapture(const char *) __page(CORE_SEG);
LS void do_urlhist(COMMAND_ARGS) __page(CMD1_SEG);
#endif /* ifdef URLCAPTURE */
/* /*
* WEB prototypes * WEB prototypes
*/ */

View File

@@ -182,7 +182,7 @@ help_loop:
/* /*
* We dont want to show help for "../../../../../../etc/passwd" * We dont want to show help for "../../../../../../etc/passwd"
*/ */
if (!is_safepath(line)) if (is_safepath(line,FILE_MUST_EXIST) != FILE_IS_SAFE)
#ifdef DEBUG #ifdef DEBUG
{ {
debug("(do_help) unsafe help filename (%s), exiting\n",line); debug("(do_help) unsafe help filename (%s), exiting\n",line);

View File

@@ -31,6 +31,12 @@
#include <sys/utsname.h> #include <sys/utsname.h>
/*---Help:HOSTINFO:(no arguments)
Equivalent to ``uname -orm''
See also: meminfo, cpuinfo
*/
void do_hostinfo(COMMAND_ARGS) void do_hostinfo(COMMAND_ARGS)
{ {
struct utsname un; struct utsname un;
@@ -94,6 +100,19 @@ int parse_proc_status(char *line)
return(FALSE); return(FALSE);
} }
/*---Help:MEMINFO:(no arguments)
Will display memory usage of the energymech process.
VM Virtual size, size if everything was loaded into memory)
RSS Resident set size, physical memory actually in use right now.
Code Memory allocated for code
Data Memory allocated for data
Libs Memory used by shared libraries
Stack Memory allocated for stack
See also: hostinfo, cpuinfo
*/
void do_meminfo(COMMAND_ARGS) void do_meminfo(COMMAND_ARGS)
{ {
char fn[64]; char fn[64];
@@ -113,6 +132,10 @@ void do_meminfo(COMMAND_ARGS)
vmsize,vmpeak,vmrss,vmexe,vmdata,vmlib,vmstk); vmsize,vmpeak,vmrss,vmexe,vmdata,vmlib,vmstk);
} }
/*---Help:CPUINFO:(no arguments)
See also: hostinfo, meminfo
*/
void do_cpuinfo(COMMAND_ARGS) void do_cpuinfo(COMMAND_ARGS)
{ {
} }

View File

@@ -1,7 +1,7 @@
/* /*
EnergyMech, IRC bot software EnergyMech, IRC bot software
Parts Copyright (c) 1997-2009 proton Parts Copyright (c) 1997-2018 proton
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@@ -774,6 +774,7 @@ int main(int argc, char **argv, char **envp) __attribute__ ((__sect(INIT_SEG)));
#endif #endif
int main(int argc, char **argv, char **envp) int main(int argc, char **argv, char **envp)
{ {
struct stat st;
char *opt; char *opt;
int do_fork = TRUE; int do_fork = TRUE;
int versiononly = FALSE; int versiononly = FALSE;
@@ -786,15 +787,14 @@ int main(int argc, char **argv, char **envp)
_exit(1); _exit(1);
} }
{ stat("..",&st);
struct stat st; // allocate temporary parent_inode = st.st_ino; // used for is_safepath()
stat("..",&st);
parent_inode = st.st_ino; // used for is_safepath()
}
srand(now+getpid()); srand(now+getpid());
/*
* Code to detect and recover after a RESET
*/
while(*envp) while(*envp)
{ {
char *p1; char *p1;

View File

@@ -49,6 +49,7 @@
#include "toybox.c" #include "toybox.c"
#include "trivia.c" #include "trivia.c"
#include "uptime.c" #include "uptime.c"
#include "urlcap.c"
#include "user.c" #include "user.c"
#include "vars.c" #include "vars.c"
#include "web.c" #include "web.c"

View File

@@ -1,7 +1,7 @@
/* /*
EnergyMech, IRC bot software EnergyMech, IRC bot software
Parts Copyright (c) 1997-2009 proton Parts Copyright (c) 1997-2018 proton
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@@ -354,6 +354,9 @@ void parse_privmsg(char *from, char *rest)
{ {
ChanUser *cu; ChanUser *cu;
char *to,*channel; char *to,*channel;
#ifdef URLCAPTURE
const char *src;
#endif /* URLCAPTURE */
to = chop(&rest); to = chop(&rest);
if (*rest == ':') if (*rest == ':')
@@ -404,6 +407,24 @@ void parse_privmsg(char *from, char *rest)
if (CurrentChan && CurrentChan->stats) if (CurrentChan && CurrentChan->stats)
CurrentChan->stats->privmsg++; CurrentChan->stats->privmsg++;
#endif /* STATS */ #endif /* STATS */
#ifdef URLCAPTURE
src = rest;
while(*src)
{
if (tolowertab[*src] == 'h')
{
if (tolowertab[src[1]] == 't' && tolowertab[src[2]] == 't' && tolowertab[src[3]] == 'p')
{
if ((src[4] == ':') || // "http:"
(tolowertab[src[4]] == 's' && src[5] == ':')) // "https:"
{
urlcapture(src);
}
}
}
src++;
}
#endif /* URLCAPTURE */
on_msg(from,to,rest); on_msg(from,to,rest);
} }

View File

@@ -1,7 +1,7 @@
/* /*
EnergyMech, IRC bot software EnergyMech, IRC bot software
Copyright (c) 1997-2004 proton Copyright (c) 1997-2018 proton
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@@ -78,7 +78,7 @@ int begin_redirect(char *from, char *args)
to_user(from,"Missing name for redirect."); to_user(from,"Missing name for redirect.");
return(-1); return(-1);
} }
if (!is_safepath(nick)) if (is_safepath(nick,FILE_MAY_EXIST) != FILE_IS_SAFE) // redirect output is appended
{ {
to_user(from,"Bad filename."); to_user(from,"Bad filename.");
return(-1); return(-1);

View File

@@ -1,7 +1,7 @@
/* /*
EnergyMech, IRC bot software EnergyMech, IRC bot software
Copyright (c) 2001-2009 proton Copyright (c) 2001-2018 proton
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@@ -76,73 +76,76 @@ LS const Setting VarName[SIZE_VARS] =
/* /*
* all global variables * all global variables
*/ */
/* TYPE UACCES MIN DEFAULT NAME MAX */ /* TYPE UACCES MIN DEFAULT NAME MAX */
{ INT_GLOBAL, 40, 0, ZERO, "AAWAY", 1440 }, /* set auto-away after ___ minutes */ { INT_GLOBAL, 40, 0, ZERO, "AAWAY", 1440 }, /* set auto-away after ___ minutes */
{ STR_GLOBAL, 90, 0, VNULL, "ALTNICK" }, /* alternative nick */ { STR_GLOBAL, 90, 0, VNULL, "ALTNICK" }, /* alternative nick */
#ifdef BOTNET #ifdef BOTNET
{ TOG_PROC, 90, 0, TOGPROC(autolink), "AUTOLINK", 1 }, /* establish links automagically */ { TOG_PROC, 90, 0, TOGPROC(autolink), "AUTOLINK", 1 }, /* establish links automagically */
#endif /* BOTNET */ #endif /* BOTNET */
#ifdef BOUNCE #ifdef BOUNCE
{ INT_PROC, 100, 0, INTPROC(bounce_port), "BNCPORT", 65535, (&new_port_bounce) }, /* irc proxy port to listen on */ { INT_PROC, 100, 0, INTPROC(bounce_port), "BNCPORT", 65535, (&new_port_bounce) }, /* irc proxy port to listen on */
#endif /* BOUNCE */ #endif /* BOUNCE */
{ TOG_GLOBAL, 90, 0, INTCAST(1), "CC", 1 }, /* require command char */ { TOG_GLOBAL, 90, 0, INTCAST(1), "CC", 1 }, /* require command char */
{ CHR_GLOBAL, 90, 1, CMDCHAR, "CMDCHAR", 255 }, /* command char */ { CHR_GLOBAL, 90, 1, CMDCHAR, "CMDCHAR", 255 }, /* command char */
#ifdef CTCP #ifdef CTCP
{ TOG_GLOBAL, 90, 0, INTCAST(1), "CTCP", 1 }, /* ctcp replies enable */ { TOG_GLOBAL, 90, 0, INTCAST(1), "CTCP", 1 }, /* ctcp replies enable */
#endif /* CTCP */ #endif /* CTCP */
{ INT_PROC, 100, 10, INTPROC(ctimeout), "CTIMEOUT", 3600 }, /* how long to wait between connect attempts */ { INT_PROC, 100, 10, INTPROC(ctimeout), "CTIMEOUT", 3600 }, /* how long to wait between connect attempts */
#ifdef DCC_FILE #ifdef DCC_FILE
{ INT_GLOBAL, 80, 0, ZERO, "DCCANON", 100 }, /* anonymous (non user) DCC slots */ { INT_GLOBAL, 80, 0, ZERO, "DCCANON", 100 }, /* anonymous (non user) DCC slots */
{ STR_GLOBAL, 80, 0, VNULL, "DCCFILES" }, /* string with space separated masks for auto-accepted filenames */ { STR_GLOBAL, 80, 0, VNULL, "DCCFILES" }, /* string with space separated masks for auto-accepted filenames */
{ INT_GLOBAL, 80, 0, INTCAST(4), "DCCUSER", 100 }, /* user DCC slots */ { INT_GLOBAL, 80, 0, INTCAST(4), "DCCUSER", 100 }, /* user DCC slots */
#endif /* DCC_FILE */ #endif /* DCC_FILE */
{ TOG_GLOBAL, 80, 0, ZERO, "ENFPASS", 1 }, /* disallow users with no passwords */ { TOG_GLOBAL, 80, 0, ZERO, "ENFPASS", 1 }, /* disallow users with no passwords */
{ STR_GLOBAL, 90, 0, VNULL, "IDENT" }, /* register with this in the `user' field */ { STR_GLOBAL, 90, 0, VNULL, "IDENT" }, /* register with this in the `user' field */
{ STR_GLOBAL, 90, 0, VNULL, "IRCNAME" }, /* register with this in the `real name' field */ { STR_GLOBAL, 90, 0, VNULL, "IRCNAME" }, /* register with this in the `real name' field */
#ifdef NOTIFY #ifdef NOTIFY
{ INT_GLOBAL, 80, 10, INTCAST(30), "ISONDELAY", 600 }, /* seconds between each ISON */ { INT_GLOBAL, 80, 10, INTCAST(30), "ISONDELAY", 600 }, /* seconds between each ISON */
#endif /* NOTIFY */ #endif /* NOTIFY */
#ifdef BOTNET #ifdef BOTNET
{ STR_PROC, 90, 0, STRPROC(linkpass), "LINKPASS" }, /* local process linkpass */ { STR_PROC, 90, 0, STRPROC(linkpass), "LINKPASS" }, /* local process linkpass */
{ INT_PROC, 100, 0, INTPROC(linkport), "LINKPORT", 65535 }, /* listen on <linkport> for botnet connections */ { INT_PROC, 100, 0, INTPROC(linkport), "LINKPORT", 65535 }, /* listen on <linkport> for botnet connections */
#endif /* BOTNET */ #endif /* BOTNET */
{ INT_GLOBAL, 80, 1, INTCAST(3), "MODES", 20 }, /* max number of channel modes to send */ { INT_GLOBAL, 80, 1, INTCAST(3), "MODES", 20 }, /* max number of channel modes to send */
#ifdef BOTNET #ifdef BOTNET
{ TOG_GLOBAL, 90, 0, INTCAST(1), "NETUSERS", 1 }, /* this bot accepts shared users (on by default) */ { TOG_GLOBAL, 90, 0, INTCAST(1), "NETUSERS", 1 }, /* this bot accepts shared users (on by default) */
#endif /* BOTNET */ #endif /* BOTNET */
{ TOG_GLOBAL, 80, 0, ZERO, "NOIDLE", 1 }, /* dont idle */ { TOG_GLOBAL, 80, 0, ZERO, "NOIDLE", 1 }, /* dont idle */
#ifdef NOTIFY #ifdef NOTIFY
{ STR_GLOBAL, 80, 0, VNULL, "NOTIFYFILE" }, /* read notify settings from <notifyfile> */ { STR_GLOBAL, 80, 0, VNULL, "NOTIFYFILE" }, /* read notify settings from <notifyfile> */
#endif /* NOTIFY */ #endif /* NOTIFY */
{ TOG_GLOBAL, 90, 0, ZERO, "ONOTICE", 1 }, /* ircd has /notice @#channel */ { TOG_GLOBAL, 90, 0, ZERO, "ONOTICE", 1 }, /* ircd has /notice @#channel */
#ifdef TRIVIA #ifdef TRIVIA
{ CHR_PROC, 80, 0, CHRPROC(triv_qchar), "QCHAR" }, /* use <qchar> as mask char when displaying answer */ { CHR_PROC, 80, 0, CHRPROC(triv_qchar), "QCHAR" }, /* use <qchar> as mask char when displaying answer */
{ INT_PROC, 80, 1, INTPROC(triv_qdelay), "QDELAY", 3600 }, /* seconds between each question */ { INT_PROC, 80, 1, INTPROC(triv_qdelay), "QDELAY", 3600 }, /* seconds between each question */
{ STR_PROC, 80, 0, STRPROC(triv_qfile), "QFILE" }, /* load questions from <qfile> */ { STR_PROC, 80, 0, STRPROC(triv_qfile), "QFILE" }, /* load questions from <qfile> */
#endif /* TRIVIA */ #endif /* TRIVIA */
#ifdef CTCP #ifdef CTCP
{ TOG_GLOBAL, 80, 0, ZERO, "RF", 1 }, /* random ctcp finger reply */ { TOG_GLOBAL, 80, 0, ZERO, "RF", 1 }, /* random ctcp finger reply */
{ TOG_GLOBAL, 80, 0, ZERO, "RV", 1 }, /* random ctcp version reply */ { TOG_GLOBAL, 80, 0, ZERO, "RV", 1 }, /* random ctcp version reply */
#endif /* CTCP */ #endif /* CTCP */
#ifdef SEEN #ifdef SEEN
{ STR_PROC, 90, 0, STRPROC(seenfile), "SEENFILE" }, /* load/save seen database from <seenfile> */ { STR_PROC, 90, 0, STRPROC(seenfile), "SEENFILE" }, /* load/save seen database from <seenfile> */
#endif /* SEEN */ #endif /* SEEN */
{ STR_GLOBAL, 80, 0, VNULL, "SERVERGROUP" }, /* connect bot to a certain group of servers */ { STR_GLOBAL, 80, 0, VNULL, "SERVERGROUP" }, /* connect bot to a certain group of servers */
{ TOG_GLOBAL, 90, 0, ZERO, "SPY", 1 }, /* send info about executed commands to status channel */ { TOG_GLOBAL, 90, 0, ZERO, "SPY", 1 }, /* send info about executed commands to status channel */
{ STR_GLOBAL, 90, 0, VNULL, "UMODES" }, /* send these modes on connect */ { STR_GLOBAL, 90, 0, VNULL, "UMODES" }, /* send these modes on connect */
#ifdef UPTIME #ifdef UPTIME
{ STR_PROC, 100, 0, STRPROC(uptimehost), "UPHOST" }, /* send uptime packets to <uphost> */ { STR_PROC, 100, 0, STRPROC(uptimehost), "UPHOST" }, /* send uptime packets to <uphost> */
{ STR_PROC, 100, 0, STRPROC(uptimenick), "UPNICK" }, /* send <upnick> as identifier instead of bots nick */ { STR_PROC, 100, 0, STRPROC(uptimenick), "UPNICK" }, /* send <upnick> as identifier instead of bots nick */
{ INT_PROC, 100, 0, INTPROC(uptimeport), "UPPORT", 65535 }, /* send packets to port <upport> */ { INT_PROC, 100, 0, INTPROC(uptimeport), "UPPORT", 65535 }, /* send packets to port <upport> */
#ifdef URLCAPTURE
{ INT_PROC, 100, 0, INTPROC(urlhistmax), "URLHIST", 100 }, /* max # of url's to keep in history */
#endif /* URLCAPTURE */
#endif /* UPTIME */ #endif /* UPTIME */
{ STR_GLOBAL, 90, 0, VNULL, "USERFILE" }, /* what file to load/save userlist from/to */ { STR_GLOBAL, 90, 0, VNULL, "USERFILE" }, /* what file to load/save userlist from/to */
{ STR_GLOBAL, 90, 0, VNULL, "VIRTUAL", 0, (&var_resolve_host) }, /* visual host */ { STR_GLOBAL, 90, 0, VNULL, "VIRTUAL", 0, (&var_resolve_host) }, /* visual host */
#ifdef WEB #ifdef WEB
{ INT_PROC, 100, 0, INTPROC(webport), "WEBPORT", 65535 }, /* httpd should listen on... */ { INT_PROC, 100, 0, INTPROC(webport), "WEBPORT", 65535 }, /* httpd should listen on... */
#endif /* WEB */ #endif /* WEB */
#ifdef WINGATE #ifdef WINGATE
{ STR_GLOBAL, 90, 0, VNULL, "WINGATE", 0, (&var_resolve_host) }, /* wingate hostname */ { STR_GLOBAL, 90, 0, VNULL, "WINGATE", 0, (&var_resolve_host) }, /* wingate hostname */
{ INT_GLOBAL, 90, 0, ZERO, "WINGPORT", 65535 }, /* wingate port */ { INT_GLOBAL, 90, 0, ZERO, "WINGPORT", 65535 }, /* wingate port */
#endif /* WINGATE */ #endif /* WINGATE */
{ 0, }}; { 0, }};

View File

@@ -1,7 +1,7 @@
/* /*
EnergyMech, IRC bot software EnergyMech, IRC bot software
Parts Copyright (c) 1997-2004 proton Parts Copyright (c) 1997-2018 proton
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@@ -30,7 +30,7 @@
#ifdef DEBUG #ifdef DEBUG
LS const char SPY_DEFS[7][12] = LS const char SPY_DEFS[][12] =
{ {
"SPY_FILE", "SPY_FILE",
"SPY_CHANNEL", "SPY_CHANNEL",
@@ -38,7 +38,10 @@ LS const char SPY_DEFS[7][12] =
"SPY_STATUS", "SPY_STATUS",
"SPY_MESSAGE", "SPY_MESSAGE",
"SPY_RAWIRC", "SPY_RAWIRC",
"SPY_BOTNET" "SPY_BOTNET",
#ifdef URLCAPTURE
"SPY_URL",
#endif /* URLCAPTURE */
}; };
#endif /* DEBUG */ #endif /* DEBUG */
@@ -161,7 +164,7 @@ void spy_typecount(Mech *bot)
struct struct
{ {
char *idstring; const char *idstring;
int typenum; int typenum;
} spy_source_list[] = } spy_source_list[] =
@@ -170,13 +173,20 @@ struct
{ SPYSTR_MESSAGE, SPY_MESSAGE }, { SPYSTR_MESSAGE, SPY_MESSAGE },
{ SPYSTR_RAWIRC, SPY_RAWIRC }, { SPYSTR_RAWIRC, SPY_RAWIRC },
{ SPYSTR_BOTNET, SPY_BOTNET }, { SPYSTR_BOTNET, SPY_BOTNET },
#ifdef URLCAPTURE
{ SPYSTR_URL, SPY_URL },
#endif /* URLCAPTURE */
{ NULL, 0 }, { NULL, 0 },
}; };
int spy_source(char *from, int *t_src, char **src) int spy_source(char *from, int *t_src, const char **src)
{ {
int i; int i;
#ifdef DEBUG
debug("(spy_source) t_src %i, src %s\n",*t_src,*src);
#endif /* ifdef DEBUG */
for(i=0;spy_source_list[i].idstring;i++) for(i=0;spy_source_list[i].idstring;i++)
{ {
if (!Strcasecmp(*src,spy_source_list[i].idstring)) if (!Strcasecmp(*src,spy_source_list[i].idstring))
@@ -198,6 +208,31 @@ int spy_source(char *from, int *t_src, char **src)
* *
*/ */
/*---Help:SPY:[STATUS|MESSAGE|RAWIRC|URL|[guid:|botnick:] [channel|> filename]
Spy on a certain source of messages. When you join DCC chat,
the STATUS source is added by default as a spy source for you.
If no arguments are given, the current list of active spy
channels is shown. Output is not line buffered and can cause
excess flood if not careful.
(sources)
STATUS Status messages.
MESSAGE Pivate messages that the bot receives.
RAWIRC Lines received from irc server before processing.
URL URLs seen by the bot.
guid: Messages from a bot specified by guid.
botnick: Messages from a bot specified by nick.
channel Activities on the specified channel.
(destinations)
(none) Send output to you (default).
channel Send output to the specified channel.
>file Send output to file. Lines are appended to the end of the file.
This file needs to exist before logging to it.
See also: rspy
*/
void do_spy(COMMAND_ARGS) void do_spy(COMMAND_ARGS)
{ {
/* /*
@@ -205,10 +240,10 @@ void do_spy(COMMAND_ARGS)
*/ */
Spy *spy; Spy *spy;
Mech *backup,*destbot; Mech *backup,*destbot;
char *src,*dest; const char *src;
char *dest;
int t_src,t_dest; int t_src,t_dest;
int sz; int sz,r,guid;
int guid;
if (!*rest) if (!*rest)
{ {
@@ -291,9 +326,9 @@ guid_ok:
else else
{ {
sz = spy_source(from,&t_src,&src); sz = spy_source(from,&t_src,&src);
if (sz < 0) if (sz < 0) // user has insufficient access to source
goto spy_usage; goto spy_usage;
if (sz < cmdaccess) if (sz < cmdaccess) // user has less access relative to source than the command level of SPY
return; return;
} }
@@ -304,6 +339,7 @@ guid_ok:
*/ */
if (*dest == '>') if (*dest == '>')
{ {
// accept both ">file" and "> file"
dest++; dest++;
if (!*dest) if (!*dest)
{ {
@@ -314,8 +350,16 @@ guid_ok:
/* /*
* Dont just open anything. * Dont just open anything.
*/ */
if (!is_safepath(dest)) r = is_safepath(dest,FILE_MAY_EXIST);
if (r != FILE_IS_SAFE)
#ifdef DEBUG
{
debug("(do_spy) Filename \"%s\" was deemed unsafe (%i)\n",dest,r);
goto spy_usage; goto spy_usage;
}
#else
goto spy_usage;
#endif /* DEBUG */
t_dest = SPY_FILE; t_dest = SPY_FILE;
goto spy_dest_ok; goto spy_dest_ok;
} }
@@ -384,7 +428,7 @@ spy_dest_ok:
if (t_src == SPY_CHANNEL) if (t_src == SPY_CHANNEL)
{ {
Strcpy(spy->src,src); Strcpy((char*)spy->src,src);
} }
else else
{ {
@@ -434,7 +478,8 @@ void do_rspy(COMMAND_ARGS)
* on_msg checks: CARGS * on_msg checks: CARGS
*/ */
Spy *spy,**pspy; Spy *spy,**pspy;
char *src,*dest,*tmp; const char *src;
char *dest,*tmp;
int t_src,t_dest; int t_src,t_dest;
int n; int n;
@@ -468,18 +513,11 @@ rspy_usage:
goto rspy_usage; goto rspy_usage;
} }
/* /*
* Dont just open anything. * this is about removing an existing spy channel
* filename does not need to be checked because
* - if its a bogus filename, it wont match any open spy channels
* - if its a matching filename, its going to be removed right now
*/ */
if (!is_safepath(dest))
#ifdef NEWBIE
{
usage(from);
to_user(from,"File/path does not exist or is inaccessible");
return;
}
#else
goto rspy_usage;
#endif /* NEWBIE */
t_dest = SPY_FILE; t_dest = SPY_FILE;
goto rspy_dest_ok; goto rspy_dest_ok;
} }

View File

@@ -469,7 +469,7 @@ typedef struct Spy
Client *dcc; Client *dcc;
int destbot; int destbot;
char *src; const char *src;
char *dest; char *dest;
char p[2]; char p[2];

View File

@@ -1,7 +1,7 @@
/* /*
EnergyMech, IRC bot software EnergyMech, IRC bot software
Copyright (c) 1997-2004 proton Copyright (c) 1997-2018 proton
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@@ -101,7 +101,7 @@ void send_uptime(int type)
const char *server,*nick; const char *server,*nick;
int sz; int sz;
if (uptimeport == 0) if (uptimehost == NULL || uptimeport == 0)
return; return;
#ifdef RAWDNS #ifdef RAWDNS

120
src/urlcap.c Normal file
View File

@@ -0,0 +1,120 @@
/*
EnergyMech, IRC bot software
Copyright (c) 2018 proton
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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#define URLCAP_C
#include "config.h"
#ifdef URLCAPTURE
#include "defines.h"
#include "structs.h"
#include "global.h"
#include "h.h"
#include "text.h"
__page(CORE_SEG)
void urlcapture(const char *rest)
{
Strp *sp,*nx;
char *dest,url[MSGLEN];
int n;
dest = url;
while(*rest && *rest != ' ' && dest < url+MSGLEN-1)
*(dest++) = *(rest++);
*dest = 0;
#ifdef DEBUG
debug("(urlcapture) URL = \"%s\"\n",url);
#endif /* ifdef DEBUG */
send_spy(SPYSTR_URL,"%s",url);
if ((n = urlhistmax))
{
set_mallocdoer(urlcapture);
sp = (Strp*)Calloc(sizeof(Strp) + strlen(url));
Strcpy(sp->p,url);
sp->next = urlhistory;
urlhistory = sp;
for(sp=urlhistory;sp;sp=sp->next)
{
if (n <= 0)
{
do
{
nx = sp->next;
Free((char**)&sp);
sp = nx;
}
while(sp);
}
n--;
}
}
}
/*
*
* Commands associated with URLCAPTURE
*
*/
/*---Help:URLHIST:[max]
Display a list of URLs seen by the bot in order most recent to oldest.
[max] Maximum number of URLs to display.
*/
__page(CMD1_SEG)
void do_urlhist(COMMAND_ARGS)
{
Strp *sp;
char *thenum;
int n,maxnum;
if (urlhistory == NULL)
{
to_user(from,"No URLs recorded.");
return;
}
if (!rest || !*rest)
maxnum = urlhistmax;
else
{
thenum = chop(&rest);
maxnum = a2i(thenum);
}
if ((maxnum < 1) || (maxnum > urlhistmax))
usage(from); /* usage for CurrentCmd->name */
n = 1;
for(sp=urlhistory;sp;sp=sp->next)
{
if (n > maxnum)
break;
to_user(from,"[%i] %s",n,sp->p);
n++;
}
}
#endif /* ifdef URLCAPTURE */

View File

@@ -738,7 +738,7 @@ User *add_user(char *handle, char *pass, int axs)
/* /*
* find the user record for a named handle * find the user record for a named handle
*/ */
User *find_handle(char *handle) User *find_handle(const char *handle)
{ {
User *user; User *user;
@@ -803,7 +803,7 @@ User *get_user(const char *userhost, const char *channel)
/* /*
* highest channel on a given channel * highest channel on a given channel
*/ */
int get_useraccess(char *userhost, char *channel) int get_useraccess(const char *userhost, const char *channel)
{ {
User *user; User *user;