Пример #1
0
int lws_context_init_client_ssl(struct lws_context_creation_info *info,
			    struct libwebsocket_context *context)
{
	int error;
	int n;
	SSL_METHOD *method;

	if (info->provided_client_ssl_ctx) {
		/* use the provided OpenSSL context if given one */
		context->ssl_client_ctx = info->provided_client_ssl_ctx;
		/* nothing for lib to delete */
		context->user_supplied_ssl_ctx = 1;
		return 0;
	}

	if (info->port != CONTEXT_PORT_NO_LISTEN)
		return 0;

	/* basic openssl init */

	SSL_library_init();

	OpenSSL_add_all_algorithms();
	SSL_load_error_strings();

	method = (SSL_METHOD *)SSLv23_client_method();
	if (!method) {
		error = ERR_get_error();
		lwsl_err("problem creating ssl method %lu: %s\n",
			error, ERR_error_string(error,
				      (char *)context->service_buffer));
		return 1;
	}
	/* create context */
	context->ssl_client_ctx = SSL_CTX_new(method);
	if (!context->ssl_client_ctx) {
		error = ERR_get_error();
		lwsl_err("problem creating ssl context %lu: %s\n",
			error, ERR_error_string(error,
				      (char *)context->service_buffer));
		return 1;
	}

#ifdef SSL_OP_NO_COMPRESSION
	SSL_CTX_set_options(context->ssl_client_ctx,
						 SSL_OP_NO_COMPRESSION);
#endif
	SSL_CTX_set_options(context->ssl_client_ctx,
				       SSL_OP_CIPHER_SERVER_PREFERENCE);
	if (info->ssl_cipher_list)
		SSL_CTX_set_cipher_list(context->ssl_client_ctx,
						info->ssl_cipher_list);

#ifdef LWS_SSL_CLIENT_USE_OS_CA_CERTS
	if (!(info->options & LWS_SERVER_OPTION_DISABLE_OS_CA_CERTS))
		/* loads OS default CA certs */
		SSL_CTX_set_default_verify_paths(context->ssl_client_ctx);
#endif

	/* openssl init for cert verification (for client sockets) */
	if (!info->ssl_ca_filepath) {
		if (!SSL_CTX_load_verify_locations(
			context->ssl_client_ctx, NULL,
					     LWS_OPENSSL_CLIENT_CERTS))
			lwsl_err(
			    "Unable to load SSL Client certs from %s "
			    "(set by --with-client-cert-dir= "
			    "in configure) --  client ssl isn't "
			    "going to work", LWS_OPENSSL_CLIENT_CERTS);
	} else
		if (!SSL_CTX_load_verify_locations(
			context->ssl_client_ctx, info->ssl_ca_filepath,
							  NULL))
			lwsl_err(
				"Unable to load SSL Client certs "
				"file from %s -- client ssl isn't "
				"going to work", info->ssl_ca_filepath);
		else
			lwsl_info("loaded ssl_ca_filepath\n");

	/*
	 * callback allowing user code to load extra verification certs
	 * helping the client to verify server identity
	 */

	/* support for client-side certificate authentication */
	if (info->ssl_cert_filepath) {
		n = SSL_CTX_use_certificate_chain_file(
			context->ssl_client_ctx,
					info->ssl_cert_filepath);
		if (n != 1) {
			lwsl_err("problem getting cert '%s' %lu: %s\n",
				info->ssl_cert_filepath,
				ERR_get_error(),
				ERR_error_string(ERR_get_error(),
				(char *)context->service_buffer));
			return 1;
		}
	} 
	if (info->ssl_private_key_filepath) {
		lws_ssl_bind_passphrase(context->ssl_client_ctx, info);
		/* set the private key from KeyFile */
		if (SSL_CTX_use_PrivateKey_file(context->ssl_client_ctx,
		    info->ssl_private_key_filepath, SSL_FILETYPE_PEM) != 1) {
			lwsl_err("use_PrivateKey_file '%s' %lu: %s\n",
				info->ssl_private_key_filepath,
				ERR_get_error(),
				ERR_error_string(ERR_get_error(),
				      (char *)context->service_buffer));
			return 1;
		}

		/* verify private key */
		if (!SSL_CTX_check_private_key(
					context->ssl_client_ctx)) {
			lwsl_err("Private SSL key doesn't match cert\n");
			return 1;
		}
	} 

	context->protocols[0].callback(context, NULL,
		LWS_CALLBACK_OPENSSL_LOAD_EXTRA_CLIENT_VERIFY_CERTS,
		context->ssl_client_ctx, NULL, 0);
	
	return 0;
}
Пример #2
0
LWS_VISIBLE int
lws_context_init_server_ssl(struct lws_context_creation_info *info,
		     struct libwebsocket_context *context)
{
	SSL_METHOD *method;
	int error;
	int n;

	if (info->port != CONTEXT_PORT_NO_LISTEN) {

		context->use_ssl = info->ssl_cert_filepath != NULL;

#ifdef USE_WOLFSSL
#ifdef USE_OLD_CYASSL
		lwsl_notice(" Compiled with CyaSSL support\n");
#else
		lwsl_notice(" Compiled with wolfSSL support\n");
#endif
#else
		lwsl_notice(" Compiled with OpenSSL support\n");
#endif
		
		if (info->ssl_cipher_list)
			lwsl_notice(" SSL ciphers: '%s'\n", info->ssl_cipher_list);

		if (context->use_ssl)
			lwsl_notice(" Using SSL mode\n");
		else
			lwsl_notice(" Using non-SSL mode\n");
	}

	/* basic openssl init */

	SSL_library_init();

	OpenSSL_add_all_algorithms();
	SSL_load_error_strings();

	openssl_websocket_private_data_index =
		SSL_get_ex_new_index(0, "libwebsockets", NULL, NULL, NULL);

	/*
	 * Firefox insists on SSLv23 not SSLv3
	 * Konq disables SSLv2 by default now, SSLv23 works
	 *
	 * SSLv23_server_method() is the openssl method for "allow all TLS
	 * versions", compared to e.g. TLSv1_2_server_method() which only allows
	 * tlsv1.2. Unwanted versions must be disabled using SSL_CTX_set_options()
	 */

	method = (SSL_METHOD *)SSLv23_server_method();
	if (!method) {
		error = ERR_get_error();
		lwsl_err("problem creating ssl method %lu: %s\n", 
			error, ERR_error_string(error,
					      (char *)context->service_buffer));
		return 1;
	}
	context->ssl_ctx = SSL_CTX_new(method);	/* create context */
	if (!context->ssl_ctx) {
		error = ERR_get_error();
		lwsl_err("problem creating ssl context %lu: %s\n",
			error, ERR_error_string(error,
					      (char *)context->service_buffer));
		return 1;
	}

	/* Disable SSLv2 and SSLv3 */
	SSL_CTX_set_options(context->ssl_ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3);
#ifdef SSL_OP_NO_COMPRESSION
	SSL_CTX_set_options(context->ssl_ctx, SSL_OP_NO_COMPRESSION);
#endif
	SSL_CTX_set_options(context->ssl_ctx, SSL_OP_CIPHER_SERVER_PREFERENCE);
	if (info->ssl_cipher_list)
		SSL_CTX_set_cipher_list(context->ssl_ctx,
						info->ssl_cipher_list);

	/* as a server, are we requiring clients to identify themselves? */

	if (info->options &
			LWS_SERVER_OPTION_REQUIRE_VALID_OPENSSL_CLIENT_CERT) {
		
		int verify_options = SSL_VERIFY_PEER;
	
		if (!(info->options & LWS_SERVER_OPTION_PEER_CERT_NOT_REQUIRED))
			verify_options |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
		
		SSL_CTX_set_session_id_context(context->ssl_ctx,
				(unsigned char *)context, sizeof(void *));

		/* absolutely require the client cert */

		SSL_CTX_set_verify(context->ssl_ctx,
		       verify_options, OpenSSL_verify_callback);

		/*
		 * give user code a chance to load certs into the server
		 * allowing it to verify incoming client certs
		 */

		context->protocols[0].callback(context, NULL,
			LWS_CALLBACK_OPENSSL_LOAD_EXTRA_SERVER_VERIFY_CERTS,
						     context->ssl_ctx, NULL, 0);
	}

	if (info->options & LWS_SERVER_OPTION_ALLOW_NON_SSL_ON_SSL_PORT) {
		/* Normally SSL listener rejects non-ssl, optionally allow */
		context->allow_non_ssl_on_ssl_port = 1;
	}

	if (context->use_ssl) {

		/* openssl init for server sockets */

		/* set the local certificate from CertFile */
		n = SSL_CTX_use_certificate_chain_file(context->ssl_ctx,
					info->ssl_cert_filepath);
		if (n != 1) {
			error = ERR_get_error();
			lwsl_err("problem getting cert '%s' %lu: %s\n",
				info->ssl_cert_filepath,
				error,
				ERR_error_string(error,
					      (char *)context->service_buffer));
			return 1;
		}
		lws_ssl_bind_passphrase(context->ssl_ctx, info);

		if (info->ssl_private_key_filepath != NULL) {
			/* set the private key from KeyFile */
			if (SSL_CTX_use_PrivateKey_file(context->ssl_ctx,
				     info->ssl_private_key_filepath,
						       SSL_FILETYPE_PEM) != 1) {
				error = ERR_get_error();
				lwsl_err("ssl problem getting key '%s' %lu: %s\n",
					info->ssl_private_key_filepath,
						error,
						ERR_error_string(error,
						      (char *)context->service_buffer));
				return 1;
			}
		}
		else {
			if (context->protocols[0].callback(context, NULL,
				LWS_CALLBACK_OPENSSL_CONTEXT_REQUIRES_PRIVATE_KEY,
						context->ssl_ctx, NULL, 0)) {
				lwsl_err("ssl private key not set\n");
				return 1;
			}
		}

		/* verify private key */
		if (!SSL_CTX_check_private_key(context->ssl_ctx)) {
			lwsl_err("Private SSL key doesn't match cert\n");
			return 1;
		}

		/*
		 * SSL is happy and has a cert it's content with
		 * If we're supporting HTTP2, initialize that
		 */
		
		lws_context_init_http2_ssl(context);
	}
	
	return 0;
}
Пример #3
0
int main(int argc, char *argv[])
{
	int ret;
/* fn pointers */
	gi = &global_info;

	fns_load_defaults();

	debug_trace_init_mandatory();
/* XXX
  debug_trace_init ();
*/

/* XXX
  bot_alloc_on ();
  bot_alloc_verbose_on ();
*/

	srand(getpid());
	SSL_library_init();
	SSL_load_error_strings();
//  OpenSSL_add_all_algorithms ();

	setlocale(LC_ALL, "");

	global_signal_hooks();

	global_defaults();

	global_getopt(argc, argv);

	global_set_proc_ptrs(&argc, argv, environ);

	global_conf_parse();

	if (global_chroot() < 0) {
		debug_err(NULL, "main: bot_chroot: Failed\n");
	}

	global_on();

/*
  event_dispatch ();
*/
	setjmp(gi->sigprotect_buf);
	sigsetjmp(gi->sigprotect_sigbuf, 1);

	while (1) {

/*trying to fix gmod_grelinkd reload */
/*
global_gcmd();
*/

		gi->bot_current = NULL;
		pmodule_cur_clear();
		ret = event_loop(EVLOOP_ONCE);
		if (ret) {
			global_set_evhook_console();
		}

		timer_shouldwerun();

	}

	return 0;
}
int main(int argc, char *argv[])
{
bmd_conf *konfiguracja=NULL;
struct soap soap;
char *serverURL = NULL;
char *host = NULL;
long int ssl_enabled=0;
long int authenticate=0;
char *keyfile=NULL;
char *keyfile_passwd=NULL;
char *keyfile_ssl=NULL;
char *keyfile_passwd_ssl=NULL;
char *cacert=NULL;
char *capath=NULL;
int status = 0;
struct xsd__base64Binary *base64Cert = NULL;
struct bmd230__manyCascadeLinksResult* result=NULL;
long i=0;
long iter=0;



struct bmd230__deleteCascadeLinksList deleteCascadeLinksList;


	deleteCascadeLinksList.__size=1;
	deleteCascadeLinksList.__ptr=(struct bmd230__deleteCascadeLinksElement*)calloc(deleteCascadeLinksList.__size, sizeof(struct bmd230__deleteCascadeLinksElement));
	

	deleteCascadeLinksList.__ptr[0].ownerIdentityId="1";
	deleteCascadeLinksList.__ptr[0].ownerCertificateId=NULL;
	deleteCascadeLinksList.__ptr[0].correspondingFilesMaxLevel=0;
	deleteCascadeLinksList.__ptr[0].visible=ALL;
	deleteCascadeLinksList.__ptr[0].fileId="57";

//	deleteCascadeLinksList.__ptr[1].ownerIdentityId="1";
//	deleteCascadeLinksList.__ptr[1].ownerCertificateId=NULL;
// 	deleteCascadeLinksList.__ptr[1].correspondingFilesMaxLevel=0;
// 	deleteCascadeLinksList.__ptr[1].visible=ALL;
// 	deleteCascadeLinksList.__ptr[1].fileId="58";


	_GLOBAL_debug_level=4;
	
	/*załadowanie bibliotek ssl-owych*/
	SSL_load_error_strings();
	SSL_library_init();

	/*funkcje konfiguracyjne*/
	load_soap_configuration(&konfiguracja);
	configuration(konfiguracja,&host,&keyfile,&keyfile_passwd,&keyfile_ssl,&keyfile_passwd_ssl,&cacert,&capath,&ssl_enabled);

	/*funkcja ustanowienia połaczenia z serwerem*/
	status=connection(&soap,ssl_enabled,authenticate,keyfile_ssl,keyfile_passwd_ssl,cacert,capath);
	if (status!=SOAP_OK)
	{
		PRINT_DEBUG("SOAPCLIENTERR Connection error\n");
		return 0;
	}


	GenBuf_t *cert_pem=NULL;
	base64Cert = (struct xsd__base64Binary *)malloc(sizeof(struct xsd__base64Binary));
	status = bmd_load_binary_content(keyfile,&cert_pem);
	if (status != BMD_OK)
	{
		PRINT_DEBUG("SOAPCLIENTERR Error while reading certificate file\n");
		return 0;
	}
	base64Cert->__ptr=(unsigned char*)(cert_pem->buf);
	base64Cert->__size=cert_pem->size;

	soap_set_namespaces(&soap, bmd230_namespaces);
	
	status = soap_call_bmd230__bmdDeleteCascadeLinks(&soap, host, NULL, base64Cert, NULL, NULL, NULL, &deleteCascadeLinksList, &result);

	if (status == SOAP_OK)
	{
		if(result == NULL)
			{ printf("result = NULL\n"); }
		else
		{
			for(i=0; i< result->__size; i++)
			{
				if(result->__ptr[i].idsList != NULL)
				{
					if(result->__ptr[i].idsList->__size == 0)
					{
						printf("Dla elementu %li nie usunieto zadnego linka\n", i);
					}
					for(iter=0; iter<result->__ptr[i].idsList->__size; iter++)
					{
						printf("Dla %li elementu usunieto link z id: %i\n", i, result->__ptr[i].idsList->__ptr[iter]);
					}
				}
				else
				{
					printf("Dla %li elementu otrzymano kod bledu: %li\n", i, result->__ptr[i].errorCode);
				}
			}
		}
	}
	else
	{
		/*odpowiedz w razie bledu*/
		soap_print_fault(&soap, stderr);
		soap_end(&soap);
		soap_done(&soap);
		free(serverURL);
		return -1;
	}

	soap_end(&soap);
	soap_done(&soap);
	free(serverURL);

	return 0;
}
Пример #5
0
/*
 * \brief Initialize OpenSSl of Verse server
 */
static int vs_init_ssl(VS_CTX *vs_ctx)
{
	/* Set up the library */
	SSL_library_init();
	ERR_load_BIO_strings();
	SSL_load_error_strings();
	OpenSSL_add_all_algorithms();

	/* Set up SSL context for TLS  */
	if( (vs_ctx->tls_ctx = SSL_CTX_new(TLSv1_server_method())) == NULL ) {
		v_print_log(VRS_PRINT_ERROR, "Setting up SSL_CTX failed.\n");
		ERR_print_errors_fp(v_log_file());
		return -1;
	}

	/* Load certificate chain file from CA */
	if(vs_ctx->ca_cert_file != NULL) {
		if(SSL_CTX_use_certificate_chain_file(vs_ctx->tls_ctx, vs_ctx->ca_cert_file) != 1) {
			v_print_log(VRS_PRINT_ERROR, "TLS: Loading certificate chain file: %s failed.\n",
					vs_ctx->ca_cert_file);
			ERR_print_errors_fp(v_log_file());
			return -1;
		}
	}

	/* Load certificate with public key for TLS */
	if(SSL_CTX_use_certificate_file(vs_ctx->tls_ctx, vs_ctx->public_cert_file, SSL_FILETYPE_PEM) != 1) {
		v_print_log(VRS_PRINT_ERROR, "TLS: Loading certificate file: %s failed.\n",
				vs_ctx->public_cert_file);
		ERR_print_errors_fp(v_log_file());
		return -1;
	}

	/* Load private key for TLS */
	if(SSL_CTX_use_PrivateKey_file(vs_ctx->tls_ctx, vs_ctx->private_cert_file, SSL_FILETYPE_PEM) != 1) {
		v_print_log(VRS_PRINT_ERROR, "TLS: Loading private key file: %s failed.\n",
				vs_ctx->private_cert_file);
		ERR_print_errors_fp(v_log_file());
		return -1;
	}

	/* Check the consistency of a private key with the corresponding
	 * certificate loaded into ssl_ctx */
	if(SSL_CTX_check_private_key(vs_ctx->tls_ctx) != 1) {
		v_print_log(VRS_PRINT_ERROR, "TLS: Private key does not match the certificate public key\n");
		ERR_print_errors_fp(v_log_file());
		return -1;
	}

	/* When CA certificate file was set, then try to load it */
	if(vs_ctx->ca_cert_file != NULL) {
		if(SSL_CTX_load_verify_locations(vs_ctx->tls_ctx, vs_ctx->ca_cert_file, NULL) != 1) {
			v_print_log(VRS_PRINT_ERROR, "TLS: Loading CA certificate file: %s failed.\n",
					vs_ctx->ca_cert_file);
			ERR_print_errors_fp(v_log_file());
			return -1;
		}
	}

#if OPENSSL_VERSION_NUMBER>=0x10000000

	/* Set up SSL context for DTLS  */
	if( (vs_ctx->dtls_ctx = SSL_CTX_new(DTLSv1_server_method())) == NULL ) {
		v_print_log(VRS_PRINT_ERROR, "Setting up SSL_CTX failed.\n");
		ERR_print_errors_fp(v_log_file());
		return -1;
	}

	/* Load certificate chain file from CA */
	if(vs_ctx->ca_cert_file != NULL) {
		if(SSL_CTX_use_certificate_chain_file(vs_ctx->dtls_ctx, vs_ctx->ca_cert_file) != 1) {
			v_print_log(VRS_PRINT_ERROR, "DTLS: Loading certificate chain file: %s failed.\n",
					vs_ctx->ca_cert_file);
			ERR_print_errors_fp(v_log_file());
			return -1;
		}
	}

	/* Load certificate with public key for DTLS */
	if (SSL_CTX_use_certificate_file(vs_ctx->dtls_ctx, vs_ctx->public_cert_file, SSL_FILETYPE_PEM) != 1) {
		v_print_log(VRS_PRINT_ERROR, "DTLS: Loading certificate file: %s failed.\n",
						vs_ctx->public_cert_file);
		ERR_print_errors_fp(v_log_file());
		return -1;
	}

	/* Load private key for DTLS */
	if(SSL_CTX_use_PrivateKey_file(vs_ctx->dtls_ctx, vs_ctx->private_cert_file, SSL_FILETYPE_PEM) != 1) {
		v_print_log(VRS_PRINT_ERROR, "DTLS: Loading private key file: %s failed.\n",
						vs_ctx->private_cert_file);
		ERR_print_errors_fp(v_log_file());
		return -1;
	}

	/* Check the consistency of a private key with the corresponding
	 * certificate loaded into ssl_ctx */
	if(SSL_CTX_check_private_key(vs_ctx->dtls_ctx) != 1) {
		v_print_log(VRS_PRINT_ERROR, "DTLS: Private key does not match the certificate public key\n");
		ERR_print_errors_fp(v_log_file());
		return -1;
	}

	/* When CA certificate file was set, then try to load it */
	if(vs_ctx->ca_cert_file != NULL) {
		if(SSL_CTX_load_verify_locations(vs_ctx->dtls_ctx, vs_ctx->ca_cert_file, NULL) != 1) {
			v_print_log(VRS_PRINT_ERROR, "DTLS: Loading CA certificate file: %s failed.\n",
					vs_ctx->ca_cert_file);
			ERR_print_errors_fp(v_log_file());
			return -1;
		}
	}

	/* Set up callback functions for DTLS cookie */
	SSL_CTX_set_cookie_generate_cb(vs_ctx->dtls_ctx, vs_dtls_generate_cookie);
	SSL_CTX_set_cookie_verify_cb(vs_ctx->dtls_ctx, vs_dtls_verify_cookie);
	/* Accept all cipher including NULL cipher (testing) */
	if( SSL_CTX_set_cipher_list(vs_ctx->dtls_ctx, "ALL:NULL:eNULL:aNULL") == 0) {
		v_print_log(VRS_PRINT_ERROR, "Setting ciphers for DTLS failed.\n");
		ERR_print_errors_fp(v_log_file());
		return 0;
	}
	/* DTLS require this */
	SSL_CTX_set_read_ahead(vs_ctx->dtls_ctx, 1);
#else
	vs_ctx->dtls_ctx = NULL;
#endif

	return 1;
}
Пример #6
0
int MAIN(int argc, char **argv)
	{
	int ret=1,i;
	int verbose=0;
	char **pp;
	const char *p;
	int badops=0;
	SSL_CTX *ctx=NULL;
	SSL *ssl=NULL;
	char *ciphers=NULL;
	SSL_METHOD *meth=NULL;
	STACK_OF(SSL_CIPHER) *sk;
	char buf[512];
	BIO *STDout=NULL;

#if !defined(NO_SSL2) && !defined(NO_SSL3)
	meth=SSLv23_server_method();
#elif !defined(NO_SSL3)
	meth=SSLv3_server_method();
#elif !defined(NO_SSL2)
	meth=SSLv2_server_method();
#endif

	apps_startup();

	if (bio_err == NULL)
		bio_err=BIO_new_fp(stderr,BIO_NOCLOSE);
	STDout=BIO_new_fp(stdout,BIO_NOCLOSE);
#ifdef VMS
	{
	BIO *tmpbio = BIO_new(BIO_f_linebuffer());
	STDout = BIO_push(tmpbio, STDout);
	}
#endif

	argc--;
	argv++;
	while (argc >= 1)
		{
		if (strcmp(*argv,"-v") == 0)
			verbose=1;
#ifndef NO_SSL2
		else if (strcmp(*argv,"-ssl2") == 0)
			meth=SSLv2_client_method();
#endif
#ifndef NO_SSL3
		else if (strcmp(*argv,"-ssl3") == 0)
			meth=SSLv3_client_method();
#endif
#ifndef NO_TLS1
		else if (strcmp(*argv,"-tls1") == 0)
			meth=TLSv1_client_method();
#endif
		else if ((strncmp(*argv,"-h",2) == 0) ||
			 (strcmp(*argv,"-?") == 0))
			{
			badops=1;
			break;
			}
		else
			{
			ciphers= *argv;
			}
		argc--;
		argv++;
		}

	if (badops)
		{
		for (pp=ciphers_usage; (*pp != NULL); pp++)
			BIO_printf(bio_err,*pp);
		goto end;
		}

	OpenSSL_add_ssl_algorithms();

	ctx=SSL_CTX_new(meth);
	if (ctx == NULL) goto err;
	if (ciphers != NULL) {
		if(!SSL_CTX_set_cipher_list(ctx,ciphers)) {
			BIO_printf(bio_err, "Error in cipher list\n");
			goto err;
		}
	}
	ssl=SSL_new(ctx);
	if (ssl == NULL) goto err;


	if (!verbose)
		{
		for (i=0; ; i++)
			{
			p=SSL_get_cipher_list(ssl,i);
			if (p == NULL) break;
			if (i != 0) BIO_printf(STDout,":");
			BIO_printf(STDout,"%s",p);
			}
		BIO_printf(STDout,"\n");
		}
	else
		{
		sk=SSL_get_ciphers(ssl);

		for (i=0; i<sk_SSL_CIPHER_num(sk); i++)
			{
			BIO_puts(STDout,SSL_CIPHER_description(
				sk_SSL_CIPHER_value(sk,i),
				buf,512));
			}
		}

	ret=0;
	if (0)
		{
err:
		SSL_load_error_strings();
		ERR_print_errors(bio_err);
		}
end:
	if (ctx != NULL) SSL_CTX_free(ctx);
	if (ssl != NULL) SSL_free(ssl);
	if (STDout != NULL) BIO_free_all(STDout);
	OPENSSL_EXIT(ret);
	}
