This blob has been accessed 2,619 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