This blob has been accessed 2,891 times via Git panel.
- #include "kalasag.h"
 - #include "kalasag_io.h"
 - #include "kalasag_util.h"
 - /* Main logging function to surrogate syslog */
 - void Log(char *logentry, ...)
 - {
 - char logbuffer[MAXBUF];
 - va_list argsPtr;
 - vsnprintf(logbuffer, MAXBUF, logentry, argsPtr);
 - openlog("kalasag", LOG_PID, SYSLOG_FACILITY);
 - syslog(SYSLOG_LEVEL, "%s", logbuffer);
 - closelog();
 - }
 - void Exit(int status)
 - {
 - Log("securityalert: Kalasag is shutting down\n");
 - Log("adminalert: Kalasag is shutting down\n");
 - }
 - void Start(void)
 - {
 - Log("adminalert: Kalasag %s is starting.\n", VERSION);
 - #ifdef DEBUG
 - #endif
 - }
 - /* The daemonizing code copied from Advanced Programming */
 - /* in the UNIX Environment by W. Richard Stevens with minor changes */
 - int DaemonSeed(void)
 - {
 - int childpid;
 - signal(SIGALRM, SIG_IGN);
 - signal(SIGHUP, SIG_IGN);
 - signal(SIGPIPE, SIG_IGN);
 - signal(SIGTERM, Exit);
 - signal(SIGABRT, Exit);
 - signal(SIGURG, Exit);
 - signal(SIGKILL, Exit);
 - if ((childpid = fork()) < 0)
 - return (ERROR);
 - else if (childpid > 0)
 - setsid();
 - chdir("/");
 - umask(077);
 - /* close stdout, stdin, stderr */
 - close(0);
 - close(1);
 - close(2);
 - return (TRUE);
 - }
 - /* Compares an IP address against a listed address and its netmask*/
 - int CompareIPs(char *target, char *ignoreAddr, int ignoreNetmaskBits)
 - {
 - unsigned long int netmaskAddr, ipAddr, targetAddr;
 - ipAddr = inet_addr(ignoreAddr);
 - targetAddr = inet_addr(target);
 - netmaskAddr = htonl(0xFFFFFFFF << (32 - ignoreNetmaskBits));
 - #ifdef DEBUG
 - Log("debug: target %s\n", target);
 - Log("debug: ignoreAddr %s\n", ignoreAddr);
 - Log("debug: ignoreNetmaskBits %d\n", ignoreNetmaskBits);
 - Log("debug: ipAddr %lu\n", ipAddr);
 - Log("debug: targetAddr %lu\n", targetAddr);
 - Log("debug: netmask %x\n", netmaskAddr);
 - Log("debug: mix ipAddr %lu\n", (ipAddr & netmaskAddr));
 - Log("debug: mix target %lu\n", (targetAddr & netmaskAddr));
 - #endif
 - /* Network portion mask & op and return */
 - if ((ipAddr & netmaskAddr) == (targetAddr & netmaskAddr))
 - return (TRUE);
 - else
 - return (FALSE);
 - }
 - /* check hosts that should never be blocked */
 - int NeverBlock(char *target, char *filename)
 - {
 - FILE *input;
 - char buffer[MAXBUF], tempBuffer[MAXBUF], netmaskBuffer[MAXBUF];
 - char *slashPos;
 - int count = 0, dest = 0, netmaskBits = 0;
 - #ifdef DEBUG
 - Log("debug: NeverBlock: Opening ignore file: %s \n", filename);
 - #endif
 - return (ERROR);
 - #ifdef DEBUG
 - Log("debug: NeverBlock: Doing lookup for host: %s \n", target);
 - #endif
 - /* Reset destination counter */
 - dest = 0;
 - if ((buffer[0] == '#') || (buffer[0] == '\n'))
 - continue;
 - /* Parse out digits, colons, and slashes. Everything else rejected */
 - (buffer[count] == '.') || (buffer[count] == ':')
 - || (buffer[count] == '/')) {
 - tempBuffer[dest++] = buffer[count];
 - } else {
 - tempBuffer[dest] = '\0';
 - break;
 - }
 - }
 - /* Return pointer to slash if it exists and copy data to buffer */
 - if (slashPos) {
 - SafeStrncpy(netmaskBuffer, slashPos + 1, MAXBUF);
 - /* Terminate tempBuffer string at delimeter for later use */
 - *slashPos = '\0';
 - } else
 - /* Copy in a 32 bit netmask if none given */
 - SafeStrncpy(netmaskBuffer, "32", MAXBUF);
 - /* Convert netmaskBuffer to bits in netmask */
 - if ((netmaskBits < 0) || (netmaskBits > 32)) {
 - Log("adminalert: Invalid netmask in config file: %s Ignoring entry.\n", buffer);
 - continue;
 - }
 - if (CompareIPs(target, tempBuffer, netmaskBits)) {
 - #ifdef DEBUG
 - Log("debug: NeverBlock: Host: %s found in ignore file with netmask %s\n", target, netmaskBuffer);
 - #endif
 - return (TRUE);
 - }
 - } /* end while() */
 - #ifdef DEBUG
 - Log("debug: NeverBlock: Host: %s NOT found in ignore file\n", target);
 - #endif
 - return (FALSE);
 - }
 - /* Make sure the config file is available */
 - int CheckConfig(void)
 - {
 - FILE *input;
 - Log("adminalert: Cannot open config file: %s. Exiting\n",
 - CONFIG_FILE);
 - return (FALSE);
 - } else
 - return (TRUE);
 - }
 - /* This writes out blocked hosts to the blocked file. It adds the hostname */
 - /* time stamp, and port connection that was acted on */
 - int
 - WriteBlocked(char *target, char *resolvedHost, int port,
 - char *blockedFilename, char *historyFilename, char *portType)
 - {
 - FILE *output;
 - int blockedStatus = TRUE, historyStatus = TRUE;
 - struct tm *tmptr;
 - time_t current_time;
 - #ifdef DEBUG
 - Log("debug: WriteBlocked: Opening block file: %s \n", blockedFilename);
 - #endif
 - Log("adminalert: ERROR: Cannot open blocked file: %s.\n",
 - blockedFilename);
 - blockedStatus = FALSE;
 - } else {
 - "%ld - %02d/%02d/%04d %02d:%02d:%02d Host: %s/%s Port: %d %s Blocked\n",
 - current_time, tmptr->tm_mon + 1, tmptr->tm_mday,
 - tmptr->tm_year + 1900, tmptr->tm_hour, tmptr->tm_min,
 - tmptr->tm_sec, resolvedHost, target, port, portType);
 - blockedStatus = TRUE;
 - }
 - #ifdef DEBUG
 - Log("debug: WriteBlocked: Opening history file: %s \n",
 - historyFilename);
 - #endif
 - Log("adminalert: ERROR: Cannot open history file: %s.\n",
 - historyFilename);
 - historyStatus = FALSE;
 - } else {
 - "%ld - %02d/%02d/%04d %02d:%02d:%02d Host: %s/%s Port: %d %s Blocked\n",
 - current_time, tmptr->tm_mon + 1, tmptr->tm_mday,
 - tmptr->tm_year + 1900, tmptr->tm_hour, tmptr->tm_min,
 - tmptr->tm_sec, resolvedHost, target, port, portType);
 - historyStatus = TRUE;
 - }
 - if (historyStatus || blockedStatus == FALSE)
 - return (FALSE);
 - else
 - return (TRUE);
 - }
 - /* This reads a token from the config file up to the "=" and returns the string */
 - /* up to the first space or NULL */
 - int ConfigTokenRetrieve(char *token, char *configToken)
 - {
 - FILE *config;
 - char buffer[MAXBUF], tokenBuffer[MAXBUF];
 - int count = 0;
 - Log("adminalert: ERROR: Cannot open config file: %s.\n",
 - CONFIG_FILE);
 - return (ERROR);
 - } else {
 - #ifdef DEBUG
 - Log("debug: ConfigTokenRetrieve: checking for token %s", token);
 - #endif
 - /* this skips comments */
 - if (buffer[0] != '#') {
 - #ifdef DEBUG
 - Log("debug: ConfigTokenRetrieve: data: %s", buffer);
 - #endif
 - /* search for the token and make sure the trailing character */
 - /* is a " " or "=" to make sure the entire token was found */
 - Log("adminalert: Quotes missing from %s token. Option skipped\n", token);
 - return (FALSE);
 - }
 - MAXBUF);
 - /* strip off unprintables/linefeeds (if any) */
 - count = 0;
 - while (count < MAXBUF - 1) {
 - && tokenBuffer[count] != '"')
 - configToken[count] = tokenBuffer[count];
 - else {
 - configToken[count] = '\0';
 - break;
 - }
 - count++;
 - }
 - #ifdef DEBUG
 - Log("debug: ConfigTokenRetrieved token: %s\n",
 - configToken);
 - #endif
 - configToken[MAXBUF - 1] = '\0';
 - return (TRUE);
 - }
 - }
 - }
 - return (FALSE);
 - }
 - }
 - /* This will bind a socket to a port. It works for UDP/TCP */
 - int
 - BindSocket(int sockfd, struct sockaddr_in client,
 - struct sockaddr_in server, int port)
 - {
 - #ifdef DEBUG
 - Log("debug: BindSocket: Binding to port: %d\n", port);
 - #endif
 - bzero((char *) &server, sizeof(server));
 - server.sin_family = AF_INET;
 - server.sin_addr.s_addr = htonl(INADDR_ANY);
 - server.sin_port = htons(port);
 - if (bind(sockfd, (struct sockaddr *) &server, sizeof(server)) < 0) {
 - #ifdef DEBUG
 - Log("debug: BindSocket: Binding failed\n");
 - #endif
 - return (ERROR);
 - } else {
 - #ifdef DEBUG
 - Log("debug: BindSocket: Binding successful. Doing listen\n");
 - #endif
 - listen(sockfd, 5);
 - return (TRUE);
 - }
 - }
 - /* Open a TCP Socket */
 - int OpenTCPSocket(void)
 - {
 - int sockfd;
 - #ifdef DEBUG
 - Log("debug: OpenTCPSocket: opening TCP socket\n");
 - #endif
 - if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
 - return (ERROR);
 - else
 - return (sockfd);
 - }
 - /* Open a UDP Socket */
 - int OpenUDPSocket(void)
 - {
 - int sockfd;
 - #ifdef DEBUG
 - Log("debug: openUDPSocket opening UDP socket\n");
 - #endif
 - if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
 - return (ERROR);
 - else
 - return (sockfd);
 - }
 - #ifdef SUPPORT_STEALTH
 - /* Open a RAW TCPSocket */
 - int OpenRAWTCPSocket(void)
 - {
 - int sockfd;
 - #ifdef DEBUG
 - Log("debug: OpenRAWTCPSocket: opening RAW TCP socket\n");
 - #endif
 - if ((sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_TCP)) < 0)
 - return (ERROR);
 - else
 - return (sockfd);
 - }
 - /* Open a RAW UDP Socket */
 - int OpenRAWUDPSocket(void)
 - {
 - int sockfd;
 - #ifdef DEBUG
 - Log("debug: OpenRAWUDPSocket: opening RAW UDP socket\n");
 - #endif
 - if ((sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_UDP)) < 0)
 - return (ERROR);
 - else
 - return (sockfd);
 - }
 - #endif
 - /* This will use a system() call to change the route of the target host to */
 - /* a dead IP address on your LOCAL SUBNET. */
 - int
 - KillRoute(char *target, int port, char *killString, char *detectionType)
 - {
 - char cleanAddr[MAXBUF], commandStringTemp[MAXBUF];
 - char commandStringTemp2[MAXBUF], commandStringFinal[MAXBUF];
 - char portString[MAXBUF];
 - int killStatus = ERROR, substStatus = ERROR;
 - CleanIpAddr(cleanAddr, target);
 - substStatus =
 - SubstString(cleanAddr, "$TARGET$", killString, commandStringTemp);
 - if (substStatus == 0) {
 - Log("adminalert: No target variable specified in KILL_ROUTE option. Skipping.\n");
 - return (ERROR);
 - } else if (substStatus == ERROR) {
 - Log("adminalert: Error trying to parse $TARGET$ Token for KILL_ROUTE. Skipping.\n");
 - return (ERROR);
 - }
 - if (SubstString
 - (portString, "$PORT$", commandStringTemp,
 - commandStringTemp2) == ERROR) {
 - Log("adminalert: Error trying to parse $PORT$ Token for KILL_ROUTE. Skipping.\n");
 - return (ERROR);
 - }
 - if (SubstString
 - (detectionType, "$MODE$", commandStringTemp2,
 - commandStringFinal) == ERROR) {
 - Log("adminalert: Error trying to parse $MODE$ Token for KILL_ROUTE. Skipping.\n");
 - return (ERROR);
 - }
 - #ifdef DEBUG
 - Log("debug: KillRoute: running route command: %s\n",
 - commandStringFinal);
 - #endif
 - /* Kill the bastard and report a status */
 - if (killStatus == 127) {
 - Log("adminalert: ERROR: There was an error trying to block host (exec fail) %s", target);
 - return (ERROR);
 - } else if (killStatus < 0) {
 - Log("adminalert: ERROR: There was an error trying to block host (system fail) %s", target);
 - return (ERROR);
 - } else {
 - Log("attackalert: Host %s has been blocked via dropped route using command: \"%s\"", target, commandStringFinal);
 - return (TRUE);
 - }
 - }
 - /* This will run a specified command with TARGET as the option if one is given. */
 - int
 - KillRunCmd(char *target, int port, char *killString, char *detectionType)
 - {
 - char cleanAddr[MAXBUF], commandStringTemp[MAXBUF];
 - char commandStringTemp2[MAXBUF], commandStringFinal[MAXBUF];
 - char portString[MAXBUF];
 - int killStatus = ERROR;
 - CleanIpAddr(cleanAddr, target);
 - /* Tokens are not required, but we check for an error anyway */
 - if (SubstString(cleanAddr, "$TARGET$", killString, commandStringTemp)
 - == ERROR) {
 - Log("adminalert: Error trying to parse $TARGET$ Token for KILL_RUN_CMD. Skipping.\n");
 - return (ERROR);
 - }
 - if (SubstString
 - (portString, "$PORT$", commandStringTemp,
 - commandStringTemp2) == ERROR) {
 - Log("adminalert: Error trying to parse $PORT$ Token for KILL_RUN_CMD. Skipping.\n");
 - return (ERROR);
 - }
 - if (SubstString
 - (detectionType, "$MODE$", commandStringTemp2,
 - commandStringFinal) == ERROR) {
 - Log("adminalert: Error trying to parse $MODE$ Token for KILL_RUN_CMD. Skipping.\n");
 - return (ERROR);
 - }
 - /* Kill the bastard and report a status */
 - if (killStatus == 127) {
 - Log("adminalert: ERROR: There was an error trying to run command (exec fail) %s", target);
 - return (ERROR);
 - } else if (killStatus < 0) {
 - Log("adminalert: ERROR: There was an error trying to run command (system fail) %s", target);
 - return (ERROR);
 - } else {
 - /* report success */
 - Log("attackalert: External command run for host: %s using command: \"%s\"", target, commandStringFinal);
 - return (TRUE);
 - }
 - }
 - /* this function will drop the host into the TCP wrappers hosts.deny file to deny */
 - /* all access. The drop route method is preferred as this stops UDP attacks as well */
 - /* as TCP. You may find though that host.deny will be a more permanent home.. */
 - int
 - KillHostsDeny(char *target, int port, char *killString,
 - char *detectionType)
 - {
 - FILE *output;
 - char cleanAddr[MAXBUF], commandStringTemp[MAXBUF];
 - char commandStringTemp2[MAXBUF], commandStringFinal[MAXBUF];
 - char portString[MAXBUF];
 - int substStatus = ERROR;
 - CleanIpAddr(cleanAddr, target);
 - #ifdef DEBUG
 - Log("debug: KillHostsDeny: parsing string for block: %s\n",
 - killString);
 - #endif
 - substStatus =
 - SubstString(cleanAddr, "$TARGET$", killString, commandStringTemp);
 - if (substStatus == 0) {
 - Log("adminalert: No target variable specified in KILL_HOSTS_DENY option. Skipping.\n");
 - return (ERROR);
 - } else if (substStatus == ERROR) {
 - Log("adminalert: Error trying to parse $TARGET$ Token for KILL_HOSTS_DENY. Skipping.\n");
 - return (ERROR);
 - }
 - if (SubstString
 - (portString, "$PORT$", commandStringTemp,
 - commandStringTemp2) == ERROR) {
 - Log("adminalert: Error trying to parse $PORT$ Token for KILL_HOSTS_DENY. Skipping.\n");
 - return (ERROR);
 - }
 - if (SubstString
 - (detectionType, "$MODE$", commandStringTemp2,
 - commandStringFinal) == ERROR) {
 - Log("adminalert: Error trying to parse $MODE$ Token for KILL_HOSTS_DENY. Skipping.\n");
 - return (ERROR);
 - }
 - #ifdef DEBUG
 - Log("debug: KillHostsDeny: result string for block: %s\n",
 - commandStringFinal);
 - #endif
 - Log("adminalert: cannot open hosts.deny file: %s for blocking.",
 - WRAPPER_HOSTS_DENY);
 - Log("securityalert: ERROR: There was an error trying to block host %s", target);
 - return (FALSE);
 - } else {
 - Log("attackalert: Host %s has been blocked via wrappers with string: \"%s\"", target, commandStringFinal);
 - return (TRUE);
 - }
 - }
 - /* check if the host is already blocked */
 - int IsBlocked(char *target, char *filename)
 - {
 - FILE *input;
 - char buffer[MAXBUF], tempBuffer[MAXBUF];
 - char *ipOffset;
 - int count;
 - #ifdef DEBUG
 - Log("debug: IsBlocked: Opening block file: %s \n", filename);
 - #endif
 - Log("adminalert: ERROR: Cannot open blocked file: %s for reading. Will create.\n", filename);
 - return (FALSE);
 - }
 - tempBuffer[count] = ipOffset[count];
 - } else {
 - tempBuffer[count] = '\0';
 - break;
 - }
 - }
 - #ifdef DEBUG
 - Log("debug: isBlocked: Host: %s found in blocked file\n",
 - target);
 - #endif
 - return (TRUE);
 - }
 - }
 - }
 - #ifdef DEBUG
 - Log("debug: IsBlocked: Host: %s NOT found in blocked file\n", target);
 - #endif
 - return (FALSE);
 - }
 - /*********************************************************************************
 - * String substitute function
 - *
 - * This function takes:
 - *
 - * 1) A token to use for replacement.
 - * 2) A token to find.
 - * 3) A string with the tokens in it.
 - * 4) A string to write the replaced result.
 - *
 - * It returns the number of substitutions made during the operation.
 - **********************************************************************************/
 - int
 - SubstString(const char *replace, const char *find, const char *target,
 - char *result)
 - {
 - int replaceCount = 0, count = 0, findCount = 0, findLen =
 - 0, numberOfSubst = 0;
 - char tempString[MAXBUF], *tempStringPtr;
 - #ifdef DEBUG
 - Log("debug: SubstString: Processing string: %s %d", target,
 - Log("debug: SubstString: Processing search text: %s %d", replace,
 - Log("debug: SubstString: Processing replace text: %s %d", find,
 - #endif
 - /* string not found in target */
 - #ifdef DEBUG
 - Log("debug: SubstString: Result string: %s", result);
 - #endif
 - return (numberOfSubst);
 - }
 - /* String/victim/target too long */
 - MAXBUF)
 - return (ERROR);
 - tempStringPtr = tempString;
 - for (count = 0; count < MAXBUF; count++) {
 - if (*target == '\0')
 - break;
 - *tempStringPtr++ = *target++;
 - else {
 - numberOfSubst++;
 - replaceCount++)
 - *tempStringPtr++ = replace[replaceCount];
 - for (findCount = 0; findCount < findLen; findCount++)
 - target++;
 - }
 - }
 - #ifdef DEBUG
 - Log("debug: SubstString: Result string: %s", result);
 - #endif
 - return (numberOfSubst);
 - }
 - /* This function checks a config variable for a numerical flag and returns it */
 - int CheckFlag(char *flagName)
 - {
 - char configToken[MAXBUF];
 - if ((ConfigTokenRetrieve(flagName, configToken)) == TRUE) {
 - #ifdef DEBUG
 - Log("debug: CheckFlag: found %s string.\n", flagName);
 - #endif
 - } else {
 - #ifdef DEBUG
 - Log("debug: CheckFlag: %s option not found. Assuming FALSE.\n",
 - flagName);
 - #endif
 - return (FALSE);
 - }
 - }
 - /* snprintf for NEXTSTEP (others??) */
 - /* I don't know where this code came from and I don't */
 - /* warrant its effectiveness. CHR */
 - #ifdef HAS_NO_SNPRINTF
 - {
 - va_list ap;
 - FILE f;
 - if (n > MAXBUF) {
 - n = MAXBUF;
 - }
 - f._file = EOF;
 - f._flag = _IOWRT | _IOSTRG;
 - f._base = f._ptr = str;
 - f._bufsiz = f._cnt = n ? n - 1 : 0;
 - if (n) {
 - *f._ptr = '\0';
 - }
 - return (f._ptr - str);
 - }
 - #endif