Пример #7
0
void LibeventServer::StartServer() {
  if (FLAGS_socket_family == "AF_INET") {
    struct sockaddr_in sin;
    PL_MEMSET(&sin, 0, sizeof(sin));
    sin.sin_family = AF_INET;
    sin.sin_addr.s_addr = INADDR_ANY;
    sin.sin_port = htons(port_);

    int listen_fd;

    listen_fd = socket(AF_INET, SOCK_STREAM, 0);

    if (listen_fd < 0) {
      throw ConnectionException("Failed to create listen socket");
    }

    int conn_backlog = 12;
    int reuse = 1;
    setsockopt(listen_fd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse));

    /* Initialize SSL listener connection */
    SSL_load_error_strings();
    SSL_library_init();

    if ((ssl_context = SSL_CTX_new(TLSv1_server_method())) == nullptr)
    {
      throw ConnectionException("Error creating SSL context.");
    }

    LOG_INFO("private key file path %s", private_key_file_.c_str());
    /*
     * Temporarily commented to pass tests START
    // register private key
    if (SSL_CTX_use_PrivateKey_file(ssl_context, private_key_file_.c_str(),
                                    SSL_FILETYPE_PEM) == 0)
    {
      SSL_CTX_free(ssl_context);
      throw ConnectionException("Error associating private key.\n");
    }
    LOG_INFO("certificate file path %s", certificate_file_.c_str());
    // register public key (certificate)
    if (SSL_CTX_use_certificate_file(ssl_context, certificate_file_.c_str(),
                                     SSL_FILETYPE_PEM) == 0)
    {
      SSL_CTX_free(ssl_context);
      throw ConnectionException("Error associating certificate.\n");
    }
    * Temporarily commented to pass tests END
    */
    if (bind(listen_fd, (struct sockaddr *) &sin, sizeof(sin)) < 0)
    {
      SSL_CTX_free(ssl_context);
      throw ConnectionException("Failed binding socket.");
    }

    if (listen(listen_fd, conn_backlog) < 0)
    {
      SSL_CTX_free(ssl_context);
      throw ConnectionException("Error listening onsocket.");
    }

    master_thread_->Start();

    LibeventServer::CreateNewConn(listen_fd, EV_READ | EV_PERSIST,
                                  master_thread_.get(), CONN_LISTENING);

    LOG_INFO("Listening on port %llu", (unsigned long long) port_);
    event_base_dispatch(base_);
    LibeventServer::GetConn(listen_fd)->CloseSocket();

    // Free events and event base
    event_free(LibeventServer::GetConn(listen_fd)->event);
    event_free(ev_stop_);
    event_free(ev_timeout_);
    event_base_free(base_);

    master_thread_->Stop();
    LOG_INFO("Server Closed");
  }

  // This socket family code is not implemented yet
  else {
    throw ConnectionException("Unsupported socket family");
  }
}
Пример #8
0
void sycSSL_load_error_strings(void) {
   Debug("SSL_load_error_strings()");
   SSL_load_error_strings();
   Debug("SSL_load_error_strings() ->");
}
int main(int argc, char *argv[])
{
bmd_conf *konfiguracja=NULL;
struct soap soap;
int result;
char *serverURL = NULL;
char *host = NULL;
long int ssl_enabled=0;
long int authenticate=0;
char *keyfile=NULL;
char *keyfile_passwd=NULL;
char *keyfile_ssl=NULL;
char *keyfile_passwd_ssl=NULL;
char *cacert=NULL;
char *capath=NULL;
int status = 0;
struct xsd__base64Binary *base64Cert = NULL;
int i=0;

	_GLOBAL_debug_level=0;
	if (argc==3)
	{
		for (i=1; i<argc; i++)
		{
			if (strcmp(argv[i],"-d")==0)
			{
				if (argc>i+1) _GLOBAL_debug_level=atoi(argv[i+1]);
			}
		}
	}
	else
	{
		printf("%s\n",argv[0]);
		printf("\nniepoprawne wywołanie\n\nuzyj ponizszych parametrow\n");
		printf("-------------------------------------------------------\n");
		printf("\t-d liczba\tpoziom logowania\n");
		printf("-------------------------------------------------------\n");
		return -1;
	}

	/*załadowanie bibliotek ssl-owych*/
	SSL_load_error_strings();
        SSL_library_init();

	/*funkcje konfiguracyjne*/
	load_soap_configuration(&konfiguracja);
	configuration(konfiguracja,&host,&keyfile,&keyfile_passwd,&keyfile_ssl,&keyfile_passwd_ssl,&cacert,&capath,&ssl_enabled);

	/*funkcja ustanowienia połaczenia z serwerem*/
	status=connection(&soap,ssl_enabled,authenticate,keyfile_ssl,keyfile_passwd_ssl,cacert,capath);
	if (status!=SOAP_OK)
	{
		PRINT_DEBUG("SOAPCLIENTERR Connection error\n");
		return 0;
	}

	/*********************/
	/* informacja o roli */
	/*********************/
	struct bmd230__singleGroupInfo *groupInfo = NULL;

	groupInfo = (struct bmd230__singleGroupInfo *)calloc(1, sizeof(struct bmd230__singleGroupInfo));
	groupInfo->groupName="nowa_nazwa";


	groupInfo->groupParentIds=(struct bmd230__stringList *)calloc(1, sizeof(struct bmd230__stringList));
	groupInfo->groupParentIds->__size=0;
	//groupInfo->groupParentIds->__ptr=(xsd__string *)calloc(groupInfo->groupParentIds->__size, sizeof(xsd__string));
	//groupInfo->groupParentIds->__ptr[0]=(xsd__string)calloc(2, sizeof(char*));
	//groupInfo->groupParentIds->__ptr[0][0]='4';


	groupInfo->groupChildIds=(struct bmd230__stringList *)calloc(1, sizeof(struct bmd230__stringList));
	groupInfo->groupChildIds->__size=0;
	//groupInfo->groupChildIds->__ptr=(xsd__string *)calloc(groupInfo->groupChildIds->__size, sizeof(xsd__string));
	//groupInfo->groupChildIds->__ptr[0]=(xsd__string)calloc(2, sizeof(char*));
	//groupInfo->groupChildIds->__ptr[0][0]='5';


	GenBuf_t *cert_pem=NULL;
	base64Cert = (struct xsd__base64Binary *)malloc(sizeof(struct xsd__base64Binary));
	status = bmd_load_binary_content(keyfile,&cert_pem);

	if (status != BMD_OK)
	{
		PRINT_DEBUG("SOAPCLIENTERR Error while reading certificate file\n");
		return 0;
	}

	base64Cert->__ptr=(unsigned char*)cert_pem->buf;
	base64Cert->__size=cert_pem->size;

	soap_set_namespaces(&soap, bmd230_namespaces);

	/*********************************************************************************/
	/************************ funkcja testowa ****************************************/
	status=soap_call_bmd230__bmdUpdateGroup(&soap, host, NULL, base64Cert, NULL, NULL, NULL, "11", groupInfo, &result);
	/*********************************************************************************/
	/*********************************************************************************/
	if (status == SOAP_OK)
	{
		/*********************************************************************************/
		/************************ funkcja odpowiedź ****************************************/
		printf("Modyfikacja grupy powiodła się. id: %i\n",result);

		/*********************************************************************************/
		/*********************************************************************************/
	}
	else
	{
		/*odpowiedź w razie błędu*/
		soap_print_fault(&soap, stderr);
		soap_end(&soap);
		soap_done(&soap);
		free(serverURL);
		return -1;
	}
	soap_end(&soap);
	soap_done(&soap);
	free(serverURL);

	return 0;
}
Пример #10
0
TLS_APPL_STATE *tls_client_init(const TLS_CLIENT_INIT_PROPS *props)
{
    long    off = 0;
    int     cachable;
    int     scache_timeout;
    SSL_CTX *client_ctx;
    TLS_APPL_STATE *app_ctx;
    int     log_mask;

    /*
     * Convert user loglevel to internal logmask.
     */
    log_mask = tls_log_mask(props->log_param, props->log_level);

    if (log_mask & TLS_LOG_VERBOSE)
	msg_info("initializing the client-side TLS engine");

    /*
     * Load (mostly cipher related) TLS-library internal main.cf parameters.
     */
    tls_param_init();

    /*
     * Detect mismatch between compile-time headers and run-time library.
     */
    tls_check_version();

#if OPENSSL_VERSION_NUMBER < 0x10100000L

    /*
     * Initialize the OpenSSL library by the book! To start with, we must
     * initialize the algorithms. We want cleartext error messages instead of
     * just error codes, so we load the error_strings.
     */
    SSL_load_error_strings();
    OpenSSL_add_ssl_algorithms();
#endif

    /*
     * Create an application data index for SSL objects, so that we can
     * attach TLScontext information; this information is needed inside
     * tls_verify_certificate_callback().
     */
    if (TLScontext_index < 0) {
	if ((TLScontext_index = SSL_get_ex_new_index(0, 0, 0, 0, 0)) < 0) {
	    msg_warn("Cannot allocate SSL application data index: "
		     "disabling TLS support");
	    return (0);
	}
    }

    /*
     * If the administrator specifies an unsupported digest algorithm, fail
     * now, rather than in the middle of a TLS handshake.
     */
    if (!tls_validate_digest(props->mdalg)) {
	msg_warn("disabling TLS support");
	return (0);
    }

    /*
     * Initialize the PRNG (Pseudo Random Number Generator) with some seed
     * from external and internal sources. Don't enable TLS without some real
     * entropy.
     */
    if (tls_ext_seed(var_tls_daemon_rand_bytes) < 0) {
	msg_warn("no entropy for TLS key generation: disabling TLS support");
	return (0);
    }
    tls_int_seed();

    /*
     * The SSL/TLS specifications require the client to send a message in the
     * oldest specification it understands with the highest level it
     * understands in the message. RFC2487 is only specified for TLSv1, but
     * we want to be as compatible as possible, so we will start off with a
     * SSLv2 greeting allowing the best we can offer: TLSv1. We can restrict
     * this with the options setting later, anyhow.
     */
    ERR_clear_error();
    client_ctx = SSL_CTX_new(TLS_client_method());
    if (client_ctx == 0) {
	msg_warn("cannot allocate client SSL_CTX: disabling TLS support");
	tls_print_errors();
	return (0);
    }
#ifdef SSL_SECOP_PEER
    /* Backwards compatible security as a base for opportunistic TLS. */
    SSL_CTX_set_security_level(client_ctx, 0);
#endif

    /*
     * See the verify callback in tls_verify.c
     */
    SSL_CTX_set_verify_depth(client_ctx, props->verifydepth + 1);

    /*
     * Protocol selection is destination dependent, so we delay the protocol
     * selection options to the per-session SSL object.
     */
    off |= tls_bug_bits();
    SSL_CTX_set_options(client_ctx, off);

    /*
     * Set the call-back routine for verbose logging.
     */
    if (log_mask & TLS_LOG_DEBUG)
	SSL_CTX_set_info_callback(client_ctx, tls_info_callback);

    /*
     * Load the CA public key certificates for both the client cert and for
     * the verification of server certificates. As provided by OpenSSL we
     * support two types of CA certificate handling: One possibility is to
     * add all CA certificates to one large CAfile, the other possibility is
     * a directory pointed to by CApath, containing separate files for each
     * CA with softlinks named after the hash values of the certificate. The
     * first alternative has the advantage that the file is opened and read
     * at startup time, so that you don't have the hassle to maintain another
     * copy of the CApath directory for chroot-jail.
     */
    if (tls_set_ca_certificate_info(client_ctx,
				    props->CAfile, props->CApath) < 0) {
	/* tls_set_ca_certificate_info() already logs a warning. */
	SSL_CTX_free(client_ctx);		/* 200411 */
	return (0);
    }

    /*
     * We do not need a client certificate, so the certificates are only
     * loaded (and checked) if supplied. A clever client would handle
     * multiple client certificates and decide based on the list of
     * acceptable CAs, sent by the server, which certificate to submit.
     * OpenSSL does however not do this and also has no call-back hooks to
     * easily implement it.
     * 
     * Load the client public key certificate and private key from file and
     * check whether the cert matches the key. We can use RSA certificates
     * ("cert") DSA certificates ("dcert") or ECDSA certificates ("eccert").
     * All three can be made available at the same time. The CA certificates
     * for all three are handled in the same setup already finished. Which
     * one is used depends on the cipher negotiated (that is: the first
     * cipher listed by the client which does match the server). The client
     * certificate is presented after the server chooses the session cipher,
     * so we will just present the right cert for the chosen cipher (if it
     * uses certificates).
     */
    if (tls_set_my_certificate_key_info(client_ctx,
					props->cert_file,
					props->key_file,
					props->dcert_file,
					props->dkey_file,
					props->eccert_file,
					props->eckey_file) < 0) {
	/* tls_set_my_certificate_key_info() already logs a warning. */
	SSL_CTX_free(client_ctx);		/* 200411 */
	return (0);
    }

    /*
     * 2015-12-05: Ephemeral RSA removed from OpenSSL 1.1.0-dev
     */
#if OPENSSL_VERSION_NUMBER < 0x10100000L

    /*
     * According to the OpenSSL documentation, temporary RSA key is needed
     * export ciphers are in use. We have to provide one, so well, we just do
     * it.
     */
    SSL_CTX_set_tmp_rsa_callback(client_ctx, tls_tmp_rsa_cb);
#endif

    /*
     * With OpenSSL 1.0.2 and later the client EECDH curve list becomes
     * configurable with the preferred curve negotiated via the supported
     * curves extension.
     */
    tls_auto_eecdh_curves(client_ctx);

    /*
     * Finally, the setup for the server certificate checking, done "by the
     * book".
     */
    SSL_CTX_set_verify(client_ctx, SSL_VERIFY_NONE,
		       tls_verify_certificate_callback);

    /*
     * Initialize the session cache.
     * 
     * Since the client does not search an internal cache, we simply disable it.
     * It is only useful for expiring old sessions, but we do that in the
     * tlsmgr(8).
     * 
     * This makes SSL_CTX_remove_session() not useful for flushing broken
     * sessions from the external cache, so we must delete them directly (not
     * via a callback).
     */
    if (tls_mgr_policy(props->cache_type, &cachable,
		       &scache_timeout) != TLS_MGR_STAT_OK)
	scache_timeout = 0;
    if (scache_timeout <= 0)
	cachable = 0;

    /*
     * Allocate an application context, and populate with mandatory protocol
     * and cipher data.
     */
    app_ctx = tls_alloc_app_context(client_ctx, log_mask);

    /*
     * The external session cache is implemented by the tlsmgr(8) process.
     */
    if (cachable) {

	app_ctx->cache_type = mystrdup(props->cache_type);

	/*
	 * OpenSSL does not use callbacks to load sessions from a client
	 * cache, so we must invoke that function directly. Apparently,
	 * OpenSSL does not provide a way to pass session names from here to
	 * call-back routines that do session lookup.
	 * 
	 * OpenSSL can, however, automatically save newly created sessions for
	 * us by callback (we create the session name in the call-back
	 * function).
	 * 
	 * XXX gcc 2.95 can't compile #ifdef .. #endif in the expansion of
	 * SSL_SESS_CACHE_CLIENT | SSL_SESS_CACHE_NO_INTERNAL_STORE |
	 * SSL_SESS_CACHE_NO_AUTO_CLEAR.
	 */
#ifndef SSL_SESS_CACHE_NO_INTERNAL_STORE
#define SSL_SESS_CACHE_NO_INTERNAL_STORE 0
#endif

	SSL_CTX_set_session_cache_mode(client_ctx,
				       SSL_SESS_CACHE_CLIENT |
				       SSL_SESS_CACHE_NO_INTERNAL_STORE |
				       SSL_SESS_CACHE_NO_AUTO_CLEAR);
	SSL_CTX_sess_set_new_cb(client_ctx, new_client_session_cb);

	/*
	 * OpenSSL ignores timed-out sessions. We need to set the internal
	 * cache timeout at least as high as the external cache timeout. This
	 * applies even if no internal cache is used.  We set the session to
	 * twice the cache lifetime.  This way a session always lasts longer
	 * than its lifetime in the cache.
	 */
	SSL_CTX_set_timeout(client_ctx, 2 * scache_timeout);
    }
    return (app_ctx);
}
Пример #11
0
/*
 *	Initialize global SSL context.
 */
