Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Fetching contributors…

Cannot retrieve contributors at this time

348 lines (291 sloc) 9.42 kB
/*
********************************************************************************
*
* File: psad_funcs.c
*
* Purpose: psad_funcs.c contains several functions that are needed by
* the all of the psad daemons, so putting these functions in
* a single file make sense.
*
* Author: Michael Rash (mbr@cipherdyne.org)
*
* Credits: (see the CREDITS file)
*
* Copyright (C) 1999-2002 Michael Rash (mbr@cipherdyne.org)
*
* License (GNU Public License):
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA
*
********************************************************************************
*/
/* includes */
#include "psad.h"
/* shared functions */
void slogr(const char *ident, const char *msg) {
openlog(ident, LOG_DAEMON, LOG_LOCAL7);
syslog(LOG_INFO, "%s", msg);
closelog();
return;
}
void check_unique_pid(const char *pid_file, const char *prog_name)
{
FILE *pidfile_ptr;
pid_t pid;
char pid_line[MAX_PID_SIZE+1];
#ifdef DEBUG
fprintf(stderr,
"[+] check_unique_pid(): opening pid file %s\n", pid_file);
#endif
if ((pidfile_ptr = fopen(pid_file, "r")) == NULL) {
/* the pid file must not exist (or we can't read it), so
* return... write_pid() will create it */
return;
}
/* read the first line of the pid_file, which will contain the
* process id of any running kmsgsd process */
if (fgets(pid_line, MAX_PID_SIZE+1, pidfile_ptr) == NULL) {
return;
}
/* turn the pid_line into an integer */
pid = atoi(pid_line);
/* close the pid_file now that we have read it */
fclose(pidfile_ptr);
#ifdef DEBUG
fprintf(stderr,
"[+] check_unique_pid(): checking pid: %d with kill 0\n", pid);
#endif
if (kill(pid, 0) == 0) { /* another prog_name is already running */
fprintf(stderr, "[*] %s is already running as pid: %d\n",
prog_name, pid);
exit(EXIT_FAILURE);
} else {
return;
}
return; /* for completness */
}
void write_pid(const char *pid_file, const pid_t pid)
{
FILE *pidfile_ptr;
if ((pidfile_ptr = fopen(pid_file, "w")) == NULL) {
/* could not open the pid file */
fprintf(stderr, "[*] Could not open the pid file: %s", pid_file);
exit(EXIT_FAILURE);
}
/* write the pid to the pid file */
if (fprintf(pidfile_ptr, "%d\n", pid) == 0) {
fprintf(stderr, "[*] pid: %d could not be written to pid file: %s",
pid, pid_file);
exit(EXIT_FAILURE);
}
/* the pid_file now that we have read it */
fclose(pidfile_ptr);
return;
}
int find_char_var(const char *search_str, char *charvar, char *line)
{
char *index_tmp;
int char_ctr = 0, i;
/* There is no need to check for this variable since this one
* is already setup */
if (*charvar != '\0')
return 0;
index_tmp = line;
/* look for specific variables in the config
* file that match the search_str */
for (i=0; i < strlen(search_str); i++)
if (index_tmp[i] != search_str[i])
return 0;
/* require trailing space char */
if (index_tmp[i] != ' ')
return 0;
#ifdef DEBUG
fprintf(stderr, "[+] find_char_var(): found %s in line: %s",
search_str, line);
#endif
/* increment the pointer past the variable name */
while (*index_tmp != ' ') index_tmp++;
/* increment the pointer past the whitespace
* before the variable value */
while (*index_tmp == ' ') index_tmp++;
/* make sure that the variable has a semicolon
* at the end of the line */
/* get the number of characters in the variable
* before the ending semicolon */
while (index_tmp[char_ctr] != ';' && index_tmp[char_ctr] != '\0' &&
index_tmp[char_ctr] != '\n')
char_ctr++;
if (index_tmp[char_ctr] != ';') {
fprintf(stderr,
"[*] find_char_var(): No ending semicolon found for: %s.\n",
search_str);
exit(EXIT_FAILURE);
}
if (char_ctr > MAX_GEN_LEN-1) {
fprintf(stderr,
"[*] find_char_var(): the config line for %s is too long. Exiting.\n",
search_str);
exit(EXIT_FAILURE);
}
strncpy(charvar, index_tmp, char_ctr);
charvar[char_ctr] = '\0'; /* replace the ';' with the NULL character */
return 1;
}
void *safe_malloc(const unsigned int len)
{
void *buf = NULL;
buf = malloc(len);
if (buf == NULL) {
fprintf(stderr, "[*] Could not malloc() %d bytes\n", len);
exit(EXIT_FAILURE);
}
return buf;
}
int has_sub_var(char *var_name, char *value, char *sub_var,
char *pre_str, char *post_str)
{
unsigned int i, sub_var_ctr = 0, found_sub_var = 0;
unsigned int pre_str_ctr = 0, found_pre_str = 1;
unsigned int post_str_ctr = 0, found_post_str = 0;
unsigned int found_one_var = 0;
sub_var[0] = '\0';
pre_str[0] = '\0';
post_str[0] = '\0';
for (i=0; i < strlen(value); i++) {
if (found_sub_var) {
if (! isdigit(value[i])
&& ! isalpha(value[i]) && value[i] != '_') {
found_sub_var = 0;
found_post_str = 1;
found_one_var = 1;
} else {
if (! found_one_var) {
sub_var[sub_var_ctr] = value[i];
sub_var_ctr++;
}
}
}
if (found_pre_str && value[i] != '$') {
pre_str[pre_str_ctr] = value[i];
pre_str_ctr++;
}
if (found_post_str) {
post_str[post_str_ctr] = value[i];
post_str_ctr++;
}
if (value[i] == '$') {
found_sub_var = 1;
found_pre_str = 0;
pre_str[pre_str_ctr] = '\0';
}
}
if (sub_var_ctr >= MAX_GEN_LEN - 1) {
printf("[*] Sub-var length exceeds maximum of %d chars within var: %s\n",
MAX_GEN_LEN, var_name);
exit(EXIT_FAILURE);
}
if (sub_var[0] != '\0') {
sub_var[sub_var_ctr] = '\0';
post_str[post_str_ctr] = '\0';
if (strncmp(sub_var, var_name, MAX_GEN_LEN) == 0) {
printf("[*] Cannot have identical var to sub-var: %s\n",
sub_var);
exit(EXIT_FAILURE);
}
return 1;
}
return 0;
}
void expand_sub_var_value(char *value, const char *sub_var,
const char *pre_str, const char *post_str)
{
if (strlen(sub_var) + strlen(pre_str) + strlen(post_str)
> MAX_GEN_LEN) {
printf("[*] Variable value too long: %s%s%s\n",
sub_var, pre_str, post_str);
exit(EXIT_FAILURE);
}
strlcpy(value, pre_str, MAX_GEN_LEN);
strlcat(value, sub_var, MAX_GEN_LEN);
strlcat(value, post_str, MAX_GEN_LEN);
return;
}
/*
* Do everything required to cleanly become a daemon: fork(), start
* a new session, chdir "/", and close un-needed standard filehandles.
*/
void daemonize_process(const char *pid_file)
{
pid_t child_pid, sid;
if ((child_pid = fork()) < 0) {
fprintf(stderr, "[*] Could not fork()");
exit(EXIT_FAILURE);
}
if (child_pid > 0) {
#ifdef DEBUG
fprintf(stderr, "[+] writing pid: %d to pid file: %s\n",
child_pid, pid_file);
#endif
write_pid(pid_file, child_pid);
exit(EXIT_SUCCESS); /* exit the parent process */
}
/*
* Now we are in the child process
*/
/* start a new session */
if ((sid = setsid()) < 0) {
fprintf(stderr, "[*] setsid() Could not start a new session");
exit(EXIT_FAILURE);
}
/* make "/" the current directory */
if ((chdir("/")) < 0) {
fprintf(stderr, "[*] Could not chdir() to /");
exit(EXIT_FAILURE);
}
/* reset the our umask (for completeness) */
umask(0);
/* close un-needed file handles */
close(STDIN_FILENO);
close(STDOUT_FILENO);
close(STDERR_FILENO);
return;
}
void send_alert_email(const char *shCmd, const char *mailCmd,
const char *mail_str)
{
char mail_line[MAX_MSG_LEN] = "";
pid_t child_pid;
strlcat(mail_line, mailCmd, MAX_MSG_LEN);
strlcat(mail_line, " ", MAX_MSG_LEN);
strlcat(mail_line, mail_str, MAX_MSG_LEN);
if ((child_pid = fork()) < 0)
/* could not fork */
exit(EXIT_FAILURE);
else if (child_pid > 0)
wait(NULL); /* mail better work */
else
execle(shCmd, shCmd, "-c", mail_line, (char *)NULL, (char *)NULL); /* don't use env */
return;
}
void list_to_array(char *list_ptr, const char sep, char **array,
unsigned char max_arg)
{
unsigned char ix;
ix = 0;
while ( (list_ptr != NULL) && (ix < max_arg) ) {
array[ix] = list_ptr;
list_ptr = strchr(list_ptr, sep);
if (list_ptr != NULL)
*list_ptr++ = '\0';
ix++;
}
array[ix] = NULL;
}
Jump to Line
Something went wrong with that request. Please try again.