X-Git-Url: http://ftp.carnet.hr/carnet-debian/scm?p=ossec-hids.git;a=blobdiff_plain;f=src%2Futil%2Fsyscheck_control.c;h=fdf645a077846ec8db6941c3fdd6baca87cd3f96;hp=71c705b0189a1d565c3c32f459a04b8822797c96;hb=3f728675941dc69d4e544d3a880a56240a6e394a;hpb=927951d1c1ad45ba9e7325f07d996154a91c911b diff --git a/src/util/syscheck_control.c b/src/util/syscheck_control.c old mode 100755 new mode 100644 index 71c705b..fdf645a --- a/src/util/syscheck_control.c +++ b/src/util/syscheck_control.c @@ -1,7 +1,4 @@ -/* @(#) $Id: ./src/util/syscheck_control.c, 2011/09/08 dcid Exp $ - */ - -/* Copyright (C) 2009 Trend Micro Inc. +/* Copyright (C) 2019 OSSEC Foundation * All right reserved. * * This program is a free software; you can redistribute it @@ -10,71 +7,71 @@ * Foundation */ - #include "addagent/manage_agents.h" #include "sec.h" - #undef ARGV0 #define ARGV0 "syscheck_control" +/* Prototypes */ +static void helpmsg(void) __attribute__((noreturn)); -/** help **/ -void helpmsg() + +static void helpmsg() { printf("\nOSSEC HIDS %s: Manages the integrity checking database.\n", ARGV0); printf("Available options:\n"); printf("\t-h This help message.\n"); - printf("\t-l List available (active or not) agents.\n"); + printf("\t-l List available (active or inactive) agents.\n"); printf("\t-lc List only active agents.\n"); - printf("\t-u Updates (clear) the database for the agent.\n"); - printf("\t-u all Updates (clear) the database for all agents.\n"); + printf("\t-u Updates (clears) the database for the agent.\n"); + printf("\t-u all Updates (clears) the database for all agents.\n"); printf("\t-i List modified files for the agent.\n"); printf("\t-r -i List modified registry entries for the agent " "(Windows only).\n"); printf("\t-f Prints information about a modified file.\n"); - printf("\t-z Used with the -f, zeroes the auto-ignore counter.\n"); - printf("\t-d Used with the -f, ignores that file.\n"); + printf("\t Must be used with -i .\n"); + printf("\t-z Used with -f, zeroes the auto-ignore counter.\n"); + printf("\t-d Used with -f, ignores that file.\n"); printf("\t-s Changes the output to CSV (comma delimited).\n"); + printf("\t-j Changes the output to JSON.\n"); + printf("\n"); + printf("\tExamples:\n"); + printf("\n"); + printf("\t'Show information about /etc/passwd from agent with ID 019'\n"); + printf("\t%s -i 019 -f /etc/passwd\n", ARGV0); exit(1); } - -/** main **/ int main(int argc, char **argv) { - char *dir = DEFAULTDIR; - char *group = GROUPGLOBAL; - char *user = USER; - char *agent_id = NULL; - char *fname = NULL; - - int gid = 0; - int uid = 0; + const char *dir = DEFAULTDIR; + const char *group = GROUPGLOBAL; + const char *user = USER; + const char *agent_id = NULL; + const char *fname = NULL; + + gid_t gid; + uid_t uid; int c = 0, info_agent = 0, update_syscheck = 0, - list_agents = 0, zero_counter = 0, - registry_only = 0; - int active_only = 0, csv_output = 0; + list_agents = 0, zero_counter = 0, + registry_only = 0; + int active_only = 0, csv_output = 0, json_output = 0; char shost[512]; + cJSON *json_root; - - - /* Setting the name */ + /* Set the name */ OS_SetName(ARGV0); - - /* user arguments */ - if(argc < 2) - { + /* User arguments */ + if (argc < 2) { helpmsg(); } - - while((c = getopt(argc, argv, "VhzrDdlcsu:i:f:")) != -1) - { - switch(c){ + while ((c = getopt(argc, argv, "VhzrDdlcsju:i:f:")) != -1) { + switch (c) { case 'V': print_version(); break; @@ -96,6 +93,9 @@ int main(int argc, char **argv) case 's': csv_output = 1; break; + case 'j': + json_output = 1; + break; case 'c': active_only++; break; @@ -104,25 +104,22 @@ int main(int argc, char **argv) break; case 'i': info_agent++; - if(!optarg) - { - merror("%s: -u needs an argument",ARGV0); + if (!optarg) { + merror("%s: -u needs an argument", ARGV0); helpmsg(); } agent_id = optarg; break; case 'f': - if(!optarg) - { - merror("%s: -u needs an argument",ARGV0); + if (!optarg) { + merror("%s: -u needs an argument", ARGV0); helpmsg(); } fname = optarg; break; case 'u': - if(!optarg) - { - merror("%s: -u needs an argument",ARGV0); + if (!optarg) { + merror("%s: -u needs an argument", ARGV0); helpmsg(); } agent_id = optarg; @@ -132,132 +129,137 @@ int main(int argc, char **argv) helpmsg(); break; } - } - - /* Getting the group name */ + /* Get the group name */ gid = Privsep_GetGroup(group); uid = Privsep_GetUser(user); - if(gid < 0) - { - ErrorExit(USER_ERROR, ARGV0, user, group); + if (uid == (uid_t) - 1 || gid == (gid_t) - 1) { + ErrorExit(USER_ERROR, ARGV0, user, group); } - - /* Setting the group */ - if(Privsep_SetGroup(gid) < 0) - { - ErrorExit(SETGID_ERROR,ARGV0, group); + /* Set the group */ + if (Privsep_SetGroup(gid) < 0) { + ErrorExit(SETGID_ERROR, ARGV0, group, errno, strerror(errno)); } - - /* Chrooting to the default directory */ - if(Privsep_Chroot(dir) < 0) - { - ErrorExit(CHROOT_ERROR, ARGV0, dir); + /* Chroot to the default directory */ + if (Privsep_Chroot(dir) < 0) { + ErrorExit(CHROOT_ERROR, ARGV0, dir, errno, strerror(errno)); } - /* Inside chroot now */ nowChroot(); - - /* Setting the user */ - if(Privsep_SetUser(uid) < 0) - { - ErrorExit(SETUID_ERROR, ARGV0, user); + /* Set the user */ + if (Privsep_SetUser(uid) < 0) { + ErrorExit(SETUID_ERROR, ARGV0, user, errno, strerror(errno)); } - - - /* Getting servers hostname */ + /* Get server hostname */ memset(shost, '\0', 512); - if(gethostname(shost, 512 -1) != 0) - { + if (gethostname(shost, 512 - 1) != 0) { strncpy(shost, "localhost", 32); - return(0); + return (0); } - - - /* Listing available agents. */ - if(list_agents) - { - if(!csv_output) - { - printf("\nOSSEC HIDS %s. List of available agents:", - ARGV0); + if (json_output) + json_root = cJSON_CreateObject(); + + /* List available agents */ + if (list_agents) { + cJSON *json_agents = NULL; + + if (json_output) { + cJSON *first = cJSON_CreateObject(); + json_agents = cJSON_CreateArray(); + cJSON_AddNumberToObject(json_root, "error", 0); + cJSON_AddStringToObject(first, "id", "000"); + cJSON_AddStringToObject(first, "name", shost); + cJSON_AddStringToObject(first, "ip", "127.0.0.1"); + cJSON_AddStringToObject(first, "status", "Active"); + cJSON_AddItemToArray(json_agents, first); + } else if (csv_output) + printf("000,%s (server),127.0.0.1,Active/Local,\n", shost); + else { + printf("\nOSSEC HIDS %s. List of available agents:", ARGV0); printf("\n ID: 000, Name: %s (server), IP: 127.0.0.1, " "Active/Local\n", shost); } - else - { - printf("000,%s (server),127.0.0.1,Active/Local,\n", shost); - } - print_agents(1, active_only, csv_output); - printf("\n"); - exit(0); - } + print_agents(1, active_only, csv_output, json_agents); + if (json_output) { + cJSON_AddItemToObject(json_root, "response", json_agents); + printf("%s", cJSON_PrintUnformatted(json_root)); + } else + printf("\n"); - /* Update syscheck database. */ - if(update_syscheck) - { - /* Cleaning all agents (and server) db. */ - if(strcmp(agent_id, "all") == 0) - { + exit(0); + } + + /* Update syscheck database */ + if (update_syscheck) { + /* Clean all agents (and server) db */ + if (strcmp(agent_id, "all") == 0) { DIR *sys_dir; struct dirent *entry; sys_dir = opendir(SYSCHECK_DIR); - if(!sys_dir) - { - ErrorExit("%s: Unable to open: '%s'", ARGV0, SYSCHECK_DIR); + if (!sys_dir) { + if (json_output) { + char buffer[1024]; + cJSON_AddNumberToObject(json_root, "error", 31); + snprintf(buffer, 1023, "%s: Unable to open: '%s'", ARGV0, SYSCHECK_DIR); + cJSON_AddStringToObject(json_root, "description", buffer); + printf("%s", cJSON_PrintUnformatted(json_root)); + exit(1); + } else + ErrorExit("%s: Unable to open: '%s'", ARGV0, SYSCHECK_DIR); } - while((entry = readdir(sys_dir)) != NULL) - { + while ((entry = readdir(sys_dir)) != NULL) { FILE *fp; - char full_path[OS_MAXSTR +1]; + char full_path[OS_MAXSTR + 1]; /* Do not even attempt to delete . and .. :) */ - if((strcmp(entry->d_name,".") == 0)|| - (strcmp(entry->d_name,"..") == 0)) - { + if ((strcmp(entry->d_name, ".") == 0) || + (strcmp(entry->d_name, "..") == 0)) { continue; } - snprintf(full_path, OS_MAXSTR,"%s/%s", SYSCHECK_DIR, + snprintf(full_path, OS_MAXSTR, "%s/%s", SYSCHECK_DIR, entry->d_name); fp = fopen(full_path, "w"); - if(fp) - { + if (fp) { fclose(fp); } - if(entry->d_name[0] == '.') - { + if (entry->d_name[0] == '.') { unlink(full_path); } } closedir(sys_dir); - printf("\n** Integrity check database updated.\n\n"); + + if (json_output) { + cJSON_AddNumberToObject(json_root, "error", 0); + cJSON_AddStringToObject(json_root, "response", "Integrity check database updated"); + printf("%s", cJSON_PrintUnformatted(json_root)); + } else + printf("\n** Integrity check database updated.\n\n"); + exit(0); } - else if((strcmp(agent_id, "000") == 0) || - (strcmp(agent_id, "local") == 0)) - { + else if ((strcmp(agent_id, "000") == 0) || + (strcmp(agent_id, "local") == 0)) { char final_dir[1024]; FILE *fp; snprintf(final_dir, 1020, "/%s/syscheck", SYSCHECK_DIR); fp = fopen(final_dir, "w"); - if(fp) - { + if (fp) { fclose(fp); } unlink(final_dir); @@ -267,131 +269,153 @@ int main(int argc, char **argv) snprintf(final_dir, 1020, "/%s/.syscheck.cpt", SYSCHECK_DIR); fp = fopen(final_dir, "w"); - if(fp) - { + if (fp) { fclose(fp); } unlink(final_dir); - printf("\n** Integrity check database updated.\n\n"); + if (json_output) { + cJSON_AddNumberToObject(json_root, "error", 0); + cJSON_AddStringToObject(json_root, "response", "Integrity check database updated"); + printf("%s", cJSON_PrintUnformatted(json_root)); + } else + printf("\n** Integrity check database updated.\n\n"); + exit(0); } - /* Database from remote agents. */ - else - { + /* Database from remote agents */ + else { int i; keystore keys; OS_ReadKeys(&keys); i = OS_IsAllowedID(&keys, agent_id); - if(i < 0) - { - printf("\n** Invalid agent id '%s'.\n", agent_id); - helpmsg(); + if (i < 0) { + if (json_output) { + char buffer[1024]; + cJSON_AddNumberToObject(json_root, "error", 33); + snprintf(buffer, 1023, "Invalid agent id '%s'.", agent_id); + cJSON_AddStringToObject(json_root, "description", buffer); + printf("%s", cJSON_PrintUnformatted(json_root)); + exit(1); + } else { + printf("\n** Invalid agent id '%s'.\n", agent_id); + helpmsg(); + } } - /* Deleting syscheck */ + /* Delete syscheck */ delete_syscheck(keys.keyentries[i]->name, keys.keyentries[i]->ip->ip, 0); - printf("\n** Integrity check database updated.\n\n"); + if (json_output) { + cJSON_AddNumberToObject(json_root, "error", 0); + cJSON_AddStringToObject(json_root, "response", "Integrity check database updated"); + printf("%s", cJSON_PrintUnformatted(json_root)); + } else + printf("\n** Integrity check database updated.\n\n"); + exit(0); } } - - /* Printing information from an agent. */ - if(info_agent) - { + /* Print information from an agent */ + if (info_agent) { int i; - char final_ip[128 +1]; - char final_mask[128 +1]; + char final_ip[IPSIZE + 4]; keystore keys; - - - if((strcmp(agent_id, "000") == 0) || - (strcmp(agent_id, "local") == 0)) - { - printf("\nIntegrity checking changes for local system '%s - %s':\n", - shost, "127.0.0.1"); - if(fname) - { - printf("Detailed information for entries matching: '%s'\n", - fname); + cJSON *json_entries = NULL; + + if (json_output) + json_entries = cJSON_CreateArray(); + + if ((strcmp(agent_id, "000") == 0) || + (strcmp(agent_id, "local") == 0)) { + if (!(csv_output || json_output)) { + printf("\nIntegrity checking changes for local system '%s - %s':\n", + shost, "127.0.0.1"); + if (fname) { + printf("Detailed information for entries matching: '%s'\n", + fname); + } } - print_syscheck(NULL, - NULL, fname, 0, 0, - csv_output, zero_counter); - } - else if(strchr(agent_id, '@')) - { - if(fname) - { + print_syscheck(NULL, NULL, fname, 0, 0, csv_output, json_entries, zero_counter); + } else if (strchr(agent_id, '@')) { + if (fname && ! (csv_output || json_output)) { printf("Detailed information for entries matching: '%s'\n", fname); } print_syscheck(agent_id, NULL, fname, registry_only, 0, - csv_output, zero_counter); - } - else - { + csv_output, json_entries, zero_counter); + } else { OS_ReadKeys(&keys); i = OS_IsAllowedID(&keys, agent_id); - if(i < 0) - { - printf("\n** Invalid agent id '%s'.\n", agent_id); - helpmsg(); + if (i < 0) { + if (json_output) { + char buffer[1024]; + cJSON_AddNumberToObject(json_root, "error", 32); + snprintf(buffer, 1023, "Invalid agent id '%s'.", agent_id); + cJSON_AddStringToObject(json_root, "description", buffer); + printf("%s", cJSON_PrintUnformatted(json_root)); + exit(1); + } else { + printf("\n** Invalid agent id '%s'.\n", agent_id); + helpmsg(); + } } - /* Getting netmask from ip. */ - final_ip[128] = '\0'; - final_mask[128] = '\0'; - getNetmask(keys.keyentries[i]->ip->netmask, final_mask, 128); - snprintf(final_ip, 128, "%s%s",keys.keyentries[i]->ip->ip, - final_mask); - - if(registry_only) - { - printf("\nIntegrity changes for 'Windows Registry' of" - " agent '%s (%s) - %s':\n", - keys.keyentries[i]->name, keys.keyentries[i]->id, - final_ip); - } - else - { - printf("\nIntegrity changes for agent " - "'%s (%s) - %s':\n", - keys.keyentries[i]->name, keys.keyentries[i]->id, - final_ip); - } + /* Getting full address/prefix length from ip. */ + final_ip[(sizeof final_ip) - 1] = '\0'; + snprintf(final_ip, sizeof final_ip, "%s/%u", + keys.keyentries[i]->ip->ip, + keys.keyentries[i]->ip->prefixlength); + + if (!(csv_output || json_output)) { + if (registry_only) { + printf("\nIntegrity changes for 'Windows Registry' of" + " agent '%s (%s) - %s':\n", + keys.keyentries[i]->name, keys.keyentries[i]->id, + final_ip); + } else { + printf("\nIntegrity changes for agent " + "'%s (%s) - %s':\n", + keys.keyentries[i]->name, keys.keyentries[i]->id, + final_ip); + } - if(fname) - { - printf("Detailed information for entries matching: '%s'\n", - fname); + if (fname) { + printf("Detailed information for entries matching: '%s'\n", + fname); + } } - print_syscheck(keys.keyentries[i]->name, - keys.keyentries[i]->ip->ip, fname, - registry_only, 0, csv_output, zero_counter); + print_syscheck(keys.keyentries[i]->name, keys.keyentries[i]->ip->ip, fname, + registry_only, 0, csv_output, json_entries, zero_counter); + } + + if (json_output) { + cJSON_AddNumberToObject(json_root, "error", 0); + cJSON_AddItemToObject(json_root, "response", json_entries); + printf("%s", cJSON_PrintUnformatted(json_root)); } exit(0); } + if (json_output) { + cJSON_AddNumberToObject(json_root, "error", 30); + cJSON_AddStringToObject(json_root, "description", "Invalid argument combination"); + printf("%s", cJSON_PrintUnformatted(json_root)); + exit(1); + } else { + printf("\n** Invalid argument combination.\n"); + helpmsg(); + } - - printf("\n** Invalid argument combination.\n"); - helpmsg(); - - - return(0); + return (0); } - - -/* EOF */