void
be_tls_init(void)
{
    struct stat buf;

    STACK_OF(X509_NAME) *root_cert_list = NULL;

    if (!SSL_context)
    {
#if SSLEAY_VERSION_NUMBER >= 0x0907000L
        OPENSSL_config(NULL);
#endif
        SSL_library_init();
        SSL_load_error_strings();

        /*
         * We use SSLv23_method() because it can negotiate use of the highest
         * mutually supported protocol version, while alternatives like
         * TLSv1_2_method() permit only one specific version.  Note that we
         * don't actually allow SSL v2 or v3, only TLS protocols (see below).
         */
        SSL_context = SSL_CTX_new(SSLv23_method());
        if (!SSL_context)
            ereport(FATAL,
                    (errmsg("could not create SSL context: %s",
                            SSLerrmessage(ERR_get_error()))));

        /*
         * Disable OpenSSL's moving-write-buffer sanity check, because it
         * causes unnecessary failures in nonblocking send cases.
         */
        SSL_CTX_set_mode(SSL_context, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);

        /*
         * Load and verify server's certificate and private key
         */
        if (SSL_CTX_use_certificate_chain_file(SSL_context,
                                               ssl_cert_file) != 1)
            ereport(FATAL,
                    (errcode(ERRCODE_CONFIG_FILE_ERROR),
                     errmsg("could not load server certificate file \"%s\": %s",
                            ssl_cert_file, SSLerrmessage(ERR_get_error()))));

        if (stat(ssl_key_file, &buf) != 0)
            ereport(FATAL,
                    (errcode_for_file_access(),
                     errmsg("could not access private key file \"%s\": %m",
                            ssl_key_file)));

        if (!S_ISREG(buf.st_mode))
            ereport(FATAL,
                    (errcode(ERRCODE_CONFIG_FILE_ERROR),
                     errmsg("private key file \"%s\" is not a regular file",
                            ssl_key_file)));

        /*
         * Refuse to load files owned by users other than us or root.
         *
         * XXX surely we can check this on Windows somehow, too.
         */
#if !defined(WIN32) && !defined(__CYGWIN__)
        if (buf.st_uid != geteuid() && buf.st_uid != 0)
            ereport(FATAL,
                    (errcode(ERRCODE_CONFIG_FILE_ERROR),
                     errmsg("private key file \"%s\" must be owned by the database user or root",
                            ssl_key_file)));
#endif

        /*
         * Require no public access to key file. If the file is owned by us,
         * require mode 0600 or less. If owned by root, require 0640 or less
         * to allow read access through our gid, or a supplementary gid that
         * allows to read system-wide certificates.
         *
         * XXX temporarily suppress check when on Windows, because there may
         * not be proper support for Unix-y file permissions.  Need to think
         * of a reasonable check to apply on Windows.  (See also the data
         * directory permission check in postmaster.c)
         */
#if !defined(WIN32) && !defined(__CYGWIN__)
        if ((buf.st_uid == geteuid() && buf.st_mode & (S_IRWXG | S_IRWXO)) ||
                (buf.st_uid == 0 && buf.st_mode & (S_IWGRP | S_IXGRP | S_IRWXO)))
            ereport(FATAL,
                    (errcode(ERRCODE_CONFIG_FILE_ERROR),
                     errmsg("private key file \"%s\" has group or world access",
                            ssl_key_file),
                     errdetail("File must have permissions u=rw (0600) or less if owned by the database user, or permissions u=rw,g=r (0640) or less if owned by root.")));
#endif

        if (SSL_CTX_use_PrivateKey_file(SSL_context,
                                        ssl_key_file,
                                        SSL_FILETYPE_PEM) != 1)
            ereport(FATAL,
                    (errmsg("could not load private key file \"%s\": %s",
                            ssl_key_file, SSLerrmessage(ERR_get_error()))));

        if (SSL_CTX_check_private_key(SSL_context) != 1)
            ereport(FATAL,
                    (errmsg("check of private key failed: %s",
                            SSLerrmessage(ERR_get_error()))));
    }

    /* set up ephemeral DH keys, and disallow SSL v2/v3 while at it */
    SSL_CTX_set_tmp_dh_callback(SSL_context, tmp_dh_cb);
    SSL_CTX_set_options(SSL_context,
                        SSL_OP_SINGLE_DH_USE |
                        SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3);

    /* set up ephemeral ECDH keys */
    initialize_ecdh();

    /* set up the allowed cipher list */
    if (SSL_CTX_set_cipher_list(SSL_context, SSLCipherSuites) != 1)
        elog(FATAL, "could not set the cipher list (no valid ciphers available)");

    /* Let server choose order */
    if (SSLPreferServerCiphers)
        SSL_CTX_set_options(SSL_context, SSL_OP_CIPHER_SERVER_PREFERENCE);

    /*
     * Load CA store, so we can verify client certificates if needed.
     */
    if (ssl_ca_file[0])
    {
        if (SSL_CTX_load_verify_locations(SSL_context, ssl_ca_file, NULL) != 1 ||
                (root_cert_list = SSL_load_client_CA_file(ssl_ca_file)) == NULL)
            ereport(FATAL,
                    (errmsg("could not load root certificate file \"%s\": %s",
                            ssl_ca_file, SSLerrmessage(ERR_get_error()))));
    }

    /*----------
     * Load the Certificate Revocation List (CRL).
     * http://searchsecurity.techtarget.com/sDefinition/0,,sid14_gci803160,00.html
     *----------
     */
    if (ssl_crl_file[0])
    {
        X509_STORE *cvstore = SSL_CTX_get_cert_store(SSL_context);

        if (cvstore)
        {
            /* Set the flags to check against the complete CRL chain */
            if (X509_STORE_load_locations(cvstore, ssl_crl_file, NULL) == 1)
            {
                /* OpenSSL 0.96 does not support X509_V_FLAG_CRL_CHECK */
#ifdef X509_V_FLAG_CRL_CHECK
                X509_STORE_set_flags(cvstore,
                                     X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL);
#else
                ereport(LOG,
                        (errmsg("SSL certificate revocation list file \"%s\" ignored",
                                ssl_crl_file),
                         errdetail("SSL library does not support certificate revocation lists.")));
#endif
            }
            else
                ereport(FATAL,
                        (errmsg("could not load SSL certificate revocation list file \"%s\": %s",
                                ssl_crl_file, SSLerrmessage(ERR_get_error()))));
        }
    }

    if (ssl_ca_file[0])
    {
        /*
         * Always ask for SSL client cert, but don't fail if it's not
         * presented.  We might fail such connections later, depending on what
         * we find in pg_hba.conf.
         */
        SSL_CTX_set_verify(SSL_context,
                           (SSL_VERIFY_PEER |
                            SSL_VERIFY_CLIENT_ONCE),
                           verify_cb);

        /* Set flag to remember CA store is successfully loaded */
        ssl_loaded_verify_locations = true;

        /*
         * Tell OpenSSL to send the list of root certs we trust to clients in
         * CertificateRequests.  This lets a client with a keystore select the
         * appropriate client certificate to send to us.
         */
        SSL_CTX_set_client_CA_list(SSL_context, root_cert_list);
    }
}
Пример #12
0
/*
 * This function initialize one web_server handler
 */
int web_server_init(struct web_server *server,int port,const char *logfile,int flags) {
#ifdef WIN32	
	unsigned long t=IOC_INOUT;
	WSADATA WSAinfo;
	WSAStartup(2,&WSAinfo); // Damn w32 sockets
#endif

	current_web_server=server;
	server->port=port;
	server->conffile=NULL;
	server->mimefile=NULL;
	server->weblog=NULL;
	server->usessl=0;
	server->flags=flags;
	server->dataconf="";
	if((flags & WS_USEEXTCONF) == WS_USEEXTCONF) {
		if(!(web_server_setup(server,logfile))) {
#ifdef WIN32		
			WSACleanup();
#endif
			return 0;
		};
		_logfile=server->weblog; // Set current log stream
		web_log("%s using config file %s\n",_libwebserver_version,logfile);
	};
	// Create a listen socket port 'port' and listen addr (0) (all interfaces)
	server->socket=__ILWS_listensocket((short)server->port,0);	
	if(server->socket==-1) {
		LWSERR(LE_NET);
#ifdef WIN32		
		WSACleanup();
#endif
		return 0;
	};
#ifdef WIN32
	ioctlsocket(server->socket,FIONBIO,&t);  //non blocking sockets for win32
#else
	fcntl(server->socket,F_SETFL,O_NONBLOCK);
#endif
	// Setup FILE structure of logfile
	if(logfile!=NULL && !((flags & WS_USEEXTCONF) == WS_USEEXTCONF)) {
		server->logfile=__ILWS_malloc(strlen(logfile)+1);
		memcpy(server->logfile,logfile,strlen(logfile));
		server->logfile[strlen(logfile)]=0;
		server->weblog=open_weblog(logfile); // Create File stream for log
	};
	
	web_log("\n[%s] Server started at port %d (%s)\n",__ILWS_date(time(NULL),"%d/%b/%Y:%H:%M:%S %z"),server->port,_libwebserver_version);
	
	// Setup Flags
	
	// openssl
#ifdef HAVE_OPENSSL	
	if((server->flags & WS_USESSL) == WS_USESSL) {
		web_log("[%s] (FLAG) Using SSL in connections\n",__ILWS_date(time(NULL),"%d/%b/%Y:%H:%M:%S %z"));	
		web_log("                       +-- %s certificate file\n",server->cert_file);
		SSL_load_error_strings();
		SSLeay_add_ssl_algorithms(); 	
		server->ctx=SSL_CTX_new (SSLv23_server_method());
		if (SSL_CTX_use_certificate_file(server->ctx, server->cert_file, SSL_FILETYPE_PEM) <= 0) {
			ERR_print_errors_fp(stderr);
			exit(3);
		}
		if (SSL_CTX_use_PrivateKey_file(server->ctx, server->cert_file, SSL_FILETYPE_PEM) <= 0) {
			ERR_print_errors_fp(stderr);
			exit(4);
		}                      
	 	if (SSL_CTX_check_private_key(server->ctx)<= 0)  	 {
			ERR_print_errors_fp(stderr);
			exit(4);
		};
		server->usessl=1;
	};
#endif
	if((server->flags & WS_LOCAL) == WS_LOCAL) {
		web_log("[%s] (FLAG) Accepting only local connections\n",__ILWS_date(time(NULL),"%d/%b/%Y:%H:%M:%S %z"));	
	};
	server->client=__ILWS_init_client_list();										// Initializate client list
	server->gethandler=__ILWS_init_handler_list();									// Initializate handlers list
	web_server_addhandler(server,"* /libwebserver.gif",_web_server_logo,0,NULL);	// Add logo default handler

#ifndef WIN32	
	signal(SIGPIPE,SIG_IGN);
#endif
	return 1;
}                            
Пример #13
0
/*
 * Initialize OpenSSL and verify the random number generator works.
 * Returns -1 on failure, 0 on success.
 */
int
ssl_init(void)
{
#ifndef PURIFY
	int fd;
#endif /* !PURIFY */
	char buf[256];

	if (ssl_initialized)
		return 0;

	/* general initialization */
	SSL_library_init();
#ifdef PURIFY
	CRYPTO_umalloc_init();
	CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
#endif /* PURIFY */
	SSL_load_error_strings();
	OpenSSL_add_all_algorithms();

	/* thread-safety */
#ifdef OPENSSL_THREADS
	ssl_mutex_num = CRYPTO_num_locks();
	ssl_mutex = umalloc(ssl_mutex_num * sizeof(*ssl_mutex));
	int i;
	for (i = 0; i < ssl_mutex_num; i++) {
		pthread_mutex_init(&ssl_mutex[i], NULL);
	}
	CRYPTO_set_locking_callback(ssl_thr_locking_cb);
	CRYPTO_set_dynlock_create_callback(ssl_thr_dyn_create_cb);
	CRYPTO_set_dynlock_lock_callback(ssl_thr_dyn_lock_cb);
	CRYPTO_set_dynlock_destroy_callback(ssl_thr_dyn_destroy_cb);
#ifdef OPENSSL_NO_THREADID
	CRYPTO_set_id_callback(ssl_thr_id_cb);
#else /* !OPENSSL_NO_THREADID */
	CRYPTO_THREADID_set_callback(ssl_thr_id_cb);
#endif /* !OPENSSL_NO_THREADID */
#endif /* OPENSSL_THREADS */

	/* randomness */
#ifndef PURIFY
	if ((fd = open("/dev/urandom", O_RDONLY)) == -1) {
		log_err_printf("Error opening /dev/urandom for reading: %s\n",
		               strerror(errno));
		return -1;
	}
	while (!RAND_status()) {
		if (read(fd, buf, sizeof(buf)) == -1) {
			log_err_printf("Error reading from /dev/urandom: %s\n",
			               strerror(errno));
			close(fd);
			return -1;
		}
		RAND_seed(buf, sizeof(buf));
	}
	close(fd);
	if (!RAND_poll()) {
		log_err_printf("RAND_poll() failed.\n");
		return -1;
	}
#else /* PURIFY */
	log_err_printf("Warning: not seeding OpenSSL RAND due to PURITY!\n");
	memset(buf, 0, sizeof(buf));
	while (!RAND_status()) {
		RAND_seed(buf, sizeof(buf));
	}
#endif /* PURIFY */

#ifdef USE_FOOTPRINT_HACKS
	/* HACK: disable compression by zeroing the global comp algo stack.
	 * This lowers the per-connection memory footprint by ~500k. */
	STACK_OF(SSL_COMP)* comp_methods = SSL_COMP_get_compression_methods();
	sk_SSL_COMP_zero(comp_methods);
#endif /* USE_FOOTPRINT_HACKS */

	ssl_initialized = 1;
	return 0;
}
Пример #14
0
int MAIN(int argc, char **argv)
	{
	int ret=1,i;
	int verbose=0,Verbose=0;
	int use_supported = 0;
#ifndef OPENSSL_NO_SSL_TRACE
	int stdname = 0;
#endif
	const char **pp;
	const char *p;
	int badops=0;
	SSL_CTX *ctx=NULL;
	SSL *ssl=NULL;
	char *ciphers=NULL;
	const SSL_METHOD *meth=NULL;
	STACK_OF(SSL_CIPHER) *sk=NULL;
	char buf[512];
	BIO *STDout=NULL;

	meth=SSLv23_server_method();

	apps_startup();

	if (bio_err == NULL)
		bio_err=BIO_new_fp(stderr,BIO_NOCLOSE);
	STDout=BIO_new_fp(stdout,BIO_NOCLOSE);
#ifdef OPENSSL_SYS_VMS
	{
	BIO *tmpbio = BIO_new(BIO_f_linebuffer());
	STDout = BIO_push(tmpbio, STDout);
	}
#endif
	if (!load_config(bio_err, NULL))
		goto end;

	argc--;
	argv++;
	while (argc >= 1)
		{
		if (strcmp(*argv,"-v") == 0)
			verbose=1;
		else if (strcmp(*argv,"-V") == 0)
			verbose=Verbose=1;
		else if (strcmp(*argv,"-s") == 0)
			use_supported = 1;
#ifndef OPENSSL_NO_SSL_TRACE
		else if (strcmp(*argv,"-stdname") == 0)
			stdname=verbose=1;
#endif
#ifndef OPENSSL_NO_SSL2
		else if (strcmp(*argv,"-ssl2") == 0)
			meth=SSLv2_client_method();
#endif
#ifndef OPENSSL_NO_SSL3
		else if (strcmp(*argv,"-ssl3") == 0)
			meth=SSLv3_client_method();
#endif
#ifndef OPENSSL_NO_TLS1
		else if (strcmp(*argv,"-tls1") == 0)
			meth=TLSv1_client_method();
#endif
		else if ((strncmp(*argv,"-h",2) == 0) ||
			 (strcmp(*argv,"-?") == 0))
			{
			badops=1;
			break;
			}
		else
			{
			ciphers= *argv;
			}
		argc--;
		argv++;
		}

	if (badops)
		{
		for (pp=ciphers_usage; (*pp != NULL); pp++)
			BIO_printf(bio_err,"%s",*pp);
		goto end;
		}

	OpenSSL_add_ssl_algorithms();

	ctx=SSL_CTX_new(meth);
	if (ctx == NULL) goto err;
	if (ciphers != NULL) {
		if(!SSL_CTX_set_cipher_list(ctx,ciphers)) {
			BIO_printf(bio_err, "Error in cipher list\n");
			goto err;
		}
	}
	ssl=SSL_new(ctx);
	if (ssl == NULL) goto err;

	if (use_supported)
		sk=SSL_get1_supported_ciphers(ssl);
	else
		sk=SSL_get_ciphers(ssl);

	if (!verbose)
		{
		for (i=0; i<sk_SSL_CIPHER_num(sk); i++)
			{
			SSL_CIPHER *c = sk_SSL_CIPHER_value(sk,i);
			p = SSL_CIPHER_get_name(c);
			if (p == NULL) break;
			if (i != 0) BIO_printf(STDout,":");
			BIO_printf(STDout,"%s",p);
			}
		BIO_printf(STDout,"\n");
		}
	else /* verbose */
		{

		for (i=0; i<sk_SSL_CIPHER_num(sk); i++)
			{
			SSL_CIPHER *c;

			c = sk_SSL_CIPHER_value(sk,i);
			
			if (Verbose)
				{
				unsigned long id = SSL_CIPHER_get_id(c);
				int id0 = (int)(id >> 24);
				int id1 = (int)((id >> 16) & 0xffL);
				int id2 = (int)((id >> 8) & 0xffL);
				int id3 = (int)(id & 0xffL);
				
				if ((id & 0xff000000L) == 0x02000000L)
					BIO_printf(STDout, "     0x%02X,0x%02X,0x%02X - ", id1, id2, id3); /* SSL2 cipher */
				else if ((id & 0xff000000L) == 0x03000000L)
					BIO_printf(STDout, "          0x%02X,0x%02X - ", id2, id3); /* SSL3 cipher */
				else
					BIO_printf(STDout, "0x%02X,0x%02X,0x%02X,0x%02X - ", id0, id1, id2, id3); /* whatever */
				}
#ifndef OPENSSL_NO_SSL_TRACE
			if (stdname)
				{
				const char *nm = SSL_CIPHER_standard_name(c);
				if (nm == NULL)
					nm = "UNKNOWN";
				BIO_printf(STDout, "%s - ", nm);
				}
#endif
			BIO_puts(STDout,SSL_CIPHER_description(c,buf,sizeof buf));
			}
		}

	ret=0;
	if (0)
		{
err:
		SSL_load_error_strings();
		ERR_print_errors(bio_err);
		}
end:
	if (use_supported && sk)
		sk_SSL_CIPHER_free(sk);
	if (ctx != NULL) SSL_CTX_free(ctx);
	if (ssl != NULL) SSL_free(ssl);
	if (STDout != NULL) BIO_free_all(STDout);
	apps_shutdown();
	OPENSSL_EXIT(ret);
	}
Пример #15
0
int
main(int argc, char **argv) {
  int sockfd = 0;
  int on = 1;
  struct sockaddr_in6 listen_addr = { AF_INET6, htons(20220), 0, IN6ADDR_ANY_INIT, 0 };
  size_t addr_size = sizeof(struct sockaddr_in6);
  fd_set fds[2];
  int result, flags;
  int idx, res = 0;
  struct timeval timeout;
  struct sigaction act, oact;
  
#ifdef WITH_DTLS
  SSL_CTX *ctx;

  memset(ssl_peer_storage, 0, sizeof(ssl_peer_storage));

  SSL_load_error_strings();
  SSL_library_init();
  ctx = SSL_CTX_new(DTLSv1_server_method());

  SSL_CTX_set_cipher_list(ctx, "ALL");
  SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_OFF);

  res = SSL_CTX_use_certificate_file(ctx, SERVER_CERT_PEM, SSL_FILETYPE_PEM);
  if (res != 1) {
    fprintf(stderr, "cannot read server certificate from file '%s' (%s)\n", 
	    SERVER_CERT_PEM, ERR_error_string(res,NULL));
    goto end;
  }

  res = SSL_CTX_use_PrivateKey_file(ctx, SERVER_KEY_PEM, SSL_FILETYPE_PEM);
  if (res != 1) {
    fprintf(stderr, "cannot read server key from file '%s' (%s)\n", 
	    SERVER_KEY_PEM, ERR_error_string(res,NULL));
    goto end;
  }

  res = SSL_CTX_check_private_key (ctx);
  if (res != 1) {
    fprintf(stderr, "invalid private key\n");
    goto end;
  }

  res = SSL_CTX_load_verify_locations(ctx, CA_CERT_PEM, NULL);
  if (res != 1) {
    fprintf(stderr, "cannot read ca file '%s'\n", CA_CERT_PEM);
    goto end;
  }

  /* Client has to authenticate */

  /* Client has to authenticate */
  SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE, NULL);

  SSL_CTX_set_read_ahead(ctx, 1); /* disable read-ahead */
  SSL_CTX_set_cookie_generate_cb(ctx, generate_cookie);
  SSL_CTX_set_cookie_verify_cb(ctx, verify_cookie);

  SSL_CTX_use_psk_identity_hint(ctx, "Enter password for CoAP-Gateway");
  SSL_CTX_set_psk_server_callback(ctx, psk_server_callback);

  SSL_CTX_set_info_callback(ctx, info_callback);
