DH *ssl_dh_GetTmpParam(int nKeyLen)
{
    DH *dh;

    if (nKeyLen == 512)
        dh = get_dh512();
    else if (nKeyLen == 1024)
        dh = get_dh1024();
    else
        dh = get_dh1024();
    return dh;
}
Exemple #2
0
static void init_dhparams( void )
{
    if ( (dh512==NULL)
         && ((dh512=load_dhparam("dh512.pem")) ==NULL) ) {
        dh512 = get_dh512();
    }

    if ( (dh1024==NULL)
         && ((dh1024=load_dhparam("dh1024.pem")) ==NULL) ) {
        dh1024 = get_dh1024();
    }
}
Exemple #3
0
static void init()
{
    if (gSSL_CTX) return;
    SSL_load_error_strings();
    SSL_library_init();
    gSSL_CTX = SSL_CTX_new(TLSv1_method());
#if OPENSSL_VERSION_NUMBER >= 0x00905000L
    SSL_CTX_set_cipher_list(gSSL_CTX, "ADH:@STRENGTH");
#else
    SSL_CTX_set_cipher_list(gSSL_CTX, "ADH");
#endif
    SSL_CTX_set_info_callback(gSSL_CTX, (void (*)())ssl_info_callback);
    DH *dh = get_dh512();
    SSL_CTX_set_tmp_dh(gSSL_CTX, dh);
    DH_free(dh);
}
bool SSLClient::initTLS1(bool bDH, bool forceSSL)
{
    mpCTX = SSL_CTX_new(forceSSL ? SSLv23_method() : TLSv1_method());
    if (mpCTX == NULL)
        return false;
    if (bDH){
#if OPENSSL_VERSION_NUMBER >= 0x00905000L
        SSL_CTX_set_cipher_list(mpCTX, "ADH:@STRENGTH");
#else
        SSL_CTX_set_cipher_list(mpCTX, "ADH");
#endif
        DH *dh = get_dh512();
        SSL_CTX_set_tmp_dh(mpCTX, dh);
        DH_free(dh);
    }
    mpSSL = SSL_new(mpCTX);
    if(!mpSSL)
        return false;
    return true;
}
Exemple #5
0
int MaOpenSslConfig::start()
{
	const SSL_METHOD	*meth;
	char		        *hostName;

	if (keyFile == 0) {
		mprError(MPR_L, MPR_LOG, "OpenSSL: Cant start SSL: missing key file");
		return MPR_ERR_CANT_INITIALIZE;
	}
	if (certFile == 0) {
		mprError(MPR_L, MPR_LOG, "OpenSSL: Cant start SSL: missing certificate file");
		return MPR_ERR_CANT_INITIALIZE;
	}

	//
	//	Depending on the order in the configuration file, we may get called 
	//	by sslModule::start() before OpenSslModule::start has run. So we 
	//	must initialize here.
	//
	openSslModule->start();
	
	hostName = host->getName();
	
	if (protocols == MPR_HTTP_PROTO_SSLV2) {
		meth = SSLv2_server_method();
	} else {
		meth = SSLv23_server_method();
	}
	context = SSL_CTX_new(meth);
	mprAssert(context);
	if (context == 0) {
		mprError(MPR_L, MPR_LOG, "OpenSSL: Unable to create SSL context"); 
		return MPR_ERR_CANT_CREATE;
	}

    SSL_CTX_set_app_data(context, (void*) this);
	SSL_CTX_set_quiet_shutdown(context, 1);
	SSL_CTX_sess_set_cache_size(context, 512);

	//
	//	Configure the certificate for this host
	//
	if (configureCertificates(context, keyFile, certFile) != 0) {
		SSL_CTX_free(context);
		context = 0;
		return MPR_ERR_CANT_INITIALIZE;
	}

	mprLog(4, "SSL: %s: Using ciphers %s\n", hostName, ciphers);
	SSL_CTX_set_cipher_list(context, ciphers);

	//
	//	Configure the client verification certificate locations
	//
	if (verifyClient) {
		if (caFile == 0 && caPath == 0) {
			mprError(MPR_L, MPR_LOG, 
				"OpenSSL: Must define CA certificates if using client verification");
			SSL_CTX_free(context);
			context = 0;
			return MPR_ERR_BAD_STATE;
		}
		if (caFile || caPath) {
			if ((!SSL_CTX_load_verify_locations(context, caFile, caPath)) ||
					(!SSL_CTX_set_default_verify_paths(context))) {
				mprError(MPR_L, MPR_LOG, 
					"OpenSSL: Unable to set certificate locations"); 
				SSL_CTX_free(context);
				context = 0;
				return MPR_ERR_CANT_ACCESS;
			}
			if (caFile) {
				STACK_OF(X509_NAME) *certNames;
				certNames = SSL_load_client_CA_file(caFile);
				if (certNames == 0) {
				} else {
					//
					//	Define the list of CA certificates to send to the client
					//	before they send their client certificate for validation
					//
					SSL_CTX_set_client_CA_list(context, certNames);
				}
			}
		}
		mprLog(4, "SSL: %s: is verifying client connections\n", hostName);
		if (caFile) {
			mprLog(4, "SSL: %s: Using certificates from %s\n", hostName, 
				caFile);
		} else if (caPath) {
			mprLog(4, "SSL: %s: Using certificates from directory %s\n", 
				hostName, caPath);
		}
		SSL_CTX_set_verify(context, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, verifyX509Certificate);
		SSL_CTX_set_verify_depth(context, verifyDepth);

	} else {
		SSL_CTX_set_verify(context, SSL_VERIFY_NONE, verifyX509Certificate);
	}

	//
	//	Define callbacks
	//
	SSL_CTX_set_tmp_rsa_callback(context, rsaCallback);
	SSL_CTX_set_tmp_dh_callback(context, dhCallback);

	//
	//	Enable all buggy client work-arounds 
	//
	SSL_CTX_set_options(context, SSL_OP_ALL);

#ifdef SSL_OP_NO_TICKET
    SSL_CTX_set_options(context, SSL_OP_NO_TICKET);
#endif
#ifdef SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION
    SSL_CTX_set_options(context, SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION);
#endif
    SSL_CTX_set_mode(context, SSL_MODE_ENABLE_PARTIAL_WRITE | SSL_MODE_AUTO_RETRY);

	//
	//	Select the required protocols
	//
    SSL_CTX_set_options(context, SSL_OP_NO_SSLv2);
	if (!(protocols & MPR_HTTP_PROTO_SSLV3)) {
		SSL_CTX_set_options(context, SSL_OP_NO_SSLv3);
		mprLog(4, "SSL: %s: Disabling SSLv3\n", hostName);
	}
	if (!(protocols & MPR_HTTP_PROTO_TLSV1)) {
		SSL_CTX_set_options(context, SSL_OP_NO_TLSv1);
		mprLog(4, "SSL: %s: Disabling TLSv1\n", hostName);
	}

	//
	//	Ensure we generate a new private key for each connection
	//
    SSL_CTX_set_options(context, SSL_OP_SINGLE_DH_USE);

	//
	//	Pre-generate some keys that are slow to compute
	//
	rsaKey512 = RSA_generate_key(512, RSA_F4, 0, 0);
	rsaKey1024 = RSA_generate_key(1024, RSA_F4, 0, 0);

	dhKey512 = get_dh512();
	dhKey1024 = get_dh1024();

	return 0;
}
/*
  TODO:
       Add option --verify to mysqld to be able to change verification mode
*/
struct st_VioSSLAcceptorFd*
new_VioSSLAcceptorFd(const char *key_file,
		     const char *cert_file,
		     const char *ca_file,
		     const char *ca_path,
		     const char *cipher)
{
  int verify = (SSL_VERIFY_PEER			|
		SSL_VERIFY_CLIENT_ONCE);
  struct st_VioSSLAcceptorFd* ptr;
  int result;
  DH *dh;
  DBUG_ENTER("new_VioSSLAcceptorFd");

  ptr= ((struct st_VioSSLAcceptorFd*)
	my_malloc(sizeof(struct st_VioSSLAcceptorFd),MYF(0)));
  ptr->ssl_context=0;
  ptr->ssl_method=0;
  /* FIXME: constants! */
  ptr->session_id_context= ptr;

  if (!ssl_algorithms_added)
  {
    DBUG_PRINT("info", ("todo: OpenSSL_add_all_algorithms()"));
    ssl_algorithms_added = TRUE;
    SSL_library_init();
    OpenSSL_add_all_algorithms();

  }
#ifdef __NETWARE__
  netware_ssl_init();
#endif

  if (!ssl_error_strings_loaded)
  {
    DBUG_PRINT("info", ("todo: SSL_load_error_strings()"));
    ssl_error_strings_loaded = TRUE;
    SSL_load_error_strings();
  }
  ptr->ssl_method=  TLSv1_server_method();
  ptr->ssl_context= SSL_CTX_new(ptr->ssl_method);
  if (ptr->ssl_context == 0)
  {
    DBUG_PRINT("error", ("SSL_CTX_new failed"));
    report_errors();
    goto ctor_failure;
  }
  if (cipher)
  {
    result=SSL_CTX_set_cipher_list(ptr->ssl_context, cipher);
    DBUG_PRINT("info",("SSL_set_cipher_list() returned %d",result));
  }
  /* SSL_CTX_set_quiet_shutdown(ctx,1); */
  SSL_CTX_sess_set_cache_size(ptr->ssl_context,128);

  /* DH? */
  SSL_CTX_set_verify(ptr->ssl_context, verify, vio_verify_callback);
  SSL_CTX_set_session_id_context(ptr->ssl_context,
				 (const uchar*) &(ptr->session_id_context),
				 sizeof(ptr->session_id_context));

  /*
    SSL_CTX_set_client_CA_list(ctx,SSL_load_client_CA_file(CAfile));
  */
  if (vio_set_cert_stuff(ptr->ssl_context, cert_file, key_file) == -1)
  {
    DBUG_PRINT("error", ("vio_set_cert_stuff failed"));
    report_errors();
    goto ctor_failure;
  }
  if (SSL_CTX_load_verify_locations( ptr->ssl_context, ca_file, ca_path) == 0)
  {
    DBUG_PRINT("warning", ("SSL_CTX_load_verify_locations failed"));
    if (SSL_CTX_set_default_verify_paths(ptr->ssl_context)==0)
    {
      DBUG_PRINT("error", ("SSL_CTX_set_default_verify_paths failed"));
      report_errors();
      goto ctor_failure;
    }
  }
  /* DH stuff */
  dh=get_dh512();
  SSL_CTX_set_tmp_dh(ptr->ssl_context,dh);
  DH_free(dh);
  DBUG_RETURN(ptr);

ctor_failure:
  DBUG_PRINT("exit", ("there was an error"));
  my_free((gptr) ptr,MYF(0));
  DBUG_RETURN(0);
}
struct st_VioSSLConnectorFd *
new_VioSSLConnectorFd(const char* key_file,
		      const char* cert_file,
		      const char* ca_file,
		      const char* ca_path,
		      const char* cipher)
{
  int	verify = SSL_VERIFY_NONE;
  struct st_VioSSLConnectorFd* ptr;
  int result;
  DH *dh;
  DBUG_ENTER("new_VioSSLConnectorFd");

  if (!(ptr=((struct st_VioSSLConnectorFd*)
	     my_malloc(sizeof(struct st_VioSSLConnectorFd),MYF(0)))))
    DBUG_RETURN(0);

  ptr->ssl_context= 0;
  ptr->ssl_method=  0;
  /* FIXME: constants! */

  if (!ssl_algorithms_added)
  {
    DBUG_PRINT("info", ("todo: OpenSSL_add_all_algorithms()"));
    ssl_algorithms_added = TRUE;
    SSL_library_init();
    OpenSSL_add_all_algorithms();
  }
#ifdef __NETWARE__
  netware_ssl_init();
#endif

  if (!ssl_error_strings_loaded)
  {
    DBUG_PRINT("info", ("todo:SSL_load_error_strings()"));
    ssl_error_strings_loaded = TRUE;
    SSL_load_error_strings();
  }
  ptr->ssl_method = TLSv1_client_method();
  ptr->ssl_context = SSL_CTX_new(ptr->ssl_method);
  DBUG_PRINT("info", ("ssl_context: %p",ptr->ssl_context));
  if (ptr->ssl_context == 0)
  {
    DBUG_PRINT("error", ("SSL_CTX_new failed"));
    report_errors();
    goto ctor_failure;
  }
  /*
    SSL_CTX_set_options
    SSL_CTX_set_info_callback
   */
  if (cipher)
  {
    result=SSL_CTX_set_cipher_list(ptr->ssl_context, cipher);
    DBUG_PRINT("info",("SSL_set_cipher_list() returned %d",result));
  }
  SSL_CTX_set_verify(ptr->ssl_context, verify, vio_verify_callback);
  if (vio_set_cert_stuff(ptr->ssl_context, cert_file, key_file) == -1)
  {
    DBUG_PRINT("error", ("vio_set_cert_stuff failed"));
    report_errors();
    goto ctor_failure;
  }
  if (SSL_CTX_load_verify_locations( ptr->ssl_context, ca_file,ca_path) == 0)
  {
    DBUG_PRINT("warning", ("SSL_CTX_load_verify_locations failed"));
    if (SSL_CTX_set_default_verify_paths(ptr->ssl_context) == 0)
    {
      DBUG_PRINT("error", ("SSL_CTX_set_default_verify_paths failed"));
      report_errors();
      goto ctor_failure;
    }
  } 

  /* DH stuff */
  dh=get_dh512();
  SSL_CTX_set_tmp_dh(ptr->ssl_context,dh);
  DH_free(dh);

  DBUG_RETURN(ptr);
ctor_failure:
  DBUG_PRINT("exit", ("there was an error"));
  my_free((gptr)ptr,MYF(0));
  DBUG_RETURN(0);
}
Exemple #8
0
int main(int argc, char **argv){
	int result=OK;
	int x;
	char buffer[MAX_INPUT_BUFFER];
	char *env_string=NULL;
#ifdef HAVE_SSL
	DH *dh;
	char seedfile[FILENAME_MAX];
	int i,c;
#endif

	/* set some environment variables */
	asprintf(&env_string,"NRPE_MULTILINESUPPORT=1");
	putenv(env_string);
	asprintf(&env_string,"NRPE_PROGRAMVERSION=%s",PROGRAM_VERSION);
	putenv(env_string);

	/* process command-line args */
	result=process_arguments(argc,argv);

        if(result!=OK || show_help==TRUE || show_license==TRUE || show_version==TRUE){

		printf("\n");
		printf("NRPE - Nagios Remote Plugin Executor\n");
		printf("Copyright (c) 1999-2008 Ethan Galstad ([email protected])\n");
		printf("Version: %s\n",PROGRAM_VERSION);
		printf("Last Modified: %s\n",MODIFICATION_DATE);
		printf("License: GPL v2 with exemptions (-l for more info)\n");
#ifdef HAVE_SSL
		printf("SSL/TLS Available: Anonymous DH Mode, OpenSSL 0.9.6 or higher required\n");
#endif
#ifdef HAVE_LIBWRAP
		printf("TCP Wrappers Available\n");
#endif
		printf("\n");
#ifdef ENABLE_COMMAND_ARGUMENTS
		printf("***************************************************************\n");
		printf("** POSSIBLE SECURITY RISK - COMMAND ARGUMENTS ARE SUPPORTED! **\n");
		printf("**      Read the NRPE SECURITY file for more information     **\n");
		printf("***************************************************************\n");
		printf("\n");
#endif
#ifndef HAVE_LIBWRAP
		printf("***************************************************************\n");
		printf("** POSSIBLE SECURITY RISK - TCP WRAPPERS ARE NOT AVAILABLE!  **\n");
		printf("**      Read the NRPE SECURITY file for more information     **\n");
		printf("***************************************************************\n");
		printf("\n");
#endif
	        }

	if(show_license==TRUE)
		display_license();

	else if(result!=OK || show_help==TRUE){

		printf("Usage: nrpe [-n] -c <config_file> <mode>\n");
		printf("\n");
		printf("Options:\n");
		printf(" -n            = Do not use SSL\n");
		printf(" <config_file> = Name of config file to use\n");
		printf(" <mode>        = One of the following two operating modes:\n");  
		printf("   -i          =    Run as a service under inetd or xinetd\n");
		printf("   -d          =    Run as a standalone daemon\n");
		printf("\n");
		printf("Notes:\n");
		printf("This program is designed to process requests from the check_nrpe\n");
		printf("plugin on the host(s) running Nagios.  It can run as a service\n");
		printf("under inetd or xinetd (read the docs for info on this), or as a\n");
		printf("standalone daemon. Once a request is received from an authorized\n");
		printf("host, NRPE will execute the command/plugin (as defined in the\n");
		printf("config file) and return the plugin output and return code to the\n");
		printf("check_nrpe plugin.\n");
		printf("\n");
		}

        if(result!=OK || show_help==TRUE || show_license==TRUE || show_version==TRUE)
		exit(STATE_UNKNOWN);


	/* open a connection to the syslog facility */
	/* facility name may be overridden later */
	get_log_facility(NRPE_LOG_FACILITY);
        openlog("nrpe",LOG_PID,log_facility); 

	/* make sure the config file uses an absolute path */
	if(config_file[0]!='/'){

		/* save the name of the config file */
		strncpy(buffer,config_file,sizeof(buffer));
		buffer[sizeof(buffer)-1]='\x0';

		/* get absolute path of current working directory */
		strcpy(config_file,"");
		getcwd(config_file,sizeof(config_file));

		/* append a forward slash */
		strncat(config_file,"/",sizeof(config_file)-2);
		config_file[sizeof(config_file)-1]='\x0';

		/* append the config file to the path */
		strncat(config_file,buffer,sizeof(config_file)-strlen(config_file)-1);
		config_file[sizeof(config_file)-1]='\x0';
	        }

	/* read the config file */
	result=read_config_file(config_file);	

	/* exit if there are errors... */
	if(result==ERROR){
		syslog(LOG_ERR,"Config file '%s' contained errors, aborting...",config_file);
		return STATE_CRITICAL;
		}

        /* generate the CRC 32 table */
        generate_crc32_table();

	/* initialize macros */
	for(x=0;x<MAX_COMMAND_ARGUMENTS;x++)
		macro_argv[x]=NULL;

#ifdef HAVE_SSL
	/* initialize SSL */
	if(use_ssl==TRUE){
		SSL_library_init();
		SSLeay_add_ssl_algorithms();
		meth=SSLv23_server_method();
		SSL_load_error_strings();

		/* use week random seed if necessary */
		if(allow_weak_random_seed && (RAND_status()==0)){

			if(RAND_file_name(seedfile,sizeof(seedfile)-1))
				if(RAND_load_file(seedfile,-1))
					RAND_write_file(seedfile);

			if(RAND_status()==0){
				syslog(LOG_ERR,"Warning: SSL/TLS uses a weak random seed which is highly discouraged");
				srand(time(NULL));
				for(i=0;i<500 && RAND_status()==0;i++){
					for(c=0;c<sizeof(seedfile);c+=sizeof(int)){
						*((int *)(seedfile+c))=rand();
					        }
					RAND_seed(seedfile,sizeof(seedfile));
					}
				}
			}

		if((ctx=SSL_CTX_new(meth))==NULL){
			syslog(LOG_ERR,"Error: could not create SSL context.\n");
			exit(STATE_CRITICAL);
		        }

		/* ADDED 01/19/2004 */
		/* use only TLSv1 protocol */
		SSL_CTX_set_options(ctx,SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3);

		/* use anonymous DH ciphers */
		SSL_CTX_set_cipher_list(ctx,"ADH");
		dh=get_dh512();
		SSL_CTX_set_tmp_dh(ctx,dh);
		DH_free(dh);
		if(debug==TRUE)
			syslog(LOG_INFO,"INFO: SSL/TLS initialized. All network traffic will be encrypted.");
	        }
	else{
		if(debug==TRUE)
			syslog(LOG_INFO,"INFO: SSL/TLS NOT initialized. Network encryption DISABLED.");
	        }
#endif

	/* if we're running under inetd... */
	if(use_inetd==TRUE){

		/* make sure we're not root */
		check_privileges();

		/* redirect STDERR to /dev/null */
		close(2);
		open("/dev/null",O_WRONLY);

		/* handle the connection */
		handle_connection(0);
	        }

	/* else daemonize and start listening for requests... */
	else if(fork()==0){
		
		/* we're a daemon - set up a new process group */
		setsid();

		/* close standard file descriptors */
		close(0);
		close(1);
		close(2);

		/* redirect standard descriptors to /dev/null */
		open("/dev/null",O_RDONLY);
		open("/dev/null",O_WRONLY);
		open("/dev/null",O_WRONLY);

		chdir("/");
		/*umask(0);*/

		/* handle signals */
		signal(SIGQUIT,sighandler);
		signal(SIGTERM,sighandler);
		signal(SIGHUP,sighandler);

		/* log info to syslog facility */
		syslog(LOG_NOTICE,"Starting up daemon");

		/* write pid file */
		if(write_pid_file()==ERROR)
			return STATE_CRITICAL;
		
		/* drop privileges */
		drop_privileges(nrpe_user,nrpe_group);

		/* make sure we're not root */
		check_privileges();

		do{

			/* reset flags */
			sigrestart=FALSE;
			sigshutdown=FALSE;

			/* wait for connections */
			wait_for_connections();

			/* free all memory we allocated */
			free_memory();

			if(sigrestart==TRUE){

				/* read the config file */
				result=read_config_file(config_file);	

				/* exit if there are errors... */
				if(result==ERROR){
					syslog(LOG_ERR,"Config file '%s' contained errors, bailing out...",config_file);
					return STATE_CRITICAL;
				        }
			        }
	
		        }while(sigrestart==TRUE && sigshutdown==FALSE);

		/* remove pid file */
		remove_pid_file();

		syslog(LOG_NOTICE,"Daemon shutdown\n");
	        }

#ifdef HAVE_SSL
	if(use_ssl==TRUE)
		SSL_CTX_free(ctx);
#endif

	/* We are now running in daemon mode, or the connection handed over by inetd has
	   been completed, so the parent process exits */
        return STATE_OK;
	}
