1 /* Copyright (C) 2019 OSSEC Foundation
4 * This program is a free software; you can redistribute it
5 * and/or modify it under the terms of the GNU General Public
6 * License (version 2) as published by the FSF - Free Software
10 #include "manage_agents.h"
11 #include "os_crypto/md5/md5_op.h"
12 #include "external/cJSON/cJSON.h"
17 static char *trimwhitespace(char *str);
20 static char *trimwhitespace(char *str)
24 /* Trim leading space */
25 while (isspace(*str)) {
29 if (*str == 0) { /* All spaces? */
33 /* Trim trailing space */
34 end = str + strlen(str) - 1;
35 while (end > str && isspace(*end)) {
39 /* Write new null terminator */
46 int k_import(const char *cmdimport)
49 const char *user_input;
56 char line_read[FILE_SIZE + 1];
58 char auth_file_tmp[] = AUTH_FILE;
59 char *keys_file = basename_ex(auth_file_tmp);
61 char tmp_path[strlen(TMP_DIR) + 1 + strlen(keys_file) + 6 + 1];
63 snprintf(tmp_path, sizeof(tmp_path), "%s/%sXXXXXX", TMP_DIR, keys_file);
65 /* Parse user argument */
67 user_input = cmdimport;
71 user_input = getenv("OSSEC_AGENT_KEY");
72 if (user_input == NULL) {
73 user_input = read_from_user();
78 if (strcmp(user_input, QUIT) == 0) {
82 b64_dec = decode_base64(user_input);
83 if (b64_dec == NULL) {
90 memset(line_read, '\0', FILE_SIZE + 1);
91 strncpy(line_read, b64_dec, FILE_SIZE);
93 name = strchr(b64_dec, ' ');
94 if (name && strlen(line_read) < FILE_SIZE) {
97 ip = strchr(name, ' ');
102 tmp_key = strchr(ip, ' ');
111 printf(AGENT_INFO, b64_dec, name, ip);
117 user_input = getenv("OSSEC_ACTION_CONFIRMED");
118 if (user_input == NULL) {
119 user_input = read_from_user();
122 if (user_input[0] == 'y' || user_input[0] == 'Y') {
123 if (mkstemp_ex(tmp_path)) {
124 ErrorExit(MKSTEMP_ERROR, ARGV0, tmp_path, errno, strerror(errno));
128 if (chmod(tmp_path, 0440) == -1) {
129 if (unlink(tmp_path)) {
130 verbose(DELETE_ERROR, ARGV0, tmp_path, errno, strerror(errno));
133 ErrorExit(CHMOD_ERROR, ARGV0, tmp_path, errno, strerror(errno));
137 fp = fopen(tmp_path, "w");
139 if (unlink(tmp_path)) {
140 verbose(DELETE_ERROR, ARGV0, tmp_path, errno, strerror(errno));
143 ErrorExit(FOPEN_ERROR, ARGV0, tmp_path, errno, strerror(errno));
145 fprintf(fp, "%s\n", line_read);
148 if (rename_ex(tmp_path, KEYS_FILE)) {
149 if (unlink(tmp_path)) {
150 verbose(DELETE_ERROR, ARGV0, tmp_path, errno, strerror(errno));
153 ErrorExit(RENAME_ERROR, ARGV0, tmp_path, KEYS_FILE, errno, strerror(errno));
156 /* Remove sender counter */
157 OS_RemoveCounter("sender");
162 restart_necessary = 1;
166 } else { /* if(user_input[0] == 'n' || user_input[0] == 'N') */
167 printf("%s", ADD_NOT);
184 /* Extract base64 for a specific agent */
185 int k_extract(const char *cmdextract, int json_output)
190 char line_read[FILE_SIZE + 1];
191 char n_id[USER_SIZE + 1];
192 cJSON *json_root = NULL;
195 json_root = cJSON_CreateObject();
198 user_input = strdup(cmdextract);
199 FormatID(user_input);
201 if (!IDExist(user_input)) {
204 snprintf(buffer, 1023, "Invalid ID '%s' given. ID is not present", user_input);
205 cJSON_AddNumberToObject(json_root, "error", 70);
206 cJSON_AddStringToObject(json_root, "description", buffer);
207 printf("%s", cJSON_PrintUnformatted(json_root));
209 printf(NO_ID, user_input);
213 if (!print_agents(0, 0, 0, 0)) {
223 user_input = read_from_user();
226 if (strcmp(user_input, QUIT) == 0) {
230 FormatID(user_input);
232 if (IDExist(user_input)) {
235 printf(NO_ID, user_input);
241 /* Try to open the auth file */
243 extern int willchroot;
245 snprintf(authfile, 256, "%s", AUTH_FILE); //XXX
247 const char *dir = DEFAULTDIR;
248 snprintf(authfile, 256, "%s/%s", dir, AUTH_FILE); //XXX
251 fp = fopen(authfile, "r");
255 snprintf(buffer, 1023, "Could not open file '%s' due to [(%d)-(%s)]", AUTH_FILE, errno, strerror(errno));
256 cJSON_AddNumberToObject(json_root, "error", 71);
257 cJSON_AddStringToObject(json_root, "description", buffer);
258 printf("%s", cJSON_PrintUnformatted(json_root));
261 ErrorExit(FOPEN_ERROR, ARGV0, AUTH_FILE, errno, strerror(errno));
266 if (fsetpos(fp, &fp_pos)) {
268 cJSON_AddNumberToObject(json_root, "error", 72);
269 cJSON_AddStringToObject(json_root, "description", "Can not set fileposition");
270 printf("%s", cJSON_PrintUnformatted(json_root));
272 merror("%s: Can not set fileposition.", ARGV0);
276 memset(n_id, '\0', USER_SIZE + 1);
277 strncpy(n_id, user_input, USER_SIZE - 1);
279 if (fgets(line_read, FILE_SIZE, fp) == NULL) {
281 cJSON_AddNumberToObject(json_root, "error", 73);
282 cJSON_AddStringToObject(json_root, "description", "Unable to handle keys file");
283 printf("%s", cJSON_PrintUnformatted(json_root));
292 b64_enc = encode_base64(strlen(line_read), line_read);
293 if (b64_enc == NULL) {
295 cJSON_AddNumberToObject(json_root, "error", 74);
296 cJSON_AddStringToObject(json_root, "description", "Unable to extract agent key");
297 printf("%s", cJSON_PrintUnformatted(json_root));
299 printf(EXTRACT_ERROR);
304 cJSON_AddNumberToObject(json_root, "error", 0);
305 cJSON_AddStringToObject(json_root, "response", b64_enc);
306 printf("%s", cJSON_PrintUnformatted(json_root));
308 printf(EXTRACT_MSG, n_id, b64_enc);
312 printf("\n" PRESS_ENTER);
322 /* Bulk generate client keys from file */
323 int k_bulkload(const char *cmdbulk)
327 char str1[STR_SIZE + 1];
328 char str2[STR_SIZE + 1];
332 char line[FILE_SIZE + 1];
333 char name[FILE_SIZE + 1];
334 char id[FILE_SIZE + 1];
335 char ip[FILE_SIZE + 1];
339 /* Check if we can open the input file */
340 printf("Opening: [%s]\n", cmdbulk);
341 infp = fopen(cmdbulk, "r");
344 ErrorExit(FOPEN_ERROR, ARGV0, cmdbulk, errno, strerror(errno));
347 /* Check if we can open the auth_file */
350 snprintf(authfile, 256, "%s", AUTH_FILE); //XXX
352 const char *dir = DEFAULTDIR;
353 snprintf(authfile, 256, "%s/%s", dir, AUTH_FILE); //XXX
356 fp = fopen(authfile, "a");
358 ErrorExit(FOPEN_ERROR, ARGV0, authfile, errno, strerror(errno));
362 while (fgets(line, FILE_SIZE - 1, infp) != NULL) {
366 if (1 >= strlen(trimwhitespace(line))) {
370 memset(ip, '\0', FILE_SIZE + 1);
371 token = strtok(line, delims);
372 strncpy(ip, trimwhitespace(token), FILE_SIZE - 1);
374 memset(name, '\0', FILE_SIZE + 1);
375 token = strtok(NULL, delims);
376 strncpy(name, trimwhitespace(token), FILE_SIZE - 1);
379 if (chmod(authfile, 0440) == -1) {
380 ErrorExit(CHMOD_ERROR, ARGV0, authfile, errno, strerror(errno));
391 memset(str1, '\0', STR_SIZE + 1);
392 memset(str2, '\0', STR_SIZE + 1);
395 if (!OS_IsValidName(name)) {
396 printf(INVALID_NAME, name);
400 /* Search for name -- no duplicates */
401 if (NameExist(name)) {
402 printf(ADD_ERROR_NAME, name);
406 if (!OS_IsValidIP(ip, &c_ip)) {
407 printf(IP_ERROR, ip);
412 i = MAX_AGENTS + 32512;
413 snprintf(id, 8, "%03d", i);
414 while (!IDExist(id)) {
416 snprintf(id, 8, "%03d", i);
418 /* No key present, use id 0 */
424 snprintf(id, 8, "%03d", i + 1);
426 if (!OS_IsValidID(id)) {
427 printf(INVALID_ID, id);
431 /* Search for ID KEY -- no duplicates */
433 printf(NO_DEFAULT, i + 1);
437 printf(AGENT_INFO, id, name, ip);
443 fp = fopen(authfile, "a");
445 ErrorExit(FOPEN_ERROR, ARGV0, KEYS_FILE, errno, strerror(errno));
448 if (chmod(authfile, 0440) == -1) {
449 ErrorExit(CHMOD_ERROR, ARGV0, authfile, errno, strerror(errno));
453 /* Random 1: Time took to write the agent information
454 * Random 2: Time took to choose the action
455 * Random 3: All of this + time + pid
456 * Random 4: MD5 all of this + the name, key and IP
457 * Random 5: Final key
460 snprintf(str1, STR_SIZE, "%d%s%d", (int)(time3 - time2), name, (int)rand1);
461 snprintf(str2, STR_SIZE, "%d%s%s%d", (int)(time2 - time1), ip, id, (int)rand2);
463 OS_MD5_Str(str1, md1);
464 OS_MD5_Str(str2, md2);
466 snprintf(str1, STR_SIZE, "%s%d%d%d", md1, (int)getpid(), (int)random(),
468 OS_MD5_Str(str1, md1);
470 fprintf(fp, "%s %s %s %s%s\n", id, name, c_ip.ip, md1, md2);
473 printf(AGENT_ADD, id);
474 restart_necessary = 1;