#endif

  sockfd = socket(listen_addr.sin6_family, SOCK_DGRAM, 0);
  if ( sockfd < 0 ) {
    perror("socket");
    return -1;
  }

  if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on) ) < 0)
    perror("setsockopt SO_REUSEADDR");

  flags = fcntl(sockfd, F_GETFL, 0);
  if (flags < 0 || fcntl(sockfd, F_SETFL, flags | O_NONBLOCK) < 0) {
    perror("fcntl");
    return -1;
  }

  on = 1;
  if (setsockopt(sockfd, IPPROTO_IPV6, IPV6_RECVPKTINFO, &on, sizeof(on) ) < 0) {
    perror("setsockopt IPV6_PKTINFO");
  }

  if (bind (sockfd, (const struct sockaddr *)&listen_addr, addr_size) < 0) {
    perror("bind");
    res = -2;
    goto end;
  }

  act.sa_handler = handle_sigint;
  sigemptyset(&act.sa_mask);
  act.sa_flags = 0;
  sigaction(SIGINT, &act, &oact);

  while (!quit) {
    FD_ZERO(&fds[READ]);
    FD_ZERO(&fds[WRITE]);
    FD_SET(sockfd, &fds[READ]);

    timeout.tv_sec = 1;
    timeout.tv_usec = 0;
    result = select( FD_SETSIZE, &fds[READ], &fds[WRITE], 0, &timeout);

    if (result < 0) {		/* error */
      if (errno != EINTR)
	perror("select");
    } else if (result > 0) {	/* read from socket */
      if ( FD_ISSET( sockfd, &fds[READ]) ) {
	_read(ctx, sockfd);	/* read received data */
      } else if ( FD_ISSET( sockfd, &fds[WRITE]) ) { /* write to socket */
	_write(ctx, sockfd);		/* write data */
      }
    } else {			/* timeout */
      check_timeout();
    }
    remove_closed();
  }
  
 end:
#ifdef WITH_DTLS
  for (idx = 0; idx < MAX_SSL_PEERS; idx++) {
    if (ssl_peer_storage[idx] && ssl_peer_storage[idx]->ssl) {
      if (ssl_peer_storage[idx]->state == PEER_ST_ESTABLISHED)
	SSL_shutdown(ssl_peer_storage[idx]->ssl);
      SSL_free(ssl_peer_storage[idx]->ssl);
    }
  }

  SSL_CTX_free(ctx);
#endif
  close(sockfd);		/* don't care if we close stdin at this point */
  return res;
}
Пример #16
0
/**
 * Allocate a new TLS context
 *
 * @param tlsp    Pointer to allocated TLS context
 * @param method  TLS method
 * @param keyfile Optional private key file
 * @param pwd     Optional password
 *
 * @return 0 if success, otherwise errorcode
 */