Exemple #9
0
int main(int argc, char **argv){
	int result=OK;
	int x;
	char buffer[MAX_INPUT_BUFFER];
#ifdef HAVE_SSL
	DH *dh;
#endif

	result=process_arguments(argc,argv);

        if(result!=OK || show_help==TRUE || show_license==TRUE || show_version==TRUE){

		printf("\n");
		printf("NRPE - Nagios Remote Plugin Executor\n");
		printf("Copyright (c) 1999-2003 Ethan Galstad ([email protected])\n");
		printf("Version: %s\n",PROGRAM_VERSION);
		printf("Last Modified: %s\n",MODIFICATION_DATE);
		printf("License: GPL with exemptions (-l for more info)\n");
#ifdef HAVE_SSL
		printf("SSL/TLS Available: Anonymous DH Mode, OpenSSL 0.9.6 or higher required\n");
#endif
		printf("\n");
#ifdef ENABLE_COMMAND_ARGUMENTS
		printf("***************************************************************\n");
		printf("** POSSIBLE SECURITY RISK - COMMAND ARGUMENTS ARE SUPPORTED! **\n");
		printf("**      Read the NRPE SECURITY file for more information     **\n");
		printf("***************************************************************\n");
		printf("\n");
#endif
	        }

	if(show_license==TRUE)
		display_license();

	else if(result!=OK || show_help==TRUE){

		printf("Usage: nrpe -c <config_file> <mode>\n");
		printf("\n");
		printf("Options:\n");
		printf(" <config_file> = Name of config file to use\n");
		printf(" <mode>        = One of the following two operating modes:\n");  
		printf("   -i          =    Run as a service under inetd or xinetd\n");
		printf("   -d          =    Run as a standalone daemon\n");
		printf("\n");
		printf("Notes:\n");
		printf("This program is designed to process requests from the check_nrpe\n");
		printf("plugin on the host(s) running Nagios.  It can run as a service\n");
		printf("under inetd or xinetd (read the docs for info on this), or as a\n");
		printf("standalone daemon. Once a request is received from an authorized\n");
		printf("host, NRPE will execute the command/plugin (as defined in the\n");
		printf("config file) and return the plugin output and return code to the\n");
		printf("check_nrpe plugin.\n");
		printf("\n");
		}

        if(result!=OK || show_help==TRUE || show_license==TRUE || show_version==TRUE)
		exit(STATE_UNKNOWN);


	/* open a connection to the syslog facility */
        openlog("nrpe",LOG_PID,LOG_DAEMON); 

	/* read the config file */
	result=read_config_file(config_file);	

	/* exit if there are errors... */
	if(result==ERROR){
		syslog(LOG_ERR,"Config file '%s' contained errors, bailing out...",config_file);
		return STATE_CRITICAL;
		}

	/* initialize macros */
	for(x=0;x<MAX_COMMAND_ARGUMENTS;x++)
		macro_argv[x]=NULL;

        /* generate the CRC 32 table */
        generate_crc32_table();

#ifdef HAVE_SSL
	/* initialize SSL */
	if(use_ssl==TRUE){
		SSL_library_init();
		SSLeay_add_ssl_algorithms();
		meth=SSLv23_server_method();
		SSL_load_error_strings();
		if((ctx=SSL_CTX_new(meth))==NULL){
			syslog(LOG_ERR,"Error: could not create SSL context.\n");
			exit(STATE_CRITICAL);
		        }
		/*SSL_CTX_set_cipher_list(ctx,"ALL");*/
		SSL_CTX_set_cipher_list(ctx,"ADH");
		dh=get_dh512();
		SSL_CTX_set_tmp_dh(ctx,dh);
		DH_free(dh);
		if(debug==TRUE)
			syslog(LOG_INFO,"INFO: SSL/TLS initialized. All network traffic will be encrypted.");
	        }
	else{
		if(debug==TRUE)
			syslog(LOG_INFO,"INFO: SSL/TLS NOT initialized. Network encryption DISABLED.");
	        }
#endif

	/* wait for connections */
	wait_for_connections();

#ifdef HAVE_SSL
	if(use_ssl==TRUE)
		SSL_CTX_free(ctx);
#endif

	/* We are now running in daemon mode, or the connection handed over by inetd has
	   been completed, so the parent process exits */
        return STATE_OK;
	}
