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/mcmd.h
src/usercombo.h
src/aliastest
src/safepathtest
*~
*.bak

View File

@ -92,6 +92,14 @@ mega: FORCE
mega-install: FORCE
$(MAKE) -C src mega-install
#
# code validation tests
#
test: FORCE
$(MAKE) -C src test
#
# 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)
* 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 configuration option: hostinfo
* Fixed: Custom ld script fintuning the core order.

19
configure vendored
View File

@ -79,6 +79,7 @@ do
toybox ) ft_toybox=$yesno ;;
trivia ) ft_trivia=$yesno ;;
uptime ) ft_uptime=$yesno ;;
urlcapture ) ft_urlcapture=$yesno ;;
web ) ft_web=$yesno ;;
wingate ) ft_wingate=$yesno ;;
esac
@ -109,7 +110,7 @@ do
case "$feature" in
debug | botnet | telnet | alias | seen | session | dyncmd | newbie | wingate | md5 | sha \
| 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
_yes_ | _no_ | __ )
;;
@ -193,6 +194,8 @@ do
trivia_no ) ft_trivia=no ;;
uptime_yes | uptime_ ) ft_uptime=yes ;;
uptime_no ) ft_uptime=no ;;
urlcapture_yes | urlcapture_ ) ft_urlcapture=yes ;;
urlcapture_no ) ft_urlcapture=no ;;
web_yes | web_ ) ft_web=yes ;;
web_no ) ft_web=no ;;
wingate_yes | wingate_ ) ft_wingate=yes ;;
@ -234,6 +237,7 @@ do
toybox ) ft_toybox=no ;;
trivia ) ft_trivia=no ;;
uptime ) ft_uptime=no ;;
urlcapture ) ft_urlcapture=no ;;
web ) ft_web=no ;;
wingate ) ft_wingate=no ;;
esac
@ -280,6 +284,7 @@ do
ft_toybox=yes
ft_trivia=yes
ft_uptime=yes
ft_urlcapture=yes
ft_web=yes
ft_wingate=yes
;;
@ -302,13 +307,15 @@ Features and packages:
--with-debug Debug support
--with-dyncmd Dynamic command levels support
--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-profiling Profiling (gcc+gprof)
--with-seen SEEN support
--with-session Session support
--with-tcl Tcl 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
__EOT__
exit 0
@ -1186,6 +1193,13 @@ test "$ft_uptime" && echo "$ft_uptime" && ans=$ft_uptime
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'
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'
unset ans
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_TRIVIA@|$def_trivia|;
s|@DEF_UPTIME@|$def_uptime|;
s|@DEF_URLCAPTURE@|$def_urlcapture|;
s|@DEF_WEB@|$def_web|;
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
TESTFILES = aliastest safepathtest
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 \
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 \
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@
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 \
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 \
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
all: $(INSTALLNAME)
@ -72,7 +74,7 @@ install: $(INSTALLNAME)
$(MV) $(INSTALLNAME) $(INSTALLDIR)
clean: FORCE
$(RM) $(INSTALLNAME) gencmd mcmd.h core aliastest $(OFILES)
$(RM) $(INSTALLNAME) gencmd mcmd.h core $(TESTFILES) $(OFILES)
$(INSTALLNAME): $(OFILES)
$(CROSS_COMPILE)$(CC) $(LFLAGS) -o $(INSTALLNAME) $(OFILES) $(LPROF) $(LIBS) $(LDSCRIPT)
@ -109,8 +111,15 @@ mega-static: $(SRCFILES) $(INCS) usage.h
# testing stuff
#
test: $(TESTFILES)
./aliastest
./safepathtest
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)
$(CROSS_COMPILE)$(CC) $(CFLAGS) -c $< $(CPROF)
urlcap.o: urlcap.c $(INCS)
$(CROSS_COMPILE)$(CC) $(CFLAGS) -c $< $(CPROF)
user.o: user.c $(INCS)
$(CROSS_COMPILE)$(CC) $(CFLAGS) -c $< $(CPROF)

View File

