END_TEST START_TEST(test_gethost_success_ipv6) { char *ret; ck_assert_str_eq((ret = OS_GetHost("ipv6.test-ipv6.com", 2)), "2001:470:1:18::119"); free(ret); }
END_TEST START_TEST(test_gethost_success) { char *ret; ck_assert_str_eq((ret = OS_GetHost("google-public-dns-a.google.com", 2)), "8.8.8.8"); free(ret); }
END_TEST START_TEST(test_gethost_success_ipv4) { char *ret; ck_assert_str_eq((ret = OS_GetHost("ipv4.test-ipv6.com", 2)), "216.218.228.119"); free(ret); }
/* Set OSSEC Server IP */ int set_ossec_server(char *ip, HWND hwnd) { char **xml_pt = NULL; char *(xml_serverip[])={"ossec_config","client","server-ip", NULL}; char *(xml_serverhost[])={"ossec_config","client","server-hostname", NULL}; /* Verifying IP Address */ if(OS_IsValidIP(ip, NULL) != 1) { char *s_ip; s_ip = OS_GetHost(ip, 0); if(!s_ip) { MessageBox(hwnd, "Invalid Server IP Address.\r\n" "It must be the valid Ipv4 address of the " "OSSEC server or its resolvable hostname.", "Invalid Server IP Address.",MB_OK); return(0); } config_inst.server_type = SERVER_HOST_USED; xml_pt = xml_serverhost; } else { config_inst.server_type = SERVER_IP_USED; xml_pt = xml_serverip; } /* Reading the XML. Printing error and line number */ if(OS_WriteXML(CONFIG, NEWCONFIG, xml_pt, NULL, NULL, ip, 0) != 0) { MessageBox(hwnd, "Unable to set OSSEC Server IP Address.\r\n" "(Internal error on the XML Write).", "Unable to set Server IP Address.",MB_OK); return(0); } /* Renaming config files */ unlink(LASTCONFIG); rename(CONFIG, LASTCONFIG); rename(NEWCONFIG, CONFIG); return(1); }
/* Set OSSEC Server IP */ int set_ossec_server(char *ip, HWND hwnd) { const char **xml_pt = NULL; const char *(xml_serverip[]) = {"ossec_config", "client", "server-ip", NULL}; const char *(xml_serverhost[]) = {"ossec_config", "client", "server-hostname", NULL}; char config_tmp[] = CONFIG; char *conf_file = basename_ex(config_tmp); char tmp_path[strlen(TMP_DIR) + 1 + strlen(conf_file) + 6 + 1]; snprintf(tmp_path, sizeof(tmp_path), "%s/%sXXXXXX", TMP_DIR, conf_file); /* Verify IP Address */ if (OS_IsValidIP(ip, NULL) != 1) { char *s_ip; s_ip = OS_GetHost(ip, 0); if (!s_ip) { MessageBox(hwnd, "Invalid Server IP Address.\r\n" "It must be the valid IPv4 address of the " "OSSEC server or the resolvable hostname.", "Error -- Failure Setting IP", MB_OK); return (0); } config_inst.server_type = SERVER_HOST_USED; xml_pt = xml_serverhost; } else { config_inst.server_type = SERVER_IP_USED; xml_pt = xml_serverip; } /* Create temporary file */ if (mkstemp_ex(tmp_path) == -1) { MessageBox(hwnd, "Could not create temporary file.", "Error -- Failure Setting IP", MB_OK); return (0); } /* Read the XML. Print error and line number. */ if (OS_WriteXML(CONFIG, tmp_path, xml_pt, NULL, ip) != 0) { MessageBox(hwnd, "Unable to set OSSEC Server IP Address.\r\n" "(Internal error on the XML Write).", "Error -- Failure Setting IP", MB_OK); if (unlink(tmp_path)) { MessageBox(hwnd, "Could not delete temporary file.", "Error -- Failure Deleting Temporary File", MB_OK); } return (0); } /* Rename config files */ if (rename_ex(CONFIG, LASTCONFIG)) { MessageBox(hwnd, "Unable to backup configuration.", "Error -- Failure Backing Up Configuration", MB_OK); if (unlink(tmp_path)) { MessageBox(hwnd, "Could not delete temporary file.", "Error -- Failure Deleting Temporary File", MB_OK); } return (0); } if (rename_ex(tmp_path, CONFIG)) { MessageBox(hwnd, "Unable rename temporary file.", "Error -- Failure Renaming Temporary File", MB_OK); if (unlink(tmp_path)) { MessageBox(hwnd, "Could not delete temporary file.", "Error -- Failure Deleting Temporary File", MB_OK); } return (0); } return (1); }
/* Get OSSEC Server IP */ int get_ossec_server() { OS_XML xml; char *str = NULL; /* Definitions */ const char *(xml_serverip[]) = {"ossec_config", "client", "server-ip", NULL}; const char *(xml_serverhost[]) = {"ossec_config", "client", "server-hostname", NULL}; /* Read XML */ if (OS_ReadXML(CONFIG, &xml) < 0) { return (0); } /* We need to remove the entry for the server */ if (config_inst.server) { free(config_inst.server); config_inst.server = NULL; } config_inst.server_type = 0; /* Get IP */ str = OS_GetOneContentforElement(&xml, xml_serverip); if (str && (OS_IsValidIP(str, NULL) == 1)) { config_inst.server_type = SERVER_IP_USED; config_inst.server = str; OS_ClearXML(&xml); return (1); } /* If we don't find the IP, try the server hostname */ else { if (str) { free(str); str = NULL; } str = OS_GetOneContentforElement(&xml, xml_serverhost); if (str) { char *s_ip; s_ip = OS_GetHost(str, 0); if (s_ip) { /* Clear the host memory */ free(s_ip); /* Assign the hostname to the server info */ config_inst.server_type = SERVER_HOST_USED; config_inst.server = str; OS_ClearXML(&xml); return (1); } free(str); } } /* Set up final server name when not available */ config_inst.server = strdup(FL_NOSERVER); OS_ClearXML(&xml); return (0); }
/** void connect_server() * Attempts to connect to all configured servers. */ int connect_server(int initial_id) { int attempts = 2; int rc = initial_id; /* Checking if the initial is zero, meaning we have to rotate to the * beginning. */ if(agt->rip[initial_id] == NULL) { rc = 0; initial_id = 0; } /* Closing socket if available. */ if(agt->sock >= 0) { sleep(1); CloseSocket(agt->sock); agt->sock = -1; if(agt->rip[1]) { verbose("%s: INFO: Closing connection to server (%s:%d).", ARGV0, agt->rip[rc], agt->port); } } while(agt->rip[rc]) { char *tmp_str; /* Checking if we have a hostname. */ tmp_str = strchr(agt->rip[rc], '/'); if(tmp_str) { char *f_ip; *tmp_str = '\0'; f_ip = OS_GetHost(agt->rip[rc], 5); if(f_ip) { char ip_str[128]; ip_str[127] = '\0'; snprintf(ip_str, 127, "%s/%s", agt->rip[rc], f_ip); free(f_ip); free(agt->rip[rc]); os_strdup(ip_str, agt->rip[rc]); tmp_str = strchr(agt->rip[rc], '/'); tmp_str++; } else { merror("%s: WARN: Unable to get hostname for '%s'.", ARGV0, agt->rip[rc]); *tmp_str = '/'; tmp_str++; } } else { tmp_str = agt->rip[rc]; } verbose("%s: INFO: Trying to connect to server (%s:%d).", ARGV0, agt->rip[rc], agt->port); /* IPv6 address: */ if(strchr(tmp_str,':') != NULL) { verbose("%s: INFO: Using IPv6 for: %s .", ARGV0, tmp_str); agt->sock = OS_ConnectUDP(agt->port, tmp_str, 1); } else { verbose("%s: INFO: Using IPv4 for: %s .", ARGV0, tmp_str); agt->sock = OS_ConnectUDP(agt->port, tmp_str, 0); } if(agt->sock < 0) { agt->sock = -1; merror(CONNS_ERROR, ARGV0, tmp_str); rc++; if(agt->rip[rc] == NULL) { attempts += 10; /* Only log that if we have more than 1 server configured. */ if(agt->rip[1]) merror("%s: ERROR: Unable to connect to any server.",ARGV0); sleep(attempts); rc = 0; } } else { /* Setting socket non-blocking on HPUX */ #ifdef HPUX //fcntl(agt->sock, O_NONBLOCK); #endif #ifdef WIN32 int bmode = 1; /* Setting socket to non-blocking */ ioctlsocket(agt->sock, FIONBIO, (u_long FAR*) &bmode); #endif agt->rip_id = rc; return(1); } } return(0); }
/* Set OSSEC Server IP */ int set_ossec_server(char *ip, HWND hwnd) { FILE *fp; char **xml_pt = NULL; char *(xml_serverip[])= {"ossec_config","client","server-ip", NULL}; char *(xml_serverhost[])= {"ossec_config","client","server-hostname", NULL}; char *cacls; int cmdlen; /* Build command line to change permissions */ cacls = "echo y|cacls \"%s\" /T /G Administrators:f"; cmdlen = strlen(cacls) + strlen(NEWCONFIG); char cmd[cmdlen]; snprintf(cmd, cmdlen, cacls, NEWCONFIG); /* Verifying IP Address */ if(OS_IsValidIP(ip, NULL) != 1) { char *s_ip; s_ip = OS_GetHost(ip, 0); if(!s_ip) { MessageBox(hwnd, "Invalid Server IP Address.\r\n" "It must be the valid Ipv4 address of the " "OSSEC server or its resolvable hostname.", "Error -- Failure Setting IP",MB_OK); return(0); } config_inst.server_type = SERVER_HOST_USED; xml_pt = xml_serverhost; } else { config_inst.server_type = SERVER_IP_USED; xml_pt = xml_serverip; } /* Create file */ fp = fopen(NEWCONFIG, "w"); if(fp) { fclose(fp); } else { MessageBox(hwnd, "Could not create configuration file.", "Error -- Failure Setting IP",MB_OK); return(0); } /* Change permissions */ if (run_cmd(cmd, hwnd)) { MessageBox(hwnd, "Unable to set permissions on new configuration file.", "Error -- Failure Setting IP",MB_OK); /* Remove config */ if(unlink(NEWCONFIG)) { MessageBox(hwnd, "Unable to remove new configuration file.", "Error -- Failure Setting IP",MB_OK); } return(0); } /* Reading the XML. Printing error and line number. */ if(OS_WriteXML(CONFIG, NEWCONFIG, xml_pt, NULL, ip) != 0) { MessageBox(hwnd, "Unable to set OSSEC Server IP Address.\r\n" "(Internal error on the XML Write).", "Error -- Failure Setting IP",MB_OK); return(0); } /* Renaming config files */ unlink(LASTCONFIG); rename(CONFIG, LASTCONFIG); rename(NEWCONFIG, CONFIG); return(1); }
END_TEST START_TEST(test_gethost_fail2) { ck_assert_ptr_eq(OS_GetHost("this.should.not.exist", 2), NULL); }
END_TEST START_TEST(test_gethost_fail1) { ck_assert_ptr_eq(OS_GetHost(NULL, 2), NULL); }
int main(int argc, char **argv) { int key_added = 0; int c; int test_config = 0; int auto_method = 0; #ifndef WIN32 gid_t gid = 0; #endif int sock = 0, port = DEFAULT_PORT, ret = 0; const char *dir = DEFAULTDIR; const char *group = GROUPGLOBAL; char *authpass = NULL; const char *manager = NULL; const char *ipaddress = NULL; const char *agentname = NULL; const char *agent_cert = NULL; const char *agent_key = NULL; const char *ca_cert = NULL; char lhostname[512 + 1]; char buf[4096 + 1]; SSL_CTX *ctx; SSL *ssl; BIO *sbio; bio_err = 0; buf[4096] = '\0'; #ifdef WIN32 WSADATA wsaData; #endif /* Set the name */ OS_SetName(ARGV0); while ((c = getopt(argc, argv, "Vdhtg:m:p:A:v:x:k:D:P:a")) != -1) { switch (c) { case 'V': print_version(); break; case 'h': help_agent_auth(); break; case 'd': nowDebug(); break; case 'g': if (!optarg) { ErrorExit("%s: -g needs an argument", ARGV0); } group = optarg; break; case 'D': if (!optarg) { ErrorExit("%s: -g needs an argument", ARGV0); } dir = optarg; break; case 't': test_config = 1; break; case 'm': if (!optarg) { ErrorExit("%s: -%c needs an argument", ARGV0, c); } manager = optarg; break; case 'A': if (!optarg) { ErrorExit("%s: -%c needs an argument", ARGV0, c); } agentname = optarg; break; case 'p': if (!optarg) { ErrorExit("%s: -%c needs an argument", ARGV0, c); } port = atoi(optarg); if (port <= 0 || port >= 65536) { ErrorExit("%s: Invalid port: %s", ARGV0, optarg); } break; case 'v': if (!optarg) { ErrorExit("%s: -%c needs an argument", ARGV0, c); } ca_cert = optarg; break; case 'x': if (!optarg) { ErrorExit("%s: -%c needs an argument", ARGV0, c); } agent_cert = optarg; break; case 'k': if (!optarg) { ErrorExit("%s: -%c needs an argument", ARGV0, c); } agent_key = optarg; break; case 'P': if (!optarg) ErrorExit("%s: -%c needs an argument", ARGV0, c); authpass = optarg; break; case 'a': auto_method = 1; break; default: help_agent_auth(); break; } } /* Start daemon */ debug1(STARTED_MSG, ARGV0); #ifndef WIN32 /* Check if the user/group given are valid */ gid = Privsep_GetGroup(group); if (gid == (gid_t) - 1) { ErrorExit(USER_ERROR, ARGV0, "", group); } /* Exit here if test config is set */ if (test_config) { exit(0); } /* Privilege separation */ if (Privsep_SetGroup(gid) < 0) { ErrorExit(SETGID_ERROR, ARGV0, group, errno, strerror(errno)); } /* Signal manipulation */ StartSIG(ARGV0); /* Create PID files */ if (CreatePID(ARGV0, getpid()) < 0) { ErrorExit(PID_ERROR, ARGV0); } #else /* Initialize Windows socket stuff */ if (WSAStartup(MAKEWORD(2, 0), &wsaData) != 0) { ErrorExit("%s: WSAStartup() failed", ARGV0); } #endif /* WIN32 */ /* Start up message */ verbose(STARTUP_MSG, ARGV0, (int)getpid()); if (agentname == NULL) { lhostname[512] = '\0'; if (gethostname(lhostname, 512 - 1) != 0) { merror("%s: ERROR: Unable to extract hostname. Custom agent name not set.", ARGV0); exit(1); } agentname = lhostname; } #ifdef LEGACY_SSL auto_method = 1; merror("WARN: TLS v1.2 method-forcing disabled. This program was compiled to use SSL/TLS auto-negotiation."); #endif /* Start SSL */ ctx = os_ssl_keys(0, dir, agent_cert, agent_key, ca_cert, auto_method); if (!ctx) { merror("%s: ERROR: SSL error. Exiting.", ARGV0); exit(1); } if (!manager) { merror("%s: ERROR: Manager IP not set.", ARGV0); exit(1); } /* Check to see if the manager to connect to was specified as an IP address * or hostname on the command line. If it was given as a hostname then ensure * the hostname is preserved so that certificate verification can be done. */ if (!(ipaddress = OS_GetHost(manager, 3))) { merror("%s: Could not resolve hostname: %s\n", ARGV0, manager); exit(1); } /* Checking if there is a custom password file */ if (authpass == NULL) { FILE *fp; fp = fopen(AUTHDPASS_PATH, "r"); buf[0] = '\0'; if (fp) { buf[4096] = '\0'; char *ret = fgets(buf, 4095, fp); if (ret && strlen(buf) > 2) { authpass = buf; } fclose(fp); printf("INFO: Using password specified on file: %s\n", AUTHDPASS_PATH); } } if (!authpass) { printf("WARN: No authentication password provided.\n"); } /* Connect via TCP */ sock = OS_ConnectTCP(port, ipaddress, 0); if (sock <= 0) { merror("%s: Unable to connect to %s:%d", ARGV0, ipaddress, port); exit(1); } /* Connect the SSL socket */ ssl = SSL_new(ctx); sbio = BIO_new_socket(sock, BIO_NOCLOSE); SSL_set_bio(ssl, sbio, sbio); ret = SSL_connect(ssl); if (ret <= 0) { ERR_print_errors_fp(stderr); merror("%s: ERROR: SSL error (%d). Exiting.", ARGV0, ret); exit(1); } printf("INFO: Connected to %s:%d\n", ipaddress, port); /* Additional verification of the manager's certificate if a hostname * rather than an IP address is given on the command line. Could change * this to do the additional validation on IP addresses as well if needed. */ if (ca_cert) { printf("INFO: Verifing manager's certificate\n"); if (check_x509_cert(ssl, manager) != VERIFY_TRUE) { debug1("%s: DEBUG: Unable to verify server certificate.", ARGV0); exit(1); } } printf("INFO: Using agent name as: %s\n", agentname); if (authpass) { snprintf(buf, 2048, "OSSEC PASS: %s OSSEC A:'%s'\n", authpass, agentname); } else { snprintf(buf, 2048, "OSSEC A:'%s'\n", agentname); } ret = SSL_write(ssl, buf, strlen(buf)); if (ret < 0) { printf("SSL write error (unable to send message.)\n"); ERR_print_errors_fp(stderr); exit(1); } printf("INFO: Send request to manager. Waiting for reply.\n"); while (1) { ret = SSL_read(ssl, buf, sizeof(buf) - 1); switch (SSL_get_error(ssl, ret)) { case SSL_ERROR_NONE: buf[ret] = '\0'; if (strncmp(buf, "ERROR", 5) == 0) { char *tmpstr; tmpstr = strchr(buf, '\n'); if (tmpstr) { *tmpstr = '\0'; } printf("%s (from manager)\n", buf); } else if (strncmp(buf, "OSSEC K:'", 9) == 0) { char *key; char *tmpstr; char **entry; printf("INFO: Received response with agent key\n"); key = buf; key += 9; tmpstr = strchr(key, '\''); if (!tmpstr) { printf("ERROR: Invalid key received. Closing connection.\n"); exit(1); } *tmpstr = '\0'; entry = OS_StrBreak(' ', key, 4); if (!OS_IsValidID(entry[0]) || !OS_IsValidName(entry[1]) || !OS_IsValidName(entry[2]) || !OS_IsValidName(entry[3])) { printf("ERROR: Invalid key received (2). Closing connection.\n"); exit(1); } { FILE *fp; fp = fopen(KEYSFILE_PATH, "w"); if (!fp) { printf("ERROR: Unable to open key file: %s", KEYSFILE_PATH); exit(1); } fprintf(fp, "%s\n", key); fclose(fp); } key_added = 1; printf("INFO: Valid key created. Finished.\n"); } break; case SSL_ERROR_ZERO_RETURN: case SSL_ERROR_SYSCALL: if (key_added == 0) { printf("ERROR: Unable to create key. Either wrong password or connection not accepted by the manager.\n"); } printf("INFO: Connection closed.\n"); exit(0); break; default: printf("ERROR: SSL read (unable to receive message)\n"); exit(1); break; } } /* Shut down the socket */ if (key_added == 0) { printf("ERROR: Unable to create key. Either wrong password or connection not accepted by the manager.\n"); } SSL_CTX_free(ctx); close(sock); exit(0); }
/* GlobalConf v0.2: 2005/03/03 * v0.2: Changing to support the new OS_XML */ int Read_Global(XML_NODE node, void *configp, void *mailp) { int i = 0; /* White list size */ int white_size = 1; int hostname_white_size = 1; int mailto_size = 1; /* XML definitions */ char *xml_mailnotify = "email_notification"; char *xml_logall = "logall"; char *xml_integrity = "integrity_checking"; char *xml_rootcheckd = "rootkit_detection"; char *xml_hostinfo = "host_information"; char *xml_picviz = "picviz_output"; char *xml_picviz_socket = "picviz_socket"; char *xml_prelude = "prelude_output"; char *xml_prelude_profile = "prelude_profile"; char *xml_prelude_log_level = "prelude_log_level"; char *xml_zeromq_output = "zeromq_output"; char *xml_zeromq_output_uri = "zeromq_uri"; char *xml_stats = "stats"; char *xml_memorysize = "memory_size"; char *xml_white_list = "white_list"; char *xml_compress_alerts = "compress_alerts"; char *xml_custom_alert_output = "custom_alert_output"; char *xml_emailto = "email_to"; char *xml_emailfrom = "email_from"; char *xml_emailidsname = "email_idsname"; char *xml_smtpserver = "smtp_server"; char *xml_mailmaxperhour = "email_maxperhour"; #ifdef GEOIP /* GeoIP */ char *xml_geoip_db_path = "geoip_db_path"; char *xml_geoip6_db_path = "geoip6_db_path"; #endif _Config *Config; MailConfig *Mail; Config = (_Config *)configp; Mail = (MailConfig *)mailp; /* Getting right white_size */ if(Config && Config->white_list) { os_ip **ww; ww = Config->white_list; while(*ww != NULL) { white_size++; ww++; } } /* Getting right white_size */ if(Config && Config->hostname_white_list) { OSMatch **ww; ww = Config->hostname_white_list; while(*ww != NULL) { hostname_white_size++; ww++; } } /* Getting mail_to size */ if(Mail && Mail->to) { char **ww; ww = Mail->to; while(*ww != NULL) { mailto_size++; ww++; } } while(node[i]) { if(!node[i]->element) { merror(XML_ELEMNULL, ARGV0); return(OS_INVALID); } else if(!node[i]->content) { merror(XML_VALUENULL, ARGV0, node[i]->element); return(OS_INVALID); } else if(strcmp(node[i]->element, xml_custom_alert_output) == 0) { if(Config) { Config->custom_alert_output= 1; os_strdup(node[i]->content, Config->custom_alert_output_format); } } /* Mail notification */ else if(strcmp(node[i]->element, xml_mailnotify) == 0) { if(strcmp(node[i]->content, "yes") == 0) { if(Config) Config->mailnotify = 1; if(Mail) Mail->mn = 1; } else if(strcmp(node[i]->content, "no") == 0) { if(Config) Config->mailnotify = 0; if(Mail) Mail->mn = 0; } else { merror(XML_VALUEERR,ARGV0,node[i]->element,node[i]->content); return(OS_INVALID); } } /* Picviz support */ else if(strcmp(node[i]->element, xml_picviz) == 0) { if(strcmp(node[i]->content, "yes") == 0) { if(Config) Config->picviz = 1; } else if(strcmp(node[i]->content, "no") == 0) { if(Config) Config->picviz = 0; } else { merror(XML_VALUEERR,ARGV0,node[i]->element, node[i]->content); return(OS_INVALID); } } else if(strcmp(node[i]->element, xml_picviz_socket) == 0) { if(Config) { os_strdup(node[i]->content, Config->picviz_socket); } } /* Prelude support */ else if(strcmp(node[i]->element, xml_prelude) == 0) { if(strcmp(node[i]->content, "yes") == 0) { if(Config) Config->prelude = 1; } else if(strcmp(node[i]->content, "no") == 0) { if(Config) Config->prelude = 0; } else { merror(XML_VALUEERR,ARGV0,node[i]->element, node[i]->content); return(OS_INVALID); } } else if(strcmp(node[i]->element, xml_prelude_profile) == 0) { if(Config) { Config->prelude_profile = strdup(node[i]->content); } } else if(strcmp(node[i]->element, xml_prelude_log_level) == 0) { if(!OS_StrIsNum(node[i]->content)) { merror(XML_VALUEERR,ARGV0,node[i]->element,node[i]->content); return(OS_INVALID); } if(Config) { Config->prelude_log_level = atoi(node[i]->content); } } /* ZeroMQ output */ else if(strcmp(node[i]->element, xml_zeromq_output) == 0) { if(strcmp(node[i]->content, "yes") == 0) { if(Config) Config->zeromq_output = 1; } else if(strcmp(node[i]->content, "no") == 0) { if(Config) Config->zeromq_output = 0; } else { merror(XML_VALUEERR,ARGV0,node[i]->element, node[i]->content); return(OS_INVALID); } } else if(strcmp(node[i]->element, xml_zeromq_output_uri) == 0) { if(Config) { Config->zeromq_output_uri = strdup(node[i]->content); } } /* Log all */ else if(strcmp(node[i]->element, xml_logall) == 0) { if(strcmp(node[i]->content, "yes") == 0) { if(Config) Config->logall = 1;} else if(strcmp(node[i]->content, "no") == 0) {if(Config) Config->logall = 0;} else { merror(XML_VALUEERR,ARGV0,node[i]->element,node[i]->content); return(OS_INVALID); } } /* compress alerts */ else if(strcmp(node[i]->element, xml_compress_alerts) == 0) { /* removed from here -- compatility issues only */ } /* Integrity */ else if(strcmp(node[i]->element, xml_integrity) == 0) { if(!OS_StrIsNum(node[i]->content)) { merror(XML_VALUEERR,ARGV0,node[i]->element,node[i]->content); return(OS_INVALID); } if(Config) { Config->integrity = atoi(node[i]->content); } } /* rootcheck */ else if(strcmp(node[i]->element, xml_rootcheckd) == 0) { if(!OS_StrIsNum(node[i]->content)) { merror(XML_VALUEERR,ARGV0,node[i]->element,node[i]->content); return(OS_INVALID); } if(Config) { Config->rootcheck = atoi(node[i]->content); } } /* hostinfo */ else if(strcmp(node[i]->element, xml_hostinfo) == 0) { if(!OS_StrIsNum(node[i]->content)) { merror(XML_VALUEERR,ARGV0,node[i]->element,node[i]->content); return(OS_INVALID); } if(Config) { Config->hostinfo = atoi(node[i]->content); } } /* stats */ else if(strcmp(node[i]->element, xml_stats) == 0) { if(!OS_StrIsNum(node[i]->content)) { merror(XML_VALUEERR,ARGV0,node[i]->element,node[i]->content); return(OS_INVALID); } if(Config) { Config->stats = atoi(node[i]->content); } } else if(strcmp(node[i]->element, xml_memorysize) == 0) { if(!OS_StrIsNum(node[i]->content)) { merror(XML_VALUEERR,ARGV0,node[i]->element,node[i]->content); return(OS_INVALID); } if(Config) { Config->memorysize = atoi(node[i]->content); } } /* whitelist */ else if(strcmp(node[i]->element, xml_white_list) == 0) { /* Windows do not need it */ #ifndef WIN32 char *ip_address_regex = "^[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}/?" "([0-9]{0,2}|[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3})$"; if(Config && OS_PRegex(node[i]->content, ip_address_regex)) { white_size++; Config->white_list = realloc(Config->white_list, sizeof(os_ip *)*white_size); if(!Config->white_list) { merror(MEM_ERROR, ARGV0); return(OS_INVALID); } os_calloc(1, sizeof(os_ip), Config->white_list[white_size -2]); Config->white_list[white_size -1] = NULL; if(!OS_IsValidIP(node[i]->content, Config->white_list[white_size -2])) { merror(INVALID_IP, ARGV0, node[i]->content); return(OS_INVALID); } } /* Adding hostname */ else if(Config) { hostname_white_size++; Config->hostname_white_list = realloc(Config->hostname_white_list, sizeof(OSMatch *)*hostname_white_size); if(!Config->hostname_white_list) { merror(MEM_ERROR, ARGV0); return(OS_INVALID); } os_calloc(1, sizeof(OSMatch), Config->hostname_white_list[hostname_white_size -2]); Config->hostname_white_list[hostname_white_size -1] = NULL; if(!OSMatch_Compile( node[i]->content, Config->hostname_white_list[hostname_white_size -2], 0)) { merror(REGEX_COMPILE, ARGV0, node[i]->content, Config->hostname_white_list [hostname_white_size -2]->error); return(-1); } } #endif } /* For the email now * email_to, email_from, idsname, smtp_Server and maxperhour. * We will use a separate structure for that. */ else if(strcmp(node[i]->element, xml_emailto) == 0) { #ifndef WIN32 if(!OS_PRegex(node[i]->content, "[a-zA-Z0-9\\._-]+@[a-zA-Z0-9\\._-]")) { merror("%s: ERROR: Invalid Email address: %s.", ARGV0, node[i]->content); return(OS_INVALID); } #endif if(Mail) { mailto_size++; Mail->to = realloc(Mail->to, sizeof(char *)*mailto_size); if(!Mail->to) { merror(MEM_ERROR, ARGV0); return(OS_INVALID); } os_strdup(node[i]->content, Mail->to[mailto_size - 2]); Mail->to[mailto_size - 1] = NULL; } } else if(strcmp(node[i]->element, xml_emailfrom) == 0) { if(Mail) { if(Mail->from) { free(Mail->from); } os_strdup(node[i]->content, Mail->from); } } else if(strcmp(node[i]->element, xml_emailidsname) == 0) { if(Mail) { if(Mail->idsname) { free(Mail->idsname); } os_strdup(node[i]->content, Mail->idsname); } } else if(strcmp(node[i]->element, xml_smtpserver) == 0) { #ifndef WIN32 if(Mail && (Mail->mn)) { Mail->smtpserver = OS_GetHost(node[i]->content, 5); if(!Mail->smtpserver) { merror(INVALID_SMTP, ARGV0, node[i]->content); return(OS_INVALID); } } #endif } else if(strcmp(node[i]->element, xml_mailmaxperhour) == 0) { if(Mail) { if(!OS_StrIsNum(node[i]->content)) { merror(XML_VALUEERR,ARGV0,node[i]->element,node[i]->content); return(OS_INVALID); } Mail->maxperhour = atoi(node[i]->content); if((Mail->maxperhour <= 0) || (Mail->maxperhour > 9999)) { merror(XML_VALUEERR,ARGV0,node[i]->element,node[i]->content); return(OS_INVALID); } } } #ifdef GEOIP /* GeoIP v4 DB location */ else if(strcmp(node[i]->element, xml_geoip_db_path) == 0) { if(Config) { os_strdup(node[i]->content, Config->geoip_db_path); } } /* GeoIP v6 DB location */ else if(strcmp(node[i]->element, xml_geoip6_db_path) == 0) { if(Config) { os_strdup(node[i]->content, Config->geoip6_db_path); } } #endif else { merror(XML_INVELEM, ARGV0, node[i]->element); return(OS_INVALID); } i++; } return(0); }
int main(int argc, char **argv) { int c, test_config = 0; #ifndef WIN32 int gid = 0; #endif int sock = 0, port = 1515, ret = 0; char *dir = DEFAULTDIR; char *user = USER; char *group = GROUPGLOBAL; char *cfg = DEFAULTCPATH; char *manager = NULL; char *agentname = NULL; char lhostname[512 + 1]; char buf[2048 +1]; SSL_CTX *ctx; SSL *ssl; BIO *sbio; bio_err = 0; buf[2048] = '\0'; /* Setting the name */ OS_SetName(ARGV0); while((c = getopt(argc, argv, "Vdhu:g:D:c:m:p:A:")) != -1) { switch(c) { case 'V': print_version(); break; case 'h': report_help(); break; case 'd': nowDebug(); break; case 'u': if(!optarg) ErrorExit("%s: -u needs an argument",ARGV0); user=optarg; break; case 'g': if(!optarg) ErrorExit("%s: -g needs an argument",ARGV0); group=optarg; break; case 'D': if(!optarg) ErrorExit("%s: -D needs an argument",ARGV0); dir=optarg; break; case 'c': if(!optarg) ErrorExit("%s: -c needs an argument",ARGV0); cfg = optarg; break; case 't': test_config = 1; break; case 'm': if(!optarg) ErrorExit("%s: -%c needs an argument",ARGV0, c); manager = optarg; break; case 'A': if(!optarg) ErrorExit("%s: -%c needs an argument",ARGV0, c); agentname = optarg; break; case 'p': if(!optarg) ErrorExit("%s: -%c needs an argument",ARGV0, c); port = atoi(optarg); if(port <= 0 || port >= 65536) { ErrorExit("%s: Invalid port: %s", ARGV0, optarg); } break; default: report_help(); break; } } /* Starting daemon */ debug1(STARTED_MSG,ARGV0); #ifndef WIN32 /* Check if the user/group given are valid */ gid = Privsep_GetGroup(group); if(gid < 0) ErrorExit(USER_ERROR,ARGV0,user,group); /* Privilege separation */ if(Privsep_SetGroup(gid) < 0) ErrorExit(SETGID_ERROR,ARGV0,group); /* Signal manipulation */ StartSIG(ARGV0); /* Creating PID files */ if(CreatePID(ARGV0, getpid()) < 0) ErrorExit(PID_ERROR,ARGV0); #endif /* Start up message */ verbose(STARTUP_MSG, ARGV0, (int)getpid()); if(agentname == NULL) { lhostname[512] = '\0'; if(gethostname(lhostname, 512 -1) != 0) { merror("%s: ERROR: Unable to extract hostname. Custom agent name not set.", ARGV0); exit(1); } agentname = lhostname; } /* Starting SSL */ ctx = os_ssl_keys(1, NULL); if(!ctx) { merror("%s: ERROR: SSL error. Exiting.", ARGV0); exit(1); } if(!manager) { merror("%s: ERROR: Manager IP not set.", ARGV0); exit(1); } /* Check to see if manager is an IP */ int is_ip = 1; struct sockaddr_in iptest; memset(&iptest, 0, sizeof(iptest)); if(inet_pton(AF_INET, manager, &iptest.sin_addr) != 1) is_ip = 0; /* This is not an IPv4 address */ /* Not IPv4, IPv6 maybe? */ if(is_ip == 0) { struct sockaddr_in6 iptest6; memset(&iptest6, 0, sizeof(iptest6)); if(inet_pton(AF_INET6, manager, &iptest6.sin6_addr) != 1) is_ip = 0; else is_ip = 1; /* This is an IPv6 address */ } /* If it isn't an ip, try to resolve the IP */ if(is_ip == 0) { char *ipaddress; ipaddress = OS_GetHost(manager, 3); if(ipaddress != NULL) strncpy(manager, ipaddress, 16); else { printf("Could not resolve hostname: %s\n", manager); return(1); } } /* Connecting via TCP */ sock = OS_ConnectTCP(port, manager, 0); if(sock <= 0) { merror("%s: Unable to connect to %s:%d", ARGV0, manager, port); exit(1); } /* Connecting the SSL socket */ ssl = SSL_new(ctx); sbio = BIO_new_socket(sock, BIO_NOCLOSE); SSL_set_bio(ssl, sbio, sbio); ret = SSL_connect(ssl); if(ret <= 0) { ERR_print_errors_fp(stderr); merror("%s: ERROR: SSL error (%d). Exiting.", ARGV0, ret); exit(1); } printf("INFO: Connected to %s:%d\n", manager, port); printf("INFO: Using agent name as: %s\n", agentname); snprintf(buf, 2048, "OSSEC A:'%s'\n", agentname); ret = SSL_write(ssl, buf, strlen(buf)); if(ret < 0) { printf("SSL write error (unable to send message.)\n"); ERR_print_errors_fp(stderr); exit(1); } printf("INFO: Send request to manager. Waiting for reply.\n"); while(1) { ret = SSL_read(ssl,buf,sizeof(buf) -1); switch(SSL_get_error(ssl,ret)) { case SSL_ERROR_NONE: buf[ret] = '\0'; if(strncmp(buf, "ERROR", 5) == 0) { char *tmpstr; tmpstr = strchr(buf, '\n'); if(tmpstr) *tmpstr = '\0'; printf("%s (from manager)\n", buf); } else if(strncmp(buf, "OSSEC K:'",9) == 0) { char *key; char *tmpstr; char **entry; printf("INFO: Received response with agent key\n"); key = buf; key += 9; tmpstr = strchr(key, '\''); if(!tmpstr) { printf("ERROR: Invalid key received. Closing connection.\n"); exit(1); } *tmpstr = '\0'; entry = OS_StrBreak(' ', key, 4); if(!OS_IsValidID(entry[0]) || !OS_IsValidName(entry[1]) || !OS_IsValidName(entry[2]) || !OS_IsValidName(entry[3])) { printf("ERROR: Invalid key received (2). Closing connection.\n"); exit(1); } { FILE *fp; fp = fopen(KEYSFILE_PATH,"w"); if(!fp) { printf("ERROR: Unable to open key file: %s", KEYSFILE_PATH); exit(1); } fprintf(fp, "%s\n", key); fclose(fp); } printf("INFO: Valid key created. Finished.\n"); } break; case SSL_ERROR_ZERO_RETURN: case SSL_ERROR_SYSCALL: printf("INFO: Connection closed.\n"); exit(0); break; default: printf("ERROR: SSL read (unable to receive message)\n"); exit(1); break; } } /* Shutdown the socket */ SSL_CTX_free(ctx); close(sock); exit(0); }
int main(int argc, char **argv) { int c, test_config = 0, run_foreground = 0; int uid=0,gid=0; char *dir = DEFAULTDIR; char *user = USER; char *group = GROUPGLOBAL; char *cfg = DEFAULTCPATH; /* Initializing global variables */ mond.a_queue = 0; /* Setting the name */ OS_SetName(ARGV0); while((c = getopt(argc, argv, "Vdhtfu:g:D:c:")) != -1){ switch(c){ case 'V': print_version(); break; case 'h': help(ARGV0); break; case 'd': nowDebug(); break; case 'f': run_foreground = 1; break; case 'u': if(!optarg) ErrorExit("%s: -u needs an argument",ARGV0); user=optarg; break; case 'g': if(!optarg) ErrorExit("%s: -g needs an argument",ARGV0); group=optarg; break; case 'D': if(!optarg) ErrorExit("%s: -D needs an argument",ARGV0); dir=optarg; case 'c': if(!optarg) ErrorExit("%s: -c needs an argument",ARGV0); cfg = optarg; break; case 't': test_config = 1; break; default: help(ARGV0); break; } } /* Starting daemon */ debug1(STARTED_MSG,ARGV0); /*Check if the user/group given are valid */ uid = Privsep_GetUser(user); gid = Privsep_GetGroup(group); if((uid < 0)||(gid < 0)) ErrorExit(USER_ERROR,ARGV0,user,group); /* Getting config options */ mond.day_wait = getDefine_Int("monitord", "day_wait", 5,240); mond.compress = getDefine_Int("monitord", "compress", 0,1); mond.sign = getDefine_Int("monitord","sign",0,1); mond.monitor_agents = getDefine_Int("monitord","monitor_agents",0,1); mond.agents = NULL; mond.smtpserver = NULL; mond.emailfrom = NULL; c = 0; c|= CREPORTS; if(ReadConfig(c, cfg, &mond, NULL) < 0) { ErrorExit(CONFIG_ERROR, ARGV0, cfg); } /* If we have any reports configured, read smtp/emailfrom */ if(mond.reports) { OS_XML xml; char *tmpsmtp; char *(xml_smtp[])={"ossec_config", "global", "smtp_server", NULL}; char *(xml_from[])={"ossec_config", "global", "email_from", NULL}; if(OS_ReadXML(cfg, &xml) < 0) { ErrorExit(CONFIG_ERROR, ARGV0, cfg); } tmpsmtp = OS_GetOneContentforElement(&xml,xml_smtp); mond.emailfrom = OS_GetOneContentforElement(&xml,xml_from); if(tmpsmtp && mond.emailfrom) { mond.smtpserver = OS_GetHost(tmpsmtp, 5); if(!mond.smtpserver) { merror(INVALID_SMTP, ARGV0, tmpsmtp); if(mond.emailfrom) free(mond.emailfrom); mond.emailfrom = NULL; merror("%s: Invalid SMTP server. Disabling email reports.", ARGV0); } } else { if(tmpsmtp) free(tmpsmtp); if(mond.emailfrom) free(mond.emailfrom); mond.emailfrom = NULL; merror("%s: SMTP server or 'email from' missing. Disabling email reports.", ARGV0); } OS_ClearXML(&xml); } /* Exit here if test config is set */ if(test_config) exit(0); if (!run_foreground) { /* Going on daemon mode */ nowDaemon(); goDaemon(); } /* Privilege separation */ if(Privsep_SetGroup(gid) < 0) ErrorExit(SETGID_ERROR,ARGV0,group); /* chrooting */ if(Privsep_Chroot(dir) < 0) ErrorExit(CHROOT_ERROR,ARGV0,dir); nowChroot(); /* Changing user */ if(Privsep_SetUser(uid) < 0) ErrorExit(SETUID_ERROR,ARGV0,user); debug1(PRIVSEP_MSG,ARGV0,dir,user); /* Signal manipulation */ StartSIG(ARGV0); /* Creating PID files */ if(CreatePID(ARGV0, getpid()) < 0) ErrorExit(PID_ERROR,ARGV0); /* Start up message */ verbose(STARTUP_MSG, ARGV0, (int)getpid()); /* the real daemon now */ Monitord(); exit(0); }
int Read_Client(XML_NODE node, void *d1, void *d2) { int i = 0; /* XML definitions */ char *xml_client_ip = "server-ip"; char *xml_client_hostname = "server-hostname"; char *xml_local_ip = "local_ip"; char *xml_client_port = "port"; char *xml_ar_disabled = "disable-active-response"; char *xml_notify_time = "notify_time"; char *xml_max_time_reconnect_try = "time-reconnect"; /* cmoraes */ char *xml_profile_name = "config-profile"; agent *logr; logr = (agent *)d1; logr->notify_time = 0; logr->max_time_reconnect_try = 0; while(node[i]) { if(!node[i]->element) { merror(XML_ELEMNULL, ARGV0); return(OS_INVALID); } else if(!node[i]->content) { merror(XML_VALUENULL, ARGV0, node[i]->element); return(OS_INVALID); } /* Getting local ip. */ else if(strcmp(node[i]->element, xml_local_ip) == 0) { os_strdup(node[i]->content, logr->lip); if(OS_IsValidIP(logr->lip, NULL) != 1) { merror(INVALID_IP, ARGV0, logr->lip); return(OS_INVALID); } } /* Getting server ip */ else if(strcmp(node[i]->element,xml_client_ip) == 0) { int ip_id = 0; /* Getting last ip */ if(logr->rip) { while(logr->rip[ip_id]) { ip_id++; } } os_realloc(logr->rip, (ip_id + 2) * sizeof(char*), logr->rip); logr->rip[ip_id] = NULL; logr->rip[ip_id +1] = NULL; os_strdup(node[i]->content, logr->rip[ip_id]); if(OS_IsValidIP(logr->rip[ip_id], NULL) != 1) { merror(INVALID_IP, ARGV0, logr->rip[ip_id]); return(OS_INVALID); } logr->rip_id++; } else if(strcmp(node[i]->element,xml_client_hostname) == 0) { int ip_id = 0; char *s_ip; char f_ip[128]; /* Getting last ip. */ if(logr->rip) { while(logr->rip[ip_id]) { ip_id++; } } os_realloc(logr->rip, (ip_id + 2) * sizeof(char*), logr->rip); s_ip = OS_GetHost(node[i]->content, 5); if(!s_ip) { merror("%s: WARN: Unable to get hostname for '%s'.", ARGV0, node[i]->content); merror(AG_INV_HOST, ARGV0, node[i]->content); os_strdup("invalid_ip", s_ip); } f_ip[127] = '\0'; snprintf(f_ip, 127, "%s/%s", node[i]->content, s_ip); os_strdup(f_ip, logr->rip[ip_id]); logr->rip[ip_id +1] = NULL; free(s_ip); logr->rip_id++; } else if(strcmp(node[i]->element,xml_client_port) == 0) { if(!OS_StrIsNum(node[i]->content)) { merror(XML_VALUEERR,ARGV0,node[i]->element,node[i]->content); return(OS_INVALID); } logr->port = atoi(node[i]->content); if(logr->port <= 0 || logr->port > 65535) { merror(PORT_ERROR, ARGV0, logr->port); return(OS_INVALID); } } else if(strcmp(node[i]->element,xml_notify_time) == 0) { if(!OS_StrIsNum(node[i]->content)) { merror(XML_VALUEERR,ARGV0,node[i]->element,node[i]->content); return(OS_INVALID); } logr->notify_time = atoi(node[i]->content); } else if(strcmp(node[i]->element,xml_max_time_reconnect_try) == 0) { if(!OS_StrIsNum(node[i]->content)) { merror(XML_VALUEERR,ARGV0,node[i]->element,node[i]->content); return(OS_INVALID); } logr->max_time_reconnect_try = atoi(node[i]->content); } else if(strcmp(node[i]->element,xml_ar_disabled) == 0) { if(strcmp(node[i]->content, "yes") == 0) logr->execdq = -1; else if(strcmp(node[i]->content, "no") == 0) logr->execdq = 0; else { merror(XML_VALUEERR,ARGV0,node[i]->element,node[i]->content); return(OS_INVALID); } } /* cmoraes */ else if(strcmp(node[i]->element,xml_profile_name) == 0) { /* profile name can be anything hence no validation */ os_strdup(node[i]->content, logr->profile); } else { merror(XML_INVELEM, ARGV0, node[i]->element); return(OS_INVALID); } i++; } if(!logr->rip) { return(OS_INVALID); } return(0); }