Exemple #10
0
int main(int argc, char *argv[])
	{
	char *CApath=NULL,*CAfile=NULL;
	int badop=0;
	int bio_pair=0;
	int force=0;
	int tls1=0,ssl2=0,ssl3=0,ret=1;
	int client_auth=0;
	int server_auth=0,i;
	int app_verify=0;
	char *server_cert=TEST_SERVER_CERT;
	char *server_key=NULL;
	char *client_cert=TEST_CLIENT_CERT;
	char *client_key=NULL;
	SSL_CTX *s_ctx=NULL;
	SSL_CTX *c_ctx=NULL;
	SSL_METHOD *meth=NULL;
	SSL *c_ssl,*s_ssl;
	int number=1,reuse=0;
	long bytes=1L;
#ifndef OPENSSL_NO_DH
	DH *dh;
	int dhe1024 = 0, dhe1024dsa = 0;
#endif
	int no_dhe = 0;
	int print_time = 0;
	clock_t s_time = 0, c_time = 0;
	int comp = 0;
	COMP_METHOD *cm = NULL;

	verbose = 0;
	debug = 0;
	cipher = 0;

	bio_err=BIO_new_fp(stderr,BIO_NOCLOSE);	

	CRYPTO_set_locking_callback(lock_dbg_cb);

	/* enable memory leak checking unless explicitly disabled */
	if (!((getenv("OPENSSL_DEBUG_MEMORY") != NULL) && (0 == strcmp(getenv("OPENSSL_DEBUG_MEMORY"), "off"))))
		{
		CRYPTO_malloc_debug_init();
		CRYPTO_set_mem_debug_options(V_CRYPTO_MDEBUG_ALL);
		}
	else
		{
		/* OPENSSL_DEBUG_MEMORY=off */
		CRYPTO_set_mem_debug_functions(0, 0, 0, 0, 0);
		}
	CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);

	RAND_seed(rnd_seed, sizeof rnd_seed);

	bio_stdout=BIO_new_fp(stdout,BIO_NOCLOSE);

	argc--;
	argv++;

	while (argc >= 1)
		{
		if	(strcmp(*argv,"-server_auth") == 0)
			server_auth=1;
		else if	(strcmp(*argv,"-client_auth") == 0)
			client_auth=1;
		else if	(strcmp(*argv,"-v") == 0)
			verbose=1;
		else if	(strcmp(*argv,"-d") == 0)
			debug=1;
		else if	(strcmp(*argv,"-reuse") == 0)
			reuse=1;
		else if	(strcmp(*argv,"-dhe1024") == 0)
			{
#ifndef OPENSSL_NO_DH
			dhe1024=1;
#else
			fprintf(stderr,"ignoring -dhe1024, since I'm compiled without DH\n");
#endif
			}
		else if	(strcmp(*argv,"-dhe1024dsa") == 0)
			{
#ifndef OPENSSL_NO_DH
			dhe1024dsa=1;
#else
			fprintf(stderr,"ignoring -dhe1024, since I'm compiled without DH\n");
#endif
			}
		else if	(strcmp(*argv,"-no_dhe") == 0)
			no_dhe=1;
		else if	(strcmp(*argv,"-ssl2") == 0)
			ssl2=1;
		else if	(strcmp(*argv,"-tls1") == 0)
			tls1=1;
		else if	(strcmp(*argv,"-ssl3") == 0)
			ssl3=1;
		else if	(strncmp(*argv,"-num",4) == 0)
			{
			if (--argc < 1) goto bad;
			number= atoi(*(++argv));
			if (number == 0) number=1;
			}
		else if	(strcmp(*argv,"-bytes") == 0)
			{
			if (--argc < 1) goto bad;
			bytes= atol(*(++argv));
			if (bytes == 0L) bytes=1L;
			i=strlen(argv[0]);
			if (argv[0][i-1] == 'k') bytes*=1024L;
			if (argv[0][i-1] == 'm') bytes*=1024L*1024L;
			}
		else if	(strcmp(*argv,"-cert") == 0)
			{
			if (--argc < 1) goto bad;
			server_cert= *(++argv);
			}
		else if	(strcmp(*argv,"-s_cert") == 0)
			{
			if (--argc < 1) goto bad;
			server_cert= *(++argv);
			}
		else if	(strcmp(*argv,"-key") == 0)
			{
			if (--argc < 1) goto bad;
			server_key= *(++argv);
			}
		else if	(strcmp(*argv,"-s_key") == 0)
			{
			if (--argc < 1) goto bad;
			server_key= *(++argv);
			}
		else if	(strcmp(*argv,"-c_cert") == 0)
			{
			if (--argc < 1) goto bad;
			client_cert= *(++argv);
			}
		else if	(strcmp(*argv,"-c_key") == 0)
			{
			if (--argc < 1) goto bad;
			client_key= *(++argv);
			}
		else if	(strcmp(*argv,"-cipher") == 0)
			{
			if (--argc < 1) goto bad;
			cipher= *(++argv);
			}
		else if	(strcmp(*argv,"-CApath") == 0)
			{
			if (--argc < 1) goto bad;
			CApath= *(++argv);
			}
		else if	(strcmp(*argv,"-CAfile") == 0)
			{
			if (--argc < 1) goto bad;
			CAfile= *(++argv);
			}
		else if	(strcmp(*argv,"-bio_pair") == 0)
			{
			bio_pair = 1;
			}
		else if	(strcmp(*argv,"-f") == 0)
			{
			force = 1;
			}
		else if	(strcmp(*argv,"-time") == 0)
			{
			print_time = 1;
			}
		else if	(strcmp(*argv,"-zlib") == 0)
			{
			comp = COMP_ZLIB;
			}
		else if	(strcmp(*argv,"-rle") == 0)
			{
			comp = COMP_RLE;
			}
		else if	(strcmp(*argv,"-app_verify") == 0)
			{
			app_verify = 1;
			}
		else
			{
			fprintf(stderr,"unknown option %s\n",*argv);
			badop=1;
			break;
			}
		argc--;
		argv++;
		}
	if (badop)
		{
bad:
		sv_usage();
		goto end;
		}

	if (!ssl2 && !ssl3 && !tls1 && number > 1 && !reuse && !force)
		{
		fprintf(stderr, "This case cannot work.  Use -f to perform "
			"the test anyway (and\n-d to see what happens), "
			"or add one of -ssl2, -ssl3, -tls1, -reuse\n"
			"to avoid protocol mismatch.\n");
		EXIT(1);
		}

	if (print_time)
		{
		if (!bio_pair)
			{
			fprintf(stderr, "Using BIO pair (-bio_pair)\n");
			bio_pair = 1;
			}
		if (number < 50 && !force)
			fprintf(stderr, "Warning: For accurate timings, use more connections (e.g. -num 1000)\n");
		}

