|
|
@@ -29,6 +29,8 @@
|
|
|
#include "users.h"
|
|
|
#include "botnet.h"
|
|
|
#include "src/mod/server.mod/server.h"
|
|
|
+#include <bdlib/src/String.h>
|
|
|
+#include <bdlib/src/Stream.h>
|
|
|
|
|
|
#include <sys/types.h>
|
|
|
#include <pwd.h>
|
|
|
@@ -51,36 +53,6 @@
|
|
|
|
|
|
bool clear_tmpdir = 0;
|
|
|
|
|
|
-int my_system(const char *run)
|
|
|
-{
|
|
|
-#ifdef WIN32NOFUCK
|
|
|
- int ret = -1;
|
|
|
-
|
|
|
- PROCESS_INFORMATION pinfo;
|
|
|
- STARTUPINFO sinfo;
|
|
|
-
|
|
|
- memset(&sinfo, 0, sizeof(STARTUPINFO));
|
|
|
- sinfo.cb = sizeof(sinfo);
|
|
|
-
|
|
|
- sinfo.wShowWindow = SW_HIDE;
|
|
|
- sinfo.dwFlags |= STARTF_USESTDHANDLES;
|
|
|
- sinfo.hStdInput =
|
|
|
- sinfo.hStdOutput =
|
|
|
- sinfo.hStdError =
|
|
|
-
|
|
|
- ret =
|
|
|
- CreateProcess(NULL, (char *) run, NULL, NULL, TRUE, NORMAL_PRIORITY_CLASS | DETACHED_PROCESS, NULL, NULL,
|
|
|
- (STARTUPINFO *) &sinfo, (PROCESS_INFORMATION *) &pinfo);
|
|
|
-
|
|
|
- if (ret == 0)
|
|
|
- return -1;
|
|
|
- else
|
|
|
- return 0;
|
|
|
-#else
|
|
|
- return system(run);
|
|
|
-#endif /* WIN32 */
|
|
|
-}
|
|
|
-
|
|
|
void clear_tmp()
|
|
|
{
|
|
|
if (!clear_tmpdir)
|
|
|
@@ -190,7 +162,7 @@ void check_last() {
|
|
|
char *out = NULL, buf[50] = "";
|
|
|
|
|
|
simple_snprintf(buf, sizeof(buf), STR("last -10 %s"), conf.username);
|
|
|
- if (shell_exec(buf, NULL, &out, NULL)) {
|
|
|
+ if (shell_exec(buf, NULL, &out, NULL, 1)) {
|
|
|
if (out) {
|
|
|
char *p = NULL;
|
|
|
|
|
|
@@ -342,7 +314,7 @@ void check_trace(int start)
|
|
|
}
|
|
|
#endif /* !CYGWIN_HACKS */
|
|
|
|
|
|
-int shell_exec(char *cmdline, char *input, char **output, char **erroutput)
|
|
|
+int shell_exec(char *cmdline, char *input, char **output, char **erroutput, bool simple)
|
|
|
{
|
|
|
if (!cmdline)
|
|
|
return 0;
|
|
|
@@ -444,11 +416,10 @@ int shell_exec(char *cmdline, char *input, char **output, char **erroutput)
|
|
|
} else {
|
|
|
/* Child: make fd's and set them up as std* */
|
|
|
// int ind, outd, errd;
|
|
|
- char *argv[4] = { NULL, NULL, NULL, NULL };
|
|
|
-
|
|
|
// ind = fileno(inpFile);
|
|
|
// outd = fileno(outFile);
|
|
|
// errd = fileno(errFile);
|
|
|
+
|
|
|
if (dup2(in->fd, STDIN_FILENO) == (-1)) {
|
|
|
kill(parent, SIGCHLD);
|
|
|
exit(1);
|
|
|
@@ -461,16 +432,54 @@ int shell_exec(char *cmdline, char *input, char **output, char **erroutput)
|
|
|
kill(parent, SIGCHLD);
|
|
|
exit(1);
|
|
|
}
|
|
|
- argv[0] = "/bin/sh";
|
|
|
- argv[1] = "-c";
|
|
|
- argv[2] = cmdline;
|
|
|
- argv[3] = NULL;
|
|
|
+
|
|
|
+ char *argv[15];
|
|
|
+ if (simple) {
|
|
|
+ char *p = NULL;
|
|
|
+ int n = 0;
|
|
|
+ char *mycmdline = strdup(cmdline);
|
|
|
+
|
|
|
+ while (mycmdline[0] && (p = newsplit(&mycmdline)))
|
|
|
+ argv[n++] = p;
|
|
|
+ argv[n] = NULL;
|
|
|
+
|
|
|
+ // Close all sockets
|
|
|
+ for (int fd = 3; fd < MAX_SOCKETS; ++fd) close(fd);
|
|
|
+ } else {
|
|
|
+ argv[0] = "/bin/sh";
|
|
|
+ argv[1] = "-c";
|
|
|
+ argv[2] = cmdline;
|
|
|
+ argv[3] = NULL;
|
|
|
+ }
|
|
|
+
|
|
|
execvp(argv[0], &argv[0]);
|
|
|
kill(parent, SIGCHLD);
|
|
|
exit(1);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+int simple_exec(const char* argv[]) {
|
|
|
+ pid_t pid, savedpid;
|
|
|
+ int status;
|
|
|
+
|
|
|
+ switch ((pid = fork())) {
|
|
|
+ case -1:
|
|
|
+ break;
|
|
|
+ case 0: //child
|
|
|
+ // Close all sockets
|
|
|
+ for (int fd = 3; fd < MAX_SOCKETS; ++fd) close(fd);
|
|
|
+ execvp(argv[0], (char* const*) &argv[0]);
|
|
|
+ _exit(127);
|
|
|
+ default: //parent
|
|
|
+ savedpid = pid;
|
|
|
+ do {
|
|
|
+ pid = wait4(savedpid, &status, 0, (struct rusage *)0);
|
|
|
+ } while (pid == -1 && errno == EINTR);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ return(pid == -1 ? -1 : status);
|
|
|
+}
|
|
|
+
|
|
|
void suicide(const char *msg)
|
|
|
{
|
|
|
char tmp[512] = "";
|
|
|
@@ -775,84 +784,79 @@ void check_crontab()
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-void crontab_del() {
|
|
|
- char *tmpFile = NULL, *p = NULL, buf[2048] = "";
|
|
|
+static void crontab_install(bd::Stream& crontab) {
|
|
|
+ // Write out the new crontab
|
|
|
+ Tempfile new_crontab = Tempfile("crontab");
|
|
|
+ crontab.writeFile(new_crontab.fd);
|
|
|
|
|
|
- size_t tmplen = strlen(binname) + 100;
|
|
|
- tmpFile = (char *) my_calloc(1, tmplen);
|
|
|
+ // Install new crontab
|
|
|
+ const char* argv[] = {"crontab", new_crontab.file, 0};
|
|
|
+ simple_exec(argv);
|
|
|
+}
|
|
|
|
|
|
- strlcpy(tmpFile, shell_escape(binname), tmplen);
|
|
|
- if (!(p = strrchr(tmpFile, '/')))
|
|
|
- return;
|
|
|
- p++;
|
|
|
- strcpy(p, STR(".ctb"));
|
|
|
- simple_snprintf(buf, sizeof(buf), STR("crontab -l | grep -v '%s' | grep -v \"^#\" | grep -v \"^\\$\" > %s"), binname, tmpFile);
|
|
|
- if (shell_exec(buf, NULL, NULL, NULL)) {
|
|
|
- simple_snprintf(buf, sizeof(buf), STR("crontab %s"), tmpFile);
|
|
|
- shell_exec(buf, NULL, NULL, NULL);
|
|
|
- }
|
|
|
- unlink(tmpFile);
|
|
|
+void crontab_del() {
|
|
|
+ bd::Stream crontab;
|
|
|
+ if (crontab_exists(&crontab, 1) == 1)
|
|
|
+ crontab_install(crontab);
|
|
|
}
|
|
|
|
|
|
#ifndef CYGWIN_HACKS
|
|
|
-int crontab_exists() {
|
|
|
- char buf[2048] = "", *out = NULL;
|
|
|
+int crontab_exists(bd::Stream* crontab, bool excludeSelf) {
|
|
|
+ char *out = NULL;
|
|
|
+ int ret = -1;
|
|
|
+
|
|
|
+ if (shell_exec("crontab -l", NULL, &out, NULL, 1)) {
|
|
|
+ if (out) {
|
|
|
+ bd::Stream stream(out);
|
|
|
+ bd::String line;
|
|
|
+
|
|
|
+ ret = 0;
|
|
|
+ while (stream.tell() < stream.length()) {
|
|
|
+ line = stream.getline();
|
|
|
+ if (line[0] != '#' && line.find(binname) != bd::String::npos) {
|
|
|
+ ret = 1;
|
|
|
+
|
|
|
+ // Need to continue if the existing crontab is requested
|
|
|
+ if (crontab && !excludeSelf)
|
|
|
+ (*crontab) << line;
|
|
|
+ else if (!crontab)
|
|
|
+ break;
|
|
|
+ } else if (crontab)
|
|
|
+ (*crontab) << line;
|
|
|
+ }
|
|
|
|
|
|
- simple_snprintf(buf, sizeof buf, STR("crontab -l | grep '%s' | grep -v \"^#\""), binname);
|
|
|
- if (shell_exec(buf, NULL, &out, NULL)) {
|
|
|
- if (out && strstr(out, binname)) {
|
|
|
free(out);
|
|
|
- return 1;
|
|
|
- } else {
|
|
|
- if (out)
|
|
|
- free(out);
|
|
|
- return 0;
|
|
|
}
|
|
|
- } else
|
|
|
- return (-1);
|
|
|
+ }
|
|
|
+ return ret;
|
|
|
}
|
|
|
|
|
|
char s1_2[3] = "",s1_8[3] = "",s2_5[3] = "";
|
|
|
|
|
|
void crontab_create(int interval) {
|
|
|
- char tmpFile[161] = "";
|
|
|
- FILE *f = NULL;
|
|
|
- int fd;
|
|
|
+ bd::Stream crontab;
|
|
|
|
|
|
- simple_snprintf(tmpFile, sizeof tmpFile, STR("%s.crontab-XXXXXX"), tempdir);
|
|
|
- if ((fd = mkstemp(tmpFile)) == -1) {
|
|
|
- unlink(tmpFile);
|
|
|
+ if (crontab_exists(&crontab) == 1)
|
|
|
return;
|
|
|
- }
|
|
|
-
|
|
|
- char buf[256] = "";
|
|
|
|
|
|
- simple_snprintf(buf, sizeof buf, STR("crontab -l | grep -v \"%s\" | grep -v \"^#\" | grep -v \"^\\$\"> %s"),
|
|
|
- binname, tmpFile);
|
|
|
- if (shell_exec(buf, NULL, NULL, NULL) && (f = fdopen(fd, "a")) != NULL) {
|
|
|
- buf[0] = 0;
|
|
|
- if (interval == 1)
|
|
|
- strlcpy(buf, "*", 2);
|
|
|
- else {
|
|
|
- int i = 1;
|
|
|
- int si = randint(interval);
|
|
|
-
|
|
|
- while (i < 60) {
|
|
|
- if (buf[0])
|
|
|
- strlcat(buf, ",", sizeof(buf));
|
|
|
- simple_snprintf(&buf[strlen(buf)], sizeof(buf) - strlen(buf), "%i", (i + si) % 60);
|
|
|
- i += interval;
|
|
|
- }
|
|
|
+ char buf[1024] = "";
|
|
|
+ if (interval == 1)
|
|
|
+ strlcpy(buf, "*", 2);
|
|
|
+ else {
|
|
|
+ int i = 1;
|
|
|
+ int si = randint(interval);
|
|
|
+
|
|
|
+ while (i < 60) {
|
|
|
+ if (buf[0])
|
|
|
+ strlcat(buf, ",", sizeof(buf));
|
|
|
+ simple_snprintf(&buf[strlen(buf)], sizeof(buf) - strlen(buf), "%i", (i + si) % 60);
|
|
|
+ i += interval;
|
|
|
}
|
|
|
- simple_snprintf(buf + strlen(buf), sizeof buf, STR(" * * * * %s > /dev/null 2>&1"), binname);
|
|
|
- fseek(f, 0, SEEK_END);
|
|
|
- fprintf(f, "\n%s\n", buf);
|
|
|
- fclose(f);
|
|
|
- simple_snprintf(buf, sizeof(buf), STR("crontab %s"), tmpFile);
|
|
|
- shell_exec(buf, NULL, NULL, NULL);
|
|
|
}
|
|
|
- close(fd);
|
|
|
- unlink(tmpFile);
|
|
|
+ simple_snprintf(buf + strlen(buf), sizeof buf, STR(" * * * * %s > /dev/null 2>&1\n"), shell_escape(binname));
|
|
|
+
|
|
|
+ crontab << buf;
|
|
|
+ crontab_install(crontab);
|
|
|
}
|
|
|
#endif /* !CYGWIN_HACKS */
|
|
|
|