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"
14 static void helpmsg(void) __attribute__((noreturn));
15 static void print_banner(void);
17 static void manage_shutdown(int sig) __attribute__((noreturn));
21 #if defined(__MINGW32__)
22 static int setenv(const char *name, const char *val, __attribute__((unused)) int overwrite)
24 int len = strlen(name) + strlen(val) + 2;
25 char *str = (char *)malloc(len);
27 merror("%s: malloc failed", ARGV0);
30 snprintf(str, len, "%s=%s", name, val);
39 print_out(" %s: -[Vhlj] [-a <ip> -n <name>] [-d sec] [-e id] [-r id] [-i id] [-f file]", ARGV0);
40 print_out(" -V Version and license message");
41 print_out(" -h This help message");
42 print_out(" -j Use JSON output");
43 print_out(" -l List available agents.");
44 print_out(" -a <ip> Add new agent");
46 print_out(" -e <id> Extracts key for an agent (Manager only)");
47 print_out(" -r <id> Remove an agent (Manager only)");
48 print_out(" -i <id> Import authentication key (Agent only)");
49 print_out(" -n <name> Name for new agent");
50 print_out(" -F <sec> Remove agents with duplicated IP if disconnected since <sec> seconds");
51 print_out(" -f <file> Bulk generate client keys from file (Manager only)");
52 print_out(" <file> contains lines in IP,NAME format");
53 print_out(" <file> should also exist within /var/ossec due to manage_agents chrooting");
57 static void print_banner()
60 printf(BANNER, __ossec_name, __version);
63 printf(BANNER_CLIENT);
72 /* Clean shutdown on kill */
73 static void manage_shutdown(__attribute__((unused)) int sig)
75 /* Checking if restart message is necessary */
76 if (restart_necessary) {
87 int main(int argc, char **argv)
90 int c = 0, cmdlist = 0, json_output = 0;
93 const char *cmdexport = NULL;
94 const char *cmdimport = NULL;
95 const char *cmdbulk = NULL;
97 const char *dir = DEFAULTDIR;
98 const char *group = GROUPGLOBAL;
107 extern int willchroot;
113 while ((c = getopt(argc, argv, "Vhle:r:i:f:ja:n:F:")) != -1) {
123 ErrorExit("%s: Key export only available on a master.", ARGV0);
126 ErrorExit("%s: -e needs an argument.", ARGV0);
132 ErrorExit("%s: Key removal only available on a master.", ARGV0);
135 ErrorExit("%s: -r needs an argument.", ARGV0);
138 /* Use environment variables already available to remove_agent() */
139 setenv("OSSEC_ACTION", "r", 1);
140 setenv("OSSEC_AGENT_ID", optarg, 1);
141 setenv("OSSEC_ACTION_CONFIRMED", "y", 1);
145 ErrorExit("%s: Key import only available on an agent.", ARGV0);
148 ErrorExit("%s: -i needs an argument.", ARGV0);
154 ErrorExit("%s: Bulk generate keys only available on a master.", ARGV0);
157 ErrorExit("%s: -f needs an argument.", ARGV0);
161 printf("Bulk load file: %s\n", cmdbulk);
171 ErrorExit("%s: Agent adding only available on a master.", ARGV0);
174 ErrorExit("%s: -a needs an argument.", ARGV0);
175 setenv("OSSEC_ACTION", "a", 1);
176 setenv("OSSEC_ACTION_CONFIRMED", "y", 1);
177 setenv("OSSEC_AGENT_IP", optarg, 1);
178 setenv("OSSEC_AGENT_ID", "0", 1);
182 ErrorExit("%s: -n needs an argument.", ARGV0);
183 setenv("OSSEC_AGENT_NAME", optarg, 1);
187 ErrorExit("%s: -d needs an argument.", ARGV0);
189 force_antiquity = strtol(optarg, &end, 10);
191 if (optarg == end || force_antiquity < 0)
192 ErrorExit("%s: Invalid number for -d", ARGV0);
194 setenv("OSSEC_REMOVE_DUPLICATED", optarg, 1);
202 /* Get current time */
204 restart_necessary = 0;
210 /* Get the group name */
211 gid = Privsep_GetGroup(group);
212 if (gid == (gid_t) - 1) {
213 ErrorExit(USER_ERROR, ARGV0, "", group);
217 if (Privsep_SetGroup(gid) < 0) {
218 ErrorExit(SETGID_ERROR, ARGV0, group, errno, strerror(errno));
221 /* Inside chroot now */
224 /* Chroot to the default directory */
225 if (Privsep_Chroot(dir) < 0) {
226 ErrorExit(CHROOT_ERROR, ARGV0, dir, errno, strerror(errno));
232 /* Start signal handler */
233 StartSIG2(ARGV0, manage_shutdown);
235 /* Get full path to the directory this executable lives in */
236 ret = GetModuleFileName(NULL, path, sizeof(path));
238 /* Check for errors */
240 ErrorExit(GMF_ERROR);
244 last_error = GetLastError();
246 /* Look for errors */
247 if (last_error != ERROR_SUCCESS) {
248 if (last_error == ERROR_INSUFFICIENT_BUFFER) {
249 ErrorExit(GMF_BUFF_ERROR, ret, sizeof(path));
251 ErrorExit(GMF_UNKN_ERROR, last_error);
255 /* Remove file name from path */
256 PathRemoveFileSpec(path);
258 /* Move to correct directory */
260 ErrorExit(CHDIR_ERROR, ARGV0, path, errno, strerror(errno));
263 /* Check permissions */
264 fp = fopen(OSSECCONF, "r");
268 ErrorExit(CONF_ERROR, OSSECCONF);
273 list_agents(cmdlist);
275 } else if (cmdimport) {
278 } else if (cmdexport) {
279 k_extract(cmdexport, json_output);
281 } else if (cmdbulk) {
294 /* Get ACTION from the environment. If ACTION is specified,
295 * we must set leave_s = 1 to ensure that the loop will end */
296 user_msg = getenv("OSSEC_ACTION");
297 if (user_msg == NULL) {
298 user_msg = read_from_user();
303 /* All the allowed actions */
304 switch (user_msg[0]) {
308 printf("\n ** Agent adding only available on a master ** \n\n");
311 add_agent(json_output);
316 printf("\n ** Key export only available on a master ** \n\n");
319 k_extract(NULL, json_output);
324 printf("\n ** Key import only available on an agent ** \n\n");
337 printf("\n ** Key removal only available on a master ** \n\n");
340 remove_agent(json_output);
350 printf("\n ** Invalid Action ** \n\n");
362 if (restart_necessary) {
363 printf(MUST_RESTART);