/*	if (cipher == NULL) cipher=getenv("SSL_CIPHER"); */

	SSL_library_init();
	SSL_load_error_strings();

	if (comp == COMP_ZLIB) cm = COMP_zlib();
	if (comp == COMP_RLE) cm = COMP_rle();
	if (cm != NULL)
		{
		if (cm->type != NID_undef)
			SSL_COMP_add_compression_method(comp, cm);
		else
			{
			fprintf(stderr,
				"Warning: %s compression not supported\n",
				(comp == COMP_RLE ? "rle" :
					(comp == COMP_ZLIB ? "zlib" :
						"unknown")));
			ERR_print_errors_fp(stderr);
			}
		}

#if !defined(OPENSSL_NO_SSL2) && !defined(OPENSSL_NO_SSL3)
	if (ssl2)
		meth=SSLv2_method();
	else 
	if (tls1)
		meth=TLSv1_method();
	else
	if (ssl3)
		meth=SSLv3_method();
	else
		meth=SSLv23_method();
#else
#ifdef OPENSSL_NO_SSL2
	meth=SSLv3_method();
#else
	meth=SSLv2_method();
#endif
#endif

	c_ctx=SSL_CTX_new(meth);
	s_ctx=SSL_CTX_new(meth);
	if ((c_ctx == NULL) || (s_ctx == NULL))
		{
		ERR_print_errors(bio_err);
		goto end;
		}

	if (cipher != NULL)
		{
		SSL_CTX_set_cipher_list(c_ctx,cipher);
		SSL_CTX_set_cipher_list(s_ctx,cipher);
		}