@ -23,29 +23,17 @@
#ifdef ALIAS
#include "defines.h"
#include "structs.h"
#ifdef ALIASTEST
#ifdef TEST
#define MAIN_C
#endif
#include "global.h"
#ifndef ALIASTEST
#include "h.h"
#include "text.h"
#include "mcmd.h"
#else /* ALIASTEST */
void afmt(char *, const char *, const char *);
#ifdef TEST
void debug(char *format, ...)
{
va_list msg;
va_start(msg,format);
vsprintf(debugbuf,format,msg);
va_end(msg);
write(1,debugbuf,strlen(debugbuf));
}
#include "debug.c"
char result[MSGLEN];
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)
{
char *format = argv[1];
dodebug = 1;
strcpy(CurrentNick,"noob");
if (format == NULL)
{
@ -89,7 +79,7 @@ int main(int argc, char **argv)
exit(0);
}
#endif /* ALIASTEST */
#endif /* TEST */
/*
* 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
#ifndef TEST
debug("(afmt) args #%i-#%i, characters %i-%i\n",startnum,endnum,argstart-input,argend-input);
#endif /* ifndef TEST */
#endif /* DEBUG */
while(*argstart && argstart < argend && dest <= BUFTAIL)
*(dest++) = *(argstart++);
@ -172,11 +164,13 @@ void afmt(char *copy_to, const char *src, const char *input)
}
*dest = 0;
#ifdef DEBUG
#ifndef TEST
debug("(afmt) start %i end %i spc %i\n",startnum,endnum,spc);
#endif /* ifndef TEST */
#endif /* DEBUG */
}
#ifndef ALIASTEST
#ifndef TEST
/*
*
@ -290,6 +284,6 @@ void do_unalias(COMMAND_ARGS)
to_user(from,"Couldnt find matching alias");
}
#endif /* not ALIASTEST */
#endif /* not TEST */
#endif /* ALIAS */

View File

