END_TEST START_TEST(test_tcpv4_inet) { int server_root_socket, server_client_socket, client_socket; char buffer[BUFFERSIZE]; char *msg; char ipbuffer[BUFFERSIZE]; ck_assert_int_ge((server_root_socket = OS_Bindporttcp(PORT, NULL, 0)), 0); ck_assert_int_ge((client_socket = OS_ConnectTCP(PORT, IPV4, 0, NULL)) , 0); ck_assert_int_ge((server_client_socket = OS_AcceptTCP(server_root_socket, ipbuffer, BUFFERSIZE)), 0); ck_assert_str_eq(ipbuffer, IPV4); ck_assert_int_eq(OS_SendTCP(client_socket, SENDSTRING), 0); ck_assert_int_eq(OS_RecvTCPBuffer(server_client_socket, buffer, BUFFERSIZE), 0); ck_assert_str_eq(buffer, SENDSTRING); ck_assert_int_eq(OS_SendTCPbySize(server_client_socket, 5, SENDSTRING), 0); ck_assert_ptr_ne((msg = OS_RecvTCP(client_socket, BUFFERSIZE)), NULL); ck_assert_str_eq(msg, "Hello"); /* only 5 bytes send */ free(msg); OS_CloseSocket(client_socket); OS_CloseSocket(server_client_socket); OS_CloseSocket(server_root_socket); }
/* OS_Sendsms. */ int OS_Sendsms(MailConfig *mail, struct tm *p, MailMsg *sms_msg) { int socket, i = 0, final_to_sz; char *msg; char snd_msg[128]; char final_to[512]; /* Connecting to the smtp server */ socket = OS_ConnectTCP(SMTP_DEFAULT_PORT, mail->smtpserver); if(socket < 0) { return(socket); } /* Receiving the banner */ msg = OS_RecvTCP(socket, OS_SIZE_1024); if((msg == NULL)||(!OS_Match(VALIDBANNER, msg))) { merror(BANNER_ERROR); if(msg) free(msg); close(socket); return(OS_INVALID); } MAIL_DEBUG("DEBUG: Received banner: '%s' %s", msg, ""); free(msg); /* Sending HELO message */ OS_SendTCP(socket,HELOMSG); msg = OS_RecvTCP(socket, OS_SIZE_1024); if((msg == NULL)||(!OS_Match(VALIDMAIL, msg))) { if(msg) { /* Ugly fix warning :) */ /* In some cases (with virus scans in the middle) * we may get two banners. Check for that in here. */ if(OS_Match(VALIDBANNER, msg)) { free(msg); /* Try again */ msg = OS_RecvTCP(socket, OS_SIZE_1024); if((msg == NULL)||(!OS_Match(VALIDMAIL, msg))) { merror("%s:%s",HELO_ERROR,msg!= NULL?msg:"null"); if(msg) free(msg); close(socket); return(OS_INVALID); } } else { merror("%s:%s",HELO_ERROR,msg); free(msg); close(socket); return(OS_INVALID); } } else { merror("%s:%s",HELO_ERROR,"null"); close(socket); return(OS_INVALID); } } MAIL_DEBUG("DEBUG: Sent '%s', received: '%s'", HELOMSG, msg); free(msg); /* Building "Mail from" msg */ memset(snd_msg,'\0',128); snprintf(snd_msg,127, MAILFROM, mail->from); OS_SendTCP(socket, snd_msg); msg = OS_RecvTCP(socket, OS_SIZE_1024); if((msg == NULL)||(!OS_Match(VALIDMAIL, msg))) { merror(FROM_ERROR); if(msg) free(msg); close(socket); return(OS_INVALID); } MAIL_DEBUG("DEBUG: Sent '%s', received: '%s'", snd_msg, msg); free(msg); /* Additional RCPT to */ final_to[0] = '\0'; final_to_sz = sizeof(final_to) -2; if(mail->gran_to) { i = 0; while(mail->gran_to[i] != NULL) { if(mail->gran_set[i] != SMS_FORMAT) { i++; continue; } memset(snd_msg,'\0',128); snprintf(snd_msg,127, RCPTTO, mail->gran_to[i]); OS_SendTCP(socket, snd_msg); msg = OS_RecvTCP(socket, OS_SIZE_1024); if((msg == NULL)||(!OS_Match(VALIDMAIL, msg))) { merror(TO_ERROR, mail->gran_to[i]); if(msg) free(msg); close(socket); return(OS_INVALID); } MAIL_DEBUG("DEBUG: Sent '%s', received: '%s'", snd_msg, msg); free(msg); /* Creating header for to */ memset(snd_msg,'\0',128); snprintf(snd_msg,127, TO, mail->gran_to[i]); strncat(final_to, snd_msg, final_to_sz); final_to_sz -= strlen(snd_msg) +2; i++; continue; } } /* Sending the "DATA" msg */ OS_SendTCP(socket,DATAMSG); msg = OS_RecvTCP(socket, OS_SIZE_1024); if((msg == NULL)||(!OS_Match(VALIDDATA, msg))) { merror(DATA_ERROR); if(msg) free(msg); close(socket); return(OS_INVALID); } MAIL_DEBUG("DEBUG: Sent '%s', received: '%s'", DATAMSG, msg); free(msg); /* Building "From" and "To" in the e-mail header */ OS_SendTCP(socket, final_to); memset(snd_msg,'\0',128); snprintf(snd_msg,127, FROM, mail->from); OS_SendTCP(socket, snd_msg); /* Sending date */ memset(snd_msg,'\0',128); /* Solaris doesn't have the "%z", so we set the timezone to 0. */ #ifdef SOLARIS strftime(snd_msg, 127, "Date: %a, %d %b %Y %T -0000\r\n",p); #else strftime(snd_msg, 127, "Date: %a, %d %b %Y %T %z\r\n",p); #endif OS_SendTCP(socket,snd_msg); /* Sending subject */ memset(snd_msg,'\0',128); snprintf(snd_msg, 127, SUBJECT, sms_msg->subject); OS_SendTCP(socket,snd_msg); /* Sending body */ OS_SendTCP(socket, sms_msg->body); /* Sending end of data \r\n.\r\n */ OS_SendTCP(socket,ENDDATA); msg = OS_RecvTCP(socket, OS_SIZE_1024); if(mail->strict_checking && ((msg == NULL)||(!OS_Match(VALIDMAIL, msg)))) { merror(END_DATA_ERROR); if(msg) free(msg); close(socket); return(OS_INVALID); } /* Checking msg in here, since it may be null */ if(msg) free(msg); /* quitting and closing socket */ OS_SendTCP(socket,QUITMSG); msg = OS_RecvTCP(socket, OS_SIZE_1024); if(msg) free(msg); memset(snd_msg,'\0',128); /* Returning 0 (success) */ close(socket); return(0); }
/* OS_Sendmail v0.1: 2005/03/18 */ int OS_Sendmail(MailConfig *mail, struct tm *p) { int socket,i=0; char *msg; char snd_msg[128]; char additional_to[512]; MailNode *mailmsg; additional_to[0] = '\0'; /* If there is no sms message, we attempt to get from the * email list. */ mailmsg = OS_PopLastMail(); if(mailmsg == NULL) { merror("%s: No email to be sent. Inconsistent state.",ARGV0); } /* Connecting to the smtp server */ socket = OS_ConnectTCP(SMTP_DEFAULT_PORT, mail->smtpserver); if(socket < 0) { return(socket); } /* Receiving the banner */ msg = OS_RecvTCP(socket, OS_SIZE_1024); if((msg == NULL)||(!OS_Match(VALIDBANNER, msg))) { merror(BANNER_ERROR); if(msg) free(msg); close(socket); return(OS_INVALID); } MAIL_DEBUG("DEBUG: Received banner: '%s' %s", msg, ""); free(msg); /* Sending HELO message */ OS_SendTCP(socket,HELOMSG); msg = OS_RecvTCP(socket, OS_SIZE_1024); if((msg == NULL)||(!OS_Match(VALIDMAIL, msg))) { if(msg) { /* Ugly fix warning :) */ /* In some cases (with virus scans in the middle) * we may get two banners. Check for that in here. */ if(OS_Match(VALIDBANNER, msg)) { free(msg); /* Try again */ msg = OS_RecvTCP(socket, OS_SIZE_1024); if((msg == NULL)||(!OS_Match(VALIDMAIL, msg))) { merror("%s:%s",HELO_ERROR,msg!= NULL?msg:"null"); if(msg) free(msg); close(socket); return(OS_INVALID); } } else { merror("%s:%s",HELO_ERROR,msg); free(msg); close(socket); return(OS_INVALID); } } else { merror("%s:%s",HELO_ERROR,"null"); close(socket); return(OS_INVALID); } } MAIL_DEBUG("DEBUG: Sent '%s', received: '%s'", HELOMSG, msg); free(msg); /* Building "Mail from" msg */ memset(snd_msg,'\0',128); snprintf(snd_msg,127, MAILFROM, mail->from); OS_SendTCP(socket, snd_msg); msg = OS_RecvTCP(socket, OS_SIZE_1024); if((msg == NULL)||(!OS_Match(VALIDMAIL, msg))) { merror(FROM_ERROR); if(msg) free(msg); close(socket); return(OS_INVALID); } MAIL_DEBUG("DEBUG: Sent '%s', received: '%s'", snd_msg, msg); free(msg); /* Building "RCPT TO" msg */ while(1) { if(mail->to[i] == NULL) { if(i == 0) { merror(INTERNAL_ERROR); close(socket); return(OS_INVALID); } break; } memset(snd_msg,'\0',128); snprintf(snd_msg,127,RCPTTO, mail->to[i++]); OS_SendTCP(socket,snd_msg); msg = OS_RecvTCP(socket, OS_SIZE_1024); if((msg == NULL)||(!OS_Match(VALIDMAIL, msg))) { merror(TO_ERROR, mail->to[i -1]); if(msg) free(msg); close(socket); return(OS_INVALID); } MAIL_DEBUG("DEBUG: Sent '%s', received: '%s'", snd_msg, msg); free(msg); } /* Additional RCPT to */ if(mail->gran_to) { i = 0; while(mail->gran_to[i] != NULL) { if(mail->gran_set[i] != FULL_FORMAT) { i++; continue; } memset(snd_msg,'\0',128); snprintf(snd_msg,127,RCPTTO, mail->gran_to[i]); OS_SendTCP(socket,snd_msg); msg = OS_RecvTCP(socket, OS_SIZE_1024); if((msg == NULL)||(!OS_Match(VALIDMAIL, msg))) { merror(TO_ERROR, mail->gran_to[i]); if(msg) free(msg); i++; continue; } MAIL_DEBUG("DEBUG: Sent '%s', received: '%s'", snd_msg, msg); free(msg); i++; continue; } } /* Sending the "DATA" msg */ OS_SendTCP(socket,DATAMSG); msg = OS_RecvTCP(socket, OS_SIZE_1024); if((msg == NULL)||(!OS_Match(VALIDDATA, msg))) { merror(DATA_ERROR); if(msg) free(msg); close(socket); return(OS_INVALID); } MAIL_DEBUG("DEBUG: Sent '%s', received: '%s'", DATAMSG, msg); free(msg); /* Building "From" and "To" in the e-mail header */ memset(snd_msg,'\0',128); snprintf(snd_msg,127, TO, mail->to[0]); OS_SendTCP(socket, snd_msg); memset(snd_msg,'\0',128); snprintf(snd_msg,127, FROM, mail->from); OS_SendTCP(socket, snd_msg); /* Adding CCs */ if(mail->to[1]) { i = 1; while(1) { if(mail->to[i] == NULL) { break; } memset(snd_msg,'\0',128); snprintf(snd_msg,127, TO, mail->to[i]); OS_SendTCP(socket,snd_msg); i++; } } /* More CCs - from granular options */ if(mail->gran_to) { i = 0; while(mail->gran_to[i] != NULL) { if(mail->gran_set[i] != FULL_FORMAT) { i++; continue; } memset(snd_msg,'\0',128); snprintf(snd_msg,127, TO, mail->gran_to[i]); OS_SendTCP(socket, snd_msg); i++; continue; } } /* Sending date */ memset(snd_msg,'\0',128); /* Solaris doesn't have the "%z", so we set the timezone to 0. */ #ifdef SOLARIS strftime(snd_msg, 127, "Date: %a, %d %b %Y %T -0000\r\n",p); #else strftime(snd_msg, 127, "Date: %a, %d %b %Y %T %z\r\n",p); #endif OS_SendTCP(socket,snd_msg); /* Sending subject */ memset(snd_msg,'\0',128); /* Checking if global subject is available */ if((_g_subject_level != 0) && (_g_subject[0] != '\0')) { snprintf(snd_msg, 127, SUBJECT, _g_subject); /* Clearing global values */ _g_subject[0] = '\0'; _g_subject_level = 0; } else { snprintf(snd_msg, 127, SUBJECT, mailmsg->mail->subject); } OS_SendTCP(socket,snd_msg); /* Sending body */ /* Sending multiple emails together if we have to */ do { OS_SendTCP(socket, mailmsg->mail->body); mailmsg = OS_PopLastMail(); }while(mailmsg); /* Sending end of data \r\n.\r\n */ OS_SendTCP(socket,ENDDATA); msg = OS_RecvTCP(socket, OS_SIZE_1024); if(mail->strict_checking && ((msg == NULL)||(!OS_Match(VALIDMAIL, msg)))) { merror(END_DATA_ERROR); if(msg) free(msg); close(socket); return(OS_INVALID); } /* Checking msg in here, since it may be null */ if(msg) free(msg); /* quitting and closing socket */ OS_SendTCP(socket,QUITMSG); msg = OS_RecvTCP(socket, OS_SIZE_1024); if(msg) free(msg); memset(snd_msg,'\0',128); /* Returning 0 (success) */ close(socket); return(0); }
/* OS_SendCustomEmail */ int OS_SendCustomEmail(char **to, char *subject, char *smtpserver, char *from, FILE *fp, struct tm *p) { int socket,i = 0; char *msg; char snd_msg[128]; char buffer[2049]; buffer[2048] = '\0'; /* Connecting to the smtp server */ socket = OS_ConnectTCP(SMTP_DEFAULT_PORT, smtpserver, 0); if(socket < 0) { return(socket); } /* Receiving the banner */ msg = OS_RecvTCP(socket, OS_SIZE_1024); if((msg == NULL)||(!OS_Match(VALIDBANNER, msg))) { merror(BANNER_ERROR); if(msg) free(msg); close(socket); return(OS_INVALID); } MAIL_DEBUG("DEBUG: Received banner: '%s' %s", msg, ""); free(msg); /* Sending HELO message */ OS_SendTCP(socket,HELOMSG); msg = OS_RecvTCP(socket, OS_SIZE_1024); if((msg == NULL)||(!OS_Match(VALIDMAIL, msg))) { if(msg) { /* Ugly fix warning :) */ /* In some cases (with virus scans in the middle) * we may get two banners. Check for that in here. */ if(OS_Match(VALIDBANNER, msg)) { free(msg); /* Try again */ msg = OS_RecvTCP(socket, OS_SIZE_1024); if((msg == NULL)||(!OS_Match(VALIDMAIL, msg))) { merror("%s:%s",HELO_ERROR,msg!= NULL?msg:"null"); if(msg) free(msg); close(socket); return(OS_INVALID); } } else { merror("%s:%s",HELO_ERROR,msg); free(msg); close(socket); return(OS_INVALID); } } else { merror("%s:%s",HELO_ERROR,"null"); close(socket); return(OS_INVALID); } } MAIL_DEBUG("DEBUG: Sent '%s', received: '%s'", HELOMSG, msg); free(msg); /* Building "Mail from" msg */ memset(snd_msg,'\0',128); snprintf(snd_msg,127, MAILFROM, from); OS_SendTCP(socket, snd_msg); msg = OS_RecvTCP(socket, OS_SIZE_1024); if((msg == NULL)||(!OS_Match(VALIDMAIL, msg))) { merror(FROM_ERROR); if(msg) free(msg); close(socket); return(OS_INVALID); } MAIL_DEBUG("DEBUG: Sent '%s', received: '%s'", snd_msg, msg); free(msg); /* Building "RCPT TO" msg */ while(to[i]) { memset(snd_msg,'\0',128); snprintf(snd_msg,127,RCPTTO, to[i]); OS_SendTCP(socket,snd_msg); msg = OS_RecvTCP(socket, OS_SIZE_1024); if((msg == NULL)||(!OS_Match(VALIDMAIL, msg))) { merror(TO_ERROR, to[i]); if(msg) free(msg); close(socket); return(OS_INVALID); } MAIL_DEBUG("DEBUG: Sent '%s', received: '%s'", snd_msg, msg); free(msg); i++; } /* Sending the "DATA" msg */ OS_SendTCP(socket,DATAMSG); msg = OS_RecvTCP(socket, OS_SIZE_1024); if((msg == NULL)||(!OS_Match(VALIDDATA, msg))) { merror(DATA_ERROR); if(msg) free(msg); close(socket); return(OS_INVALID); } MAIL_DEBUG("DEBUG: Sent '%s', received: '%s'", DATAMSG, msg); free(msg); /* Building "From" and "To" in the e-mail header */ memset(snd_msg,'\0',128); snprintf(snd_msg,127, TO, to[0]); OS_SendTCP(socket, snd_msg); memset(snd_msg,'\0',128); snprintf(snd_msg,127, FROM, from); OS_SendTCP(socket, snd_msg); /* Adding CCs */ if(to[1]) { i = 1; while(1) { if(to[i] == NULL) { break; } memset(snd_msg,'\0',128); snprintf(snd_msg,127, TO, to[i]); OS_SendTCP(socket,snd_msg); i++; } } /* Sending date */ memset(snd_msg,'\0',128); /* Solaris doesn't have the "%z", so we set the timezone to 0. */ #ifdef SOLARIS strftime(snd_msg, 127, "Date: %a, %d %b %Y %T -0000\r\n",p); #else strftime(snd_msg, 127, "Date: %a, %d %b %Y %T %z\r\n",p); #endif OS_SendTCP(socket,snd_msg); /* Sending subject */ memset(snd_msg, '\0', 128); snprintf(snd_msg, 127, SUBJECT, subject); OS_SendTCP(socket, snd_msg); OS_SendTCP(socket,ENDHEADER); /* Sending body */ fseek(fp, 0, SEEK_SET); while(fgets(buffer, 2048, fp) != NULL) { OS_SendTCP(socket,buffer); } /* Sending end of data \r\n.\r\n */ OS_SendTCP(socket,ENDDATA); msg = OS_RecvTCP(socket, OS_SIZE_1024); /* Checking msg in here, since it may be null */ if(msg) free(msg); /* quitting and closing socket */ OS_SendTCP(socket,QUITMSG); msg = OS_RecvTCP(socket, OS_SIZE_1024); if(msg) free(msg); memset(snd_msg,'\0',128); /* Returning 0 (success) */ close(socket); return(0); }
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); }
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; int sock = 0, portnum, ret = 0; char *host = NULL, *port = "443"; SSL_CTX *ctx; SSL *ssl; SSL_METHOD *sslmeth; BIO *sbio; BIO *bio_err = 0; while ((c = getopt(argc, argv, "h:p:")) != -1) { switch (c) { case 'h': host = optarg; break; case 'p': portnum = atoi(optarg); if (portnum <= 0 || portnum >= 65536) { exit(1); } port = optarg; break; default: exit(1); break; } } if (!bio_err) { SSL_library_init(); SSL_load_error_strings(); OpenSSL_add_all_algorithms(); bio_err = BIO_new_fp(stderr, BIO_NOCLOSE); } sslmeth = SSLv23_method(); ctx = SSL_CTX_new(sslmeth); if (!ctx) { printf("CTX ERROR\n"); exit(1); } if (!host) { printf("ERROR - host not set.\n"); exit(1); } /* Connect via TCP */ sock = OS_ConnectTCP(port, host); if (sock <= 0) { printf("connect error\n"); 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) { printf("SSL connect error\n"); ERR_print_errors_fp(stderr); exit(1); } printf("Connected!\n"); ret = SSL_write(ssl, TEST, sizeof(TEST)); if (ret < 0) { printf("SSL write error\n"); ERR_print_errors_fp(stderr); exit(1); } while (1) { char buf[2048]; ret = SSL_read(ssl, buf, sizeof(buf) - 1); printf("ret: %d\n", ret); switch (SSL_get_error(ssl, ret)) { case SSL_ERROR_NONE: buf[ret] = '\0'; printf("no error: %s\n", buf); break; case SSL_ERROR_ZERO_RETURN: printf("no return\n"); exit(1); break; case SSL_ERROR_SYSCALL: fprintf(stderr, "SSL Error: Premature close\n"); exit(1); break; default: printf("default error\n"); exit(1); break; } } exit(0); }