int tls_alloc(struct tls **tlsp, enum tls_method method, const char *keyfile,
	      const char *pwd)
{
	struct tls *tls;
	int r, err;

	if (!tlsp)
		return EINVAL;

	tls = mem_zalloc(sizeof(*tls), destructor);
	if (!tls)
		return ENOMEM;

	if (!tlsg.up) {
#ifdef SIGPIPE
		/* Set up a SIGPIPE handler */
		(void)signal(SIGPIPE, sigpipe_handle);
#endif

		SSL_library_init();
		tlsg.up = true;
	}

	if (tlsg.tlsc++ == 0) {
		DEBUG_INFO("error strings loaded\n");
		SSL_load_error_strings();
	}

	switch (method) {

	case TLS_METHOD_SSLV23:
		tls->ctx = SSL_CTX_new(SSLv23_method());
		break;

#ifdef USE_OPENSSL_DTLS
	case TLS_METHOD_DTLSV1:
		tls->ctx = SSL_CTX_new(DTLSv1_method());
		break;
#endif

	default:
		DEBUG_WARNING("tls method %d not supported\n", method);
		err = ENOSYS;
		goto out;
	}

	if (!tls->ctx) {
		err = ENOMEM;
		goto out;
	}

#if (OPENSSL_VERSION_NUMBER < 0x00905100L)
	SSL_CTX_set_verify_depth(tls->ctx, 1);
#endif

	if (method == TLS_METHOD_DTLSV1) {
		SSL_CTX_set_read_ahead(tls->ctx, 1);
	}

	/* Load our keys and certificates */
	if (keyfile) {
		if (pwd) {
			err = str_dup(&tls->pass, pwd);
			if (err)
				goto out;

			SSL_CTX_set_default_passwd_cb(tls->ctx, password_cb);
			SSL_CTX_set_default_passwd_cb_userdata(tls->ctx, tls);
		}

		r = SSL_CTX_use_certificate_chain_file(tls->ctx, keyfile);
		if (r <= 0) {
			DEBUG_WARNING("Can't read certificate file: %s (%d)\n",
				      keyfile, r);
			err = EINVAL;
			goto out;
		}

		r = SSL_CTX_use_PrivateKey_file(tls->ctx, keyfile,
						SSL_FILETYPE_PEM);
		if (r <= 0) {
			DEBUG_WARNING("Can't read key file: %s (%d)\n",
				      keyfile, r);
			err = EINVAL;
			goto out;
		}
	}

	err = 0;
 out:
	if (err)
		mem_deref(tls);
	else
		*tlsp = tls;

	return err;
}
Пример #17
0
int MAIN(int argc, char **argv)
{
    ENGINE *e = NULL;
    char **args;
    char *host = NULL, *port = NULL, *path = "/";
    char *thost = NULL, *tport = NULL, *tpath = NULL;
    char *reqin = NULL, *respin = NULL;
    char *reqout = NULL, *respout = NULL;
    char *signfile = NULL, *keyfile = NULL;
    char *rsignfile = NULL, *rkeyfile = NULL;
    char *outfile = NULL;
    int add_nonce = 1, noverify = 0, use_ssl = -1;
    STACK_OF(CONF_VALUE) *headers = NULL;
    OCSP_REQUEST *req = NULL;
    OCSP_RESPONSE *resp = NULL;
    OCSP_BASICRESP *bs = NULL;
    X509 *issuer = NULL, *cert = NULL;
    X509 *signer = NULL, *rsigner = NULL;
    EVP_PKEY *key = NULL, *rkey = NULL;
    BIO *acbio = NULL, *cbio = NULL;
    BIO *derbio = NULL;
    BIO *out = NULL;
    int req_timeout = -1;
    int req_text = 0, resp_text = 0;
    long nsec = MAX_VALIDITY_PERIOD, maxage = -1;
    char *CAfile = NULL, *CApath = NULL;
    X509_STORE *store = NULL;
    STACK_OF(X509) *sign_other = NULL, *verify_other = NULL, *rother = NULL;
    char *sign_certfile = NULL, *verify_certfile = NULL, *rcertfile = NULL;
    unsigned long sign_flags = 0, verify_flags = 0, rflags = 0;
    int ret = 1;
    int accept_count = -1;
    int badarg = 0;
    int i;
    int ignore_err = 0;
    STACK_OF(OPENSSL_STRING) *reqnames = NULL;
    STACK_OF(OCSP_CERTID) *ids = NULL;

    X509 *rca_cert = NULL;
    char *ridx_filename = NULL;
    char *rca_filename = NULL;
    CA_DB *rdb = NULL;
    int nmin = 0, ndays = -1;
    const EVP_MD *cert_id_md = NULL;

    if (bio_err == NULL)
        bio_err = BIO_new_fp(stderr, BIO_NOCLOSE);

    if (!load_config(bio_err, NULL))
        goto end;
    SSL_load_error_strings();
    OpenSSL_add_ssl_algorithms();
    args = argv + 1;
    reqnames = sk_OPENSSL_STRING_new_null();
    ids = sk_OCSP_CERTID_new_null();
    while (!badarg && *args && *args[0] == '-') {
        if (!strcmp(*args, "-out")) {
            if (args[1]) {
                args++;
                outfile = *args;
            } else
                badarg = 1;
        } else if (!strcmp(*args, "-timeout")) {
            if (args[1]) {
                args++;
                req_timeout = atol(*args);
                if (req_timeout < 0) {
                    BIO_printf(bio_err, "Illegal timeout value %s\n", *args);
                    badarg = 1;
                }
            } else
                badarg = 1;
        } else if (!strcmp(*args, "-url")) {
            if (thost)
                OPENSSL_free(thost);
            if (tport)
                OPENSSL_free(tport);
            if (tpath)
                OPENSSL_free(tpath);
            if (args[1]) {
                args++;
                if (!OCSP_parse_url(*args, &host, &port, &path, &use_ssl)) {
                    BIO_printf(bio_err, "Error parsing URL\n");
                    badarg = 1;
                }
                thost = host;
                tport = port;
                tpath = path;
            } else
                badarg = 1;
        } else if (!strcmp(*args, "-host")) {
            if (args[1]) {
                args++;
                host = *args;
            } else
                badarg = 1;
        } else if (!strcmp(*args, "-port")) {
            if (args[1]) {
                args++;
                port = BUF_strdup(*args);
            } else
                badarg = 1;
        } else if (!strcmp(*args, "-header")) {
            if (args[1] && args[2]) {
                if (!X509V3_add_value(args[1], args[2], &headers))
                    goto end;
                args += 2;
            } else
                badarg = 1;
        } else if (!strcmp(*args, "-ignore_err"))
            ignore_err = 1;
        else if (!strcmp(*args, "-noverify"))
            noverify = 1;
        else if (!strcmp(*args, "-nonce"))
            add_nonce = 2;
        else if (!strcmp(*args, "-no_nonce"))
            add_nonce = 0;
        else if (!strcmp(*args, "-resp_no_certs"))
            rflags |= OCSP_NOCERTS;
        else if (!strcmp(*args, "-resp_key_id"))
            rflags |= OCSP_RESPID_KEY;
        else if (!strcmp(*args, "-no_certs"))
            sign_flags |= OCSP_NOCERTS;
        else if (!strcmp(*args, "-no_signature_verify"))
            verify_flags |= OCSP_NOSIGS;
        else if (!strcmp(*args, "-no_cert_verify"))
            verify_flags |= OCSP_NOVERIFY;
        else if (!strcmp(*args, "-no_chain"))
            verify_flags |= OCSP_NOCHAIN;
        else if (!strcmp(*args, "-no_cert_checks"))
            verify_flags |= OCSP_NOCHECKS;
        else if (!strcmp(*args, "-no_explicit"))
            verify_flags |= OCSP_NOEXPLICIT;
        else if (!strcmp(*args, "-trust_other"))
            verify_flags |= OCSP_TRUSTOTHER;
        else if (!strcmp(*args, "-no_intern"))
            verify_flags |= OCSP_NOINTERN;
        else if (!strcmp(*args, "-text")) {
            req_text = 1;
            resp_text = 1;
        } else if (!strcmp(*args, "-req_text"))
            req_text = 1;
        else if (!strcmp(*args, "-resp_text"))
            resp_text = 1;
        else if (!strcmp(*args, "-reqin")) {
            if (args[1]) {
                args++;
                reqin = *args;
            } else
                badarg = 1;
        } else if (!strcmp(*args, "-respin")) {
            if (args[1]) {
                args++;
                respin = *args;
            } else
                badarg = 1;
        } else if (!strcmp(*args, "-signer")) {
            if (args[1]) {
                args++;
                signfile = *args;
            } else
                badarg = 1;
        } else if (!strcmp(*args, "-VAfile")) {
            if (args[1]) {
                args++;
                verify_certfile = *args;
                verify_flags |= OCSP_TRUSTOTHER;
            } else
                badarg = 1;
        } else if (!strcmp(*args, "-sign_other")) {
            if (args[1]) {
                args++;
                sign_certfile = *args;
            } else
                badarg = 1;
        } else if (!strcmp(*args, "-verify_other")) {
            if (args[1]) {
                args++;
                verify_certfile = *args;
            } else
                badarg = 1;
        } else if (!strcmp(*args, "-CAfile")) {
            if (args[1]) {
                args++;
                CAfile = *args;
            } else
                badarg = 1;
        } else if (!strcmp(*args, "-CApath")) {
            if (args[1]) {
                args++;
                CApath = *args;
            } else
                badarg = 1;
        } else if (!strcmp(*args, "-validity_period")) {
            if (args[1]) {
                args++;
                nsec = atol(*args);
                if (nsec < 0) {
                    BIO_printf(bio_err,
                               "Illegal validity period %s\n", *args);
                    badarg = 1;
                }
            } else
                badarg = 1;
        } else if (!strcmp(*args, "-status_age")) {
            if (args[1]) {
                args++;
                maxage = atol(*args);
                if (maxage < 0) {
                    BIO_printf(bio_err, "Illegal validity age %s\n", *args);
                    badarg = 1;
                }
            } else
                badarg = 1;
        } else if (!strcmp(*args, "-signkey")) {
            if (args[1]) {
                args++;
                keyfile = *args;
            } else
                badarg = 1;
        } else if (!strcmp(*args, "-reqout")) {
            if (args[1]) {
                args++;
                reqout = *args;
            } else
                badarg = 1;
        } else if (!strcmp(*args, "-respout")) {
            if (args[1]) {
                args++;
                respout = *args;
            } else
                badarg = 1;
        } else if (!strcmp(*args, "-path")) {
            if (args[1]) {
                args++;
                path = *args;
            } else
                badarg = 1;
        } else if (!strcmp(*args, "-issuer")) {
            if (args[1]) {
                args++;
                X509_free(issuer);
                issuer = load_cert(bio_err, *args, FORMAT_PEM,
                                   NULL, e, "issuer certificate");
                if (!issuer)
                    goto end;
            } else
                badarg = 1;
        } else if (!strcmp(*args, "-cert")) {
            if (args[1]) {
                args++;
                X509_free(cert);
                cert = load_cert(bio_err, *args, FORMAT_PEM,
                                 NULL, e, "certificate");
                if (!cert)
                    goto end;
                if (!cert_id_md)
                    cert_id_md = EVP_sha1();
                if (!add_ocsp_cert(&req, cert, cert_id_md, issuer, ids))
                    goto end;
                if (!sk_OPENSSL_STRING_push(reqnames, *args))
                    goto end;
            } else
                badarg = 1;
        } else if (!strcmp(*args, "-serial")) {
            if (args[1]) {
                args++;
                if (!cert_id_md)
                    cert_id_md = EVP_sha1();
                if (!add_ocsp_serial(&req, *args, cert_id_md, issuer, ids))
                    goto end;
                if (!sk_OPENSSL_STRING_push(reqnames, *args))
                    goto end;
            } else
                badarg = 1;
        } else if (!strcmp(*args, "-index")) {
            if (args[1]) {
                args++;
                ridx_filename = *args;
            } else
                badarg = 1;
        } else if (!strcmp(*args, "-CA")) {
            if (args[1]) {
                args++;
                rca_filename = *args;
            } else
                badarg = 1;
        } else if (!strcmp(*args, "-nmin")) {
            if (args[1]) {
                args++;
                nmin = atol(*args);
                if (nmin < 0) {
                    BIO_printf(bio_err, "Illegal update period %s\n", *args);
                    badarg = 1;
                }
            }
            if (ndays == -1)
                ndays = 0;
            else
                badarg = 1;
        } else if (!strcmp(*args, "-nrequest")) {
            if (args[1]) {
                args++;
                accept_count = atol(*args);
                if (accept_count < 0) {
                    BIO_printf(bio_err, "Illegal accept count %s\n", *args);
                    badarg = 1;
                }
            } else
                badarg = 1;
        } else if (!strcmp(*args, "-ndays")) {
            if (args[1]) {
                args++;
                ndays = atol(*args);
                if (ndays < 0) {
                    BIO_printf(bio_err, "Illegal update period %s\n", *args);
                    badarg = 1;
                }
            } else
                badarg = 1;
        } else if (!strcmp(*args, "-rsigner")) {
            if (args[1]) {
                args++;
                rsignfile = *args;
            } else
                badarg = 1;
        } else if (!strcmp(*args, "-rkey")) {
            if (args[1]) {
                args++;
                rkeyfile = *args;
            } else
                badarg = 1;
        } else if (!strcmp(*args, "-rother")) {
            if (args[1]) {
                args++;
                rcertfile = *args;
            } else
                badarg = 1;
        } else if ((cert_id_md = EVP_get_digestbyname((*args) + 1)) == NULL) {
            badarg = 1;
        }
        args++;
    }

    /* Have we anything to do? */
    if (!req && !reqin && !respin && !(port && ridx_filename))
        badarg = 1;

    if (badarg) {
        BIO_printf(bio_err, "OCSP utility\n");
        BIO_printf(bio_err, "Usage ocsp [options]\n");
        BIO_printf(bio_err, "where options are\n");
        BIO_printf(bio_err, "-out file            output filename\n");
        BIO_printf(bio_err, "-issuer file         issuer certificate\n");
        BIO_printf(bio_err, "-cert file           certificate to check\n");
        BIO_printf(bio_err, "-serial n            serial number to check\n");
        BIO_printf(bio_err,
                   "-signer file         certificate to sign OCSP request with\n");
        BIO_printf(bio_err,
                   "-signkey file        private key to sign OCSP request with\n");
        BIO_printf(bio_err,
                   "-sign_other file     additional certificates to include in signed request\n");
        BIO_printf(bio_err,
                   "-no_certs            don't include any certificates in signed request\n");
        BIO_printf(bio_err,
                   "-req_text            print text form of request\n");
        BIO_printf(bio_err,
                   "-resp_text           print text form of response\n");
        BIO_printf(bio_err,
                   "-text                print text form of request and response\n");
        BIO_printf(bio_err,
                   "-reqout file         write DER encoded OCSP request to \"file\"\n");
        BIO_printf(bio_err,
                   "-respout file        write DER encoded OCSP reponse to \"file\"\n");
        BIO_printf(bio_err,
                   "-reqin file          read DER encoded OCSP request from \"file\"\n");
        BIO_printf(bio_err,
                   "-respin file         read DER encoded OCSP reponse from \"file\"\n");
        BIO_printf(bio_err,
                   "-nonce               add OCSP nonce to request\n");
        BIO_printf(bio_err,
                   "-no_nonce            don't add OCSP nonce to request\n");
        BIO_printf(bio_err, "-url URL             OCSP responder URL\n");
        BIO_printf(bio_err,
                   "-host host:n         send OCSP request to host on port n\n");
        BIO_printf(bio_err,
                   "-path                path to use in OCSP request\n");
        BIO_printf(bio_err,
                   "-CApath dir          trusted certificates directory\n");
        BIO_printf(bio_err,
                   "-CAfile file         trusted certificates file\n");
        BIO_printf(bio_err,
                   "-VAfile file         validator certificates file\n");
        BIO_printf(bio_err,
                   "-validity_period n   maximum validity discrepancy in seconds\n");
        BIO_printf(bio_err,
                   "-status_age n        maximum status age in seconds\n");
        BIO_printf(bio_err,
                   "-noverify            don't verify response at all\n");
        BIO_printf(bio_err,
                   "-verify_other file   additional certificates to search for signer\n");
        BIO_printf(bio_err,
                   "-trust_other         don't verify additional certificates\n");
        BIO_printf(bio_err,
                   "-no_intern           don't search certificates contained in response for signer\n");
        BIO_printf(bio_err,
                   "-no_signature_verify don't check signature on response\n");
        BIO_printf(bio_err,
                   "-no_cert_verify      don't check signing certificate\n");
        BIO_printf(bio_err,
                   "-no_chain            don't chain verify response\n");
        BIO_printf(bio_err,
                   "-no_cert_checks      don't do additional checks on signing certificate\n");
        BIO_printf(bio_err,
                   "-port num            port to run responder on\n");
        BIO_printf(bio_err,
                   "-index file          certificate status index file\n");
        BIO_printf(bio_err, "-CA file             CA certificate\n");
        BIO_printf(bio_err,
                   "-rsigner file        responder certificate to sign responses with\n");
        BIO_printf(bio_err,
                   "-rkey file           responder key to sign responses with\n");
        BIO_printf(bio_err,
                   "-rother file         other certificates to include in response\n");
        BIO_printf(bio_err,
                   "-resp_no_certs       don't include any certificates in response\n");
        BIO_printf(bio_err,
                   "-nmin n              number of minutes before next update\n");
        BIO_printf(bio_err,
                   "-ndays n             number of days before next update\n");
        BIO_printf(bio_err,
                   "-resp_key_id         identify reponse by signing certificate key ID\n");
        BIO_printf(bio_err,
                   "-nrequest n          number of requests to accept (default unlimited)\n");
        BIO_printf(bio_err,
                   "-<dgst alg>          use specified digest in the request\n");
        BIO_printf(bio_err,
                   "-timeout n           timeout connection to OCSP responder after n seconds\n");
        goto end;
    }

    if (outfile)
        out = BIO_new_file(outfile, "w");
    else
        out = BIO_new_fp(stdout, BIO_NOCLOSE);

    if (!out) {
        BIO_printf(bio_err, "Error opening output file\n");
        goto end;
    }

    if (!req && (add_nonce != 2))
        add_nonce = 0;

    if (!req && reqin) {
        derbio = BIO_new_file(reqin, "rb");
        if (!derbio) {
            BIO_printf(bio_err, "Error Opening OCSP request file\n");
            goto end;
        }
        req = d2i_OCSP_REQUEST_bio(derbio, NULL);
        BIO_free(derbio);
        if (!req) {
            BIO_printf(bio_err, "Error reading OCSP request\n");
            goto end;
        }
    }

    if (!req && port) {
        acbio = init_responder(port);
        if (!acbio)
            goto end;
    }

    if (rsignfile && !rdb) {
        if (!rkeyfile)
            rkeyfile = rsignfile;
        rsigner = load_cert(bio_err, rsignfile, FORMAT_PEM,
                            NULL, e, "responder certificate");
        if (!rsigner) {
            BIO_printf(bio_err, "Error loading responder certificate\n");
            goto end;
        }
        rca_cert = load_cert(bio_err, rca_filename, FORMAT_PEM,
                             NULL, e, "CA certificate");
        if (rcertfile) {
            rother = load_certs(bio_err, rcertfile, FORMAT_PEM,
                                NULL, e, "responder other certificates");
            if (!rother)
                goto end;
        }
        rkey = load_key(bio_err, rkeyfile, FORMAT_PEM, 0, NULL, NULL,
                        "responder private key");
        if (!rkey)
            goto end;
    }
    if (acbio)
        BIO_printf(bio_err, "Waiting for OCSP client connections...\n");

 redo_accept:

    if (acbio) {
        if (!do_responder(&req, &cbio, acbio, port))
            goto end;
        if (!req) {
            resp =
                OCSP_response_create(OCSP_RESPONSE_STATUS_MALFORMEDREQUEST,
                                     NULL);
            send_ocsp_response(cbio, resp);
            goto done_resp;
        }
    }

    if (!req && (signfile || reqout || host || add_nonce || ridx_filename)) {
        BIO_printf(bio_err, "Need an OCSP request for this operation!\n");
        goto end;
    }

    if (req && add_nonce)
        OCSP_request_add1_nonce(req, NULL, -1);

    if (signfile) {
        if (!keyfile)
            keyfile = signfile;
        signer = load_cert(bio_err, signfile, FORMAT_PEM,
                           NULL, e, "signer certificate");
        if (!signer) {
            BIO_printf(bio_err, "Error loading signer certificate\n");
            goto end;
        }
        if (sign_certfile) {
            sign_other = load_certs(bio_err, sign_certfile, FORMAT_PEM,
                                    NULL, e, "signer certificates");
            if (!sign_other)
                goto end;
        }
        key = load_key(bio_err, keyfile, FORMAT_PEM, 0, NULL, NULL,
                       "signer private key");
        if (!key)
            goto end;

        if (!OCSP_request_sign
            (req, signer, key, NULL, sign_other, sign_flags)) {
            BIO_printf(bio_err, "Error signing OCSP request\n");
            goto end;
        }
    }

    if (req_text && req)
        OCSP_REQUEST_print(out, req, 0);

    if (reqout) {
        derbio = BIO_new_file(reqout, "wb");
        if (!derbio) {
            BIO_printf(bio_err, "Error opening file %s\n", reqout);
            goto end;
        }
        i2d_OCSP_REQUEST_bio(derbio, req);
        BIO_free(derbio);
    }

    if (ridx_filename && (!rkey || !rsigner || !rca_cert)) {
        BIO_printf(bio_err,
                   "Need a responder certificate, key and CA for this operation!\n");
        goto end;
    }

    if (ridx_filename && !rdb) {
        rdb = load_index(ridx_filename, NULL);
        if (!rdb)
            goto end;
        if (!index_index(rdb))
            goto end;
    }

    if (rdb) {
        i = make_ocsp_response(&resp, req, rdb, rca_cert, rsigner, rkey,
                               rother, rflags, nmin, ndays);
        if (cbio)
            send_ocsp_response(cbio, resp);
    } else if (host) {
# ifndef OPENSSL_NO_SOCK
        resp = process_responder(bio_err, req, host, path,
                                 port, use_ssl, headers, req_timeout);
        if (!resp)
            goto end;
# else
        BIO_printf(bio_err,
                   "Error creating connect BIO - sockets not supported.\n");
        goto end;
# endif
    } else if (respin) {
        derbio = BIO_new_file(respin, "rb");
        if (!derbio) {
            BIO_printf(bio_err, "Error Opening OCSP response file\n");
            goto end;
        }
        resp = d2i_OCSP_RESPONSE_bio(derbio, NULL);
        BIO_free(derbio);
        if (!resp) {
            BIO_printf(bio_err, "Error reading OCSP response\n");
            goto end;
        }

    } else {
        ret = 0;
        goto end;
    }

 done_resp:

    if (respout) {
        derbio = BIO_new_file(respout, "wb");
        if (!derbio) {
            BIO_printf(bio_err, "Error opening file %s\n", respout);
            goto end;
        }
        i2d_OCSP_RESPONSE_bio(derbio, resp);
        BIO_free(derbio);
    }

    i = OCSP_response_status(resp);

    if (i != OCSP_RESPONSE_STATUS_SUCCESSFUL) {
        BIO_printf(out, "Responder Error: %s (%d)\n",
                   OCSP_response_status_str(i), i);
        if (ignore_err)
            goto redo_accept;
        ret = 0;
        goto end;
    }

    if (resp_text)
        OCSP_RESPONSE_print(out, resp, 0);

    /* If running as responder don't verify our own response */
    if (cbio) {
        if (accept_count > 0)
            accept_count--;
        /* Redo if more connections needed */
        if (accept_count) {
            BIO_free_all(cbio);
            cbio = NULL;
            OCSP_REQUEST_free(req);
            req = NULL;
            OCSP_RESPONSE_free(resp);
            resp = NULL;
            goto redo_accept;
        }
        goto end;
    }

    if (!store)
        store = setup_verify(bio_err, CAfile, CApath);
    if (!store)
        goto end;
    if (verify_certfile) {
        verify_other = load_certs(bio_err, verify_certfile, FORMAT_PEM,
                                  NULL, e, "validator certificate");
        if (!verify_other)
            goto end;
    }

    bs = OCSP_response_get1_basic(resp);

    if (!bs) {
        BIO_printf(bio_err, "Error parsing response\n");
        goto end;
    }

    if (!noverify) {
        if (req && ((i = OCSP_check_nonce(req, bs)) <= 0)) {
            if (i == -1)
                BIO_printf(bio_err, "WARNING: no nonce in response\n");
            else {
                BIO_printf(bio_err, "Nonce Verify error\n");
                goto end;
            }
        }

        i = OCSP_basic_verify(bs, verify_other, store, verify_flags);
        if (i < 0)
            i = OCSP_basic_verify(bs, NULL, store, 0);

        if (i <= 0) {
            BIO_printf(bio_err, "Response Verify Failure\n");
            ERR_print_errors(bio_err);
        } else
            BIO_printf(bio_err, "Response verify OK\n");

    }

    if (!print_ocsp_summary(out, bs, req, reqnames, ids, nsec, maxage))
        goto end;

    ret = 0;

 end:
    ERR_print_errors(bio_err);
    X509_free(signer);
    X509_STORE_free(store);
    EVP_PKEY_free(key);
    EVP_PKEY_free(rkey);
    X509_free(issuer);
    X509_free(cert);
    X509_free(rsigner);
    X509_free(rca_cert);
    free_index(rdb);
    BIO_free_all(cbio);
    BIO_free_all(acbio);
    BIO_free(out);
    OCSP_REQUEST_free(req);
    OCSP_RESPONSE_free(resp);
    OCSP_BASICRESP_free(bs);
    sk_OPENSSL_STRING_free(reqnames);
    sk_OCSP_CERTID_free(ids);
    sk_X509_pop_free(sign_other, X509_free);
    sk_X509_pop_free(verify_other, X509_free);
    sk_CONF_VALUE_pop_free(headers, X509V3_conf_free);

    if (thost)
        OPENSSL_free(thost);
    if (tport)
        OPENSSL_free(tport);
    if (tpath)
        OPENSSL_free(tpath);

    OPENSSL_EXIT(ret);
}
Пример #18
0
int main( int argc, char *argv[] )
{
    char *fn = "main()";
    char f_randfile[ PATH_MAX ];
    int listensd;                      /* socket descriptor we'll bind to */
    int clientsd;                      /* incoming socket descriptor */
    int addrlen;                       
    struct sockaddr_in srvaddr;
    struct sockaddr_in cliaddr;
    pthread_t ThreadId;                /* thread id of each incoming conn */
    pthread_t RecycleThread;           /* used just for the recycle thread */
    pthread_attr_t attr;               /* generic thread attribute struct */
    int rc, i, fd;
    pid_t pid;                         /* used just for a fork call */
    struct linger lingerstruct;        /* for the socket reuse stuff */
    int flag;                          /* for the socket reuse stuff */
    ICC_Struct *ICC_tptr;             
    extern char *optarg;
    extern int optind;
    char ConfigFile[ MAXPATHLEN ];     /* path to our config file */
#ifdef HAVE_LIBWRAP
    struct request_info r;             /* request struct for libwrap */
#endif

    flag = 1;
    ConfigFile[0] = '\0';

    /*
     * Ignore signals we don't want to die from but we don't care enough
     * about to catch.
     */
    signal( SIGPIPE, SIG_IGN );
    signal( SIGHUP, SIG_IGN );
    

    while (( i = getopt( argc, argv, "f:h" ) ) != EOF )
    {
	switch( i )
	{
	case 'f':
	    /* user specified a config filename */
	    strncpy( ConfigFile, optarg, sizeof ConfigFile -1 );
	    syslog( LOG_INFO, "%s: Using configuration file '%s'",
		    fn, ConfigFile );
	    break;
	    
	case 'h':
	    Usage();
	    exit( 0 );

	case '?':
	    Usage();
	    exit( 1 );
	}
    }


    /* 
     * Make sure we know which config file to use and then set our config
     * options.
     */
    if ( ! ConfigFile[0] )
    {
	strncpy( ConfigFile, DEFAULT_CONFIG_FILE, sizeof ConfigFile -1 );
	syslog( LOG_INFO, "%s: Using default configuration file '%s'.",
		fn, ConfigFile );
    }
    
    SetConfigOptions( ConfigFile );
    SetLogOptions();
    
#ifdef HAVE_LIBWRAP
    /*
     * Set our tcpd service name
     */
    if (service = strrchr(argv[0], '/'))
	    service++;
    else
	    service = argv[0];
#endif

    /*
     * Initialize some stuff.
     */
    rc = pthread_mutex_init(&mp, NULL);
    if ( rc )
    {
	syslog(LOG_ERR, "%s: pthread_mutex_init() returned error [%d] initializing main mutex.  Exiting.", fn, rc );
	exit( 1 );
    }

    rc = pthread_mutex_init(&trace, NULL);
    if ( rc )
    {
	syslog(LOG_ERR, "%s: pthread_mutex_init() returned error [%d] initializing trace mutex.  Exiting.", fn, rc );
	exit( 1 );
    }

    TraceUser[0] = '\0';
    
    syslog( LOG_INFO, "%s: Allocating %d IMAP connection structures.", 
	    fn, PC_Struct.cache_size );

    ICC_free = malloc( ( sizeof ( ICC_Struct ) ) 
		       * PC_Struct.cache_size );
    
    if ( ! ICC_free )
    {
	syslog(LOG_ERR, "%s: malloc() failed to allocate [%d] IMAPConnectionContext structures: %s", fn, PC_Struct.cache_size, strerror( errno ) );
	exit( 1 );
    }
    
    memset( ICC_free, 0, sizeof ( ICC_Struct ) * PC_Struct.cache_size );
    
    ICC_tptr = ICC_free;

    /*
     * Bug fixed by Gary Mills <*****@*****.**>.  I was pre-incrementing
     * ICC_tptr and then assigning.  I guess gcc evaluates the expression
     * incorrectly, since I never had a problem with this.  Gary had the
     * problem with cc, so it's fixed here.
     */
    for ( i = 0; i < PC_Struct.cache_size - 1; i++ )
    {
	ICC_tptr->next = ICC_tptr + 1;
	ICC_tptr++;
    }
    
    memset( ICC_HashTable, 0, sizeof ICC_HashTable );

    ServerInit();

    /* detach from our parent if necessary */
    if (! (getppid() == 1) )
    {
	if ( (pid = fork()) < 0)
	{
	    syslog(LOG_ERR, "%s: initial call to fork() failed: %s", fn, strerror(errno));
	    exit( 1 );
	}
	else if ( pid > 0)
	{
	    exit( 0 );
	}
	
	if (setsid() == -1)
	{
	    syslog(LOG_WARNING, "%s: setsid() failed: %s", 
		   fn, strerror(errno));
	}
	if ( (pid = fork()) < 0)
	{
	    syslog(LOG_ERR, "%s: secondary call to fork() failed: %s", fn, 
		   strerror(errno));
	    exit( 1 );
	}
	else if ( pid > 0)
	{
	    exit( 0 );
	}
    }

    
    if ( SetBannerAndCapability() )
    {
	syslog(LOG_ERR, "%s: Failed to get banner string and capability from imap server.  Exiting.", fn);
	exit( 1 );
    }

    if ( PC_Struct.login_disabled )
    {
#if HAVE_LIBSSL
	if ( PC_Struct.support_starttls )
	{
	    /* Initialize SSL_CTX */
	    SSL_library_init();
	    
            /* Need to seed PRNG, too! */
            if ( RAND_egd( RAND_file_name( f_randfile, sizeof( f_randfile ) ) ) < 0) 
	    {
                /* Not an EGD, so read and write it. */
                if ( RAND_load_file( f_randfile, -1 ) )
                    RAND_write_file( f_randfile );
            }
	    
	    SSL_load_error_strings();
	    tls_ctx = SSL_CTX_new( TLSv1_client_method() );
	    if ( tls_ctx == NULL )
	    {
		syslog(LOG_ERR, "%s: Failed to create new SSL_CTX.  Exiting.", fn);
		exit( 1 );
	    }

	    /* Work around all known bugs */
	    SSL_CTX_set_options( tls_ctx, SSL_OP_ALL );

	    if ( ! SSL_CTX_load_verify_locations( tls_ctx,
						  PC_Struct.tls_ca_file,
						  PC_Struct.tls_ca_path ) ||
		 ! SSL_CTX_set_default_verify_paths( tls_ctx ) )
	    {
		syslog(LOG_ERR, "%s: Failed to load CA data.  Exiting.", fn);
		exit( 1 );
	    }

	    if ( ! set_cert_stuff( tls_ctx,
				   PC_Struct.tls_cert_file,
				   PC_Struct.tls_key_file ) )
	    {
		syslog(LOG_ERR, "%s: Failed to load cert/key data.  Exiting.", fn);
		exit( 1 );
	    }

	    SSL_CTX_set_verify(tls_ctx, SSL_VERIFY_NONE, verify_callback);
	}
	else
#endif /* HAVE_LIBSSL */
	{
	    /* We're screwed!  We won't be able to login without SASL */
	    syslog(LOG_ERR, "%s: IMAP server has LOGINDISABLED and we can't do STARTTLS.  Exiting.", fn);
	    exit( 1 );
	}
    }
    


    memset( (char *) &srvaddr, 0, sizeof srvaddr );
    srvaddr.sin_family = PF_INET;
    srvaddr.sin_addr.s_addr = htonl(INADDR_ANY);

    syslog(LOG_INFO, "%s: Binding to tcp port %d", fn, PC_Struct.listen_port );
    srvaddr.sin_port = htons(PC_Struct.listen_port);

    listensd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
    if ( listensd == -1 )
    {
	syslog(LOG_ERR, "%s: socket() failed: %s", fn, strerror(errno));
	exit( 1 );
    }

    setsockopt(listensd, SOL_SOCKET, SO_REUSEADDR, (void *)&flag, 
	       sizeof(flag));
    lingerstruct.l_onoff = 1;
    lingerstruct.l_linger = 5;
    setsockopt(listensd, SOL_SOCKET, SO_LINGER, (void *)&lingerstruct, 
	       sizeof(lingerstruct));

    if ( PC_Struct.send_tcp_keepalives )
    {
	lingerstruct.l_onoff = 1;
	syslog( LOG_INFO, "%s: Enabling SO_KEEPALIVE.", fn );
	setsockopt( listensd, SOL_SOCKET, SO_KEEPALIVE, (void *)&lingerstruct.l_onoff, sizeof lingerstruct.l_onoff );
    }

	    
    if ( bind(listensd, (struct sockaddr *)&srvaddr, sizeof( srvaddr ) ) < 0 )
    {
	syslog(LOG_ERR, "%s: bind() failed: %s", fn, strerror(errno) );
	exit( 1 );
    }

    /*
     * Create and mmap() our stat file while we're still root.  Since it's
     * configurable, we want to make sure we do this as root so there's the
     * greatest possibility that we'll have permission to write where we
     * need to.
     */
    syslog( LOG_INFO, "%s: Using global statistics file '%s'", fn,
	    PC_Struct.stat_filename );
    
    fd = open( PC_Struct.stat_filename, O_RDWR | O_CREAT, S_IREAD | S_IWRITE );
    if ( fd == -1 )
    {
	syslog(LOG_ERR, "%s: open() failed for '%s': %s -- Exiting.", fn, 
	       PC_Struct.stat_filename, strerror( errno ) );
	exit( 1 );
    }
    
    if ( ( ftruncate( fd, sizeof( IMAPCounter_Struct ) ) ) == -1 )
    {
	syslog(LOG_ERR, "%s: ftruncate() failed: %s -- Exiting.", 
	       fn, strerror( errno ) );
	exit( 1 );
    }
    
    IMAPCount = ( IMAPCounter_Struct *)mmap( 0, sizeof( IMAPCounter_Struct ), 
		    PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0 );
    
    if ( IMAPCount == MAP_FAILED )
    {
	syslog(LOG_ERR, "%s: mmap() failed: %s -- Exiting.", 
	       fn, strerror( errno ) );
	exit( 1 );
    }
    
    memset( IMAPCount, 0, sizeof( IMAPCounter_Struct ) );
    IMAPCount->StartTime = time( 0 );
    IMAPCount->CountTime = time( 0 );

    if ( BecomeNonRoot() )
	exit( 1 );

    /* some misc thread setup */
    rc = pthread_attr_init( &attr );
    if ( rc )
    {
	syslog(LOG_ERR, "%s: pthread_attr_init() failed: [%d]\n", fn, rc);
	exit( 1 );
    }
    
    rc = pthread_attr_setdetachstate( &attr, PTHREAD_CREATE_DETACHED );
    if ( rc )
    {
	syslog(LOG_ERR, "%s: pthread_attr_setdetachstate() failed: [%d]\n", 
	       fn, rc);
	exit( 1 );
    }

    /* launch a recycle thread before we loop */
    pthread_create( &RecycleThread, &attr, (void *)ICC_Recycle_Loop, NULL );

    syslog(LOG_INFO, "%s: Launched ICC recycle thread with id %d", 
	   fn, RecycleThread );

    /*
     * Now start listening and accepting connections.
     */
    if ( listen(listensd, MAX_CONN_BACKLOG) < 0)
    {
	syslog( LOG_ERR, "%s: listen() failed: %s -- Exiting", 
	       fn, strerror(errno));
	exit( 1 );
    }

    syslog( LOG_INFO, "%s: Normal server startup.", fn );

    /*
     * Main server loop
     */
    for ( ;; )
    {
	/*
	 * Bug fixed by Gary Mills <*****@*****.**>.  I forgot
	 * to initialize addrlen.
	 */
	addrlen = sizeof cliaddr;
	clientsd = accept( listensd, (struct sockaddr *)&cliaddr, &addrlen );
	if ( clientsd == -1 )
	{
	    syslog(LOG_WARNING, "%s: accept() failed: %s -- retrying", 
		   fn, strerror(errno));
	    sleep( 1 );
	    continue;
	}

#ifdef HAVE_LIBWRAP
	request_init(&r, RQ_DAEMON, service, 0);
	request_set(&r, RQ_FILE, clientsd, 0);
	sock_host(&r);
	if (!hosts_access(&r))
	{
	    shutdown(clientsd, SHUT_RDWR);
	    close(clientsd);
	    syslog(deny_severity, "refused connection from %s", eval_client(&r));
	    continue;
	}
#endif

	IMAPCount->TotalClientConnectionsAccepted++;
	IMAPCount->CurrentClientConnections++;
	
	if ( IMAPCount->CurrentClientConnections > 
	     IMAPCount->PeakClientConnections )
	    IMAPCount->PeakClientConnections = IMAPCount->CurrentClientConnections;
	
	pthread_create( &ThreadId, &attr, (void *)HandleRequest, (void *)clientsd );
	
    }
}
Пример #19
0
int
main(int argc, char **argv)
{
  int i;
  sigset_t set;
#if ENABLE_MPEGTS
  uint32_t adapter_mask = 0;
#endif
  int  log_level   = LOG_INFO;
  int  log_options = TVHLOG_OPT_MILLIS | TVHLOG_OPT_STDERR | TVHLOG_OPT_SYSLOG;
  const char *log_debug = NULL, *log_trace = NULL;
  char buf[512];
  FILE *pidfile = NULL;
  extern int dvb_bouquets_parse;

  main_tid = pthread_self();

  /* Setup global mutexes */
  pthread_mutex_init(&ffmpeg_lock, NULL);
  pthread_mutex_init(&fork_lock, NULL);
  pthread_mutex_init(&global_lock, NULL);
  pthread_mutex_init(&atomic_lock, NULL);
  pthread_cond_init(&gtimer_cond, NULL);

  /* Defaults */
  tvheadend_webui_port      = 9981;
  tvheadend_webroot         = NULL;
  tvheadend_htsp_port       = 9982;
  tvheadend_htsp_port_extra = 0;

  /* Command line options */
  int         opt_help         = 0,
              opt_version      = 0,
              opt_fork         = 0,
              opt_firstrun     = 0,
              opt_stderr       = 0,
              opt_syslog       = 0,
              opt_uidebug      = 0,
              opt_abort        = 0,
              opt_noacl        = 0,
              opt_fileline     = 0,
              opt_threadid     = 0,
              opt_ipv6         = 0,
#if ENABLE_TSFILE
              opt_tsfile_tuner = 0,
#endif
              opt_dump         = 0,
              opt_xspf         = 0,
              opt_dbus         = 0,
              opt_dbus_session = 0,
              opt_nobackup     = 0,
              opt_nobat        = 0;
  const char *opt_config       = NULL,
             *opt_user         = NULL,
             *opt_group        = NULL,
             *opt_logpath      = NULL,
             *opt_log_debug    = NULL,
             *opt_log_trace    = NULL,
             *opt_pidpath      = "/var/run/tvheadend.pid",
#if ENABLE_LINUXDVB
             *opt_dvb_adapters = NULL,
#endif
             *opt_bindaddr     = NULL,
             *opt_subscribe    = NULL,
             *opt_user_agent   = NULL;
  str_list_t  opt_satip_xml    = { .max = 10, .num = 0, .str = calloc(10, sizeof(char*)) };
  str_list_t  opt_tsfile       = { .max = 10, .num = 0, .str = calloc(10, sizeof(char*)) };
  cmdline_opt_t cmdline_opts[] = {
    {   0, NULL,        "Generic Options",         OPT_BOOL, NULL         },
    { 'h', "help",      "Show this page",          OPT_BOOL, &opt_help    },
    { 'v', "version",   "Show version infomation", OPT_BOOL, &opt_version },

    {   0, NULL,        "Service Configuration",   OPT_BOOL, NULL         },
    { 'c', "config",    "Alternate config path",   OPT_STR,  &opt_config  },
    { 'B', "nobackup",  "Do not backup config tree at upgrade", OPT_BOOL, &opt_nobackup },
    { 'f', "fork",      "Fork and run as daemon",  OPT_BOOL, &opt_fork    },
    { 'u', "user",      "Run as user",             OPT_STR,  &opt_user    },
    { 'g', "group",     "Run as group",            OPT_STR,  &opt_group   },
    { 'p', "pid",       "Alternate pid path",      OPT_STR,  &opt_pidpath },
    { 'C', "firstrun",  "If no user account exists then create one with\n"
	                      "no username and no password. Use with care as\n"
	                      "it will allow world-wide administrative access\n"
	                      "to your Tvheadend installation until you edit\n"
	                      "the access-control from within the Tvheadend UI",
      OPT_BOOL, &opt_firstrun },
#if ENABLE_DBUS_1
    { 'U', "dbus",      "Enable DBus",
      OPT_BOOL, &opt_dbus },
    { 'e', "dbus_session", "DBus - use the session message bus instead system one",
      OPT_BOOL, &opt_dbus_session },
#endif
#if ENABLE_LINUXDVB
    { 'a', "adapters",  "Only use specified DVB adapters (comma separated)",
      OPT_STR, &opt_dvb_adapters },
#endif
#if ENABLE_SATIP_CLIENT
    {   0, "satip_xml", "URL with the SAT>IP server XML location",
      OPT_STR_LIST, &opt_satip_xml },
#endif
    {   0, NULL,         "Server Connectivity",    OPT_BOOL, NULL         },
    { '6', "ipv6",       "Listen on IPv6",         OPT_BOOL, &opt_ipv6    },
    { 'b', "bindaddr",   "Specify bind address",   OPT_STR,  &opt_bindaddr},
    {   0, "http_port",  "Specify alternative http port",
      OPT_INT, &tvheadend_webui_port },
    {   0, "http_root",  "Specify alternative http webroot",
      OPT_STR, &tvheadend_webroot },
    {   0, "htsp_port",  "Specify alternative htsp port",
      OPT_INT, &tvheadend_htsp_port },
    {   0, "htsp_port2", "Specify extra htsp port",
      OPT_INT, &tvheadend_htsp_port_extra },
    {   0, "useragent",  "Specify User-Agent header for the http client",
      OPT_STR, &opt_user_agent },
    {   0, "xspf",       "Use xspf playlist instead M3U",
      OPT_BOOL, &opt_xspf },

    {   0, NULL,        "Debug Options",           OPT_BOOL, NULL         },
    { 'd', "stderr",    "Enable debug on stderr",  OPT_BOOL, &opt_stderr  },
    { 's', "syslog",    "Enable debug to syslog",  OPT_BOOL, &opt_syslog  },
    { 'l', "logfile",   "Enable debug to file",    OPT_STR,  &opt_logpath },
    {   0, "debug",     "Enable debug subsystems", OPT_STR,  &opt_log_debug },
#if ENABLE_TRACE
    {   0, "trace",     "Enable trace subsystems", OPT_STR,  &opt_log_trace },
#endif
    {   0, "fileline",  "Add file and line numbers to debug", OPT_BOOL, &opt_fileline },
    {   0, "threadid",  "Add the thread ID to debug", OPT_BOOL, &opt_threadid },
    {   0, "uidebug",   "Enable webUI debug (non-minified JS)", OPT_BOOL, &opt_uidebug },
    { 'A', "abort",     "Immediately abort",       OPT_BOOL, &opt_abort   },
    { 'D', "dump",      "Enable coredumps for daemon", OPT_BOOL, &opt_dump },
    {   0, "noacl",     "Disable all access control checks",
      OPT_BOOL, &opt_noacl },
    {   0, "nobat",     "Disable DVB bouquets",
      OPT_BOOL, &opt_nobat },
    { 'j', "join",      "Subscribe to a service permanently",
      OPT_STR, &opt_subscribe },


#if ENABLE_TSFILE || ENABLE_TSDEBUG
    { 0, NULL, "TODO: testing", OPT_BOOL, NULL },
#if ENABLE_TSFILE
    { 0, "tsfile_tuners", "Number of tsfile tuners", OPT_INT, &opt_tsfile_tuner },
    { 0, "tsfile", "tsfile input (mux file)", OPT_STR_LIST, &opt_tsfile },
#endif
#if ENABLE_TSDEBUG
    { 0, "tsdebug", "Output directory for tsdebug", OPT_STR, &tvheadend_tsdebug },
#endif
#endif

  };

  /* Get current directory */
  tvheadend_cwd = dirname(dirname(tvh_strdupa(argv[0])));

  /* Set locale */
  setlocale(LC_ALL, "");
  setlocale(LC_NUMERIC, "C");

  /* make sure the timezone is set */
  tzset();

  /* Process command line */
  for (i = 1; i < argc; i++) {

    /* Find option */
    cmdline_opt_t *opt
      = cmdline_opt_find(cmdline_opts, ARRAY_SIZE(cmdline_opts), argv[i]);
    if (!opt)
      show_usage(argv[0], cmdline_opts, ARRAY_SIZE(cmdline_opts),
                 "invalid option specified [%s]", argv[i]);

    /* Process */
    if (opt->type == OPT_BOOL)
      *((int*)opt->param) = 1;
    else if (++i == argc)
      show_usage(argv[0], cmdline_opts, ARRAY_SIZE(cmdline_opts),
                 "option %s requires a value", opt->lopt);
    else if (opt->type == OPT_INT)
      *((int*)opt->param) = atoi(argv[i]);
    else if (opt->type == OPT_STR_LIST) {
      str_list_t *strl = opt->param;
      if (strl->num < strl->max)
        strl->str[strl->num++] = argv[i];
    }
    else
      *((char**)opt->param) = argv[i];

    /* Stop processing */
    if (opt_help)
      show_usage(argv[0], cmdline_opts, ARRAY_SIZE(cmdline_opts), NULL);
    if (opt_version)
      show_version(argv[0]);
  }

  /* Additional cmdline processing */
  if (opt_nobat)
    dvb_bouquets_parse = 0;
#if ENABLE_LINUXDVB
  if (!opt_dvb_adapters) {
    adapter_mask = ~0;
  } else {
    char *p, *e;
    char *r = NULL;
    char *dvb_adapters = strdup(opt_dvb_adapters);
    adapter_mask = 0x0;
    p = strtok_r(dvb_adapters, ",", &r);
    while (p) {
      int a = strtol(p, &e, 10);
      if (*e != 0 || a < 0 || a > 31) {
        tvhlog(LOG_ERR, "START", "Invalid adapter number '%s'", p);
        free(dvb_adapters);
        return 1;
      }
      adapter_mask |= (1 << a);
      p = strtok_r(NULL, ",", &r);
    }
    free(dvb_adapters);
    if (!adapter_mask) {
      tvhlog(LOG_ERR, "START", "No adapters specified!");
      return 1;
    }
  }
#endif
  if (tvheadend_webroot) {
    char *tmp;
    if (*tvheadend_webroot == '/')
      tmp = strdup(tvheadend_webroot);
    else {
      tmp = malloc(strlen(tvheadend_webroot)+2);
      *tmp = '/';
      strcpy(tmp+1, tvheadend_webroot);
    }
    if (tmp[strlen(tmp)-1] == '/')
      tmp[strlen(tmp)-1] = '\0';
    tvheadend_webroot = tmp;
  }
  tvheadend_webui_debug = opt_uidebug;

  /* Setup logging */
  if (isatty(2))
    log_options |= TVHLOG_OPT_DECORATE;
  if (opt_stderr || opt_syslog || opt_logpath) {
    if (!opt_log_trace && !opt_log_debug)
      log_debug      = "all";
    log_level      = LOG_DEBUG;
    if (opt_stderr)
      log_options   |= TVHLOG_OPT_DBG_STDERR;
    if (opt_syslog)
      log_options   |= TVHLOG_OPT_DBG_SYSLOG;
    if (opt_logpath)
      log_options   |= TVHLOG_OPT_DBG_FILE;
  }
  if (opt_fileline)
    log_options |= TVHLOG_OPT_FILELINE;
  if (opt_threadid)
    log_options |= TVHLOG_OPT_THREAD;
  if (opt_log_trace) {
    log_level  = LOG_TRACE;
    log_trace  = opt_log_trace;
  }
  if (opt_log_debug)
    log_debug  = opt_log_debug;
    
  tvhlog_init(log_level, log_options, opt_logpath);
  tvhlog_set_debug(log_debug);
  tvhlog_set_trace(log_trace);
  tvhinfo("main", "Log started");
 
  signal(SIGPIPE, handle_sigpipe); // will be redundant later
  signal(SIGILL, handle_sigill);   // see handler..

  tcp_server_preinit(opt_ipv6);
  http_server_init(opt_bindaddr);  // bind to ports only
  htsp_init(opt_bindaddr);	   // bind to ports only

  if (opt_fork)
    pidfile = tvh_fopen(opt_pidpath, "w+");

  /* Set priviledges */
  if(opt_fork || opt_group || opt_user) {
    const char *homedir;
    gid_t gid;
    uid_t uid;
    struct group  *grp = getgrnam(opt_group ?: "video");
    struct passwd *pw  = opt_user ? getpwnam(opt_user) : NULL;

    if(grp != NULL) {
      gid = grp->gr_gid;
    } else {
      gid = 1;
    }

    if (pw != NULL) {
      if (getuid() != pw->pw_uid) {
        gid_t glist[16];
        int gnum;
        gnum = get_user_groups(pw, glist, ARRAY_SIZE(glist));
        if (gnum > 0 && setgroups(gnum, glist)) {
          char buf[256] = "";
          int i;
          for (i = 0; i < gnum; i++)
            snprintf(buf + strlen(buf), sizeof(buf) - 1 - strlen(buf),
                     ",%d", glist[i]);
          tvhlog(LOG_ALERT, "START",
                 "setgroups(%s) failed, do you have permission?", buf+1);
          return 1;
        }
      }
      uid     = pw->pw_uid;
      homedir = pw->pw_dir;
      setenv("HOME", homedir, 1);
    } else {
      uid = 1;
    }
    if ((getgid() != gid) && setgid(gid)) {
      tvhlog(LOG_ALERT, "START",
             "setgid(%d) failed, do you have permission?", gid);
      return 1;
    }
    if ((getuid() != uid) && setuid(uid)) {
      tvhlog(LOG_ALERT, "START",
             "setuid(%d) failed, do you have permission?", uid);
      return 1;
    }
  }

  /* Daemonise */
  if(opt_fork) {
    if(daemon(0, 0)) {
      exit(2);
    }
    if(pidfile != NULL) {
      fprintf(pidfile, "%d\n", getpid());
      fclose(pidfile);
    }

    /* Make dumpable */
    if (opt_dump) {
#ifdef PLATFORM_LINUX
      if (chdir("/tmp"))
        tvhwarn("START", "failed to change cwd to /tmp");
      prctl(PR_SET_DUMPABLE, 1);
#else
      tvhwarn("START", "Coredumps not implemented on your platform");
#endif
    }

    umask(0);
  }

  tvheadend_running = 1;

  /* Start log thread (must be done post fork) */
  tvhlog_start();

  /* Alter logging */
  if (opt_fork)
    tvhlog_options &= ~TVHLOG_OPT_STDERR;
  if (!isatty(2))
    tvhlog_options &= ~TVHLOG_OPT_DECORATE;
  
  /* Initialise clock */
  pthread_mutex_lock(&global_lock);
  time(&dispatch_clock);

  /* Signal handling */
  sigfillset(&set);
  sigprocmask(SIG_BLOCK, &set, NULL);
  trap_init(argv[0]);

  /* SSL library init */
  OPENSSL_config(NULL);
  SSL_load_error_strings();
  SSL_library_init();

  /* Initialise configuration */
  uuid_init();
  idnode_init();
  spawn_init();
  config_init(opt_config, opt_nobackup == 0);

  /**
   * Initialize subsystems
   */

  dbus_server_init(opt_dbus, opt_dbus_session);

  intlconv_init();
  
  api_init();

  fsmonitor_init();

#if ENABLE_LIBAV
  libav_init();
#endif

  profile_init();

  imagecache_init();

  http_client_init(opt_user_agent);
  esfilter_init();

  bouquet_init();

  service_init();

  dvb_init();

#if ENABLE_MPEGTS
  mpegts_init(adapter_mask, &opt_satip_xml, &opt_tsfile, opt_tsfile_tuner);
#endif

  channel_init();

  bouquet_service_resolve();

  subscription_init();

  dvr_config_init();

  access_init(opt_firstrun, opt_noacl);

#if ENABLE_TIMESHIFT
  timeshift_init();
#endif

  tcp_server_init();
  http_server_register();
  webui_init(opt_xspf);
#if ENABLE_UPNP
  upnp_server_init(opt_bindaddr);
#endif

  service_mapper_init();

  descrambler_init();

  epggrab_init();
  epg_init();

  dvr_init();

  dbus_server_start();

  htsp_register();


  if(opt_subscribe != NULL)
    subscription_dummy_join(opt_subscribe, 1);

  avahi_init();
  bonjour_init();

  epg_updated(); // cleanup now all prev ref's should have been created

  pthread_mutex_unlock(&global_lock);

  /**
   * Wait for SIGTERM / SIGINT, but only in this thread
   */

  sigemptyset(&set);
  sigaddset(&set, SIGTERM);
  sigaddset(&set, SIGINT);

  signal(SIGTERM, doexit);
  signal(SIGINT, doexit);

  pthread_sigmask(SIG_UNBLOCK, &set, NULL);

  tvhlog(LOG_NOTICE, "START", "HTS Tvheadend version %s started, "
         "running as PID:%d UID:%d GID:%d, CWD:%s CNF:%s",
         tvheadend_version,
         getpid(), getuid(), getgid(), getcwd(buf, sizeof(buf)),
         hts_settings_get_root());

  if(opt_abort)
    abort();

  mainloop();

#if ENABLE_DBUS_1
  tvhftrace("main", dbus_server_done);
#endif
#if ENABLE_UPNP
  tvhftrace("main", upnp_server_done);
#endif
  tvhftrace("main", htsp_done);
  tvhftrace("main", http_server_done);
  tvhftrace("main", webui_done);
  tvhftrace("main", fsmonitor_done);
#if ENABLE_MPEGTS
  tvhftrace("main", mpegts_done);
#endif
  tvhftrace("main", http_client_done);

  // Note: the locking is obviously a bit redundant, but without
  //       we need to disable the gtimer_arm call in epg_save()
  pthread_mutex_lock(&global_lock);
  tvhftrace("main", epg_save);

#if ENABLE_TIMESHIFT
  tvhftrace("main", timeshift_term);
#endif
  pthread_mutex_unlock(&global_lock);

  tvhftrace("main", epggrab_done);
  tvhftrace("main", tcp_server_done);
  tvhftrace("main", descrambler_done);
  tvhftrace("main", service_mapper_done);
  tvhftrace("main", service_done);
  tvhftrace("main", channel_done);
  tvhftrace("main", bouquet_done);
  tvhftrace("main", dvr_done);
  tvhftrace("main", subscription_done);
  tvhftrace("main", access_done);
  tvhftrace("main", epg_done);
  tvhftrace("main", avahi_done);
  tvhftrace("main", bonjour_done);
  tvhftrace("main", imagecache_done);
  tvhftrace("main", lang_code_done);
  tvhftrace("main", api_done);
  tvhftrace("main", hts_settings_done);
  tvhftrace("main", dvb_done);
  tvhftrace("main", lang_str_done);
  tvhftrace("main", esfilter_done);
  tvhftrace("main", profile_done);
  tvhftrace("main", intlconv_done);
  tvhftrace("main", urlparse_done);
  tvhftrace("main", idnode_done);
  tvhftrace("main", spawn_done);

  tvhlog(LOG_NOTICE, "STOP", "Exiting HTS Tvheadend");
  tvhlog_end();

  tvhftrace("main", config_done);

  if(opt_fork)
    unlink(opt_pidpath);
    
#if ENABLE_TSFILE
  free(opt_tsfile.str);
#endif
  free(opt_satip_xml.str);

  /* OpenSSL - welcome to the "cleanup" hell */
  ENGINE_cleanup();
  RAND_cleanup();
  CRYPTO_cleanup_all_ex_data();
  EVP_cleanup();
  CONF_modules_free();
#ifndef OPENSSL_NO_COMP
  COMP_zlib_cleanup();
#endif
  ERR_remove_state(0);
  ERR_free_strings();
#ifndef OPENSSL_NO_COMP
  sk_SSL_COMP_free(SSL_COMP_get_compression_methods());
#endif
  /* end of OpenSSL cleanup code */

#if ENABLE_DBUS_1
  extern void dbus_shutdown(void);
  if (opt_dbus) dbus_shutdown();
#endif
  return 0;
}

