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]; srandom_init(); muname = getuname(); 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); nid[8] = '\0'; if (id == NULL) { int i = 1024; snprintf(nid, 6, "%d", i); while (IDExist(nid)) { i++; snprintf(nid, 6, "%d", i); if (i >= (MAX_AGENTS + 1024)) { return (NULL); } } id = nid; } fp = fopen(KEYSFILE_PATH, "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); } else { snprintf(finals, 2048, "%s %s %s %s%s", id, name, ip, md1, md2); } fprintf(fp, "%s\n", finals); fclose(fp); return (finals); }
/* Generates a random and temporary shared pass to be used by the agents. */ char *__generatetmppass() { int rand1; int rand2; char *rand3; char *rand4; os_md5 md1; os_md5 md3; os_md5 md4; char *fstring = NULL; char str1[STR_SIZE +1]; char *muname = NULL; #ifndef WIN32 #ifdef __OpenBSD__ srandomdev(); #else srandom(time(0) + getpid() + getppid()); #endif #else srandom(time(0) + getpid()); #endif rand1 = random(); rand2 = random(); rand3 = GetRandomNoise(); rand4 = GetRandomNoise(); OS_MD5_Str(rand3, md3); OS_MD5_Str(rand4, md4); muname = getuname(); snprintf(str1, STR_SIZE, "%d%d%s%d%s%s",(int)time(0), rand1, muname, rand2, md3, md4); OS_MD5_Str(str1, md1); fstring = strdup(md1); return(fstring); }
/* CheckSum v0.1: 2005/02/15 * Verify the checksum of the message. * Returns NULL on error or the message on success. */ char *CheckSum(char *msg) { os_md5 recvd_sum; os_md5 checksum; /* Better way */ strncpy(recvd_sum,msg,32); recvd_sum[32]='\0'; msg+=32; OS_MD5_Str(msg, checksum); if(strncmp(checksum,recvd_sum,32) != 0) { return(NULL); } return(msg); }
int main(int argc, char **argv) { os_md5 filesum; if (argc < 3) { usage(argv); } if (strcmp(argv[1], "file") == 0) { OS_MD5_File(argv[2], filesum, OS_BINARY); } else if (strcmp(argv[1], "str") == 0) { OS_MD5_Str(argv[2], filesum); } else { usage(argv); } printf("MD5Sum for \"%s\" is: %s\n", argv[2], filesum); return (0); }
/* Creat a encrypted message. * Returns the size of it */ int CreateSecMSG(keystore *keys, char *msg, char *msg_encrypted, int id) { int bfsize; int msg_size; int cmp_size; u_int16_t rand1; char _tmpmsg[OS_MAXSTR + 2]; char _finmsg[OS_MAXSTR + 2]; os_md5 md5sum; msg_size = strlen(msg); /* Checking for invalid msg sizes */ if((msg_size > (OS_MAXSTR - OS_HEADER_SIZE))||(msg_size < 1)) { merror(ENCSIZE_ERROR, __local_name, msg); return(0); } /* Random number */ rand1 = (u_int16_t)random(); _tmpmsg[OS_MAXSTR +1] = '\0'; _finmsg[OS_MAXSTR +1] = '\0'; msg_encrypted[OS_MAXSTR] = '\0'; /* Increasing local and global counters */ if(local_count >= 9997) { local_count = 0; global_count++; } local_count++; snprintf(_tmpmsg, OS_MAXSTR,"%05hu%010u:%04hu:%s", rand1, global_count, local_count, msg); /* Generating md5sum of the unencrypted string */ OS_MD5_Str(_tmpmsg, md5sum); /* Generating final msg to be compressed */ snprintf(_finmsg, OS_MAXSTR,"%s%s",md5sum,_tmpmsg); msg_size = strlen(_finmsg); /* Compressing message. * We assing the first 8 bytes for padding. */ cmp_size = os_compress(_finmsg, _tmpmsg + 8, msg_size, OS_MAXSTR - 12); if(!cmp_size) { merror(COMPRESS_ERR, __local_name, _finmsg); return(0); } cmp_size++; /* Padding the message (needs to be div by 8) */ bfsize = 8 - (cmp_size % 8); if(bfsize == 8) bfsize = 0; _tmpmsg[0] = '!'; _tmpmsg[1] = '!'; _tmpmsg[2] = '!'; _tmpmsg[3] = '!'; _tmpmsg[4] = '!'; _tmpmsg[5] = '!'; _tmpmsg[6] = '!'; _tmpmsg[7] = '!'; cmp_size+=bfsize; /* Getting average sizes */ c_orig_size+= msg_size; c_comp_size+= cmp_size; if(evt_count > _s_comp_print) { verbose("%s: INFO: Event count after '%u': %u->%u (%d%%)", __local_name, evt_count, c_orig_size, c_comp_size, (c_comp_size * 100)/c_orig_size); evt_count = 0; c_orig_size = 0; c_comp_size = 0; } evt_count++; /* If the ip is dynamic (not single host, append agent id * to the message. */ if(!isSingleHost(keys->keyentries[id]->ip) && isAgent) { snprintf(msg_encrypted, 16, "!%s!:", keys->keyentries[id]->id); msg_size = strlen(msg_encrypted); } else { /* Setting beginning of the message */ msg_encrypted[0] = ':'; msg_size = 1; } /* msg_size is the ammount of non-encrypted message * appended to the buffer. On dynamic ips, it will * include the agent id. */ /* Encrypting everything */ OS_BF_Str(_tmpmsg + (7 - bfsize), msg_encrypted + msg_size, keys->keyentries[id]->key, cmp_size, OS_ENCRYPT); /* Storing before leaving */ StoreSenderCounter(keys, global_count, local_count); return(cmp_size + msg_size); }
/* Create the final key */ static void __chash(keystore *keys, const char *id, const char *name, char *ip, const char *key) { os_md5 filesum1; os_md5 filesum2; char *tmp_str; char _finalstr[KEYSIZE]; /* Allocate for the whole structure */ keys->keyentries = (keyentry **)realloc(keys->keyentries, (keys->keysize + 2) * sizeof(keyentry *)); if (!keys->keyentries) { ErrorExit(MEM_ERROR, __local_name, errno, strerror(errno)); } os_calloc(1, sizeof(keyentry), keys->keyentries[keys->keysize]); /* Set configured values for id */ os_strdup(id, keys->keyentries[keys->keysize]->id); OSHash_Add(keys->keyhash_id, keys->keyentries[keys->keysize]->id, keys->keyentries[keys->keysize]); /* Agent IP */ os_calloc(1, sizeof(os_ip), keys->keyentries[keys->keysize]->ip); if (OS_IsValidIP(ip, keys->keyentries[keys->keysize]->ip) == 0) { ErrorExit(INVALID_IP, __local_name, ip); } /* We need to remove the "/" from the CIDR */ if ((tmp_str = strchr(keys->keyentries[keys->keysize]->ip->ip, '/')) != NULL) { *tmp_str = '\0'; } OSHash_Add(keys->keyhash_ip, keys->keyentries[keys->keysize]->ip->ip, keys->keyentries[keys->keysize]); /* Agent name */ os_strdup(name, keys->keyentries[keys->keysize]->name); /* Initialize the variables */ keys->keyentries[keys->keysize]->rcvd = 0; keys->keyentries[keys->keysize]->local = 0; keys->keyentries[keys->keysize]->keyid = keys->keysize; keys->keyentries[keys->keysize]->global = 0; keys->keyentries[keys->keysize]->fp = NULL; /** Generate final symmetric key **/ /* MD5 from name, id and key */ OS_MD5_Str(name, filesum1); OS_MD5_Str(id, filesum2); /* Generate new filesum1 */ snprintf(_finalstr, sizeof(_finalstr) - 1, "%s%s", filesum1, filesum2); /* Use just half of the first MD5 (name/id) */ OS_MD5_Str(_finalstr, filesum1); filesum1[15] = '\0'; filesum1[16] = '\0'; /* Second md is just the key */ OS_MD5_Str(key, filesum2); /* Generate final key */ snprintf(_finalstr, 49, "%s%s", filesum2, filesum1); /* Final key is 48 * 4 = 192bits */ os_strdup(_finalstr, keys->keyentries[keys->keysize]->key); /* Clean final string from memory */ memset_secure(_finalstr, '\0', sizeof(_finalstr)); /* Ready for next */ keys->keysize++; return; }
/* Bulk generate client keys from file */ int k_bulkload(const char *cmdbulk) { int i = 1; FILE *fp, *infp; char str1[STR_SIZE + 1]; char str2[STR_SIZE + 1]; os_md5 md1; os_md5 md2; char line[FILE_SIZE + 1]; char name[FILE_SIZE + 1]; char id[FILE_SIZE + 1]; char ip[FILE_SIZE + 1]; char delims[] = ","; char *token = NULL; /* Check if we can open the input file */ printf("Opening: [%s]\n", cmdbulk); infp = fopen(cmdbulk, "r"); if (!infp) { perror("Failed."); ErrorExit(FOPEN_ERROR, ARGV0, cmdbulk, errno, strerror(errno)); } /* Check if we can open the auth_file */ fp = fopen(AUTH_FILE, "a"); if (!fp) { ErrorExit(FOPEN_ERROR, ARGV0, AUTH_FILE, errno, strerror(errno)); } fclose(fp); while (fgets(line, FILE_SIZE - 1, infp) != NULL) { os_ip c_ip; c_ip.ip = NULL; if (1 >= strlen(trimwhitespace(line))) { continue; } memset(ip, '\0', FILE_SIZE + 1); token = strtok(line, delims); strncpy(ip, trimwhitespace(token), FILE_SIZE - 1); memset(name, '\0', FILE_SIZE + 1); token = strtok(NULL, delims); strncpy(name, trimwhitespace(token), FILE_SIZE - 1); #ifndef WIN32 if (chmod(AUTH_FILE, 0440) == -1) { ErrorExit(CHMOD_ERROR, ARGV0, AUTH_FILE, errno, strerror(errno)); } #endif /* Set time 2 */ time2 = time(0); srandom_init(); rand1 = random(); /* Zero strings */ memset(str1, '\0', STR_SIZE + 1); memset(str2, '\0', STR_SIZE + 1); /* Check the name */ if (!OS_IsValidName(name)) { printf(INVALID_NAME, name); continue; } /* Search for name -- no duplicates */ if (NameExist(name)) { printf(ADD_ERROR_NAME, name); continue; } if (!OS_IsValidIP(ip, &c_ip)) { printf(IP_ERROR, ip); continue; } /* Default ID */ i = MAX_AGENTS + 32512; snprintf(id, 8, "%03d", i); while (!IDExist(id)) { i--; snprintf(id, 8, "%03d", i); /* No key present, use id 0 */ if (i <= 0) { i = 0; break; } } snprintf(id, 8, "%03d", i + 1); if (!OS_IsValidID(id)) { printf(INVALID_ID, id); goto cleanup; } /* Search for ID KEY -- no duplicates */ if (IDExist(id)) { printf(NO_DEFAULT, i + 1); goto cleanup; } printf(AGENT_INFO, id, name, ip); fflush(stdout); time3 = time(0); rand2 = random(); fp = fopen(AUTH_FILE, "a"); if (!fp) { ErrorExit(FOPEN_ERROR, ARGV0, KEYS_FILE, errno, strerror(errno)); } #ifndef WIN32 if (chmod(AUTH_FILE, 0440) == -1) { ErrorExit(CHMOD_ERROR, ARGV0, AUTH_FILE, errno, strerror(errno)); } #endif /* Random 1: Time took to write the agent information * Random 2: Time took to choose the action * Random 3: All of this + time + pid * Random 4: MD5 all of this + the name, key and IP * Random 5: Final key */ snprintf(str1, STR_SIZE, "%d%s%d", (int)(time3 - time2), name, (int)rand1); snprintf(str2, STR_SIZE, "%d%s%s%d", (int)(time2 - time1), ip, id, (int)rand2); OS_MD5_Str(str1, md1); OS_MD5_Str(str2, md2); snprintf(str1, STR_SIZE, "%s%d%d%d", md1, (int)getpid(), (int)random(), (int)time3); OS_MD5_Str(str1, md1); fprintf(fp, "%s %s %s %s%s\n", id, name, c_ip.ip, md1, md2); fclose(fp); printf(AGENT_ADD); restart_necessary = 1; cleanup: free(c_ip.ip); }; fclose(infp); return (0); }
char *OS_AddNewAgent(char *name, char *ip, char *id, char *key) { 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 nid[9]; #ifndef WIN32 #ifdef __OpenBSD__ srandomdev(); #else srandom(time(0) + getpid() + getppid()); #endif #else srandom(time(0) + getpid()); #endif rand1 = random(); muname = getuname(); snprintf(str1, STR_SIZE, "%d%s%d%s",(int)time(0), name, rand1, 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); nid[8] = '\0'; if(id == NULL) { i = 1024; snprintf(nid, 6, "%d", i); while(IDExist(nid)) { i++; snprintf(nid, 6, "%d", i); if(i >= 4000) { return(NULL); } } id = nid; } fp = fopen(KEYSFILE_PATH,"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); } else { snprintf(finals, 2048, "%s %s %s %s%s",id, name, ip, md1,md2); } fprintf(fp, "%s\n",finals); fclose(fp); return(finals); }
int add_agent() { int i = 1; FILE *fp; char str1[STR_SIZE + 1]; char str2[STR_SIZE + 1]; os_md5 md1; os_md5 md2; char *user_input; char *_name; char *_id; char *_ip; char name[FILE_SIZE + 1]; char id[FILE_SIZE + 1]; char ip[FILE_SIZE + 1]; os_ip *c_ip; /* Check if we can open the auth_file */ fp = fopen(AUTH_FILE, "a"); if (!fp) { ErrorExit(FOPEN_ERROR, ARGV0, AUTH_FILE, errno, strerror(errno)); } fclose(fp); /* Allocate for c_ip */ os_calloc(1, sizeof(os_ip), c_ip); #ifndef WIN32 if (chmod(AUTH_FILE, 0440) == -1) { ErrorExit(CHMOD_ERROR, ARGV0, AUTH_FILE, errno, strerror(errno)); } #endif /* Set time 2 */ time2 = time(0); rand1 = random(); /* Zero strings */ memset(str1, '\0', STR_SIZE + 1); memset(str2, '\0', STR_SIZE + 1); printf(ADD_NEW); /* Get the name */ memset(name, '\0', FILE_SIZE + 1); do { printf(ADD_NAME); fflush(stdout); /* Read the agent's name from user environment. If it is invalid * we should force user to provide a name from input device. */ _name = getenv("OSSEC_AGENT_NAME"); if (_name == NULL || NameExist(_name) || !OS_IsValidName(_name)) { _name = read_from_user(); } if (strcmp(_name, QUIT) == 0) { return (0); } strncpy(name, _name, FILE_SIZE - 1); /* Check the name */ if (!OS_IsValidName(name)) { printf(INVALID_NAME, name); } /* Search for name -- no duplicates */ if (NameExist(name)) { printf(ADD_ERROR_NAME, name); } } while (NameExist(name) || !OS_IsValidName(name)); /* Get IP */ memset(ip, '\0', FILE_SIZE + 1); do { printf(ADD_IP); fflush(stdout); /* Read IP address from user's environment. If that IP is invalid, * force user to provide IP from input device */ _ip = getenv("OSSEC_AGENT_IP"); if (_ip == NULL || !OS_IsValidIP(_ip, c_ip)) { _ip = read_from_user(); } /* Quit */ if (strcmp(_ip, QUIT) == 0) { return (0); } strncpy(ip, _ip, FILE_SIZE - 1); if (!OS_IsValidIP(ip, c_ip)) { printf(IP_ERROR, ip); _ip = NULL; } } while (!_ip); do { /* Default ID */ i = MAX_AGENTS + 32512; snprintf(id, 8, "%03d", i); while (!IDExist(id)) { i--; snprintf(id, 8, "%03d", i); /* No key present, use id 0 */ if (i <= 0) { i = 0; break; } } snprintf(id, 8, "%03d", i + 1); /* Get ID */ printf(ADD_ID, id); fflush(stdout); /* Get Agent ID from environment. If 0, use default ID. If null, * get from user input. If value from environment is invalid, * we force user to specify an ID from the terminal. Otherwise, * our program goes to infinite loop. */ _id = getenv("OSSEC_AGENT_ID"); if (_id == NULL || IDExist(_id) || !OS_IsValidID(_id)) { _id = read_from_user(); } /* If user specified 0 as Agent ID, he meant use default value. * NOTE: a bad condition can cause infinite loop. */ if (strcmp(_id, "0") == 0) { strncpy(_id, id, FILE_SIZE - 1); } /* Quit */ if (strcmp(_id, QUIT) == 0) { return (0); } if (_id[0] != '\0') { strncpy(id, _id, FILE_SIZE - 1); } if (!OS_IsValidID(id)) { printf(INVALID_ID, id); } /* Search for ID KEY -- no duplicates */ if (IDExist(id)) { printf(ADD_ERROR_ID, id); } } while (IDExist(id) || !OS_IsValidID(id)); printf(AGENT_INFO, id, name, ip); fflush(stdout); do { printf(ADD_CONFIRM); /* Confirmation by an environment variable. The valid value is y/Y. * If the user provides anything other string, it is considered as * n/N; please note that the old code only accepts y/Y/n/N. So if * the variable OSSEC_ACTION_CONFIRMED is 'foobar', the program will * go into an infinite loop. */ user_input = getenv("OSSEC_ACTION_CONFIRMED"); if (user_input == NULL) { user_input = read_from_user(); } /* If user accepts to add */ if (user_input[0] == 'y' || user_input[0] == 'Y') { time3 = time(0); rand2 = random(); fp = fopen(AUTH_FILE, "a"); if (!fp) { ErrorExit(FOPEN_ERROR, ARGV0, KEYS_FILE, errno, strerror(errno)); } #ifndef WIN32 chmod(AUTH_FILE, 0440); #endif /* Random 1: Time took to write the agent information * Random 2: Time took to choose the action * Random 3: All of this + time + pid * Random 4: Md5 all of this + the name, key and IP * Random 5: Final key */ snprintf(str1, STR_SIZE, "%d%s%d", (int)(time3 - time2), name, (int)rand1); snprintf(str2, STR_SIZE, "%d%s%s%d", (int)(time2 - time1), ip, id, (int)rand2); OS_MD5_Str(str1, md1); OS_MD5_Str(str2, md2); snprintf(str1, STR_SIZE, "%s%d%d%d", md1, (int)getpid(), (int)random(), (int)time3); OS_MD5_Str(str1, md1); fprintf(fp, "%s %s %s %s%s\n", id, name, c_ip->ip, md1, md2); fclose(fp); printf(AGENT_ADD); restart_necessary = 1; break; } else { /* if(user_input[0] == 'n' || user_input[0] == 'N') */ printf(ADD_NOT); break; } } while (1); return (0); }
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, (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) { #ifdef REUSE_ID int i = 1024; snprintf(nid, 6, "%d", i); while (IDExist(nid)) { i++; snprintf(nid, 6, "%d", i); if (i >= (MAX_AGENTS + 1024)) return (NULL); } #else char nid_p[9] = { '\0' }; int i = AUTHD_FIRST_ID; int j = MAX_AGENTS + AUTHD_FIRST_ID; int m = (i + j) / 2; snprintf(nid, 8, "%d", m); snprintf(nid_p, 8, "%d", m - 1); /* Dichotomic search */ while (1) { if (IDExist(nid)) { if (m == i) return NULL; i = m; } else if (!IDExist(nid_p) && m > i ) j = m; else break; m = (i + j) / 2; snprintf(nid, 8, "%d", m); snprintf(nid_p, 8, "%d", m - 1); } #endif id = nid; } fp = fopen(AUTH_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); } else { snprintf(finals, 2048, "%s %s %s %s%s", id, name, ip, md1, md2); } fprintf(fp, "%s\n", finals); fclose(fp); OS_AddAgentTimestamp(id, name, ip, time(0)); return (finals); }