int procauth_addprocess(char *conf) { procpid pp; int srvcode; char pidfilename[FILENAME_MAX]; /* ensure the filename length is within system limit */ if (memchr(conf, '\0', FILENAME_MAX) == NULL) return -1; /* conf format: service_code:pid_filename */ if (sscanf(conf, "%d:%s", &srvcode, pidfilename) != 2) return -1; pp.service_code = srvcode; pp.filename = (char *)malloc(strlen(pidfilename) + 1); strcpy(pp.filename, pidfilename); /* get current pid */ pp.current_pid = procauth_getprocpid(pidfilename); /* append process block to the list */ list_append(&proclist, &pp); sshguard_log(LOG_INFO, "authenticating service %d with process ID from %s", pp.service_code, pp.filename); return 0; }
static int install_temporary_conffile() { if (rename(tempflname, HOSTSFILE_PATH) != 0) { sshguard_log(LOG_CRIT, "OUCHH! Could not rename temp file '%s' to '%s' (%s).", tempflname, HOSTSFILE_PATH, strerror(errno)); return FWALL_ERR; } return FWALL_OK; }
int fw_init() { char buf[HOSTS_MAXCMDLEN]; FILE *tmp, *deny; /* set the filename of the temporary configuration file */ if (snprintf(tempflname, MAX_TEMPFILE_NAMELEN, "%s-sshguard.%u", HOSTSFILE_PATH, getpid()) >= MAX_TEMPFILE_NAMELEN) { sshguard_log(LOG_ERR, "'tempflname' buffer too small to hold '%s-sshguard.%u!'", HOSTSFILE_PATH, getpid()); return FWALL_ERR; } hosts_clearsshguardblocks(); /* place sshguard block delimiters (header/footer) into HOSTSFILE_PATH */ deny = fopen(HOSTSFILE_PATH, "r+"); if (deny == NULL) { sshguard_log(LOG_ERR, "Could not initialize " HOSTSFILE_PATH " for use by sshguard: %s", strerror(errno)); return FWALL_ERR; } tmp = make_temporary_conffile(); if (tmp == NULL) { sshguard_log(LOG_ERR, "Could not create temporary file %s!", tempflname); fclose(deny); return FWALL_ERR; } fprintf(tmp, "%s%s", HOSTS_SSHGUARD_PREFIX, HOSTS_SSHGUARD_SUFFIX); /* copy the original content of HOSTSFILE_PATH into tmp */ while (fgets(buf, HOSTS_MAXCMDLEN, deny) != NULL) { fprintf(tmp, "%s", buf); } fclose(tmp); fclose(deny); /* install temporary conf file into main file */ if (install_temporary_conffile() != FWALL_OK) return FWALL_ERR; list_init(&hosts_blockedaddrs); list_attributes_copy(&hosts_blockedaddrs, addr_service_meter, 1); list_attributes_comparator(&hosts_blockedaddrs, addr_service_comparator); return FWALL_OK; }
static pid_t procauth_getprocpid(char *filename) { FILE *pf; pid_t pid; pf = fopen(filename, "r"); if (pf == NULL) { sshguard_log(LOG_NOTICE, "unable to open pidfile '%s': %s.", filename, strerror(errno)); return -1; } if (fscanf(pf, "%d", &pid) != 1) { sshguard_log(LOG_INFO, "pid file '%s' malformed. Expecting one pid.", filename); return -1; } fclose(pf); return pid; }
static FILE *make_temporary_conffile(void) { FILE *f; f = fopen(tempflname, "w+"); if (f == NULL) return NULL; /* make sure to secure file permissions (-rw-r--r--) */ if (chmod(tempflname, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) != 0) { /* could not secure perms, return full failure */ sshguard_log(LOG_ERR, "Error in chmod(): %s", strerror(errno)); fclose(f); unlink(tempflname); return NULL; } return f; }
int procauth_refreshpids() { procpid *pp; pid_t newpid; int changed = 0; /* update each process in list with the current pid */ list_iterator_start(&proclist); while (list_iterator_hasnext(&proclist)) { pp = (procpid *)list_iterator_next(&proclist); newpid = procauth_getprocpid(pp->filename); if (newpid != pp->current_pid) changed++; pp->current_pid = newpid; } list_iterator_stop(&proclist); sshguard_log(LOG_DEBUG,"refreshing the list of pids from pidfiles... %d pids changed", changed); return changed; }
int logsuck_init() { list_init(& sources_list); list_attributes_copy(& sources_list, list_meter_sourceentry, 1); #if defined(HAVE_KQUEUE) /* will need file descriptor seeker to look up source items from fds */ list_attributes_seeker(& sources_list, list_seeker_filedescriptor); #endif #if defined(HAVE_KQUEUE) /* initialize kqueue */ if ((kq = kqueue()) == -1) { sshguard_log(LOG_CRIT, "Unable to create kqueue! %s.", strerror(errno)); return -1; } /* re-test sources every this interval */ kev_timeout.tv_sec = 1; kev_timeout.tv_nsec = 500 * 1000 * 1000; #endif return 0; }
list_t *blacklist_load(const char *filename) { char blacklist_line[BL_MAXBUF]; unsigned int linecnt; assert(blacklist_file == NULL && blacklist == NULL); blacklist_file = fopen(filename, "a+"); if (blacklist_file == NULL) { return NULL; } blacklist = (list_t *)malloc(sizeof(list_t)); list_init(blacklist); list_attributes_copy(blacklist, attacker_el_meter, 1); rewind(blacklist_file); /* loading content of the file in the blacklist */ for (linecnt = 1; fgets(blacklist_line, BL_MAXBUF, blacklist_file) != NULL; ++linecnt) { attacker_t newattacker; /* discard empty lines and lines starting with a white-space or # */ if (isspace(blacklist_line[0]) || blacklist_line[0] == '#') { while (blacklist_line[strlen(blacklist_line)-1] != '\n') { /* consume until end of line */ if (fgets(blacklist_line, BL_MAXBUF, blacklist_file) == NULL) return blacklist; } continue; } long long blacklist_time; int service_no; if (sscanf(blacklist_line, "%lld|%d|%d|%" stringify(ADDRLEN) "s", &blacklist_time, &service_no, &newattacker.attack.address.kind, newattacker.attack.address.value) != 4) { sshguard_log(LOG_NOTICE, "blacklist: ignoring malformed line %d", linecnt); continue; } newattacker.whenlast = (time_t)blacklist_time; newattacker.attack.service = (enum service)service_no; if (newattacker.attack.address.kind != ADDRKIND_IPv4 && newattacker.attack.address.kind != ADDRKIND_IPv6) { /* unknown address type */ sshguard_log(LOG_NOTICE, "blacklist: unknown address type on line %d", linecnt); continue; } /* initialization of other default information */ newattacker.attack.dangerousness = 1; newattacker.whenfirst = 0; newattacker.pardontime = 0; newattacker.numhits = 1; newattacker.cumulated_danger = 1; /* add new element to the blacklist */ list_append(blacklist, & newattacker); } atexit(blacklist_close); return blacklist; }
static int procauth_ischildof(pid_t child, pid_t parent) { int ischild; int ret; int curchild, curparent; char mystring[20]; int ps2me[2]; pid_t pid; FILE *psout; sshguard_log(LOG_DEBUG, "Testing if %d is child of %d.", (int)child, (int)parent); if (pipe(ps2me) == -1) { sshguard_log(LOG_ERR, "Can't create pipe! %s.", strerror(errno)); return 0; } /* execute ps command, pipe result to us */ if ((pid = fork()) == 0) { /* child */ close(0); dup2(ps2me[1], 1); sshguard_log(LOG_DEBUG, "Running 'ps axo pid,ppid'."); execlp("ps", "ps", "axo", "pid,ppid", NULL); sshguard_log(LOG_ERR, "Unable to run 'ps axo pid,ppid': %s.", strerror(errno)); exit(-1); } /* father */ close(ps2me[1]); /* read lines returned the ps' output, and match pschild_re */ psout = fdopen(ps2me[0], "r"); if (psout == NULL) return 0; ischild = 0; while (fgets(mystring, sizeof(mystring), psout) != NULL) { /* sshguard_log(LOG_DEBUG, "Testing child/parent line: '%s' --> %d@%d", mystring, curchild, curparent); */ sscanf(mystring, " %d %d ", & curchild, & curparent); if (curchild == child && curparent == parent) { ischild = 1; break; } } waitpid(pid, & ret, 0); fclose(psout); if (! WIFEXITED(ret) || WEXITSTATUS(ret) != 0) { sshguard_log(LOG_ERR, "ps command failed to run."); return 0; } sshguard_log(LOG_INFO, "Process %d %s child of %d.", (int)child, (ischild ? "is" : "is not"), (int)parent); /* return YES or NO answer */ if (ischild) return 1; return -1; }