/**
 *
 */
void
tvh_str_set(char **strp, const char *src)
{
  free(*strp);
  *strp = src ? strdup(src) : NULL;
}


/**
 *
 */
int
tvh_str_update(char **strp, const char *src)
{
  if(src == NULL)
    return 0;
  free(*strp);
  *strp = strdup(src);
  return 1;
}


/**
 *
 */
void
scopedunlock(pthread_mutex_t **mtxp)
{
  pthread_mutex_unlock(*mtxp);
}
Пример #20
0
int main ()
{
  int err;
  int sd;
  struct sockaddr_in sa;
  SSL_CTX* ctx;
  SSL*     ssl;
  X509*    server_cert;
  char*    str;
  char     buf [4096];
  SSL_METHOD *meth;

  SSLeay_add_ssl_algorithms();   //设置支持SSL算法
  meth = (SSL_METHOD*)SSLv2_client_method(); //客户端设置SSLV2版本
  SSL_load_error_strings();		//提供将错误解析为字符串的功能
  ctx = SSL_CTX_new (meth);                        CHK_NULL(ctx);  
  //创建一个SSL上下文环境,每个进程守护一个SSL_CTX结构体

  CHK_SSL(err);
  
  /* ----------------------------------------------- */
  /* Create a socket and connect to server using normal socket calls. */
  
  sd = socket (AF_INET, SOCK_STREAM, 0);       CHK_ERR(sd, "socket");  //
 
  memset (&sa, '\0', sizeof(sa));
  sa.sin_family      = AF_INET;
  sa.sin_addr.s_addr = inet_addr ("127.0.0.1");   /* Server IP */
  sa.sin_port        = htons     (1111);          /* Server Port number */
  
  err = connect(sd, (struct sockaddr*) &sa,
		sizeof(sa));                   CHK_ERR(err, "connect");

  /* ----------------------------------------------- */
  /* Now we have TCP conncetion. Start SSL negotiation. */
//创建一个维护当前连接信息
  ssl = SSL_new (ctx);                         CHK_NULL(ssl);    
//将SSL绑定到套接字上
  SSL_set_fd (ssl, sd);
//建立SSL连接
  err = SSL_connect (ssl);                     CHK_SSL(err);
    
  /* Following two steps are optional and not required for
     data exchange to be successful. */
  
  /* Get the cipher - opt */

  printf ("SSL connection using %s\n", SSL_get_cipher (ssl));
  
  /* Get server's certificate (note: beware of dynamic allocation) - opt */
//获取服务端证书
  server_cert = SSL_get_peer_certificate (ssl);       CHK_NULL(server_cert);
  printf ("Server certificate:\n");
  
  str = X509_NAME_oneline (X509_get_subject_name (server_cert),0,0);
  CHK_NULL(str);
  printf ("\t subject: %s\n", str);
  OPENSSL_free (str);

  str = X509_NAME_oneline (X509_get_issuer_name  (server_cert),0,0);
  CHK_NULL(str);
  printf ("\t issuer: %s\n", str);
  OPENSSL_free (str);

  /* We could do all sorts of certificate verification stuff here before
     deallocating the certificate. */
//释放服务端证书
  X509_free (server_cert);
  
  /* --------------------------------------------------- */
  /* DATA EXCHANGE - Send a message and receive a reply. */

  err = SSL_write (ssl, "Hello World!", strlen("Hello World!"));  CHK_SSL(err);
  
  err = SSL_read (ssl, buf, sizeof(buf) - 1);                     CHK_SSL(err);
  buf[err] = '\0';
  printf ("Got %d chars:'%s'\n", err, buf);
  SSL_shutdown (ssl);  /* send SSL/TLS close_notify */

  /* Clean up. */

  close(sd);
  SSL_free (ssl);
  SSL_CTX_free (ctx);
}
Пример #21
0
SSL_Connection *ssl_connect(const char *host, int port, const char *certfile, const char *keyfile, const char *capath) 
{
    int err;

	
    SSL_Connection *sslcon = NULL;
    sslcon = (SSL_Connection *)malloc(sizeof(SSL_Connection));
    if(sslcon == NULL)
    {
        printf("Could not allocate memory for SSL Connection");
        exit(1);
    }

    /* Load encryption & hashing algorithms for the SSL program */
    SSL_library_init();
 
    /* Load the error strings for SSL & CRYPTO APIs */
    SSL_load_error_strings();
 
    /* Create an SSL_METHOD structure (choose an SSL/TLS protocol version) */
    sslcon->meth = SSLv3_method();
 
    /* Create an SSL_CTX structure */
    sslcon->ctx = SSL_CTX_new(sslcon->meth);                        
    if(!sslcon->ctx)
    {
        syslog (LOG_NOTICE,"Could not get SSL Context\n");
        exit(1);
    }

    /* Load the CA from the Path */
    if(SSL_CTX_load_verify_locations(sslcon->ctx,NULL, "./Certs") <= 0)
    {
        /* Handle failed load here */
        syslog (LOG_NOTICE,"ERR Failed to set CA location...\n");
        ERR_print_errors_fp(stderr);
        exit(1);
    }

    /* Load the client certificate into the SSL_CTX structure */
    if (SSL_CTX_use_certificate_file(sslcon->ctx, certfile, SSL_FILETYPE_PEM) <= 0) {
        syslog (LOG_NOTICE,"ERR Cannot use Certificate File %s \n", certfile);
        ERR_print_errors_fp(stderr);
        exit(1);
    }
 
    /* Load the private-key corresponding to the client certificate */
    if (SSL_CTX_use_PrivateKey_file(sslcon->ctx, keyfile, SSL_FILETYPE_PEM) <= 0) {
        syslog (LOG_NOTICE,"ERR Cannot use Private Key %s\n", keyfile);
        ERR_print_errors_fp(stderr);
        exit(1);
    }
 
    /* Check if the client certificate and private-key matches */
    if (!SSL_CTX_check_private_key(sslcon->ctx)) {
        syslog (LOG_NOTICE, "ERR Private key does not match the certificate public key\n");
        exit(1);
    }
 
    /* Set up a TCP socket */
    sslcon->sock = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP);       
    if(sslcon->sock == -1)
    {
        syslog (LOG_NOTICE, "ERR Could not get Socket\n");
        exit(1);
    }
 
    memset (&sslcon->server_addr, '\0', sizeof(sslcon->server_addr));
    sslcon->server_addr.sin_family      = AF_INET;
    sslcon->server_addr.sin_port        = htons(port);       /* Server Port number */
    sslcon->host_info = gethostbyname(host);
    if(sslcon->host_info)
    {
        /* Take the first IP */
        struct in_addr *address = (struct in_addr*)sslcon->host_info->h_addr_list[0];
        sslcon->server_addr.sin_addr.s_addr = inet_addr(inet_ntoa(*address)); /* Server IP */
    }
    else
    {
        syslog (LOG_NOTICE, "Could not resolve hostname %s\n", host);
        return NULL;
    }

    /* Establish a TCP/IP connection to the SSL client */
    err = connect(sslcon->sock, (struct sockaddr*) &sslcon->server_addr, sizeof(sslcon->server_addr)); 
    if(err == -1)
    {
        syslog (LOG_NOTICE, "ERR Could not connect\n");
        exit(1);
    }    

    /* An SSL structure is created */
    sslcon->ssl = SSL_new(sslcon->ctx);
    if(!sslcon->ssl)
    {
        syslog (LOG_NOTICE, "ERR Could not get SSL Socket\n");
        exit(1);
    }    
 
    /* Assign the socket into the SSL structure (SSL and socket without BIO) */
    SSL_set_fd(sslcon->ssl, sslcon->sock);
 
    /* Perform SSL Handshake on the SSL client */
    err = SSL_connect(sslcon->ssl);
    if(err <= 0)
    {
        syslog (LOG_NOTICE, "ERR Could not connect to SSL Server\n");
        exit(1);
    }

    return sslcon;
}
Пример #22
0
int main(int argc, char **argv)
{
    SSL_library_init();
    SSL_load_error_strings();

    BIO * bio_err = BIO_new_fp(stderr, BIO_NOCLOSE);

    /* Set up a SIGPIPE handler */
    signal(SIGPIPE, SIG_IGN);

    /* Create our context*/
    SSL_CTX * ctx = SSL_CTX_new(SSLv23_method());

    /* Load our keys and certificates*/
    if(!(SSL_CTX_use_certificate_chain_file(ctx, "ftests/fixtures/rdpproxy-cert.pem")))
    {
        BIO_printf(bio_err, "Can't read certificate file\n");
        ERR_print_errors(bio_err);
        exit(0);
    }

    SSL_CTX_set_default_passwd_cb(ctx, password_cb0);
    SSL_CTX_set_default_passwd_cb_userdata(ctx, const_cast<char *>("inquisition"));
    if(!(SSL_CTX_use_PrivateKey_file(ctx, "ftests/fixtures/rdpproxy-key.pem", SSL_FILETYPE_PEM)))
    {
        BIO_printf(bio_err,"Can't read key file\n");
        ERR_print_errors(bio_err);
        exit(0);
    }

    DH *ret=nullptr;
    BIO *bio;

    if ((bio=BIO_new_file("ftests/fixtures/dh1024.pem","r")) == nullptr){
        BIO_printf(bio_err,"Couldn't open DH file\n");
        ERR_print_errors(bio_err);
        exit(0);
    }

    ret=PEM_read_bio_DHparams(bio, nullptr, nullptr, nullptr);
    BIO_free(bio);
    if(SSL_CTX_set_tmp_dh(ctx, ret)<0)
    {
        BIO_printf(bio_err,"Couldn't set DH parameters\n");
        ERR_print_errors(bio_err);
        exit(0);
    }


    union
    {
      struct sockaddr s;
      struct sockaddr_storage ss;
      struct sockaddr_in s4;
      struct sockaddr_in6 s6;
    } ucs;
    memset(&ucs, 0, sizeof(ucs));

    int val=1;

    int sock = socket(AF_INET, SOCK_STREAM,0);
    if(sock < 0) {
        fprintf(stderr, "Failed to make socket\n");
        exit(0);
    }

    memset(&ucs.s4, 0, sizeof(ucs));
    ucs.s4.sin_addr.s_addr = INADDR_ANY;
    ucs.s4.sin_family = AF_INET;
    ucs.s4.sin_port = htons(4433);
    setsockopt(sock,SOL_SOCKET,SO_REUSEADDR, &val,sizeof(val));

    int bind_res = bind(sock,&ucs.s,  sizeof(ucs));
    if(bind_res < 0){
        fprintf(stderr, "Failed to bind\n");
        exit(0);
    }
    listen(sock,5);

    while(1){
      int s = accept(sock,nullptr,nullptr);
      if(s < 0){
        fprintf(stderr,"Problem accepting\n");
        exit(0);
      }

     pid_t pid = fork();

     if(pid){
       close(s);
     }
     else {
        rdp_serve(ctx, s, bio_err);
        exit(0);
      }
    }
    SSL_CTX_free(ctx);
    exit(0);
  }
