X-Git-Url: http://ftp.carnet.hr/carnet-debian/scm?p=ossec-hids.git;a=blobdiff_plain;f=src%2Faddagent%2Fvalidate.c;fp=src%2Faddagent%2Fvalidate.c;h=39ce6e8f88bc390dd6cfe32dd4faef9c347ddbd9;hp=60dec16391fb4ba49736d76cff27c469d11e45f5;hb=3f728675941dc69d4e544d3a880a56240a6e394a;hpb=927951d1c1ad45ba9e7325f07d996154a91c911b diff --git a/src/addagent/validate.c b/src/addagent/validate.c old mode 100755 new mode 100644 index 60dec16..39ce6e8 --- a/src/addagent/validate.c +++ b/src/addagent/validate.c @@ -1,6 +1,3 @@ -/* @(#) $Id: ./src/addagent/validate.c, 2011/09/08 dcid Exp $ - */ - /* Copyright (C) 2009 Trend Micro Inc. * All rights reserved. * @@ -10,225 +7,337 @@ * Foundation */ - - +#include #include "manage_agents.h" #include "os_crypto/md5/md5_op.h" -char *OS_AddNewAgent(char *name, char *ip, char *id, char *key) +/* Global variables */ +fpos_t fp_pos; + +/*Number bit of int type*/ +#define INT_BIT_SIZE (sizeof(int)*CHAR_BIT) +/*Enable bit at a position*/ +#define SetBit(Array,pos) ( Array[(pos/INT_BIT_SIZE)] |= (1 << (pos%INT_BIT_SIZE)) ) +/*Check state of bit at a */ +#define TestBit(Array,pos) ( Array[(pos/INT_BIT_SIZE)] & (1 << (pos%INT_BIT_SIZE)) ) + +int *MapIDToBitArray() { - int i = 0; FILE *fp; - int rand1; - os_md5 md1; - os_md5 md2; - char str1[STR_SIZE +1]; - char str2[STR_SIZE +1]; - char *muname = NULL; - char *finals = NULL; + char line_read[FILE_SIZE + 1]; + line_read[FILE_SIZE] = '\0'; + int *arrayID; + int max = MAX_AGENTS + AUTHD_FIRST_ID; + if (isChroot()) { + fp = fopen(AUTH_FILE, "r"); + } else { + fp = fopen(KEYSFILE_PATH, "r"); + } - char nid[9]; + if (!fp) { + return (NULL); + } + os_calloc(MAX_AGENTS/INT_BIT_SIZE + 1, sizeof(int), arrayID); - #ifndef WIN32 - #ifdef __OpenBSD__ - srandomdev(); - #else - srandom(time(0) + getpid() + getppid()); - #endif - #else - srandom(time(0) + getpid()); - #endif + while (fgets(line_read, FILE_SIZE - 1, fp) != NULL) { + char *name; - rand1 = random(); + if (line_read[0] == '#') { + continue; + } + + name = strchr(line_read, ' '); + if (name) { + *name = '\0'; + int name_num=atoi(line_read); + /*Enable bit at ID already allocated*/ + if (name_num >= AUTHD_FIRST_ID && name_num < max) { + SetBit(arrayID, (name_num-AUTHD_FIRST_ID)); + } + } + + } + fclose(fp); + return arrayID; +} + +char *OS_AddNewAgent(const char *name, const char *ip, const char *id) +{ + FILE *fp; + os_md5 md1; + os_md5 md2; + char str1[STR_SIZE + 1]; + char str2[STR_SIZE + 1]; + char *muname; + char *finals; + char nid[9] = { '\0' }; + + srandom_init(); muname = getuname(); - snprintf(str1, STR_SIZE, "%d%s%d%s",(int)time(0), name, rand1, muname); + snprintf(str1, STR_SIZE, "%d%s%d%s", (int)time(0), name, (int)random(), muname); snprintf(str2, STR_SIZE, "%s%s%ld", ip, id, (long int)random()); OS_MD5_Str(str1, md1); OS_MD5_Str(str2, md2); + free(muname); + + if (id == NULL) { + int *arrayID; + int i; + arrayID=(int *)MapIDToBitArray(); + if (arrayID != NULL) { + /*Find first item in bit array which is not marked as allocated*/ + for (i=0; i= 4000) - { - return(NULL); + if (i == MAX_AGENTS) { + return (NULL); } } + else { + return (NULL); + } + id = nid; } - fp = fopen(KEYSFILE_PATH,"a"); - if(!fp) - { - return(NULL); + char authentication_file[2048 + 1]; + snprintf(authentication_file, 2048, "%s%s", DEFAULTDIR, AUTH_FILE); + + fp = fopen(authentication_file, "a"); + if (!fp) { + return (NULL); } os_calloc(2048, sizeof(char), finals); - if (ip == NULL){ - snprintf(finals, 2048, "%s %s any %s%s",id, name, md1,md2); + if (ip == NULL) { + snprintf(finals, 2048, "%s %s any %s%s", id, name, md1, md2); } else { - snprintf(finals, 2048, "%s %s %s %s%s",id, name, ip, md1,md2); + snprintf(finals, 2048, "%s %s %s %s%s", id, name, ip, md1, md2); } - fprintf(fp, "%s\n",finals); + fprintf(fp, "%s\n", finals); fclose(fp); - return(finals); + return (finals); } +int OS_RemoveAgent(const char *u_id) { + FILE *fp; + int id_exist; + char *full_name; + + id_exist = IDExist(u_id); -int OS_IsValidID(char *id) + if (!id_exist) + return 0; + + fp = fopen(isChroot() ? AUTH_FILE : KEYSFILE_PATH, "r+"); + + if (!fp) + return 0; + +#ifndef WIN32 + if((chmod(AUTH_FILE, 0440)) < 0) { + merror("addagent: ERROR: Cannot chmod %s: %s", AUTH_FILE, strerror(errno)); + } +#endif + +#ifdef REUSE_ID + long fp_seek; + size_t fp_read; + char *buffer; + char buf_discard[OS_BUFFER_SIZE]; + struct stat fp_stat; + + if (stat(AUTH_FILE, &fp_stat) < 0) { + fclose(fp); + return 0; + } + + buffer = malloc(fp_stat.st_size); + if (!buffer) { + fclose(fp); + return 0; + } + + fsetpos(fp, &fp_pos); + fp_seek = ftell(fp); + fseek(fp, 0, SEEK_SET); + fp_read = fread(buffer, sizeof(char), fp_seek, fp); + fgets(buf_discard, OS_BUFFER_SIZE - 1, fp); + + if (!feof(fp)) + fp_read += fread(buffer + fp_read, sizeof(char), fp_stat.st_size, fp); + + fclose(fp); + fp = fopen(AUTH_FILE, "w"); + + if (!fp) { + free(buffer); + return 0; + } + + fwrite(buffer, sizeof(char), fp_read, fp); + +#else + /* Remove the agent, but keep the id */ + fsetpos(fp, &fp_pos); + fprintf(fp, "%s #*#*#*#*#*#*#*#*#*#*#", u_id); +#endif + fclose(fp); + + full_name = getFullnameById(u_id); + if (full_name) + delete_agentinfo(full_name); + + /* Remove counter for ID */ + OS_RemoveCounter(u_id); + return 1; +} + +int OS_IsValidID(const char *id) { - int id_len = 0; - int i = 0; + size_t id_len, i; /* ID must not be null */ - if(!id) - return(0); + if (!id) { + return (0); + } id_len = strlen(id); /* Check ID length, it should contain max. 8 characters */ - if (id_len > 8) - return(0); + if (id_len > 8) { + return (0); + } /* Check ID if it contains only numeric characters [0-9] */ - for(i = 0; i < id_len; i++) - { - if(!(isdigit((int)id[i]))) - return(0); + for (i = 0; i < id_len; i++) { + if (!(isdigit((int)id[i]))) { + return (0); + } } - return(1); + return (1); } - -/* Get full agent name (name + ip) of ID. - */ -char *getFullnameById(char *id) +/* Get full agent name (name + IP) of ID */ +char *getFullnameById(const char *id) { FILE *fp; - char line_read[FILE_SIZE +1]; + char line_read[FILE_SIZE + 1]; line_read[FILE_SIZE] = '\0'; /* ID must not be null */ - if(!id) - return(NULL); + if (!id) { + return (NULL); + } fp = fopen(AUTH_FILE, "r"); - if(!fp) - return(NULL); - + if (!fp) { + return (NULL); + } - while(fgets(line_read, FILE_SIZE -1, fp) != NULL) - { + while (fgets(line_read, FILE_SIZE - 1, fp) != NULL) { char *name; char *ip; char *tmp_str; - if(line_read[0] == '#') - { + if (line_read[0] == '#') { continue; } name = strchr(line_read, ' '); - if(name) - { + if (name) { *name = '\0'; /* Didn't match */ - if(strcmp(line_read,id) != 0) - { + if (strcmp(line_read, id) != 0) { continue; } name++; /* Removed entry */ - if(*name == '#') - { + if (*name == '#') { continue; } ip = strchr(name, ' '); - if(ip) - { + if (ip) { *ip = '\0'; ip++; - /* Cleaning up ip */ + /* Clean up IP */ tmp_str = strchr(ip, ' '); - if(tmp_str) - { + if (tmp_str) { char *final_str; *tmp_str = '\0'; tmp_str = strchr(ip, '/'); - if(tmp_str) + if (tmp_str) { *tmp_str = '\0'; + } /* If we reached here, we found the IP and name */ os_calloc(1, FILE_SIZE, final_str); - snprintf(final_str, FILE_SIZE -1, "%s-%s", name, ip); + snprintf(final_str, FILE_SIZE - 1, "%s-%s", name, ip); fclose(fp); - return(final_str); + return (final_str); } } } } fclose(fp); - return(NULL); + return (NULL); } - /* ID Search (is valid ID) */ -int IDExist(char *id) +int IDExist(const char *id) { FILE *fp; - char line_read[FILE_SIZE +1]; + char line_read[FILE_SIZE + 1]; line_read[FILE_SIZE] = '\0'; /* ID must not be null */ - if(!id) - return(0); + if (!id) { + return (0); + } - if(isChroot()) - fp = fopen(AUTH_FILE, "r"); - else - fp = fopen(KEYSFILE_PATH, "r"); + if (isChroot()) { + fp = fopen(AUTH_FILE, "r"); + } else { + fp = fopen(KEYSFILE_PATH, "r"); + } - if(!fp) - return(0); + if (!fp) { + return (0); + } fseek(fp, 0, SEEK_SET); fgetpos(fp, &fp_pos); - while(fgets(line_read,FILE_SIZE -1, fp) != NULL) - { + while (fgets(line_read, FILE_SIZE - 1, fp) != NULL) { char *name; - if(line_read[0] == '#') - { + if (line_read[0] == '#') { fgetpos(fp, &fp_pos); continue; } name = strchr(line_read, ' '); - if(name) - { + if (name) { *name = '\0'; name++; - if(strcmp(line_read,id) == 0) - { + if (strcmp(line_read, id) == 0) { fclose(fp); return (1); /*(fp_pos);*/ } @@ -238,84 +347,79 @@ int IDExist(char *id) } fclose(fp); - return(0); + return (0); } - -/* Validate agent name. - */ -int OS_IsValidName(char *u_name) +/* Validate agent name */ +int OS_IsValidName(const char *u_name) { - int i = 0; + size_t i, uname_length = strlen(u_name); /* We must have something in the name */ - if(strlen(u_name) < 2 || strlen(u_name) > 128) - return(0); + if (uname_length < 2 || uname_length > 128) { + return (0); + } - /* check if it contains any non-alphanumeric characters */ - for(i = 0; i < strlen(u_name); i++) - { - if(!isalnum((int)u_name[i]) && (u_name[i] != '-') && - (u_name[i] != '_') && (u_name[i] != '.')) - return(0); + /* Check if it contains any non-alphanumeric characters */ + for (i = 0; i < uname_length; i++) { + if ( !( isalnum((int)u_name[i]) || (u_name[i] == '-') || + (u_name[i] == '_') || (u_name[i] == '.') || + (u_name[i] == ':') ) ) { + return (0); + } } - return(1); + return (1); } - -/* Is_Name (is valid name) */ -int NameExist(char *u_name) +int NameExist(const char *u_name) { FILE *fp; - char line_read[FILE_SIZE +1]; + char line_read[FILE_SIZE + 1]; line_read[FILE_SIZE] = '\0'; - if((!u_name)|| - (*u_name == '\0')|| - (*u_name == '\r')|| - (*u_name == '\n')) - return(0); - - if(isChroot()) - fp = fopen(AUTH_FILE, "r"); - else - fp = fopen(KEYSFILE_PATH, "r"); + if ((!u_name) || + (*u_name == '\0') || + (*u_name == '\r') || + (*u_name == '\n')) { + return (0); + } - if(!fp) - return(0); + if (isChroot()) { + fp = fopen(AUTH_FILE, "r"); + } else { + fp = fopen(KEYSFILE_PATH, "r"); + } + if (!fp) { + return (0); + } fseek(fp, 0, SEEK_SET); fgetpos(fp, &fp_pos); - - while(fgets(line_read, FILE_SIZE-1, fp) != NULL) - { + while (fgets(line_read, FILE_SIZE - 1, fp) != NULL) { char *name; - if(line_read[0] == '#') + if (line_read[0] == '#') { continue; + } name = strchr(line_read, ' '); - if(name) - { + if (name) { char *ip; name++; - if(*name == '#') - { + if (*name == '#') { continue; } ip = strchr(name, ' '); - if(ip) - { + if (ip) { *ip = '\0'; - if(strcmp(u_name, name) == 0) - { + if (strcmp(u_name, name) == 0) { fclose(fp); - return(1); + return (1); } } } @@ -323,130 +427,197 @@ int NameExist(char *u_name) } fclose(fp); - return(0); + return (0); } +/* Returns the ID of an agent, or NULL if not found */ +char *IPExist(const char *u_ip) +{ + FILE *fp; + char *name, *ip, *pass; + char line_read[FILE_SIZE + 1]; + line_read[FILE_SIZE] = '\0'; + + if (!(u_ip && strncmp(u_ip, "any", 3)) || strchr(u_ip, '/')) + return NULL; + + if (isChroot()) + fp = fopen(AUTH_FILE, "r"); + else + fp = fopen(KEYSFILE_PATH, "r"); -/* print available agents */ -int print_agents(int print_status, int active_only, int csv_output) + if (!fp) + return NULL; + + fseek(fp, 0, SEEK_SET); + fgetpos(fp, &fp_pos); + + while (fgets(line_read, FILE_SIZE - 1, fp) != NULL) { + if (line_read[0] == '#') { + continue; + } + + name = strchr(line_read, ' '); + if (name) { + name++; + + if (*name == '#') { + continue; + } + + ip = strchr(name, ' '); + if (ip) { + ip++; + + pass = strchr(ip, ' '); + if (pass) { + *pass = '\0'; + if (strcmp(u_ip, ip) == 0) { + fclose(fp); + name[-1] = '\0'; + return strdup(line_read); + } + } + } + } + + fgetpos(fp, &fp_pos); + } + + fclose(fp); + return NULL; +} + +/* Returns the number of seconds since last agent connection, or -1 if error. */ +double OS_AgentAntiquity(const char *id) +{ + struct stat file_stat; + char file_name[OS_FLSIZE]; + char *full_name = getFullnameById(id); + + if (!full_name) { + return -1; + } + + snprintf(file_name, OS_FLSIZE - 1, "%s/%s", AGENTINFO_DIR, full_name); + + if (stat(file_name, &file_stat) < 0) { + if(full_name) { + free(full_name); + } + return -1; + } + + free(full_name); + + return difftime(time(NULL), file_stat.st_mtime); +} + +/* Print available agents */ +int print_agents(int print_status, int active_only, int csv_output, cJSON *json_output) { int total = 0; FILE *fp; - char line_read[FILE_SIZE +1]; + char line_read[FILE_SIZE + 1]; line_read[FILE_SIZE] = '\0'; fp = fopen(AUTH_FILE, "r"); - if(!fp) - return(0); + if (!fp) { + return (0); + } fseek(fp, 0, SEEK_SET); - memset(line_read,'\0',FILE_SIZE); + memset(line_read, '\0', FILE_SIZE); - while(fgets(line_read, FILE_SIZE -1, fp) != NULL) - { + while (fgets(line_read, FILE_SIZE - 1, fp) != NULL) { char *name; - if(line_read[0] == '#') + if (line_read[0] == '#') { continue; + } name = strchr(line_read, ' '); - if(name) - { + if (name) { char *ip; *name = '\0'; name++; - - /* Removed agent. */ - if(*name == '#') - { + /* Removed agent */ + if (*name == '#') { continue; } ip = strchr(name, ' '); - if(ip) - { + if (ip) { char *key; *ip = '\0'; ip++; key = strchr(ip, ' '); - if(key) - { + if (key) { *key = '\0'; - if(!total && !print_status) + if (!total && !print_status) { printf(PRINT_AVAILABLE); + } total++; - - if(print_status) - { + if (print_status) { int agt_status = get_agent_status(name, ip); - if(active_only && (agt_status != GA_STATUS_ACTIVE)) - { + if (active_only && (agt_status != GA_STATUS_ACTIVE)) { continue; } - if(csv_output) - { - printf("%s,%s,%s,%s,\n", line_read, name, ip, - print_agent_status(agt_status)); + if (csv_output) { + printf("%s,%s,%s,%s,\n", line_read, name, ip, print_agent_status(agt_status)); + } else if (json_output) { + cJSON *json_agent = cJSON_CreateObject(); + + if (!json_agent) + return 0; + + cJSON_AddStringToObject(json_agent, "id", line_read); + cJSON_AddStringToObject(json_agent, "name", name); + cJSON_AddStringToObject(json_agent, "ip", ip); + cJSON_AddStringToObject(json_agent, "status", print_agent_status(agt_status)); + cJSON_AddItemToArray(json_output, json_agent); + } else { + printf(PRINT_AGENT_STATUS, line_read, name, ip, print_agent_status(agt_status)); } - else - { - printf(PRINT_AGENT_STATUS, line_read, name, ip, - print_agent_status(agt_status)); - } - } - else - { + } else { printf(PRINT_AGENT, line_read, name, ip); } } - } } } - /* Only print agentless for non-active only searches */ - if(!active_only && print_status) - { - char *aip = NULL; + if (!active_only && print_status) { + const char *aip = NULL; DIR *dirp; struct dirent *dp; - if(!csv_output) - { + if (!csv_output && !json_output) { printf("\nList of agentless devices:\n"); } dirp = opendir(AGENTLESS_ENTRYDIR); - if(dirp) - { - while ((dp = readdir(dirp)) != NULL) - { - if(strncmp(dp->d_name, ".", 1) == 0) - { + if (dirp) { + while ((dp = readdir(dirp)) != NULL) { + if (strncmp(dp->d_name, ".", 1) == 0) { continue; } aip = strchr(dp->d_name, '@'); - if(aip) - { + if (aip) { aip++; - } - else - { + } else { aip = ""; } - if(csv_output) - { + if (csv_output) { printf("na,%s,%s,agentless,\n", dp->d_name, aip); - } - else - { + } else { printf(" ID: na, Name: %s, IP: %s, agentless\n", dp->d_name, aip); } @@ -456,11 +627,22 @@ int print_agents(int print_status, int active_only, int csv_output) } fclose(fp); - if(total) - return(1); + if (total) { + return (1); + } - return(0); + return (0); } +void FormatID(char *id) { + int number; + char *end; -/* EOF */ + if (id && *id) { + number = strtol(id, &end, 10); + + if (!*end) { + sprintf(id, "%03d", number); + } + } +}