void SetPolicyServer(EvalContext *ctx, const char *new_policy_server) { if (new_policy_server) { snprintf(POLICY_SERVER, CF_MAX_IP_LEN, "%s", new_policy_server); ScopeNewSpecial(ctx, "sys", "policy_hub", new_policy_server, DATA_TYPE_STRING); } else { POLICY_SERVER[0] = '\0'; ScopeNewSpecial(ctx, "sys", "policy_hub", "undefined", DATA_TYPE_STRING); } // Get the timestamp on policy update struct stat sb; { char cf_promises_validated_filename[CF_MAXVARSIZE]; snprintf(cf_promises_validated_filename, CF_MAXVARSIZE, "%s/masterfiles/cf_promises_validated", CFWORKDIR); MapName(cf_promises_validated_filename); if ((stat(cf_promises_validated_filename, &sb)) != 0) { return; } } char timebuf[26]; cf_strtimestamp_local(sb.st_mtime, timebuf); ScopeNewSpecial(ctx, "sys", "last_policy_update", timebuf, DATA_TYPE_STRING); }
static bool ShowHost(const char *hostkey, const char *address, bool incoming, const KeyHostSeen *quality, void *ctx) { int *count = ctx; char timebuf[26]; char hostname[CF_BUFSIZE]; strlcpy(hostname, IPString2Hostname(address), CF_BUFSIZE); (*count)++; printf("%-10.10s %-17.17s %-25.25s %-26.26s %-s\n", incoming ? "Incoming" : "Outgoing", address, hostname, cf_strtimestamp_local(quality->lastseen, timebuf), hostkey); return true; }
bool ShowHost(const char *hostkey, const char *address, bool incoming, const KeyHostSeen *quality, void *ctx) { int *count = ctx; char timebuf[26]; char hostname[MAXHOSTNAMELEN]; int ret = IPString2Hostname(hostname, address, sizeof(hostname)); (*count)++; printf("%-10.10s %-17.17s %-25.25s %-26.26s %-s\n", incoming ? "Incoming" : "Outgoing", address, (ret != -1) ? hostname : "-", cf_strtimestamp_local(quality->lastseen, timebuf), hostkey); return true; }
void UpdateLastPolicyUpdateTime(EvalContext *ctx) { // Get the timestamp on policy update struct stat sb; { char cf_promises_validated_filename[CF_MAXVARSIZE]; snprintf(cf_promises_validated_filename, CF_MAXVARSIZE, "%s/masterfiles/cf_promises_validated", CFWORKDIR); MapName(cf_promises_validated_filename); if ((stat(cf_promises_validated_filename, &sb)) != 0) { return; } } char timebuf[26]; cf_strtimestamp_local(sb.st_mtime, timebuf); EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_SYS, "last_policy_update", timebuf, DATA_TYPE_STRING, "source=agent"); }
/** * @brief Writes a file with a contained timestamp to mark a policy file as validated * @return True if successful. */ static bool WritePolicyValidatedFile(const GenericAgentConfig *config) { char filename[CF_MAXVARSIZE]; if (MINUSF) { snprintf(filename, CF_MAXVARSIZE, "%s/state/validated_%s", CFWORKDIR, CanonifyName(config->original_input_file)); MapName(filename); } else { snprintf(filename, CF_MAXVARSIZE, "%s/masterfiles/cf_promises_validated", CFWORKDIR); MapName(filename); } if (!MakeParentDirectory(filename, true)) { Log(LOG_LEVEL_ERR, "While writing policy validated marker file '%s', could not create directory (MakeParentDirectory: %s)", filename, GetErrorStr()); return false; } int fd = creat(filename, 0600); if (fd == -1) { Log(LOG_LEVEL_ERR, "While writing policy validated marker file '%s', could not create file (creat: %s)", filename, GetErrorStr()); return false; } FILE *fp = fdopen(fd, "w"); time_t now = time(NULL); char timebuf[26]; fprintf(fp, "%s", cf_strtimestamp_local(now, timebuf)); fclose(fp); return true; }
void RemoteSysLog(int log_priority, const char *log_string) { int sd, rfc3164_len = 1024; char message[CF_BUFSIZE]; time_t now = time(NULL); int pri = log_priority | FACILITY; #if defined(HAVE_GETADDRINFO) int err; struct addrinfo query, *response, *ap; char strport[CF_MAXVARSIZE]; snprintf(strport, CF_MAXVARSIZE - 1, "%u", (unsigned) SYSLOG_PORT); memset(&query, 0, sizeof(struct addrinfo)); query.ai_family = AF_UNSPEC; query.ai_socktype = SOCK_DGRAM; if ((err = getaddrinfo(SYSLOG_HOST, strport, &query, &response)) != 0) { CfOut(OUTPUT_LEVEL_INFORM, "", "Unable to find syslog_host or service: (%s/%s) %s", SYSLOG_HOST, strport, gai_strerror(err)); return; } for (ap = response; ap != NULL; ap = ap->ai_next) { CfOut(OUTPUT_LEVEL_VERBOSE, "", " -> Connect to syslog %s = %s on port %s\n", SYSLOG_HOST, sockaddr_ntop(ap->ai_addr), strport); if ((sd = socket(ap->ai_family, ap->ai_socktype, IPPROTO_UDP)) == -1) { CfOut(OUTPUT_LEVEL_INFORM, "socket", "Couldn't open a socket"); continue; } else { char timebuffer[26]; snprintf(message, rfc3164_len, "<%u>%.15s %s %s", pri, cf_strtimestamp_local(now, timebuffer) + 4, VFQNAME, log_string); if (sendto(sd, message, strlen(message), 0, ap->ai_addr, ap->ai_addrlen) == -1) { CfOut(OUTPUT_LEVEL_VERBOSE, "sendto", " -> Couldn't send \"%s\" to syslog server \"%s\"\n", message, SYSLOG_HOST); } else { CfOut(OUTPUT_LEVEL_VERBOSE, "", " -> Syslog message: \"%s\" to server \"%s\"\n", message, SYSLOG_HOST); } close(sd); return; } } #else struct sockaddr_in addr; char timebuffer[26]; sockaddr_pton(AF_INET, SYSLOG_HOST, &addr); addr.sin_port = htons(SYSLOG_PORT); if ((sd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) { CfOut(OUTPUT_LEVEL_ERROR, "sendto", " !! Unable to send syslog datagram"); return; } snprintf(message, rfc3164_len, "<%u>%.15s %s %s", pri, cf_strtimestamp_local(now, timebuffer) + 4, VFQNAME, log_string); if (sendto(sd, message, strlen(message), 0, (struct sockaddr *) &addr, sizeof(addr)) == -1) { CfOut(OUTPUT_LEVEL_ERROR, "sendto", " !! Unable to send syslog datagram"); return; } CfOut(OUTPUT_LEVEL_VERBOSE, "", " -> Syslog message: \"%s\" to server %s\n", message, SYSLOG_HOST); close(sd); #endif }
void LocalExec(const ExecConfig *config) { FILE *pp; char line[CF_BUFSIZE], line_escaped[sizeof(line) * 2], filename[CF_BUFSIZE], *sp; char cmd[CF_BUFSIZE], esc_command[CF_BUFSIZE]; int print, count = 0; void *thread_name; time_t starttime = time(NULL); char starttime_str[64]; FILE *fp; char canonified_fq_name[CF_BUFSIZE]; thread_name = ThreadUniqueName(); cf_strtimestamp_local(starttime, starttime_str); CfOut(cf_verbose, "", "------------------------------------------------------------------\n\n"); CfOut(cf_verbose, "", " LocalExec(%sscheduled) at %s\n", config->scheduled_run ? "" : "not ", starttime_str); CfOut(cf_verbose, "", "------------------------------------------------------------------\n"); /* Need to make sure we have LD_LIBRARY_PATH here or children will die */ if (strlen(config->exec_command) > 0) { strncpy(cmd, config->exec_command, CF_BUFSIZE - 1); if (!strstr(cmd, "-Dfrom_cfexecd")) { strcat(cmd, " -Dfrom_cfexecd"); } } else { ConstructFailsafeCommand(config->scheduled_run, cmd); } strncpy(esc_command, MapName(cmd), CF_BUFSIZE - 1); snprintf(line, CF_BUFSIZE - 1, "_%jd_%s", (intmax_t) starttime, CanonifyName(cf_ctime(&starttime))); strlcpy(canonified_fq_name, config->fq_name, CF_BUFSIZE); CanonifyNameInPlace(canonified_fq_name); snprintf(filename, CF_BUFSIZE - 1, "%s/outputs/cf_%s_%s_%p", CFWORKDIR, canonified_fq_name, line, thread_name); MapName(filename); /* What if no more processes? Could sacrifice and exec() - but we need a sentinel */ if ((fp = fopen(filename, "w")) == NULL) { CfOut(cf_error, "fopen", "!! Couldn't open \"%s\" - aborting exec\n", filename); return; } #if !defined(__MINGW32__) /* * Don't inherit this file descriptor on fork/exec */ if (fileno(fp) != -1) { fcntl(fileno(fp), F_SETFD, FD_CLOEXEC); } #endif CfOut(cf_verbose, "", " -> Command => %s\n", cmd); if ((pp = cf_popen_sh(esc_command, "r")) == NULL) { CfOut(cf_error, "cf_popen", "!! Couldn't open pipe to command \"%s\"\n", cmd); fclose(fp); return; } CfOut(cf_verbose, "", " -> Command is executing...%s\n", esc_command); while (!feof(pp)) { if(!IsReadReady(fileno(pp), (config->agent_expireafter * SECONDS_PER_MINUTE))) { char errmsg[CF_MAXVARSIZE]; snprintf(errmsg, sizeof(errmsg), "cf-execd: !! Timeout waiting for output from agent (agent_expireafter=%d) - terminating it", config->agent_expireafter); CfOut(cf_error, "", "%s", errmsg); fprintf(fp, "%s\n", errmsg); count++; pid_t pid_agent; if(PipeToPid(&pid_agent, pp)) { ProcessSignalTerminate(pid_agent); } else { CfOut(cf_error, "", "!! Could not get PID of agent"); } break; } { ssize_t num_read = CfReadLine(line, CF_BUFSIZE, pp); if (num_read == -1) { FatalError("Cannot continue on CfReadLine error"); } else if (num_read == 0) { break; } } if(!CfReadLine(line, CF_BUFSIZE, pp)) { break; } if (ferror(pp)) { fflush(pp); break; } print = false; for (sp = line; *sp != '\0'; sp++) { if (!isspace((int) *sp)) { print = true; break; } } if (print) { // we must escape print format chars (%) from output ReplaceStr(line, line_escaped, sizeof(line_escaped), "%", "%%"); fprintf(fp, "%s\n", line_escaped); count++; /* If we can't send mail, log to syslog */ if (strlen(config->mail_to_address) == 0) { strncat(line_escaped, "\n", sizeof(line_escaped) - 1 - strlen(line_escaped)); if ((strchr(line_escaped, '\n')) == NULL) { line_escaped[sizeof(line_escaped) - 2] = '\n'; } CfOut(cf_inform, "", "%s", line_escaped); } line[0] = '\0'; line_escaped[0] = '\0'; } } cf_pclose(pp); CfDebug("Closing fp\n"); fclose(fp); CfOut(cf_verbose, "", " -> Command is complete\n"); if (count) { CfOut(cf_verbose, "", " -> Mailing result\n"); MailResult(config, filename); } else { CfOut(cf_verbose, "", " -> No output\n"); unlink(filename); } }
static bool IsReadReady(int fd, int timeout_sec) { fd_set rset; FD_ZERO(&rset); FD_SET(fd, &rset); struct timeval tv = { .tv_sec = timeout_sec, .tv_usec = 0, }; int ret = select(fd + 1, &rset, NULL, NULL, &tv); if(ret < 0) { Log(LOG_LEVEL_ERR, "IsReadReady: Failed checking for data. (select: %s)", GetErrorStr()); return false; } if(FD_ISSET(fd, &rset)) { return true; } if(ret == 0) // timeout { return false; } // can we get here? Log(LOG_LEVEL_ERR, "IsReadReady: Unknown outcome (ret > 0 but our only fd is not set). (select: %s)", GetErrorStr()); return false; } #if defined(__hpux) && defined(__GNUC__) #pragma GCC diagnostic warning "-Wstrict-aliasing" #endif #endif /* __MINGW32__ */ void LocalExec(const ExecConfig *config) { time_t starttime = time(NULL); void *thread_name = ThreadUniqueName(); { char starttime_str[64]; cf_strtimestamp_local(starttime, starttime_str); if (LEGACY_OUTPUT) { Log(LOG_LEVEL_VERBOSE, "------------------------------------------------------------------"); Log(LOG_LEVEL_VERBOSE, " LocalExec(%sscheduled) at %s", config->scheduled_run ? "" : "not ", starttime_str); Log(LOG_LEVEL_VERBOSE, "------------------------------------------------------------------"); } else { Log(LOG_LEVEL_VERBOSE, "LocalExec(%sscheduled) at %s", config->scheduled_run ? "" : "not ", starttime_str); } } /* Need to make sure we have LD_LIBRARY_PATH here or children will die */ char cmd[CF_BUFSIZE]; if (strlen(config->exec_command) > 0) { strncpy(cmd, config->exec_command, CF_BUFSIZE - 1); if (!strstr(cmd, "-Dfrom_cfexecd")) { strcat(cmd, " -Dfrom_cfexecd"); } } else { ConstructFailsafeCommand(config->scheduled_run, cmd); } char esc_command[CF_BUFSIZE]; strncpy(esc_command, MapName(cmd), CF_BUFSIZE - 1); char line[CF_BUFSIZE]; snprintf(line, CF_BUFSIZE - 1, "_%jd_%s", (intmax_t) starttime, CanonifyName(ctime(&starttime))); char filename[CF_BUFSIZE]; { char canonified_fq_name[CF_BUFSIZE]; strlcpy(canonified_fq_name, config->fq_name, CF_BUFSIZE); CanonifyNameInPlace(canonified_fq_name); snprintf(filename, CF_BUFSIZE - 1, "%s/outputs/cf_%s_%s_%p", CFWORKDIR, canonified_fq_name, line, thread_name); MapName(filename); } /* What if no more processes? Could sacrifice and exec() - but we need a sentinel */ FILE *fp = fopen(filename, "w"); if (!fp) { Log(LOG_LEVEL_ERR, "Couldn't open '%s' - aborting exec. (fopen: %s)", filename, GetErrorStr()); return; } #if !defined(__MINGW32__) /* * Don't inherit this file descriptor on fork/exec */ if (fileno(fp) != -1) { fcntl(fileno(fp), F_SETFD, FD_CLOEXEC); } #endif Log(LOG_LEVEL_VERBOSE, "Command => %s", cmd); FILE *pp = cf_popen_sh(esc_command, "r"); if (!pp) { Log(LOG_LEVEL_ERR, "Couldn't open pipe to command '%s'. (cf_popen: %s)", cmd, GetErrorStr()); fclose(fp); return; } Log(LOG_LEVEL_VERBOSE, "Command is executing...%s", esc_command); int count = 0; for (;;) { if(!IsReadReady(fileno(pp), (config->agent_expireafter * SECONDS_PER_MINUTE))) { char errmsg[CF_MAXVARSIZE]; snprintf(errmsg, sizeof(errmsg), "cf-execd: !! Timeout waiting for output from agent (agent_expireafter=%d) - terminating it", config->agent_expireafter); Log(LOG_LEVEL_ERR, "%s", errmsg); fprintf(fp, "%s\n", errmsg); count++; pid_t pid_agent; if(PipeToPid(&pid_agent, pp)) { ProcessSignalTerminate(pid_agent); } else { Log(LOG_LEVEL_ERR, "Could not get PID of agent"); } break; } ssize_t res = CfReadLine(line, CF_BUFSIZE, pp); if (res == 0) { break; } if (res == -1) { Log(LOG_LEVEL_ERR, "Unable to read output from command '%s'. (cfread: %s)", cmd, GetErrorStr()); cf_pclose(pp); return; } bool print = false; for (const char *sp = line; *sp != '\0'; sp++) { if (!isspace((int) *sp)) { print = true; break; } } if (print) { char line_escaped[sizeof(line) * 2]; // we must escape print format chars (%) from output ReplaceStr(line, line_escaped, sizeof(line_escaped), "%", "%%"); fprintf(fp, "%s\n", line_escaped); count++; /* If we can't send mail, log to syslog */ if (strlen(config->mail_to_address) == 0) { strncat(line_escaped, "\n", sizeof(line_escaped) - 1 - strlen(line_escaped)); if ((strchr(line_escaped, '\n')) == NULL) { line_escaped[sizeof(line_escaped) - 2] = '\n'; } Log(LOG_LEVEL_INFO, "%s", line_escaped); } line[0] = '\0'; line_escaped[0] = '\0'; } } cf_pclose(pp); Log(LOG_LEVEL_DEBUG, "Closing fp"); fclose(fp); Log(LOG_LEVEL_VERBOSE, "Command is complete"); if (count) { Log(LOG_LEVEL_VERBOSE, "Mailing result"); MailResult(config, filename); } else { Log(LOG_LEVEL_VERBOSE, "No output"); unlink(filename); } }
void RemoteSysLog(int log_priority, const char *log_string) { int sd, rfc3164_len = 1024; char message[CF_BUFSIZE]; time_t now = time(NULL); int pri = log_priority | FACILITY; int err; struct addrinfo query, *response, *ap; char strport[CF_MAXVARSIZE]; snprintf(strport, CF_MAXVARSIZE - 1, "%u", (unsigned) SYSLOG_PORT); memset(&query, 0, sizeof(query)); query.ai_family = AF_UNSPEC; query.ai_socktype = SOCK_DGRAM; if ((err = getaddrinfo(SYSLOG_HOST, strport, &query, &response)) != 0) { Log(LOG_LEVEL_INFO, "Unable to find syslog_host or service: (%s/%s) %s", SYSLOG_HOST, strport, gai_strerror(err)); return; } for (ap = response; ap != NULL; ap = ap->ai_next) { /* No DNS lookup, just convert IP address to string. */ char txtaddr[CF_MAX_IP_LEN] = ""; getnameinfo(ap->ai_addr, ap->ai_addrlen, txtaddr, sizeof(txtaddr), NULL, 0, NI_NUMERICHOST); Log(LOG_LEVEL_VERBOSE, "Connect to syslog '%s' = '%s' on port '%s'", SYSLOG_HOST, txtaddr, strport); if ((sd = socket(ap->ai_family, ap->ai_socktype, IPPROTO_UDP)) == -1) { Log(LOG_LEVEL_INFO, "Couldn't open a socket. (socket: %s)", GetErrorStr()); continue; } else { char timebuffer[26]; snprintf(message, rfc3164_len, "<%u>%.15s %s %s", pri, cf_strtimestamp_local(now, timebuffer) + 4, VFQNAME, log_string); err = sendto(sd, message, strlen(message), 0, ap->ai_addr, ap->ai_addrlen); if (err == -1) { Log(LOG_LEVEL_VERBOSE, "Couldn't send '%s' to syslog server '%s'. (sendto: %s)", message, SYSLOG_HOST, GetErrorStr()); } else { Log(LOG_LEVEL_VERBOSE, "Syslog message: '%s' to server '%s'", message, SYSLOG_HOST); } close(sd); } } freeaddrinfo(response); }
void SetPolicyServer(char *name) /* * If name contains a string, it's written to file, * if not, name is filled with the contents of file. */ { char file[CF_BUFSIZE]; FILE *fout, *fin; char fileContents[CF_MAXVARSIZE] = { 0 }; snprintf(file, CF_BUFSIZE - 1, "%s/policy_server.dat", CFWORKDIR); MapName(file); if ((fin = fopen(file, "r")) != NULL) { fscanf(fin, "%1023s", fileContents); fclose(fin); } // update file if different and we know what to put there if ((NULL_OR_EMPTY(name)) && (!NULL_OR_EMPTY(fileContents))) { snprintf(name, CF_MAXVARSIZE, "%s", fileContents); } else if ((!NULL_OR_EMPTY(name)) && (strcmp(name, fileContents) != 0)) { if ((fout = fopen(file, "w")) == NULL) { CfOut(cf_error, "fopen", "Unable to write policy server file! (%s)", file); return; } fprintf(fout, "%s", name); fclose(fout); } if (NULL_OR_EMPTY(name)) { // avoids "Scalar item in servers => { } in rvalue is out of bounds ..." // when NovaBase is checked with unprivileged (not bootstrapped) cf-promises NewScalar("sys", "policy_hub", "undefined", cf_str); } else { NewScalar("sys", "policy_hub", name, cf_str); } // Get the timestamp on policy update snprintf(file, CF_MAXVARSIZE, "%s/masterfiles/cf_promises_validated", CFWORKDIR); MapName(file); struct stat sb; if ((cfstat(file, &sb)) != 0) { return; } char timebuf[26]; cf_strtimestamp_local(sb.st_mtime, timebuf); NewScalar("sys", "last_policy_update", timebuf, cf_str); }
void UpdateLastSeen() // This function is temporarily or permanently deprecated { double lsea = LASTSEENEXPIREAFTER; int intermittency = false,qsize,ksize; struct CfKeyHostSeen q,newq; double lastseen,delta2; void *stored; CF_DB *dbp = NULL,*dbpent = NULL; CF_DBC *dbcp; char name[CF_BUFSIZE],*key; struct Rlist *rp; struct CfKeyBinding *kp; time_t now = time(NULL); static time_t then; if (now < then + 300 && then > 0 && then <= now + 300) { // Rate limiter return; } then = now; CfOut(cf_verbose,""," -> Writing last-seen observations"); ThreadLock(cft_server_keyseen); if (SERVER_KEYSEEN == NULL) { ThreadUnlock(cft_server_keyseen); CfOut(cf_verbose,""," -> Keyring is empty"); return; } if (BooleanControl("control_agent",CFA_CONTROLBODY[cfa_intermittency].lval)) { CfOut(cf_inform,""," -> Recording intermittency"); intermittency = true; } snprintf(name,CF_BUFSIZE-1,"%s/%s",CFWORKDIR,CF_LASTDB_FILE); MapName(name); if (!OpenDB(name,&dbp)) { ThreadUnlock(cft_server_keyseen); return; } /* First scan for hosts that have moved address and purge their records so that the database always has a 1:1 relationship between keyhash and IP address */ if (!NewDBCursor(dbp,&dbcp)) { ThreadUnlock(cft_server_keyseen); CfOut(cf_inform,""," !! Unable to scan class db"); return; } while(NextDB(dbp,dbcp,&key,&ksize,&stored,&qsize)) { memcpy(&q,stored,sizeof(q)); lastseen = (double)now - q.Q.q; if (lastseen > lsea) { CfOut(cf_verbose,""," -> Last-seen record for %s expired after %.1lf > %.1lf hours\n",key,lastseen/3600,lsea/3600); DeleteDB(dbp,key); } for (rp = SERVER_KEYSEEN; rp != NULL; rp=rp->next) { kp = (struct CfKeyBinding *) rp->item; if ((strcmp(q.address,kp->address) == 0) && (strcmp(key+1,kp->name+1) != 0)) { CfOut(cf_verbose,""," ! Deleting %s's address (%s=%d) as this host %s seems to have moved elsewhere (%s=5d)",key,kp->address,strlen(kp->address),kp->name,q.address,strlen(q.address)); DeleteDB(dbp,key); } } } DeleteDBCursor(dbp,dbcp); /* Now perform updates with the latest data */ for (rp = SERVER_KEYSEEN; rp != NULL; rp=rp->next) { kp = (struct CfKeyBinding *) rp->item; now = kp->timestamp; if (intermittency) { /* Open special file for peer entropy record - INRIA intermittency */ snprintf(name,CF_BUFSIZE-1,"%s/lastseen/%s.%s",CFWORKDIR,CF_LASTDB_FILE,kp->name); MapName(name); if (!OpenDB(name,&dbpent)) { continue; } } if (ReadDB(dbp,kp->name,&q,sizeof(q))) { lastseen = (double)now - q.Q.q; if (q.Q.q <= 0) { lastseen = 300; q.Q.expect = 0; q.Q.var = 0; } newq.Q.q = (double)now; newq.Q.expect = GAverage(lastseen,q.Q.expect,0.4); delta2 = (lastseen - q.Q.expect)*(lastseen - q.Q.expect); newq.Q.var = GAverage(delta2,q.Q.var,0.4); strncpy(newq.address,kp->address,CF_ADDRSIZE-1); } else { lastseen = 0.0; newq.Q.q = (double)now; newq.Q.expect = 0.0; newq.Q.var = 0.0; strncpy(newq.address,kp->address,CF_ADDRSIZE-1); } if (lastseen > lsea) { CfOut(cf_verbose,""," -> Last-seen record for %s expired after %.1lf > %.1lf hours\n",kp->name,lastseen/3600,lsea/3600); DeleteDB(dbp,kp->name); } else { char timebuf[26]; CfOut(cf_verbose,""," -> Last saw %s (alias %s) at %s (noexpiry %.1lf <= %.1lf)\n",kp->name,kp->address,cf_strtimestamp_local(now,timebuf),lastseen/3600,lsea/3600); WriteDB(dbp,kp->name,&newq,sizeof(newq)); if (intermittency) { WriteDB(dbpent,GenTimeKey(now),&newq,sizeof(newq)); } } if (intermittency && dbpent) { CloseDB(dbpent); } } ThreadUnlock(cft_server_keyseen); }
void RemoteSysLog(int log_priority, const char *log_string) { time_t now = time(NULL); struct addrinfo query = { 0 }, *response = NULL; char strport[PRINTSIZE(unsigned)]; xsnprintf(strport, sizeof(strport), "%u", (unsigned) SYSLOG_PORT); query.ai_family = AF_UNSPEC; query.ai_socktype = SOCK_DGRAM; int err = getaddrinfo(SYSLOG_HOST, strport, &query, &response); if (err != 0) { Log(LOG_LEVEL_INFO, "Unable to find syslog_host or service: (%s/%s) %s", SYSLOG_HOST, strport, gai_strerror(err)); if (response != NULL) { freeaddrinfo(response); } return; } for (const struct addrinfo *ap = response; ap != NULL; ap = ap->ai_next) { /* No DNS lookup, just convert IP address to string. */ char txtaddr[CF_MAX_IP_LEN] = ""; getnameinfo(ap->ai_addr, ap->ai_addrlen, txtaddr, sizeof(txtaddr), NULL, 0, NI_NUMERICHOST); Log(LOG_LEVEL_VERBOSE, "Connect to syslog '%s' = '%s' on port '%s'", SYSLOG_HOST, txtaddr, strport); int sd = socket(ap->ai_family, ap->ai_socktype, IPPROTO_UDP); if (sd == -1) { Log(LOG_LEVEL_INFO, "Couldn't open a socket. (socket: %s)", GetErrorStr()); continue; } else { const size_t rfc3164_len = 1024; char message[rfc3164_len]; char timebuffer[26]; pid_t pid = getpid(); snprintf(message, sizeof(message), "<%i>%.15s %s %s[%d]: %s", log_priority | SYSLOG_FACILITY, cf_strtimestamp_local(now, timebuffer) + 4, VFQNAME, VPREFIX, pid, log_string); err = sendto(sd, message, strlen(message), 0, ap->ai_addr, ap->ai_addrlen); if (err == -1) { Log(LOG_LEVEL_VERBOSE, "Couldn't send '%s' to syslog server '%s'. (sendto: %s)", message, SYSLOG_HOST, GetErrorStr()); } else { Log(LOG_LEVEL_VERBOSE, "Syslog message: '%s' to server '%s'", message, SYSLOG_HOST); } close(sd); } } freeaddrinfo(response); }
static void UpdateLastSawHost(char *rkey, char *ipaddress) { CF_DB *dbp = NULL; KeyHostSeen q, newq; double lastseen, delta2; time_t now = time(NULL); char timebuf[26]; if (!OpenDB(&dbp, dbid_lastseen)) { CfOut(cf_inform, "", " !! Unable to open last seen db"); return; } if (ReadDB(dbp, rkey, &q, sizeof(q))) { lastseen = (double) now - q.Q.q; if (q.Q.q <= 0) { lastseen = 300; q.Q = QDefinite(0.0); } newq.Q.q = (double) now; newq.Q.dq = newq.Q.q - q.Q.q; newq.Q.expect = GAverage(lastseen, q.Q.expect, 0.4); delta2 = (lastseen - q.Q.expect) * (lastseen - q.Q.expect); newq.Q.var = GAverage(delta2, q.Q.var, 0.4); strncpy(newq.address, ipaddress, CF_ADDRSIZE - 1); } else { lastseen = 0.0; newq.Q.q = (double) now; newq.Q.dq = 0; newq.Q.expect = 0.0; newq.Q.var = 0.0; strncpy(newq.address, ipaddress, CF_ADDRSIZE - 1); } if (strcmp(rkey + 1, PUBKEY_DIGEST) == 0) { Item *ip; int match = false; for (ip = IPADDRESSES; ip != NULL; ip = ip->next) { if (strcmp(VIPADDRESS, ip->name) == 0) { match = true; break; } if (strcmp(ipaddress, ip->name) == 0) { match = true; break; } } if (!match) { CfOut(cf_verbose, "", " ! Not updating last seen, as this appears to be a host with a duplicate key"); CloseDB(dbp); return; } } CfOut(cf_verbose, "", " -> Last saw %s (alias %s) at %s\n", rkey, ipaddress, cf_strtimestamp_local(now, timebuf)); PurgeMultipleIPReferences(dbp, rkey, ipaddress); WriteDB(dbp, rkey, &newq, sizeof(newq)); CloseDB(dbp); }
char *cf_ctime(const time_t *timep) { static char buf[26]; return cf_strtimestamp_local(*timep, buf); }