Пример #23
0
int main(int argc, char **argv){
        u_int32_t packet_crc32;
        u_int32_t calculated_crc32;
	int16_t result;
	int rc;
	packet send_packet;
	packet receive_packet;
	int bytes_to_send;
	int bytes_to_recv;

	result=process_arguments(argc,argv);

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

		if(result!=OK)
			printf("Incorrect command line arguments supplied\n");
                printf("\n");
		printf("NRPE Plugin for Nagios\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
		printf("\n");
	        }

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

		printf("Usage: check_nrpe -H <host> [-n] [-u] [-p <port>] [-t <timeout>] [-c <command>] [-a <arglist...>]\n");
		printf("\n");
		printf("Options:\n");
		printf(" -n         = Do no use SSL\n");
		printf(" -u         = Make socket timeouts return an UNKNOWN state instead of CRITICAL\n");
		printf(" <host>     = The address of the host running the NRPE daemon\n");
		printf(" [port]     = The port on which the daemon is running (default=%d)\n",DEFAULT_SERVER_PORT);
		printf(" [timeout]  = Number of seconds before connection times out (default=%d)\n",DEFAULT_SOCKET_TIMEOUT);
		printf(" [command]  = The name of the command that the remote daemon should run\n");
		printf(" [arglist]  = Optional arguments that should be passed to the command.  Multiple\n");
		printf("              arguments should be separated by a space.  If provided, this must be\n");
		printf("              the last option supplied on the command line.\n");
		printf("\n");
		printf("Note:\n");
		printf("This plugin requires that you have the NRPE daemon running on the remote host.\n");
		printf("You must also have configured the daemon to associate a specific plugin command\n");
		printf("with the [command] option you are specifying here.  Upon receipt of the\n");
		printf("[command] argument, the NRPE daemon will run the appropriate plugin command and\n");
		printf("send the plugin output and return code back to *this* plugin.  This allows you\n");
		printf("to execute plugins on remote hosts and 'fake' the results to make Nagios think\n");
		printf("the plugin is being run locally.\n");
		printf("\n");
	        }

	if(show_license==TRUE)
		display_license();

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


        /* 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_client_method();
		SSL_load_error_strings();
		if((ctx=SSL_CTX_new(meth))==NULL){
			printf("CHECK_NRPE: 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);
                }
#endif

	/* initialize alarm signal handling */
	signal(SIGALRM,alarm_handler);

	/* set socket timeout */
	alarm(socket_timeout);

	/* try to connect to the host at the given port number */
	result=my_tcp_connect(server_name,server_port,&sd);

#ifdef HAVE_SSL
	/* do SSL handshake */
	if(result==STATE_OK && use_ssl==TRUE){
		if((ssl=SSL_new(ctx))!=NULL){
			SSL_CTX_set_cipher_list(ctx,"ADH");
			SSL_set_fd(ssl,sd);
			if((rc=SSL_connect(ssl))!=1){
				printf("CHECK_NRPE: Error - Could not complete SSL handshake.\n");
#ifdef DEBUG
				printf("SSL_connect=%d\n",rc);
				/*
				rc=SSL_get_error(ssl,rc);
				printf("SSL_get_error=%d\n",rc);
				printf("ERR_get_error=%lu\n",ERR_get_error());
				printf("%s\n",ERR_error_string(rc,NULL));
				*/
				ERR_print_errors_fp(stdout);
#endif
				result=STATE_CRITICAL;
			        }
		        }
		else{
			printf("CHECK_NRPE: Error - Could not create SSL connection structure.\n");
			result=STATE_CRITICAL;
		        }

		/* bail if we had errors */
		if(result!=STATE_OK){
			SSL_CTX_free(ctx);
			close(sd);
			exit(result);
		        }
	        }
#endif

	/* we're connected and ready to go */
	if(result==STATE_OK){

		/* clear the packet buffer */
		bzero(&send_packet,sizeof(send_packet));

		/* fill the packet with semi-random data */
		randomize_buffer((char *)&send_packet,sizeof(send_packet));

		/* initialize packet data */
		send_packet.packet_version=(int16_t)htons(NRPE_PACKET_VERSION_2);
		send_packet.packet_type=(int16_t)htons(QUERY_PACKET);
		strncpy(&send_packet.buffer[0],query,MAX_PACKETBUFFER_LENGTH);
		send_packet.buffer[MAX_PACKETBUFFER_LENGTH-1]='\x0';

		/* calculate the crc 32 value of the packet */
		send_packet.crc32_value=(u_int32_t)0L;
		calculated_crc32=calculate_crc32((char *)&send_packet,sizeof(send_packet));
		send_packet.crc32_value=(u_int32_t)htonl(calculated_crc32);


		/***** ENCRYPT REQUEST *****/


		/* send the packet */
		bytes_to_send=sizeof(send_packet);
		if(use_ssl==FALSE)
			rc=sendall(sd,(char *)&send_packet,&bytes_to_send);
#ifdef HAVE_SSL
		else{
			rc=SSL_write(ssl,&send_packet,bytes_to_send);
			if(rc<0)
				rc=-1;
		        }
#endif
		if(rc==-1){
			printf("CHECK_NRPE: Error sending query to host.\n");
			close(sd);
			return STATE_UNKNOWN;
		        }

		/* wait for the response packet */
		bytes_to_recv=sizeof(receive_packet);
		if(use_ssl==FALSE)
			rc=recvall(sd,(char *)&receive_packet,&bytes_to_recv,socket_timeout);
#ifdef HAVE_SSL
		else
			rc=SSL_read(ssl,&receive_packet,bytes_to_recv);
#endif

		/* reset timeout */
		alarm(0);

		/* close the connection */
#ifdef HAVE_SSL
		if(use_ssl==TRUE){
			SSL_shutdown(ssl);
			SSL_free(ssl);
			SSL_CTX_free(ctx);
	                }
#endif
		graceful_close(sd,1000);

		/* recv() error */
		if(rc<0){
			printf("CHECK_NRPE: Error receiving data from daemon.\n");
			return STATE_UNKNOWN;
		        }

		/* server disconnected */
		else if(rc==0){
			printf("CHECK_NRPE: Received 0 bytes from daemon.  Check the remote server logs for error messages.\n");
			return STATE_UNKNOWN;
		        }

		/* receive underflow */
		else if(bytes_to_recv<sizeof(receive_packet)){
			printf("CHECK_NRPE: Receive underflow - only %d bytes received (%d expected).\n",bytes_to_recv,sizeof(receive_packet));
			return STATE_UNKNOWN;
		        }

		
		/***** DECRYPT RESPONSE *****/


		/* check the crc 32 value */
		packet_crc32=ntohl(receive_packet.crc32_value);
		receive_packet.crc32_value=0L;
		calculated_crc32=calculate_crc32((char *)&receive_packet,sizeof(receive_packet));
		if(packet_crc32!=calculated_crc32){
			printf("CHECK_NRPE: Response packet had invalid CRC32.\n");
			close(sd);
			return STATE_UNKNOWN;
                        }
	
		/* check packet version */
		if(ntohs(receive_packet.packet_version)!=NRPE_PACKET_VERSION_2){
			printf("CHECK_NRPE: Invalid packet version received from server.\n");
			close(sd);
			return STATE_UNKNOWN;
			}

		/* check packet type */
		if(ntohs(receive_packet.packet_type)!=RESPONSE_PACKET){
			printf("CHECK_NRPE: Invalid packet type received from server.\n");
			close(sd);
			return STATE_UNKNOWN;
			}

		/* get the return code from the remote plugin */
		result=(int16_t)ntohs(receive_packet.result_code);

		/* print the output returned by the daemon */
		receive_packet.buffer[MAX_PACKETBUFFER_LENGTH-1]='\x0';
		if(!strcmp(receive_packet.buffer,""))
			printf("CHECK_NRPE: No output returned from daemon.\n");
		else
			printf("%s\n",receive_packet.buffer);
	        }

	/* reset the alarm */
	else
		alarm(0);

	return result;
        }
