X-Git-Url: http://ftp.carnet.hr/carnet-debian/scm?p=ossec-hids.git;a=blobdiff_plain;f=src%2Faddagent%2Fmanage_keys.c;fp=src%2Faddagent%2Fmanage_keys.c;h=146b48326af64c52e306f58b54cfa7438d785d5e;hp=f18f32b94935841a9f281a72e1ac71081699c998;hb=3f728675941dc69d4e544d3a880a56240a6e394a;hpb=927951d1c1ad45ba9e7325f07d996154a91c911b diff --git a/src/addagent/manage_keys.c b/src/addagent/manage_keys.c old mode 100755 new mode 100644 index f18f32b..146b483 --- a/src/addagent/manage_keys.c +++ b/src/addagent/manage_keys.c @@ -1,230 +1,173 @@ -/* @(#) $Id: ./src/addagent/manage_keys.c, 2011/09/08 dcid Exp $ - */ - -/* Copyright (C) 2009 Trend Micro Inc. +/* Copyright (C) 2019 OSSEC Foundation * All rights reserved. * * This program is a free software; you can redistribute it * and/or modify it under the terms of the GNU General Public * License (version 2) as published by the FSF - Free Software * Foundation. - * - * License details at the LICENSE file included with OSSEC or - * online at: http://www.ossec.net/en/licensing.html */ - #include "manage_agents.h" #include "os_crypto/md5/md5_op.h" +#include "external/cJSON/cJSON.h" #include -/* b64 function prototypes */ -char *decode_base64(const char *src); -char *encode_base64(int size, char *src); -char *trimwhitespace(char *str) +/* Prototypes */ +static char *trimwhitespace(char *str); + + +static char *trimwhitespace(char *str) { - char *end; + char *end; - // Trim leading space - while(isspace(*str)) str++; + /* Trim leading space */ + while (isspace(*str)) { + str++; + } - if(*str == 0) // All spaces? - return str; + if (*str == 0) { /* All spaces? */ + return str; + } - // Trim trailing space - end = str + strlen(str) - 1; - while(end > str && isspace(*end)) end--; + /* Trim trailing space */ + end = str + strlen(str) - 1; + while (end > str && isspace(*end)) { + end--; + } - // Write new null terminator - *(end+1) = 0; + /* Write new null terminator */ + *(end + 1) = 0; - return str; + return str; } /* Import a key */ -int k_import(char *cmdimport) +int k_import(const char *cmdimport) { FILE *fp; - char *user_input; + const char *user_input; char *b64_dec; - char *name; char *ip; char *tmp_key; + char *name; + char *ip; + char *tmp_key; - char line_read[FILE_SIZE +1]; + char line_read[FILE_SIZE + 1]; - #ifdef WIN32 - int result; - int cmdlen; - int caclslen; - char *comspec; - char *cacls; - STARTUPINFO si; - PROCESS_INFORMATION pi; - DWORD exit_code; - #endif + char auth_file_tmp[] = AUTH_FILE; + char *keys_file = basename_ex(auth_file_tmp); + char tmp_path[strlen(TMP_DIR) + 1 + strlen(keys_file) + 6 + 1]; - /* Parsing user argument. */ - if(cmdimport) - { + snprintf(tmp_path, sizeof(tmp_path), "%s/%sXXXXXX", TMP_DIR, keys_file); + + /* Parse user argument */ + if (cmdimport) { user_input = cmdimport; - } - else - { + } else { printf(IMPORT_KEY); user_input = getenv("OSSEC_AGENT_KEY"); if (user_input == NULL) { - user_input = read_from_user(); + user_input = read_from_user(); } } - - /* quit */ - if(strcmp(user_input, QUIT) == 0) - return(0); + /* Quit */ + if (strcmp(user_input, QUIT) == 0) { + return (0); + } b64_dec = decode_base64(user_input); - if(b64_dec == NULL) - { + if (b64_dec == NULL) { printf(NO_KEY); printf(PRESS_ENTER); read_from_user(); - return(0); + return (0); } - - memset(line_read, '\0', FILE_SIZE +1); + memset(line_read, '\0', FILE_SIZE + 1); strncpy(line_read, b64_dec, FILE_SIZE); - name = strchr(b64_dec, ' '); - if(name && strlen(line_read) < FILE_SIZE) - { + if (name && strlen(line_read) < FILE_SIZE) { *name = '\0'; name++; ip = strchr(name, ' '); - if(ip) - { + if (ip) { *ip = '\0'; ip++; tmp_key = strchr(ip, ' '); - if(!tmp_key) - { + if (!tmp_key) { printf(NO_KEY); - return(0); + free(b64_dec); + return (0); } *tmp_key = '\0'; printf("\n"); printf(AGENT_INFO, b64_dec, name, ip); - while(1) - { + while (1) { printf(ADD_CONFIRM); fflush(stdout); user_input = getenv("OSSEC_ACTION_CONFIRMED"); if (user_input == NULL) { - user_input = read_from_user(); + user_input = read_from_user(); } - if(user_input[0] == 'y' || user_input[0] == 'Y') - { - fp = fopen(KEYS_FILE,"w"); - if(!fp) - { - ErrorExit(FOPEN_ERROR, ARGV0, KEYS_FILE); + if (user_input[0] == 'y' || user_input[0] == 'Y') { + if (mkstemp_ex(tmp_path)) { + ErrorExit(MKSTEMP_ERROR, ARGV0, tmp_path, errno, strerror(errno)); } - fprintf(fp,"%s\n",line_read); - fclose(fp); - #ifndef WIN32 - chmod(KEYS_FILE, 0440); - #else - /* Get cmd location from environment */ - comspec = getenv("COMSPEC"); - if (comspec == NULL || strncmp(comspec, "", strlen(comspec) == 0)) - { - if(unlink(KEYS_FILE)) - { - verbose(AGENT_DELETE_ERROR, KEYS_FILE); +#ifndef WIN32 + if (chmod(tmp_path, 0440) == -1) { + if (unlink(tmp_path)) { + verbose(DELETE_ERROR, ARGV0, tmp_path, errno, strerror(errno)); } - ErrorExit(COMPSEC_ERROR); - } - /* Build cacls command */ - cacls = "echo y|cacls \"%s\" /T /G Administrators:f"; - caclslen = strlen(cacls) + strlen(KEYS_FILE); - char caclscmd[caclslen]; - snprintf(caclscmd, caclslen, cacls, KEYS_FILE); - - /* Build final command */ - cmdlen = strlen(comspec) + 5 + caclslen; - char cmd[cmdlen]; - snprintf(cmd, cmdlen, "%s /c %s", comspec, caclscmd); - - /* Log command being run */ - log2file("%s: INFO: Running the following command (%s)", ARGV0, cmd); - - ZeroMemory(&si, sizeof(si)); - si.cb = sizeof(si); - ZeroMemory(&pi, sizeof(pi)); - - if(!CreateProcess(NULL, cmd, NULL, NULL, FALSE, CREATE_NO_WINDOW, NULL, NULL, - &si, &pi)) - { - if(unlink(KEYS_FILE)) - { - verbose(AGENT_DELETE_ERROR, KEYS_FILE); - } - ErrorExit(PROC_ERROR, cmd); + ErrorExit(CHMOD_ERROR, ARGV0, tmp_path, errno, strerror(errno)); } +#endif - /* Wait until process exits */ - WaitForSingleObject(pi.hProcess, INFINITE); - - /* Get exit code from command */ - result = GetExitCodeProcess(pi.hProcess, &exit_code); - - /* Close process and thread */ - CloseHandle(pi.hProcess); - CloseHandle(pi.hThread); - - if (!result) - { - if(unlink(KEYS_FILE)) - { - verbose(AGENT_DELETE_ERROR, KEYS_FILE); + fp = fopen(tmp_path, "w"); + if (!fp) { + if (unlink(tmp_path)) { + verbose(DELETE_ERROR, ARGV0, tmp_path, errno, strerror(errno)); } - ErrorExit(RESULT_ERROR, cmd, GetLastError()); + + ErrorExit(FOPEN_ERROR, ARGV0, tmp_path, errno, strerror(errno)); } + fprintf(fp, "%s\n", line_read); + fclose(fp); - if (exit_code) - { - if(unlink(KEYS_FILE)) - { - verbose(AGENT_DELETE_ERROR, KEYS_FILE); + if (rename_ex(tmp_path, KEYS_FILE)) { + if (unlink(tmp_path)) { + verbose(DELETE_ERROR, ARGV0, tmp_path, errno, strerror(errno)); } - ErrorExit(CACLS_ERROR, cmd, exit_code); + + ErrorExit(RENAME_ERROR, ARGV0, tmp_path, KEYS_FILE, errno, strerror(errno)); } - #endif - /* Removing sender counter. */ + /* Remove sender counter */ OS_RemoveCounter("sender"); printf(ADDED); printf(PRESS_ENTER); read_from_user(); restart_necessary = 1; - return(1); - } - else /* if(user_input[0] == 'n' || user_input[0] == 'N') */ - { + + free(b64_dec); + return (1); + } else { /* if(user_input[0] == 'n' || user_input[0] == 'N') */ printf("%s", ADD_NOT); - return(0); + + free(b64_dec); + return (0); } } } @@ -233,92 +176,139 @@ int k_import(char *cmdimport) printf(NO_KEY); printf(PRESS_ENTER); read_from_user(); - return(0); + free(b64_dec); + return (0); } - -/* extract base64 for a specific agent */ -int k_extract(char *cmdextract) +/* Extract base64 for a specific agent */ +int k_extract(const char *cmdextract, int json_output) { FILE *fp; char *user_input; char *b64_enc; - char line_read[FILE_SIZE +1]; - char n_id[USER_SIZE +1]; - - - if(cmdextract) - { - user_input = cmdextract; - - if(!IDExist(user_input)) - { - printf(NO_ID, user_input); + char line_read[FILE_SIZE + 1]; + char n_id[USER_SIZE + 1]; + cJSON *json_root = NULL; + + if (json_output) + json_root = cJSON_CreateObject(); + + if (cmdextract) { + user_input = strdup(cmdextract); + FormatID(user_input); + + if (!IDExist(user_input)) { + if (json_output) { + char buffer[1024]; + snprintf(buffer, 1023, "Invalid ID '%s' given. ID is not present", user_input); + cJSON_AddNumberToObject(json_root, "error", 70); + cJSON_AddStringToObject(json_root, "description", buffer); + printf("%s", cJSON_PrintUnformatted(json_root)); + } else + printf(NO_ID, user_input); exit(1); } - } - - else - { - if(!print_agents(0, 0, 0)) - { + } else { + if (!print_agents(0, 0, 0, 0)) { printf(NO_AGENT); printf(PRESS_ENTER); read_from_user(); - return(0); + return (0); } - do - { + while (1) { printf(EXTRACT_KEY); fflush(stdout); user_input = read_from_user(); /* quit */ - if(strcmp(user_input, QUIT) == 0) - return(0); + if (strcmp(user_input, QUIT) == 0) { + return (0); + } + + FormatID(user_input); - if(!IDExist(user_input)) + if (IDExist(user_input)) { + break; + } else { printf(NO_ID, user_input); + } - } while(!IDExist(user_input)); + } + } + + /* Try to open the auth file */ + char authfile[257]; + extern int willchroot; + if(willchroot > 0) { + snprintf(authfile, 256, "%s", AUTH_FILE); //XXX + } else { + const char *dir = DEFAULTDIR; + snprintf(authfile, 256, "%s/%s", dir, AUTH_FILE); //XXX } + fp = fopen(authfile, "r"); + if (!fp) { + if (json_output) { + char buffer[1024]; + snprintf(buffer, 1023, "Could not open file '%s' due to [(%d)-(%s)]", AUTH_FILE, errno, strerror(errno)); + cJSON_AddNumberToObject(json_root, "error", 71); + cJSON_AddStringToObject(json_root, "description", buffer); + printf("%s", cJSON_PrintUnformatted(json_root)); + exit(1); + } else + ErrorExit(FOPEN_ERROR, ARGV0, AUTH_FILE, errno, strerror(errno)); + - /* Trying to open the auth file */ - fp = fopen(AUTH_FILE, "r"); - if(!fp) - { - ErrorExit(FOPEN_ERROR, ARGV0, AUTH_FILE); } - fsetpos(fp, &fp_pos); + if (fsetpos(fp, &fp_pos)) { + if (json_output) { + cJSON_AddNumberToObject(json_root, "error", 72); + cJSON_AddStringToObject(json_root, "description", "Can not set fileposition"); + printf("%s", cJSON_PrintUnformatted(json_root)); + } else + merror("%s: Can not set fileposition.", ARGV0); + exit(1); + } - memset(n_id, '\0', USER_SIZE +1); - strncpy(n_id, user_input, USER_SIZE -1); + memset(n_id, '\0', USER_SIZE + 1); + strncpy(n_id, user_input, USER_SIZE - 1); + + if (fgets(line_read, FILE_SIZE, fp) == NULL) { + if (json_output) { + cJSON_AddNumberToObject(json_root, "error", 73); + cJSON_AddStringToObject(json_root, "description", "Unable to handle keys file"); + printf("%s", cJSON_PrintUnformatted(json_root)); + } else + printf(ERROR_KEYS); - if(fgets(line_read, FILE_SIZE, fp) == NULL) - { - printf(ERROR_KEYS); - fclose(fp); exit(1); } chomp(line_read); - - b64_enc = encode_base64(strlen(line_read),line_read); - if(b64_enc == NULL) - { - printf(EXTRACT_ERROR); - fclose(fp); + b64_enc = encode_base64(strlen(line_read), line_read); + if (b64_enc == NULL) { + if (json_output) { + cJSON_AddNumberToObject(json_root, "error", 74); + cJSON_AddStringToObject(json_root, "description", "Unable to extract agent key"); + printf("%s", cJSON_PrintUnformatted(json_root)); + } else + printf(EXTRACT_ERROR); exit(1); } - printf(EXTRACT_MSG, n_id, b64_enc); - if(!cmdextract) - { + if (json_output) { + cJSON_AddNumberToObject(json_root, "error", 0); + cJSON_AddStringToObject(json_root, "response", b64_enc); + printf("%s", cJSON_PrintUnformatted(json_root)); + } else + printf(EXTRACT_MSG, n_id, b64_enc); + + + if (!cmdextract) { printf("\n" PRESS_ENTER); read_from_user(); } @@ -326,185 +316,167 @@ int k_extract(char *cmdextract) free(b64_enc); fclose(fp); - return(0); + return (0); } /* Bulk generate client keys from file */ -int k_bulkload(char *cmdbulk) +int k_bulkload(const char *cmdbulk) { int i = 1; FILE *fp, *infp; - char str1[STR_SIZE +1]; - char str2[STR_SIZE +1]; + 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]; - os_ip *c_ip; + 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; + char *token = NULL; - /* Checking if we can open the input file */ + /* 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); + infp = fopen(cmdbulk, "r"); + if (!infp) { + perror("Failed."); + ErrorExit(FOPEN_ERROR, ARGV0, cmdbulk, errno, strerror(errno)); } + /* Check if we can open the auth_file */ + char authfile[257]; + if(willchroot > 0) { + snprintf(authfile, 256, "%s", AUTH_FILE); //XXX + } else { + const char *dir = DEFAULTDIR; + snprintf(authfile, 256, "%s/%s", dir, AUTH_FILE); //XXX + } - /* Checking if we can open the auth_file */ - fp = fopen(AUTH_FILE,"a"); - if(!fp) - { - ErrorExit(FOPEN_ERROR, ARGV0, AUTH_FILE); + fp = fopen(authfile, "a"); + if (!fp) { + ErrorExit(FOPEN_ERROR, ARGV0, authfile, errno, strerror(errno)); } fclose(fp); - /* Allocating for c_ip */ - os_calloc(1, sizeof(os_ip), c_ip); - - while(fgets(line, FILE_SIZE - 1, infp) != 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 - chmod(AUTH_FILE, 0440); - #endif - - /* Setting time 2 */ - time2 = time(0); - - - /* Source is time1+ time2 +pid + ppid */ - #ifndef WIN32 - #ifdef __OpenBSD__ - srandomdev(); - #else - srandom(time2 + time1 + getpid() + getppid()); - #endif - #else - srandom(time2 + time1 + getpid()); - #endif - - rand1 = random(); - - - /* Zeroing 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); - continue; - } - - /* Search for ID KEY -- no duplicates */ - if(IDExist(id)) - { - printf(NO_DEFAULT, i+1); - continue; - } - - 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); - } - #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",time3-time2, name, rand1); - snprintf(str2, STR_SIZE, "%d%s%s%d", time2-time1, ip, id, rand2); - - OS_MD5_Str(str1, md1); - OS_MD5_Str(str2, md2); - - snprintf(str1, STR_SIZE, "%s%d%d%d",md1,(int)getpid(), (int)random(), - time3); - OS_MD5_Str(str1, md1); - - //fprintf(fp,"%s %s %s %s%s\n",id, name, ip, md1,md2); - fprintf(fp,"%s %s %s %s%s\n",id, name, c_ip->ip, md1,md2); - - fclose(fp); - - printf(AGENT_ADD); - restart_necessary = 1; - }; - - fclose(infp); - return(0); -} + 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); -/* EOF */ + memset(name, '\0', FILE_SIZE + 1); + token = strtok(NULL, delims); + strncpy(name, trimwhitespace(token), FILE_SIZE - 1); + +#ifndef WIN32 + if (chmod(authfile, 0440) == -1) { + ErrorExit(CHMOD_ERROR, ARGV0, authfile, 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(authfile, "a"); + if (!fp) { + ErrorExit(FOPEN_ERROR, ARGV0, KEYS_FILE, errno, strerror(errno)); + } +#ifndef WIN32 + if (chmod(authfile, 0440) == -1) { + ErrorExit(CHMOD_ERROR, ARGV0, authfile, 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, id); + restart_necessary = 1; + +cleanup: + free(c_ip.ip); + }; + + fclose(infp); + return (0); +}