static int read_tcp(const char *proc, const char *type, llist *l, probe_ctx *ctx) { int line = 0; FILE *f; char buf[256]; unsigned long rxq, txq, time_len, retr, inode; unsigned local_port, rem_port, uid; int d, state, timer_run, timeout; char rem_addr[128], local_addr[128], more[512]; f = fopen(proc, "rt"); if (f == NULL) { if (errno != ENOENT) return 1; else return 0; } __fsetlocking(f, FSETLOCKING_BYCALLER); while (fgets(buf, sizeof(buf), f)) { if (line == 0) { line++; continue; } more[0] = 0; sscanf(buf, "%d: %64[0-9A-Fa-f]:%X %64[0-9A-Fa-f]:%X %X " "%lX:%lX %X:%lX %lX %d %d %lu %512s\n", &d, local_addr, &local_port, rem_addr, &rem_port, &state, &txq, &rxq, &timer_run, &time_len, &retr, &uid, &timeout, &inode, more); char src[NI_MAXHOST], dest[NI_MAXHOST]; addr_convert(local_addr, src, NI_MAXHOST); addr_convert(rem_addr, dest, NI_MAXHOST); dI("Have tcp port: %s:%u\n", src, local_port); if (eval_data(type, src, local_port)) { struct result_info r; r.proto = type; r.laddr = src; r.lport = local_port; r.raddr = dest; r.rport = rem_port; if (list_find_inode(l, inode)) { report_finding(&r, l, ctx); } else { report_finding(&r, NULL, ctx); } } } fclose(f); return 0; }
static int read_packet(llist *l, probe_ctx *ctx, oval_schema_version_t over) { int line = 0; FILE *f; char buf[256]; void *s; int refcnt, sk_type, ifindex, running; unsigned long inode; unsigned rmem, uid, proto_num; struct interface_t interface; f = fopen("/proc/net/packet", "rt"); if (f == NULL) { if (errno != ENOENT) return 1; else return 0; } __fsetlocking(f, FSETLOCKING_BYCALLER); while (fgets(buf, sizeof(buf), f)) { if (line == 0) { line++; continue; } /* follow structure from net/packet/af_packet.c */ sscanf(buf, "%p %d %d %04x %d %d %u %u %lu\n", &s, &refcnt, &sk_type, &proto_num, &ifindex, &running, &rmem, &uid, &inode ); if (list_find_inode(l, inode) && get_interface(ifindex, &interface)) { struct result_info r; SEXP_t *r0; dI("Have interface_name: %s, hw_address: %s\n", interface.interface_name, interface.hw_address); r0 = SEXP_string_newf("%s", interface.interface_name); if (probe_entobj_cmp(interface_name_ent, r0) != OVAL_RESULT_TRUE) { SEXP_free(r0); continue; } SEXP_free(r0); r.interface_name = interface.interface_name; r.protocol = oscap_enum_to_string(ProtocolType, proto_num); r.hw_address = interface.hw_address; report_finding(&r, l, ctx, over); } } fclose(f); return 0; }
static int read_password(SEXP_t *un_ent, probe_ctx *ctx, oval_schema_version_t over) { struct passwd *pw; while ((pw = getpwent())) { SEXP_t *un; dI("Have user: %s", pw->pw_name); un = SEXP_string_newf("%s", pw->pw_name); if (probe_entobj_cmp(un_ent, un) == OVAL_RESULT_TRUE) { struct result_info r; r.username = pw->pw_name; r.password = pw->pw_passwd; r.user_id = pw->pw_uid; r.group_id = pw->pw_gid; r.gcos = pw->pw_gecos; r.home_dir = pw->pw_dir; r.login_shell = pw->pw_shell; r.last_login = -1; if (oval_schema_version_cmp(over, OVAL_SCHEMA_VERSION(5.10)) >= 0) { FILE *ll_fp = fopen(_PATH_LASTLOG, "r"); if (ll_fp != NULL) { struct lastlog ll; if (fseeko(ll_fp, (off_t)pw->pw_uid * sizeof(ll), SEEK_SET) == 0) if (fread((char *)&ll, sizeof(ll), 1, ll_fp) == 1) r.last_login = (int64_t)ll.ll_time; fclose(ll_fp); } } report_finding(&r, ctx, over); } SEXP_free(un); } endpwent(); return 0; }
static int read_process(SEXP_t *cmd_ent, probe_ctx *ctx) { int err = 1; DIR *d; struct dirent *ent; d = opendir("/proc"); if (d == NULL) return err; psinfo_t *psinfo; // Scan the directories while (( ent = readdir(d) )) { int fd, len; char buf[336]; int pid; unsigned sched_policy; SEXP_t *cmd_sexp; // Skip non-process dir entries if(*ent->d_name<'0' || *ent->d_name>'9') continue; errno = 0; pid = strtol(ent->d_name, NULL, 10); if (errno || pid == 2) // skip err & kthreads continue; // Parse up the stat file for the proc snprintf(buf, 32, "/proc/%d/psinfo", pid); fd = open(buf, O_RDONLY, 0); if (fd < 0) continue; len = read(fd, buf, sizeof buf); close(fd); if (len < 336) continue; // The psinfo file contains a psinfo struct; this typecast gets us the struct directly psinfo = (psinfo_t *) buf; err = 0; // If we get this far, no permission problems dI("Have command: %s\n", psinfo->pr_fname); cmd_sexp = SEXP_string_newf("%s", psinfo->pr_fname); if (probe_entobj_cmp(cmd_ent, cmd_sexp) == OVAL_RESULT_TRUE) { struct result_info r; char tbuf[32], sbuf[32]; int tday,tyear; time_t s_time; struct tm *proc, *now; const char *fmt; int fixfmt_year; r.scheduling_class = malloc(PRCLSZ); strncpy(r.scheduling_class, (psinfo->pr_lwp).pr_clname, sizeof(r.scheduling_class)); // Get the start time s_time = time(NULL); now = localtime(&s_time); tyear = now->tm_year; tday = now->tm_yday; // Get current time s_time = psinfo->pr_start.tv_sec; proc = localtime(&s_time); // Select format based on how long we've been running // // FROM THE SPEC: // "This is the time of day the process started formatted in HH:MM:SS if // the same day the process started or formatted as MMM_DD (Ex.: Feb_5) // if process started the previous day or further in the past." // if (tday != proc->tm_yday || tyear != proc->tm_year) fmt = "%b_%d"; else fmt = "%H:%M:%S"; strftime(sbuf, sizeof(sbuf), fmt, proc); r.command = psinfo->pr_fname; r.exec_time = convert_time(psinfo->pr_time.tv_sec, tbuf, sizeof(tbuf)); r.pid = psinfo->pr_pid; r.ppid = psinfo->pr_ppid; r.priority = (psinfo->pr_lwp).pr_pri; r.ruid = psinfo->pr_uid; r.start_time = sbuf; r.tty = oscap_sprintf("%s", psinfo->pr_ttydev); r.user_id = psinfo->pr_euid; report_finding(&r, ctx); } SEXP_free(cmd_sexp); } closedir(d); return err; }
static int read_process(SEXP_t *cmd_ent, probe_ctx *ctx) { int err = 1; DIR *d; struct dirent *ent; d = opendir("/proc"); if (d == NULL) return err; // Get the time tick hertz ticks = (unsigned long)sysconf(_SC_CLK_TCK); get_boot_time(); // Scan the directories while (( ent = readdir(d) )) { int fd, len; char buf[256]; char *tmp, cmd[16], state, tty_dev[128]; int pid, ppid, pgrp, session, tty_nr, tpgid; unsigned flags, sched_policy; unsigned long minflt, cminflt, majflt, cmajflt, uutime, ustime; long cutime, cstime, priority, cnice, nthreads, itrealvalue; unsigned long long start; SEXP_t *cmd_sexp; // Skip non-process dir entries if(*ent->d_name<'0' || *ent->d_name>'9') continue; errno = 0; pid = strtol(ent->d_name, NULL, 10); if (errno || pid == 2) // skip err & kthreads continue; // Parse up the stat file for the proc snprintf(buf, 32, "/proc/%d/stat", pid); fd = open(buf, O_RDONLY, 0); if (fd < 0) continue; len = read(fd, buf, sizeof buf - 1); close(fd); if (len < 40) continue; buf[len] = 0; tmp = strrchr(buf, ')'); if (tmp) *tmp = 0; else continue; memset(cmd, 0, sizeof(cmd)); sscanf(buf, "%d (%15c", &ppid, cmd); sscanf(tmp+2, "%c %d %d %d %d %d " "%u %lu %lu %lu %lu " "%lu %lu %lu %ld %ld " "%ld %ld %ld %llu", &state, &ppid, &pgrp, &session, &tty_nr, &tpgid, &flags, &minflt, &cminflt, &majflt, &cmajflt, &uutime, &ustime, &cutime, &cstime, &priority, &cnice, &nthreads, &itrealvalue, &start ); // Skip kthreads if (ppid == 2) continue; err = 0; // If we get this far, no permission problems dI("Have command: %s\n", cmd); cmd_sexp = SEXP_string_newf("%s", cmd); if (probe_entobj_cmp(cmd_ent, cmd_sexp) == OVAL_RESULT_TRUE) { struct result_info r; unsigned long t = uutime/ticks + ustime/ticks; char tbuf[32], sbuf[32]; int tday,tyear; time_t s_time; struct tm *proc, *now; const char *fmt; // Now get scheduler policy sched_policy = sched_getscheduler(pid); switch (sched_policy) { case SCHED_OTHER: r.scheduling_class = "TS"; break; case SCHED_BATCH: r.scheduling_class = "B"; break; #ifdef SCHED_IDLE case SCHED_IDLE: r.scheduling_class = "#5"; break; #endif case SCHED_FIFO: r.scheduling_class = "FF"; break; case SCHED_RR: r.scheduling_class = "RR"; break; default: r.scheduling_class = "?"; break; } // Calculate the start time s_time = time(NULL); now = localtime(&s_time); tyear = now->tm_year; tday = now->tm_yday; s_time = boot + (start / ticks); proc = localtime(&s_time); // Select format based on how long we've been running // // FROM THE SPEC: // "This is the time of day the process started formatted in HH:MM:SS if // the same day the process started or formatted as MMM_DD (Ex.: Feb_5) // if process started the previous day or further in the past." // if (tday != proc->tm_yday || tyear != proc->tm_year) fmt = "%b_%d"; else fmt = "%H:%M:%S"; strftime(sbuf, sizeof(sbuf), fmt, proc); r.command = cmd; r.exec_time = convert_time(t, tbuf, sizeof(tbuf)); r.pid = pid; r.ppid = ppid; r.priority = priority; r.start_time = sbuf; dev_to_tty(tty_dev, sizeof(tty_dev), (dev_t) tty_nr, pid, ABBREV_DEV); r.tty = tty_dev; get_uids(pid, &r); report_finding(&r, ctx); } SEXP_free(cmd_sexp); } closedir(d); return err; }
static int read_process(SEXP_t *cmd_ent, SEXP_t *pid_ent, probe_ctx *ctx) { int err = 1, max_cap_id; DIR *d; struct dirent *ent; oval_version_t oval_version; d = opendir("/proc"); if (d == NULL) return err; // Get the time tick hertz ticks = (unsigned long)sysconf(_SC_CLK_TCK); get_boot_time(); oval_version = probe_obj_get_schema_version(probe_ctx_getobject(ctx)); if (oval_version_cmp(oval_version, OVAL_VERSION(5.11)) < 0) { max_cap_id = OVAL_5_8_MAX_CAP_ID; } else { max_cap_id = OVAL_5_11_MAX_CAP_ID; } struct oscap_buffer *cmdline_buffer = oscap_buffer_new(); char cmd_buffer[1 + 15 + 11 + 1]; // Format:" [ cmd:15 ] <defunc>" cmd_buffer[0] = '['; // Scan the directories while (( ent = readdir(d) )) { int fd, len; char buf[256]; char *tmp, state, tty_dev[128]; int pid, ppid, pgrp, session, tty_nr, tpgid; unsigned flags, sched_policy; unsigned long minflt, cminflt, majflt, cmajflt, uutime, ustime; long cutime, cstime, priority, cnice, nthreads, itrealvalue; unsigned long long start; SEXP_t *cmd_sexp = NULL, *pid_sexp = NULL; // Skip non-process58 dir entries if(*ent->d_name<'0' || *ent->d_name>'9') continue; errno = 0; pid = strtol(ent->d_name, NULL, 10); if (errno || pid == 2) // skip err & kthreads continue; // Parse up the stat file for the proc snprintf(buf, 32, "/proc/%d/stat", pid); fd = open(buf, O_RDONLY, 0); if (fd < 0) continue; len = read(fd, buf, sizeof buf - 1); close(fd); if (len < 40) continue; buf[len] = 0; tmp = strrchr(buf, ')'); if (tmp) *tmp = 0; else continue; memset(cmd_buffer + 1, 0, sizeof(cmd_buffer)-1); // clear cmd after starting '[' sscanf(buf, "%d (%15c", &ppid, cmd_buffer + 1); sscanf(tmp+2, "%c %d %d %d %d %d " "%u %lu %lu %lu %lu " "%lu %lu %lu %ld %ld " "%ld %ld %ld %llu", &state, &ppid, &pgrp, &session, &tty_nr, &tpgid, &flags, &minflt, &cminflt, &majflt, &cmajflt, &uutime, &ustime, &cutime, &cstime, &priority, &cnice, &nthreads, &itrealvalue, &start ); // Skip kthreads if (ppid == 2) continue; const char* cmd; if (state == 'Z') { // zombie cmd = make_defunc_str(cmd_buffer); } else { snprintf(buf, 32, "/proc/%d/cmdline", pid); if (get_process_cmdline(buf, cmdline_buffer)) { cmd = oscap_buffer_get_raw(cmdline_buffer); // use full cmdline } else { cmd = cmd_buffer + 1; } } err = 0; // If we get this far, no permission problems dI("Have command: %s\n", cmd); cmd_sexp = SEXP_string_newf("%s", cmd); pid_sexp = SEXP_number_newu_32(pid); if ((cmd_sexp == NULL || probe_entobj_cmp(cmd_ent, cmd_sexp) == OVAL_RESULT_TRUE) && (pid_sexp == NULL || probe_entobj_cmp(pid_ent, pid_sexp) == OVAL_RESULT_TRUE) ) { struct result_info r; unsigned long t = uutime/ticks + ustime/ticks; char tbuf[32], sbuf[32], *selinux_domain_label, **posix_capabilities; int tday,tyear; time_t s_time; struct tm *proc, *now; const char *fmt; // Now get scheduler policy sched_policy = sched_getscheduler(pid); switch (sched_policy) { case SCHED_OTHER: r.scheduling_class = "TS"; break; case SCHED_BATCH: r.scheduling_class = "B"; break; #ifdef SCHED_IDLE case SCHED_IDLE: r.scheduling_class = "#5"; break; #endif case SCHED_FIFO: r.scheduling_class = "FF"; break; case SCHED_RR: r.scheduling_class = "RR"; break; default: r.scheduling_class = "?"; break; } // Calculate the start time s_time = time(NULL); now = localtime(&s_time); tyear = now->tm_year; tday = now->tm_yday; s_time = boot + (start / ticks); proc = localtime(&s_time); // Select format based on how long we've been running // // FROM THE SPEC: // "This is the time of day the process started formatted in HH:MM:SS if // the same day the process started or formatted as MMM_DD (Ex.: Feb_5) // if process started the previous day or further in the past." // if (tday != proc->tm_yday || tyear != proc->tm_year) fmt = "%b_%d"; else fmt = "%H:%M:%S"; strftime(sbuf, sizeof(sbuf), fmt, proc); r.command_line = cmd; r.exec_time = convert_time(t, tbuf, sizeof(tbuf)); r.pid = pid; r.ppid = ppid; r.priority = priority; r.start_time = sbuf; dev_to_tty(tty_dev, sizeof(tty_dev), (dev_t) tty_nr, pid, ABBREV_DEV); r.tty = tty_dev; r.exec_shield = (get_exec_shield_status(pid) > 0); selinux_domain_label = get_selinux_label(pid); r.selinux_domain_label = selinux_domain_label; posix_capabilities = get_posix_capability(pid, max_cap_id); r.posix_capability = posix_capabilities; r.session_id = session; get_uids(pid, &r); report_finding(&r, ctx); if (selinux_domain_label != NULL) free(selinux_domain_label); if (posix_capabilities != NULL) { char **posix_capabilities_p = posix_capabilities; while (*posix_capabilities_p) free(*posix_capabilities_p++); free(posix_capabilities); } } SEXP_free(cmd_sexp); SEXP_free(pid_sexp); } closedir(d); oscap_buffer_free(cmdline_buffer); return err; }