Пример #24
0
int main(){
  int len = 1024; //buffer length
  char buf[len]; //read buffer
  
  /* Initializing OpenSSL */
  SSL_load_error_strings();
  ERR_load_BIO_strings();
  OpenSSL_add_all_algorithms();
  SSL_library_init();

  BIO *bio, *abio, *out; //the sockets
  SSL_CTX *ctx = SSL_CTX_new(SSLv23_server_method());
  SSL *ssl;

  if( ctx == NULL ){
    fprintf(stderr, "DEBUG ctx is null\n");
    fprintf(stderr, "ERROR::OpenSLL: %s\n", ERR_reason_error_string(ERR_get_error()));
    exit(1);
  }
  
  //get password for private key
  //  SSL_CTX_set_default_passwd_cb( ctx, &pem_passwd_cb );

  //load certificate (with public key)
  SSL_CTX_use_certificate_file( ctx, "/home/mml/Develop/ca/certs/01.pem", SSL_FILETYPE_PEM);
  //load private key
  SSL_CTX_use_PrivateKey_file( ctx, "/home/mml/Develop/ca/testkey.pem", SSL_FILETYPE_PEM);

  bio = BIO_new_ssl(ctx, 0);
  if( bio == NULL ){
    fprintf(stderr, "ERROR cannot bind\n");
    exit(1);
  }

  BIO_get_ssl(bio, &ssl);
  SSL_set_mode( ssl, SSL_MODE_AUTO_RETRY );

  abio = BIO_new_accept("localhost:15001");
  BIO_set_accept_bios(abio, bio);

  BIO_do_accept(abio);

  fprintf(stdout, "DEBUG: waiting for connection\n");
  BIO_do_accept(abio);

  out = BIO_pop(abio);

  fprintf(stdout, "DEBUG: doing handshake\n");
  BIO_do_handshake(out);
  
  if(BIO_write(out, "Hello", 5) <= 0){
    if(! BIO_should_retry(bio)) {
      fprintf(stderr, "ERROR connection is already closed. (write)\n");
      exit(1);
    } else {
      //retry routine
    }
  }
  
  bzero(buf, len); 
  if( BIO_read(out, buf, len) <= 0 ){
    if( !(BIO_should_retry(bio)) ){
      fprintf(stderr, "ERROR connection is already closed (read)\n");
      exit(0);
      
    } else {
      //retry routine
    }
  }

  fprintf(stdout, "Hello%s\n", buf);

  //close connection
  BIO_free_all(abio);
  BIO_free_all(out);
  BIO_free_all(bio);
  SSL_CTX_free(ctx);
  
  return 0;
}
Пример #25
0
int
rb_init_ssl(void)
{
	int ret = 1;
	char librb_data[] = "librb data";
	const char librb_ciphers[] = "kEECDH+HIGH:kEDH+HIGH:HIGH:!RC4:!aNULL";
	SSL_load_error_strings();
	SSL_library_init();
	librb_index = SSL_get_ex_new_index(0, librb_data, NULL, NULL, NULL);

#ifndef LRB_HAVE_TLS_METHOD_API
	ssl_server_ctx = SSL_CTX_new(SSLv23_server_method());
#else
	ssl_server_ctx = SSL_CTX_new(TLS_server_method());
#endif

	if(ssl_server_ctx == NULL)
	{
		rb_lib_log("rb_init_openssl: Unable to initialize OpenSSL server context: %s",
			   get_ssl_error(ERR_get_error()));
		ret = 0;
	}

	long server_options = SSL_CTX_get_options(ssl_server_ctx);

#ifndef LRB_HAVE_TLS_METHOD_API
	server_options |= SSL_OP_NO_SSLv2;
	server_options |= SSL_OP_NO_SSLv3;
#endif

#ifdef SSL_OP_SINGLE_DH_USE
	server_options |= SSL_OP_SINGLE_DH_USE;
#endif

#ifdef SSL_OP_SINGLE_ECDH_USE
	server_options |= SSL_OP_SINGLE_ECDH_USE;
#endif

#ifdef SSL_OP_NO_TICKET
	server_options |= SSL_OP_NO_TICKET;
#endif

	server_options |= SSL_OP_CIPHER_SERVER_PREFERENCE;

	SSL_CTX_set_options(ssl_server_ctx, server_options);
	SSL_CTX_set_verify(ssl_server_ctx, SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE, verify_accept_all_cb);
	SSL_CTX_set_session_cache_mode(ssl_server_ctx, SSL_SESS_CACHE_OFF);
	SSL_CTX_set_cipher_list(ssl_server_ctx, librb_ciphers);

	/* Set ECDHE on OpenSSL 1.00+, but make sure it's actually available
	 * (it's not by default on Solaris or Red Hat... f**k Red Hat and Oracle)
	 */
	#if (OPENSSL_VERSION_NUMBER >= 0x10000000L) && !defined(OPENSSL_NO_ECDH)
		EC_KEY *key = EC_KEY_new_by_curve_name(NID_secp384r1);
		if (key) {
			SSL_CTX_set_tmp_ecdh(ssl_server_ctx, key);
			EC_KEY_free(key);
		}
	#endif

#ifndef LRB_HAVE_TLS_METHOD_API
	ssl_client_ctx = SSL_CTX_new(SSLv23_client_method());
#else
	ssl_client_ctx = SSL_CTX_new(TLS_client_method());
#endif

	if(ssl_client_ctx == NULL)
	{
		rb_lib_log("rb_init_openssl: Unable to initialize OpenSSL client context: %s",
			   get_ssl_error(ERR_get_error()));
		ret = 0;
	}

#ifndef LRB_HAVE_TLS_METHOD_API
	SSL_CTX_set_options(ssl_client_ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3);
#endif

#ifdef SSL_OP_NO_TICKET
	SSL_CTX_set_options(ssl_client_ctx, SSL_OP_NO_TICKET);
#endif

	SSL_CTX_set_cipher_list(ssl_client_ctx, librb_ciphers);

	return ret;
}
Пример #26
0
int MAIN(int argc, char **argv)
	{
	double totalTime = 0.0;
	int nConn = 0;
	SSL *scon=NULL;
	long finishtime=0;
	int ret=1,i;
	MS_STATIC char buf[1024*8];
	int ver;

	apps_startup();
	s_time_init();

	if (bio_err == NULL)
		bio_err=BIO_new_fp(stderr,BIO_NOCLOSE);

	s_time_meth=SSLv23_client_method();

	/* parse the command line arguments */
	if( parseArgs( argc, argv ) < 0 )
		goto end;

	OpenSSL_add_ssl_algorithms();
	if ((tm_ctx=SSL_CTX_new(s_time_meth)) == NULL) return(1);

	SSL_CTX_set_quiet_shutdown(tm_ctx,1);

	if (st_bugs) SSL_CTX_set_options(tm_ctx,SSL_OP_ALL);
	SSL_CTX_set_cipher_list(tm_ctx,tm_cipher);
	if(!set_cert_stuff(tm_ctx,t_cert_file,t_key_file)) 
		goto end;

	SSL_load_error_strings();

	if ((!SSL_CTX_load_verify_locations(tm_ctx,CAfile,CApath)) ||
		(!SSL_CTX_set_default_verify_paths(tm_ctx)))
		{
		/* BIO_printf(bio_err,"error setting default verify locations\n"); */
		ERR_print_errors(bio_err);
		/* goto end; */
		}

	if (tm_cipher == NULL)
		tm_cipher = getenv("SSL_CIPHER");

	if (tm_cipher == NULL ) {
		fprintf( stderr, "No CIPHER specified\n" );
	}

	if (!(perform & 1)) goto next;
	printf( "Collecting connection statistics for %d seconds\n", maxTime );

	/* Loop and time how long it takes to make connections */

	bytes_read=0;
	finishtime=(long)time(NULL)+maxTime;
	tm_Time_F(START);
	for (;;)
		{
		if (finishtime < (long)time(NULL)) break;
#ifdef WIN32_STUFF

		if( flushWinMsgs(0) == -1 )
			goto end;

		if( waitingToDie || exitNow )		/* we're dead */
			goto end;
#endif

		if( (scon = doConnection( NULL )) == NULL )
			goto end;

		if (s_www_path != NULL)
			{
			BIO_snprintf(buf,sizeof buf,"GET %s HTTP/1.0\r\n\r\n",s_www_path);
			SSL_write(scon,buf,strlen(buf));
			while ((i=SSL_read(scon,buf,sizeof(buf))) > 0)
				bytes_read+=i;
			}

#ifdef NO_SHUTDOWN
		SSL_set_shutdown(scon,SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN);
#else
		SSL_shutdown(scon);
#endif
		SHUTDOWN2(SSL_get_fd(scon));

		nConn += 1;
		if (SSL_session_reused(scon))
			ver='r';
		else
			{
			ver=SSL_version(scon);
			if (ver == TLS1_VERSION)
				ver='t';
			else if (ver == SSL3_VERSION)
				ver='3';
			else if (ver == SSL2_VERSION)
				ver='2';
			else
				ver='*';
			}
		fputc(ver,stdout);
		fflush(stdout);

		SSL_free( scon );
		scon=NULL;
		}
	totalTime += tm_Time_F(STOP); /* Add the time for this iteration */

	i=(int)((long)time(NULL)-finishtime+maxTime);
	printf( "\n\n%d connections in %.2fs; %.2f connections/user sec, bytes read %ld\n", nConn, totalTime, ((double)nConn/totalTime),bytes_read);
	printf( "%d connections in %ld real seconds, %ld bytes read per connection\n",nConn,(long)time(NULL)-finishtime+maxTime,bytes_read/nConn);

	/* Now loop and time connections using the same session id over and over */

next:
	if (!(perform & 2)) goto end;
	printf( "\n\nNow timing with session id reuse.\n" );

	/* Get an SSL object so we can reuse the session id */
	if( (scon = doConnection( NULL )) == NULL )
		{
		fprintf( stderr, "Unable to get connection\n" );
		goto end;
		}

	if (s_www_path != NULL)
		{
		BIO_snprintf(buf,sizeof buf,"GET %s HTTP/1.0\r\n\r\n",s_www_path);
		SSL_write(scon,buf,strlen(buf));
		while (SSL_read(scon,buf,sizeof(buf)) > 0)
			;
		}
#ifdef NO_SHUTDOWN
	SSL_set_shutdown(scon,SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN);
#else
	SSL_shutdown(scon);
#endif
	SHUTDOWN2(SSL_get_fd(scon));

	nConn = 0;
	totalTime = 0.0;

	finishtime=(long)time(NULL)+maxTime;

	printf( "starting\n" );
	bytes_read=0;
	tm_Time_F(START);
		
	for (;;)
		{
		if (finishtime < (long)time(NULL)) break;

#ifdef WIN32_STUFF
		if( flushWinMsgs(0) == -1 )
			goto end;

		if( waitingToDie || exitNow )	/* we're dead */
			goto end;
#endif

	 	if( (doConnection( scon )) == NULL )
			goto end;

		if (s_www_path)
			{
			BIO_snprintf(buf,sizeof buf,"GET %s HTTP/1.0\r\n\r\n",s_www_path);
			SSL_write(scon,buf,strlen(buf));
			while ((i=SSL_read(scon,buf,sizeof(buf))) > 0)
				bytes_read+=i;
			}

#ifdef NO_SHUTDOWN
		SSL_set_shutdown(scon,SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN);
#else
		SSL_shutdown(scon);
#endif
		SHUTDOWN2(SSL_get_fd(scon));
	
		nConn += 1;
		if (SSL_session_reused(scon))
			ver='r';
		else
			{
			ver=SSL_version(scon);
			if (ver == TLS1_VERSION)
				ver='t';
			else if (ver == SSL3_VERSION)
				ver='3';
			else if (ver == SSL2_VERSION)
				ver='2';
			else
				ver='*';
			}
		fputc(ver,stdout);
		fflush(stdout);
		}
	totalTime += tm_Time_F(STOP); /* Add the time for this iteration*/


	printf( "\n\n%d connections in %.2fs; %.2f connections/user sec, bytes read %ld\n", nConn, totalTime, ((double)nConn/totalTime),bytes_read);
	printf( "%d connections in %ld real seconds, %ld bytes read per connection\n",nConn,(long)time(NULL)-finishtime+maxTime,bytes_read/nConn);

	ret=0;
end:
	if (scon != NULL) SSL_free(scon);

	if (tm_ctx != NULL)
		{
		SSL_CTX_free(tm_ctx);
		tm_ctx=NULL;
		}
	apps_shutdown();
	OPENSSL_EXIT(ret);
	}
Пример #27
0
void
libwebsock_bind_ssl_real(libwebsock_context *ctx, char *listen_host, char *port, char *keyfile, char *certfile,
                         char *chainfile)
{
    struct addrinfo hints, *servinfo, *p;
    struct event *listener_event;
    libwebsock_ssl_event_data *evdata;
    int sockfd, yes = 1;
    SSL_CTX *ssl_ctx;
    
    evdata = (libwebsock_ssl_event_data *) lws_calloc(sizeof(libwebsock_ssl_event_data));
    
    if (!ctx->ssl_init) {
        SSL_library_init();
        SSL_load_error_strings();
        OpenSSL_add_all_algorithms();
        ctx->ssl_init = 1;
    }
    
    ssl_ctx = SSL_CTX_new(SSLv23_server_method());
    if (!ssl_ctx) {
        ERR_print_errors_fp(stderr);
        exit(1);
    }
    if (chainfile != NULL) {
        if (SSL_CTX_load_verify_locations(ssl_ctx, chainfile, NULL) <= 0) {
            ERR_print_errors_fp(stderr);
            exit(1);
        }
    }
    if (SSL_CTX_use_certificate_file(ssl_ctx, certfile, SSL_FILETYPE_PEM) <= 0) {
        ERR_print_errors_fp(stderr);
        exit(1);
    }
    if (SSL_CTX_use_PrivateKey_file(ssl_ctx, keyfile, SSL_FILETYPE_PEM) <= 0) {
        ERR_print_errors_fp(stderr);
        exit(1);
    }
    
    if (!SSL_CTX_check_private_key(ssl_ctx)) {
        fprintf(stderr, "Private key does not match the certificate public key.\n");
        exit(1);
    }
    memset(&hints, 0, sizeof(struct addrinfo));
    
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_flags = AI_PASSIVE;
    if ((getaddrinfo(listen_host, port, &hints, &servinfo)) != 0) {
        fprintf(stderr, "getaddrinfo failed during libwebsock_bind.\n");
        lws_free(ctx);
        exit(-1);
    }
    for (p = servinfo; p != NULL; p = p->ai_next) {
        if ((sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1) {
            perror("socket");
            continue;
        }
        if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) {
            perror("setsockopt");
            lws_free(ctx);
            exit(-1);
        }
        if (bind(sockfd, p->ai_addr, p->ai_addrlen) == -1) {
            perror("bind");
            close(sockfd);
            continue;
        }
        break;
    }
    
    if (p == NULL) {
        fprintf(stderr, "Failed to bind to address and port.  Exiting.\n");
        lws_free(ctx);
        exit(-1);
    }
    
    freeaddrinfo(servinfo);
    
    if (listen(sockfd, LISTEN_BACKLOG) == -1) {
        perror("listen");
        exit(-1);
    }
    evdata->ssl_ctx = ssl_ctx;
    evdata->ctx = ctx;
    
    listener_event = event_new(ctx->base, sockfd, EV_READ | EV_PERSIST, libwebsock_handle_accept_ssl, (void *) evdata);
    event_add(listener_event, NULL);
}
Пример #28
0
/**
 * @fn tnet_startup
 * This is probably the most important function. You MUST call this function to initialize the network stack before calling any <b>tnet_*</b> function. 
 *			You MUST call @ref tnet_cleanup to cleanup the network stack.
 *
 * @sa @ref tnet_cleanup.
 * @return	Zero if succeed and error code otherwise. 
**/
int tnet_startup()
{
	int err = 0;
	short word = 0x4321;

	if(__tnet_started){
		goto bail;
	}

	// rand()
	srand((unsigned int) tsk_time_epoch());

	// endianness
	tnet_isBigEndian = ((*(int8_t *)&word) != 0x21);
#if TNET_UNDER_WINDOWS
	if(tnet_isBigEndian){
		TSK_DEBUG_ERROR("Big endian on Windows machine. Is it right?");
	}
#endif

#if TNET_UNDER_WINDOWS
	{
		WORD wVersionRequested;
		WSADATA wsaData;

		wVersionRequested = MAKEWORD(2, 2);

		err = WSAStartup(wVersionRequested, &wsaData);
		if (err != 0) {
			fprintf(stderr, "WSAStartup failed with error: %d\n", err);
			return -1;
		}

		if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2){
			fprintf(stderr, "Could not find a usable version of Winsock.dll\n");
			tnet_cleanup();
			return -2;
		}
		else{
			fprintf(stdout, "The Winsock 2.2 dll was found okay\n");
		}
	}
#endif /* TNET_UNDER_WINDOWS */

#if HAVE_OPENSSL
	//fprintf(stdout, "SSL is enabled :)\n");
	SSL_library_init();
	OpenSSL_add_all_algorithms();
	SSL_load_error_strings();

	//fprintf(stdout, "DTLS supported: %s\n", tnet_dtls_is_supported() ? "yes" : "no");
	//fprintf(stdout, "DTLS-SRTP supported: %s\n", tnet_dtls_is_srtp_supported() ? "yes" : "no");
#else
	//fprintf(stderr, "SSL is disabled :(\n");
#endif
	
	__tnet_started = tsk_true;

bail:
	return err;
}
Пример #29
0
int SSLTEST()
{
    SSL *ssl;
    SSL_CTX *ctx;
    BIO *bio;
    int x;
    int size=0;
  unsigned char  SendPack[1024];
  memset(SendPack,0x00,1024);
 USHORT ret= usReadFileData(SendFile,&size,&SendPack);
  if(ret!=d_OK) return ret;
   // char *request = "GET / HTTP/1.1\r\nHost: www.verisign.com\r\nConnection: Close\r\n\r\n";
    char buf[1024];
    /* Initializing OpenSSL */
    SSL_load_error_strings();
    ERR_load_BIO_strings();
    OpenSSL_add_all_algorithms();
    /* create and set up SSL context */
    ctx = SSL_CTX_new(TLSv1_client_method());
    /* load trust store */

    /* create and set up connect */
    bio = BIO_new_ssl_connect(ctx);
    /* set SSL_MODE_AUTO_RETRY flag */
    BIO_get_ssl(bio, &ssl);
    SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY);
    /* Attempt to connect */
    BIO_set_conn_hostname(bio,  "192.168.2.4:7010");
    /* Verify the connection opened and perform the handshake */
    if(BIO_do_connect(bio) <= 0)
    {
        printf("connect error.\n");
        SSL_CTX_free(ctx);
        BIO_free_all(bio);
        return -1;
    }
    /* check cert */
    if(SSL_get_verify_result(ssl) != X509_V_OK)
    {
        printf("cert is not match.\n");
        SSL_CTX_free(ctx);
        BIO_free_all(bio);
        return -1;
    }

    /* send request */
    BIO_write(bio, SendPack, strlen(size));
 
    /* read the response */
    for (;;)
    {
        x = BIO_read(bio, buf, strlen(buf)-1);
        if (x <= 0)
         break;
        buf[x] = 0;
        printf("%s\n", buf);
    }
    BIO_free_all(bio);
    SSL_CTX_free(ctx);
    return 0;
}
Пример #30
-1
int main(int argc, char *argv[])
	{
	char *CApath=NULL,*CAfile=NULL;
	int badop=0;
	int ret=1;
	int client_auth=0;
	int server_auth=0;
	SSL_CTX *s_ctx=NULL;
	SSL_CTX *c_ctx=NULL;
	char *scert=TEST_SERVER_CERT;
	char *ccert=TEST_CLIENT_CERT;
	SSL_METHOD *ssl_method=SSLv23_method();

	RAND_seed(rnd_seed, sizeof rnd_seed);

	if (bio_err == NULL)
		bio_err=BIO_new_fp(stderr,BIO_NOCLOSE);
	if (bio_stdout == NULL)
		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,"-reconnect") == 0)
			reconnect=1;
		else if	(strcmp(*argv,"-stats") == 0)
			cache_stats=1;
		else if	(strcmp(*argv,"-ssl3") == 0)
			ssl_method=SSLv3_method();
		else if	(strcmp(*argv,"-ssl2") == 0)
			ssl_method=SSLv2_method();
		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,"-cert") == 0)
			{
			if (--argc < 1) goto bad;
			scert= *(++argv);
			}
		else if	(strcmp(*argv,"-ccert") == 0)
			{
			if (--argc < 1) goto bad;
			ccert= *(++argv);
			}
		else if	(strcmp(*argv,"-threads") == 0)
			{
			if (--argc < 1) goto bad;
			thread_number= atoi(*(++argv));
			if (thread_number == 0) thread_number=1;
			if (thread_number > MAX_THREAD_NUMBER)
				thread_number=MAX_THREAD_NUMBER;
			}
		else if	(strcmp(*argv,"-loops") == 0)
			{
			if (--argc < 1) goto bad;
			number_of_loops= atoi(*(++argv));
			if (number_of_loops == 0) number_of_loops=1;
			}
		else
			{
			fprintf(stderr,"unknown option %s\n",*argv);
			badop=1;
			break;
			}
		argc--;
		argv++;
		}
	if (badop)
		{
bad:
		sv_usage();
		goto end;
		}

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

	SSL_load_error_strings();
	OpenSSL_add_ssl_algorithms();

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

	SSL_CTX_set_session_cache_mode(s_ctx,
		SSL_SESS_CACHE_NO_AUTO_CLEAR|SSL_SESS_CACHE_SERVER);
	SSL_CTX_set_session_cache_mode(c_ctx,
		SSL_SESS_CACHE_NO_AUTO_CLEAR|SSL_SESS_CACHE_SERVER);

	if (!SSL_CTX_use_certificate_file(s_ctx,scert,SSL_FILETYPE_PEM))
		{
		ERR_print_errors(bio_err);
		}
	else if (!SSL_CTX_use_RSAPrivateKey_file(s_ctx,scert,SSL_FILETYPE_PEM))
		{
		ERR_print_errors(bio_err);
		goto end;
		}

	if (client_auth)
		{
		SSL_CTX_use_certificate_file(c_ctx,ccert,
			SSL_FILETYPE_PEM);
		SSL_CTX_use_RSAPrivateKey_file(c_ctx,ccert,
			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)
		{
		fprintf(stderr,"client authentication\n");
		SSL_CTX_set_verify(s_ctx,
			SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
			verify_callback);
		}
	if (server_auth)
		{
		fprintf(stderr,"server authentication\n");
		SSL_CTX_set_verify(c_ctx,SSL_VERIFY_PEER,
			verify_callback);
		}

	thread_setup();
	do_threads(s_ctx,c_ctx);
	thread_cleanup();
end:
	
	if (c_ctx != NULL) 
		{
		fprintf(stderr,"Client SSL_CTX stats then free it\n");
		print_stats(stderr,c_ctx);
		SSL_CTX_free(c_ctx);
		}
	if (s_ctx != NULL)
		{
		fprintf(stderr,"Server SSL_CTX stats then free it\n");
		print_stats(stderr,s_ctx);
		if (cache_stats)
			{
			fprintf(stderr,"-----\n");
			lh_stats(SSL_CTX_sessions(s_ctx),stderr);
			fprintf(stderr,"-----\n");
		/*	lh_node_stats(SSL_CTX_sessions(s_ctx),stderr);
			fprintf(stderr,"-----\n"); */
			lh_node_usage_stats(SSL_CTX_sessions(s_ctx),stderr);
			fprintf(stderr,"-----\n");
			}
		SSL_CTX_free(s_ctx);
		fprintf(stderr,"done free\n");
		}
	exit(ret);
	return(0);
	}