#ifndef OPENSSL_NO_DH
	if (!no_dhe)
		{
		if (dhe1024dsa)
			{
			/* use SSL_OP_SINGLE_DH_USE to avoid small subgroup attacks */
			SSL_CTX_set_options(s_ctx, SSL_OP_SINGLE_DH_USE);
			dh=get_dh1024dsa();
			}
		else if (dhe1024)
			dh=get_dh1024();
		else
			dh=get_dh512();
		SSL_CTX_set_tmp_dh(s_ctx,dh);
		DH_free(dh);
		}
#else
	(void)no_dhe;
#endif

#ifndef OPENSSL_NO_RSA
	SSL_CTX_set_tmp_rsa_callback(s_ctx,tmp_rsa_cb);
#endif

	if (!SSL_CTX_use_certificate_file(s_ctx,server_cert,SSL_FILETYPE_PEM))
		{
		ERR_print_errors(bio_err);
		}
	else if (!SSL_CTX_use_PrivateKey_file(s_ctx,
		(server_key?server_key:server_cert), SSL_FILETYPE_PEM))
		{
		ERR_print_errors(bio_err);
		goto end;
		}

	if (client_auth)
		{
		SSL_CTX_use_certificate_file(c_ctx,client_cert,
			SSL_FILETYPE_PEM);
		SSL_CTX_use_PrivateKey_file(c_ctx,
			(client_key?client_key:client_cert),
			SSL_FILETYPE_PEM);
		}

	if (	(!SSL_CTX_load_verify_locations(s_ctx,CAfile,CApath)) ||
		(!SSL_CTX_set_default_verify_paths(s_ctx)) ||
		(!SSL_CTX_load_verify_locations(c_ctx,CAfile,CApath)) ||
		(!SSL_CTX_set_default_verify_paths(c_ctx)))
		{
		/* fprintf(stderr,"SSL_load_verify_locations\n"); */
		ERR_print_errors(bio_err);
		/* goto end; */
		}

	if (client_auth)
		{
		BIO_printf(bio_err,"client authentication\n");
		SSL_CTX_set_verify(s_ctx,
			SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
			verify_callback);
		if (app_verify) 
			{
			SSL_CTX_set_cert_verify_callback(s_ctx, app_verify_callback, app_verify_arg);
			}
		}
	if (server_auth)
		{
		BIO_printf(bio_err,"server authentication\n");
		SSL_CTX_set_verify(c_ctx,SSL_VERIFY_PEER,
			verify_callback);
		if (app_verify) 
			{
			SSL_CTX_set_cert_verify_callback(s_ctx, app_verify_callback, app_verify_arg);
			}
		}
	
	{
		int session_id_context = 0;
		SSL_CTX_set_session_id_context(s_ctx, (void *)&session_id_context, sizeof session_id_context);
	}

	c_ssl=SSL_new(c_ctx);
	s_ssl=SSL_new(s_ctx);