@ -1,7 +1,7 @@
/*
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
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))
Chan *find_channel(char *name, int anychannel)
Chan *find_channel(const char *name, int anychannel)
{
Chan *chan;
uchar ni;
@ -79,13 +79,13 @@ Chan *find_channel(char *name, int anychannel)
}
__attr(CORE_SEG, __regparm (1))
Chan *find_channel_ac(char *name)
Chan *find_channel_ac(const char *name)
{
return(find_channel(name,CHAN_ACTIVE));
}
__attr(CORE_SEG, __regparm (1))
Chan *find_channel_ny(char *name)
Chan *find_channel_ny(const char *name)
{
return(find_channel(name,CHAN_ANY));
}

View File

@ -192,6 +192,11 @@
*/
@DEF_HOSTINFO@
/*
* URLCAPTURE: capture url's mentioned
*/
@DEF_URLCAPTURE@
/*
* FASTNICK: faster nick regain if the nick is seen when released
* 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));
#endif /* DEBUG */
filename = chop(&rest);
if (!is_safepath(filename))
if (is_safepath(filename,FILE_MUST_EXIST) != FILE_IS_SAFE)
{
#ifdef DEBUG
debug("(ctcp_dcc) filename `%s' is not safe\n",filename);

View File

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

View File

@ -1,7 +1,7 @@
/*
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
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 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
*/
@ -264,6 +272,9 @@ enum {
STR_UPNICK,
INT_UPPORT,
#endif /* UPTIME */
#ifdef URLCAPTURE
INT_URLHISTMAX,
#endif /* URLCAPTURE */
STR_USERFILE,
STR_VIRTUAL,
#ifdef WEB
@ -381,6 +392,9 @@ enum {
#define SPY_MESSAGE 5
#define SPY_RAWIRC 6
#define SPY_BOTNET 7
#ifdef URLCAPTURE
#define SPY_URL 8
#endif /* URLCAPTURE */
#define SPYF_ANY 1
#define SPYF_CHANNEL (1 << SPY_CHANNEL)
@ -388,6 +402,7 @@ enum {
#define SPYF_MESSAGE (1 << SPY_MESSAGE)
#define SPYF_RAWIRC (1 << SPY_RAWIRC)
#define SPYF_BOTNET (1 << SPY_BOTNET)
#define SPYF_URL (1 << SPY_URL)
/*
* notify defines

View File

@ -1,7 +1,7 @@
/*
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
it under the terms of the GNU General Public License as published by
@ -23,25 +23,19 @@
#include "defines.h"
#include "structs.h"
#ifdef TEST
#define MAIN_C
#endif
#include "global.h"
#include "h.h"
#include "text.h"
#ifndef TEST
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 const char monlist[12][4] =
{
"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"
};
LS const char monlist[12][4] = { "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
@ -493,7 +487,7 @@ char *cluster(char *hostname)
}
else
{
/*
/*
* its not a numeric mask
*/
p = mask;
@ -841,7 +835,8 @@ char *Strchr(const char *t, int c)
return((*t == ch) ? (char*)t : NULL);
}
char *Strdup(char *src)
__attr(CORE_SEG,__regparm(1))
char *Strdup(const char *src)
{
char *dest;
@ -1064,6 +1059,8 @@ void table_send(const char *from, const int space)
e_table = NULL;
}
#ifdef OLDCODE
int is_safepath(const char *path)
{
struct stat st;
@ -1097,3 +1094,125 @@ int is_safepath(const char *path)
}
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
{ 0, "SEEN", "do_seen", 20 | CCPW | CBANG },
#endif /* SEEN */
#ifdef URLCAPTURE
{ 0, "URLHIST", "do_urlhist", 20 | CCPW | REDIR | LBUF },
#endif /* ifdef URLCAPTURE */
/*
* Level 40
@ -276,7 +279,7 @@ int main(int argc, char **argv)
ct = 0;
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)
{
@ -401,6 +404,7 @@ int main(int argc, char **argv)
printf("extern OnMsg_access acmd[];\n\n");
printf("#endif /""* MAIN_C *""/\n\n");
printf("#endif /""* MCMD_H *""/\n\n");
printf("#endif /""* TEST *""/\n\n");
unlink("usercombo.h");
of = fopen("usercombo.h","w");

View File

@ -41,7 +41,7 @@
#define MECHUSERLOGIN "v3.energymech.net"
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__
BEG const char BOTCLASS[] MDEF("WinMech");
#else /* ! CYGWIN */
@ -63,10 +63,15 @@ BEG const char __SPYSTR_RAWIRC[] MDEF("rawirc");
BEG const char __SPYSTR_MESSAGE[] MDEF("message");
BEG const char __SPYSTR_STATUS[] MDEF("status");
BEG const char __SPYSTR_BOTNET[] MDEF("botnet");
#define SPYSTR_RAWIRC (char*)__SPYSTR_RAWIRC
#define SPYSTR_MESSAGE (char*)__SPYSTR_MESSAGE
#define SPYSTR_STATUS (char*)__SPYSTR_STATUS
#define SPYSTR_BOTNET (char*)__SPYSTR_BOTNET
#define SPYSTR_RAWIRC __SPYSTR_RAWIRC
#define SPYSTR_MESSAGE __SPYSTR_MESSAGE
#define SPYSTR_STATUS __SPYSTR_STATUS
#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=");
@ -110,7 +115,6 @@ BEG User __internal_users[2];
* (functions that do not call any other non-trivial functions)
*/
BEG char gsockdata[MAXLEN];
BEG char nick_buf[MAXHOSTLEN];
BEG char nuh_buf[NUHLEN];
@ -139,10 +143,6 @@ BEG Alias *aliaslist MDEF(NULL);
#endif /* ALIAS */
#ifdef UPTIME
BEG char *defaultuptimehost MDEF("uptime.energymech.net");
#endif /* UPTIME */
#ifdef BOTNET
BEG const char UNKNOWNATUNKNOWN[] MDEF("unknown@unknown");
@ -191,11 +191,17 @@ BEG Note *notelist MDEF(NULL);
#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
@ -211,6 +217,12 @@ LS struct
#endif /* REDIRECT */
#ifdef SCRIPTING
BEG Hook *hooklist MDEF(NULL);
#endif /* SCRIPTING */
#ifdef SEEN
BEG char *seenfile MDEF(NULL); /* proc var */
@ -237,9 +249,17 @@ BEG ulong uptimeip MDEF((ulong)-1);
BEG ulong uptimecookie;
BEG ulong uptimeregnr MDEF(0);
BEG time_t uptimelast MDEF(0);
BEG const char *defaultuptimehost MDEF("uptime.energymech.net");
#endif /* UPTIME */
#ifdef URLCAPTURE
BEG int urlhistmax MDEF(20); /* proc var */
BEG Strp *urlhistory MDEF(NULL);
#endif /* URLCAPTURE */
#ifdef WEB
BEG int websock MDEF(-1);
@ -247,17 +267,6 @@ BEG int webport MDEF(0);
#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

View File

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

26
src/h.h
View File

@ -1,7 +1,7 @@
/*
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
it under the terms of the GNU General Public License as published by
@ -107,9 +107,9 @@
#endif /* DEBUG */
LS Chan *find_channel(char *, int) __attr(CORE_SEG, __regparm (2) );
LS Chan *find_channel_ac(char *) __attr(CORE_SEG, __regparm (1) );
LS Chan *find_channel_ny(char *) __attr(CORE_SEG, __regparm (1) );
LS Chan *find_channel(const char *, int) __attr(CORE_SEG, __regparm (2) );
LS Chan *find_channel_ac(const 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 Client *find_client(const 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 *get_shituser(char *, char *) __page(CORE_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_user(const char *, const 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_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 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 *Strchr(const char *, int) __att2(CORE_SEG, const, __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 char *chop(char **) __attr(CORE_SEG, __regparm (1) );
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 num_matches(const char *, const char *) __att2(CORE_SEG, const, __regparm (2) );
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 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_part(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_quit(char *, char *) __page(CORE_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 */
#ifdef URLCAPTURE
LS void urlcapture(const char *) __page(CORE_SEG);
LS void do_urlhist(COMMAND_ARGS) __page(CMD1_SEG);
#endif /* ifdef URLCAPTURE */
/*
* WEB prototypes
*/

View File

@ -182,7 +182,7 @@ help_loop:
/*
* 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
{
debug("(do_help) unsafe help filename (%s), exiting\n",line);

View File

@ -31,6 +31,12 @@
#include <sys/utsname.h>
/*---Help:HOSTINFO:(no arguments)
Equivalent to ``uname -orm''
See also: meminfo, cpuinfo
*/
void do_hostinfo(COMMAND_ARGS)
{
struct utsname un;
@ -94,6 +100,19 @@ int parse_proc_status(char *line)
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)
{
char fn[64];
@ -113,6 +132,10 @@ void do_meminfo(COMMAND_ARGS)
vmsize,vmpeak,vmrss,vmexe,vmdata,vmlib,vmstk);
}
/*---Help:CPUINFO:(no arguments)
See also: hostinfo, meminfo
*/
void do_cpuinfo(COMMAND_ARGS)
{
}

View File

@ -1,7 +1,7 @@
/*
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
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
int main(int argc, char **argv, char **envp)
{
struct stat st;
char *opt;
int do_fork = TRUE;
int versiononly = FALSE;
@ -786,15 +787,14 @@ int main(int argc, char **argv, char **envp)
_exit(1);
}
{
struct stat st; // allocate temporary
stat("..",&st);
parent_inode = st.st_ino; // used for is_safepath()
}
stat("..",&st);
parent_inode = st.st_ino; // used for is_safepath()
srand(now+getpid());
/*
* Code to detect and recover after a RESET
*/
while(*envp)
{
char *p1;

View File

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

View File

@ -1,7 +1,7 @@
/*
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
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;
char *to,*channel;
#ifdef URLCAPTURE
const char *src;
#endif /* URLCAPTURE */
to = chop(&rest);
if (*rest == ':')
@ -404,6 +407,24 @@ void parse_privmsg(char *from, char *rest)
if (CurrentChan && CurrentChan->stats)
CurrentChan->stats->privmsg++;
#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);
}

View File

@ -1,7 +1,7 @@
/*
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
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.");
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.");
return(-1);

View File

@ -1,7 +1,7 @@
/*
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
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
*/
/* TYPE UACCES MIN DEFAULT NAME MAX */
{ INT_GLOBAL, 40, 0, ZERO, "AAWAY", 1440 }, /* set auto-away after ___ minutes */
{ STR_GLOBAL, 90, 0, VNULL, "ALTNICK" }, /* alternative nick */
/* TYPE UACCES MIN DEFAULT NAME MAX */
{ INT_GLOBAL, 40, 0, ZERO, "AAWAY", 1440 }, /* set auto-away after ___ minutes */
{ STR_GLOBAL, 90, 0, VNULL, "ALTNICK" }, /* alternative nick */
#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 */
#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 */
{ TOG_GLOBAL, 90, 0, INTCAST(1), "CC", 1 }, /* require command char */
{ CHR_GLOBAL, 90, 1, CMDCHAR, "CMDCHAR", 255 }, /* command char */
{ TOG_GLOBAL, 90, 0, INTCAST(1), "CC", 1 }, /* require command char */
{ CHR_GLOBAL, 90, 1, CMDCHAR, "CMDCHAR", 255 }, /* command char */
#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 */
{ 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
{ 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 */
{ INT_GLOBAL, 80, 0, INTCAST(4), "DCCUSER", 100 }, /* 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 */
{ INT_GLOBAL, 80, 0, INTCAST(4), "DCCUSER", 100 }, /* user DCC slots */
#endif /* DCC_FILE */
{ 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, "IRCNAME" }, /* register with this in the `real name' field */
{ 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, "IRCNAME" }, /* register with this in the `real name' field */
#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 */
#ifdef BOTNET
{ STR_PROC, 90, 0, STRPROC(linkpass), "LINKPASS" }, /* local process linkpass */
{ INT_PROC, 100, 0, INTPROC(linkport), "LINKPORT", 65535 }, /* listen on <linkport> for botnet connections */
{ STR_PROC, 90, 0, STRPROC(linkpass), "LINKPASS" }, /* local process linkpass */
{ INT_PROC, 100, 0, INTPROC(linkport), "LINKPORT", 65535 }, /* listen on <linkport> for botnet connections */
#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
{ 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 */
{ TOG_GLOBAL, 80, 0, ZERO, "NOIDLE", 1 }, /* dont idle */
{ TOG_GLOBAL, 80, 0, ZERO, "NOIDLE", 1 }, /* dont idle */
#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 */
{ TOG_GLOBAL, 90, 0, ZERO, "ONOTICE", 1 }, /* ircd has /notice @#channel */
{ TOG_GLOBAL, 90, 0, ZERO, "ONOTICE", 1 }, /* ircd has /notice @#channel */
#ifdef TRIVIA
{ 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 */
{ STR_PROC, 80, 0, STRPROC(triv_qfile), "QFILE" }, /* load questions from <qfile> */
{ 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 */
{ STR_PROC, 80, 0, STRPROC(triv_qfile), "QFILE" }, /* load questions from <qfile> */
#endif /* TRIVIA */
#ifdef CTCP
{ 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, "RF", 1 }, /* random ctcp finger reply */
{ TOG_GLOBAL, 80, 0, ZERO, "RV", 1 }, /* random ctcp version reply */
#endif /* CTCP */
#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 */
{ 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 */
{ STR_GLOBAL, 90, 0, VNULL, "UMODES" }, /* send these modes on connect */
{ 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 */
{ STR_GLOBAL, 90, 0, VNULL, "UMODES" }, /* send these modes on connect */
#ifdef UPTIME
{ 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 */
{ INT_PROC, 100, 0, INTPROC(uptimeport), "UPPORT", 65535 }, /* send packets to port <upport> */
{ 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 */
{ 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 */
{ 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, "USERFILE" }, /* what file to load/save userlist from/to */
{ STR_GLOBAL, 90, 0, VNULL, "VIRTUAL", 0, (&var_resolve_host) }, /* visual host */
#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 */
#ifdef WINGATE
{ STR_GLOBAL, 90, 0, VNULL, "WINGATE", 0, (&var_resolve_host) }, /* wingate hostname */
{ INT_GLOBAL, 90, 0, ZERO, "WINGPORT", 65535 }, /* wingate port */
{ STR_GLOBAL, 90, 0, VNULL, "WINGATE", 0, (&var_resolve_host) }, /* wingate hostname */
{ INT_GLOBAL, 90, 0, ZERO, "WINGPORT", 65535 }, /* wingate port */
#endif /* WINGATE */
{ 0, }};

View File

@ -1,7 +1,7 @@
/*
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
it under the terms of the GNU General Public License as published by
@ -30,7 +30,7 @@
#ifdef DEBUG
LS const char SPY_DEFS[7][12] =
LS const char SPY_DEFS[][12] =
{
"SPY_FILE",
"SPY_CHANNEL",
@ -38,7 +38,10 @@ LS const char SPY_DEFS[7][12] =
"SPY_STATUS",
"SPY_MESSAGE",
"SPY_RAWIRC",
"SPY_BOTNET"
"SPY_BOTNET",
#ifdef URLCAPTURE
"SPY_URL",
#endif /* URLCAPTURE */
};
#endif /* DEBUG */
@ -161,7 +164,7 @@ void spy_typecount(Mech *bot)
struct
{
char *idstring;
const char *idstring;
int typenum;
} spy_source_list[] =
@ -170,13 +173,20 @@ struct
{ SPYSTR_MESSAGE, SPY_MESSAGE },
{ SPYSTR_RAWIRC, SPY_RAWIRC },
{ SPYSTR_BOTNET, SPY_BOTNET },
#ifdef URLCAPTURE
{ SPYSTR_URL, SPY_URL },
#endif /* URLCAPTURE */
{ 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;
#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++)
{
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)
{
/*
@ -205,10 +240,10 @@ void do_spy(COMMAND_ARGS)
*/
Spy *spy;
Mech *backup,*destbot;
char *src,*dest;
const char *src;
char *dest;
int t_src,t_dest;
int sz;
int guid;
int sz,r,guid;
if (!*rest)
{
@ -291,9 +326,9 @@ guid_ok:
else
{
sz = spy_source(from,&t_src,&src);
if (sz < 0)
if (sz < 0) // user has insufficient access to source
goto spy_usage;
if (sz < cmdaccess)
if (sz < cmdaccess) // user has less access relative to source than the command level of SPY
return;
}
@ -304,6 +339,7 @@ guid_ok:
*/
if (*dest == '>')
{
// accept both ">file" and "> file"
dest++;
if (!*dest)
{
@ -314,8 +350,16 @@ guid_ok:
/*
* 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;
}
#else
goto spy_usage;
#endif /* DEBUG */
t_dest = SPY_FILE;
goto spy_dest_ok;
}
@ -384,7 +428,7 @@ spy_dest_ok:
if (t_src == SPY_CHANNEL)
{
Strcpy(spy->src,src);
Strcpy((char*)spy->src,src);
}
else
{
@ -434,7 +478,8 @@ void do_rspy(COMMAND_ARGS)
* on_msg checks: CARGS
*/
Spy *spy,**pspy;
char *src,*dest,*tmp;
const char *src;
char *dest,*tmp;
int t_src,t_dest;
int n;
@ -468,18 +513,11 @@ 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;
goto rspy_dest_ok;
}

View File

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

View File

@ -1,7 +1,7 @@
/*
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
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;
int sz;
if (uptimeport == 0)
if (uptimehost == NULL || uptimeport == 0)
return;
#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
*/
User *find_handle(char *handle)
User *find_handle(const char *handle)
{
User *user;
@ -803,7 +803,7 @@ User *get_user(const char *userhost, const char *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;