#ifndef OPENSSL_NO_KRB5
	if (c_ssl  &&  c_ssl->kssl_ctx)
                {
                char	localhost[MAXHOSTNAMELEN+2];

		if (gethostname(localhost, sizeof localhost-1) == 0)
                        {
			localhost[sizeof localhost-1]='\0';
			if(strlen(localhost) == sizeof localhost-1)
				{
				BIO_printf(bio_err,"localhost name too long\n");
				goto end;
				}
			kssl_ctx_setstring(c_ssl->kssl_ctx, KSSL_SERVER,
                                localhost);
			}
		}
#endif    /* OPENSSL_NO_KRB5  */

	for (i=0; i<number; i++)
		{
		if (!reuse) SSL_set_session(c_ssl,NULL);
		if (bio_pair)
			ret=doit_biopair(s_ssl,c_ssl,bytes,&s_time,&c_time);
		else
			ret=doit(s_ssl,c_ssl,bytes);
		}

	if (!verbose)
		{
		print_details(c_ssl, "");
		}
	if ((number > 1) || (bytes > 1L))
		BIO_printf(bio_stdout, "%d handshakes of %ld bytes done\n",number,bytes);
	if (print_time)
		{
#ifdef CLOCKS_PER_SEC
		/* "To determine the time in seconds, the value returned
		 * by the clock function should be divided by the value
		 * of the macro CLOCKS_PER_SEC."
		 *                                       -- ISO/IEC 9899 */
		BIO_printf(bio_stdout, "Approximate total server time: %6.2f s\n"
			"Approximate total client time: %6.2f s\n",
			(double)s_time/CLOCKS_PER_SEC,
			(double)c_time/CLOCKS_PER_SEC);
#else
		/* "`CLOCKS_PER_SEC' undeclared (first use this function)"
		 *                            -- cc on NeXTstep/OpenStep */
		BIO_printf(bio_stdout,
			"Approximate total server time: %6.2f units\n"
			"Approximate total client time: %6.2f units\n",
			(double)s_time,
			(double)c_time);
#endif
		}

	SSL_free(s_ssl);
	SSL_free(c_ssl);

end:
	if (s_ctx != NULL) SSL_CTX_free(s_ctx);
	if (c_ctx != NULL) SSL_CTX_free(c_ctx);

	if (bio_stdout != NULL) BIO_free(bio_stdout);

#ifndef OPENSSL_NO_RSA
	free_tmp_rsa();
#endif
#ifndef OPENSSL_NO_ENGINE
	ENGINE_cleanup();
#endif
	CRYPTO_cleanup_all_ex_data();
	ERR_free_strings();
	ERR_remove_state(0);
	EVP_cleanup();
	CRYPTO_mem_leaks(bio_err);
	if (bio_err != NULL) BIO_free(bio_err);
	EXIT(ret);
	}