Esempio n. 1
0
/*
 *	Attach the EAP-TLS module.
 */
static int eaptls_attach(CONF_SECTION *cs, void **instance)
{
	EAP_TLS_CONF	 *conf;
	eap_tls_t 	 *inst;

	/* Store all these values in the data structure for later references */
	inst = (eap_tls_t *)malloc(sizeof(*inst));
	if (!inst) {
		radlog(L_ERR, "rlm_eap_tls: out of memory");
		return -1;
	}
	memset(inst, 0, sizeof(*inst));

	/*
	 *	Parse the config file & get all the configured values
	 */
	conf = (EAP_TLS_CONF *)malloc(sizeof(*conf));
	if (conf == NULL) {
		radlog(L_ERR, "rlm_eap_tls: out of memory");
		return -1;
	}
	memset(conf, 0, sizeof(*conf));

	inst->conf = conf;
	if (cf_section_parse(cs, conf, module_config) < 0) {
		eaptls_detach(inst);
		return -1;
	}


	/*
	 *	Initialize TLS
	 */
	inst->ctx = init_tls_ctx(conf);
	if (inst->ctx == NULL) {
		eaptls_detach(inst);
		return -1;
	}

	if (load_dh_params(inst->ctx, conf->dh_file) < 0) {
		eaptls_detach(inst);
		return -1;
	}
	if (generate_eph_rsa_key(inst->ctx) < 0) {
		eaptls_detach(inst);
		return -1;
	}

	*instance = inst;

	return 0;
}
/*
 *	Attach the EAP-TLS module.
 */
static int eaptls_attach(CONF_SECTION *cs, void **instance)
{
	EAP_TLS_CONF	 *conf;
	eap_tls_t 	 *inst;

	/* Store all these values in the data structure for later references */
	inst = (eap_tls_t *)malloc(sizeof(*inst));
	if (!inst) {
		radlog(L_ERR, "rlm_eap_tls: out of memory");
		return -1;
	}
	memset(inst, 0, sizeof(*inst));

	/*
	 *	Parse the config file & get all the configured values
	 */
	conf = (EAP_TLS_CONF *)malloc(sizeof(*conf));
	if (conf == NULL) {
		free(inst);
		radlog(L_ERR, "rlm_eap_tls: out of memory");
		return -1;
	}
	memset(conf, 0, sizeof(*conf));

	inst->conf = conf;
	if (cf_section_parse(cs, conf, module_config) < 0) {
		eaptls_detach(inst);
		return -1;
	}

	/*
	 *	The EAP RFC's say 1020, but we're less picky.
	 */
	if (conf->fragment_size < 100) {
		radlog(L_ERR, "rlm_eap_tls: Fragment size is too small.");
		eaptls_detach(inst);
		return -1;
	}

	/*
	 *	The maximum size for a RADIUS packet is 4096,
	 *	minus the header (20), Message-Authenticator (18),
	 *	and State (18), etc. results in about 4000 bytes of data
	 *	that can be devoted *solely* to EAP.
	 */
	if (conf->fragment_size > 4000) {
		radlog(L_ERR, "rlm_eap_tls: Fragment size is too large.");
		eaptls_detach(inst);
		return -1;
	}

	/*
	 *	Account for the EAP header (4), and the EAP-TLS header
	 *	(6), as per Section 4.2 of RFC 2716.  What's left is
	 *	the maximum amount of data we read from a TLS buffer.
	 */
	conf->fragment_size -= 10;

	/*
	 *	This magic makes the administrators life HUGELY easier
	 *	on initial deployments.
	 *
	 *	If the server starts up in debugging mode, AND the
	 *	bootstrap command is configured, AND it exists, AND
	 *	there is no server certificate
	 */
	if (conf->make_cert_command && (debug_flag >= 2)) {
		struct stat buf;

		if ((stat(conf->make_cert_command, &buf) == 0) &&
		    (stat(conf->certificate_file, &buf) < 0) &&
		    (errno == ENOENT) &&
		    (radius_exec_program(conf->make_cert_command, NULL, 1,
					 NULL, 0, NULL, NULL, 0) != 0)) {
			eaptls_detach(inst);
			return -1;
		}
	}


	/*
	 *	Initialize TLS
	 */
	inst->ctx = init_tls_ctx(conf);
	if (inst->ctx == NULL) {
		eaptls_detach(inst);
		return -1;
	}

#ifdef HAVE_OPENSSL_OCSP_H
	/*
	 * 	Initialize OCSP Revocation Store
	 */
	if (conf->ocsp_enable) {
		inst->store = init_revocation_store(conf);
		if (inst->store == NULL) {
			eaptls_detach(inst);
		  return -1;
		}
	}
#endif HAVE_OPENSSL_OCSP_H

	if (load_dh_params(inst->ctx, conf->dh_file) < 0) {
		eaptls_detach(inst);
		return -1;
	}

        if (generate_eph_rsa_key(inst->ctx) < 0) {
		eaptls_detach(inst);
                return -1;
        }

	if (conf->verify_tmp_dir) {
		if (chmod(conf->verify_tmp_dir, S_IRWXU) < 0) {
			radlog(L_ERR, "rlm_eap_tls: Failed changing permissions on %s: %s", conf->verify_tmp_dir, strerror(errno));
			eaptls_detach(inst);
			return -1;
		}
	}

	if (conf->verify_client_cert_cmd && !conf->verify_tmp_dir) {
		radlog(L_ERR, "rlm_eap_tls: You MUST set the verify directory in order to use verify_client_cmd");
		eaptls_detach(inst);
		return -1;
	}

	*instance = inst;

	return 0;
}
Esempio n. 3
0
File: tls.c Progetto: Zabrane/SPOCP
SSL_CTX        *
tls_init(srv_t * srv)
{
	char            path[_POSIX_PATH_MAX];
	SSL_CTX        *ctx;
	int             r;
	char            errorstr[1024];
	unsigned long   e;

	SSL_library_init();
	SSL_load_error_strings();	/* basic set up */
	OpenSSL_add_ssl_algorithms();

	/*
	 * Create a TLS context 
	 */

	if (!(ctx = SSL_CTX_new(SSLv23_method()))) {
		LOG(SPOCP_ERR) traceLog(LOG_ERR,"Error allocation SSL_CTX");
		return 0;
	}

	LOG(SPOCP_DEBUG) traceLog(LOG_DEBUG,"Do we have enough randomness ??");

	if (!RAND_status()) {
		/*
		 * load entropy from files 
		 */
		add_entropy(srv->SslEntropyFile);
		add_entropy(RAND_file_name(path, sizeof(path)));

		/*
		 * load entropy from egd sockets 
		 */
#ifdef HAVE_RAND_EGD
		add_entropy(getenv("EGDSOCKET"));
		snprintf(path, sizeof(path), "%s/.entropy", NONULL(Homedir));
		add_entropy(path);
		add_entropy("/tmp/entropy");
#endif

		/*
		 * shuffle $RANDFILE (or ~/.rnd if unset) 
		 */
		RAND_write_file(RAND_file_name(path, sizeof(path)));
		if (!RAND_status()) {
			LOG(SPOCP_ERR)
				traceLog(LOG_ERR,
				    "Failed to find enough entropy on your system");
			return 0;
		}
	}

	/*
	 * Initialize with DH parameters if supplied 
	 */

	if (srv->dhFile) {
		if (init_dh(ctx, (unsigned char *) srv->dhFile) == FALSE) {
			LOG(SPOCP_ERR) traceLog(LOG_ERR,"Error initializing DH");
			SSL_CTX_free(ctx);
			return 0;
		} else
			LOG(SPOCP_ERR) traceLog(LOG_ERR,"Initializing DH OK");
	}

	/*
	 * and a RSA key too 
	 */

	if (generate_eph_rsa_key(ctx, 512) == FALSE) {
		LOG(SPOCP_ERR) traceLog(LOG_ERR,"Error initializing RSA key");
		SSL_CTX_free(ctx);
		return 0;
	} else
		LOG(SPOCP_ERR) traceLog(LOG_ERR,"Initializing RSA key OK");

	/*
	 * Set up certificates and keys 
	 */

	if (srv->certificateFile != NULL) {
		LOG(SPOCP_INFO) traceLog(LOG_INFO,"Reading Certificate File");
		if (!SSL_CTX_use_certificate_chain_file
		    (ctx, srv->certificateFile)) {
			LOG(SPOCP_ERR)
			    traceLog(LOG_ERR,"Error in SSL_CTX_use_certificate_file");
			SSL_CTX_free(ctx);
			return 0;
		}
	}

	if (srv->privateKey != NULL) {

		if (srv->passwd) {
			SSL_CTX_set_default_passwd_cb_userdata(ctx,
							       (void *) srv->
							       passwd);
			SSL_CTX_set_default_passwd_cb(ctx, password_cb);
		}

		LOG(SPOCP_INFO) traceLog(LOG_INFO,"Reading Private Key File");
		r = SSL_CTX_use_PrivateKey_file(ctx, srv->privateKey,
						SSL_FILETYPE_PEM);
		if (r == 0) {
			e = ERR_get_error();
			ERR_error_string_n(e, errorstr, 1024);

			LOG(SPOCP_ERR)
			    traceLog(LOG_ERR,"Error in SSL_CTX_use_PrivateKey_file");
			LOG(SPOCP_ERR) traceLog(LOG_ERR,"%s", errorstr);

			SSL_CTX_free(ctx);
			return 0;
		}
	}

	if (srv->caList != NULL) {
		LOG(SPOCP_INFO) traceLog(LOG_INFO,"Reading Trusted CAs File");
		if (!SSL_CTX_load_verify_locations(ctx, srv->caList, 0)) {
			LOG(SPOCP_ERR)
			    traceLog(LOG_ERR,"Error in SSL_CTX_load_verify_locations");
			SSL_CTX_free(ctx);
			return 0;
		}
	}

	if (srv->clientcert == NONE)
		SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, verify_callback_ok);
	else {
		int             i = SSL_VERIFY_PEER;
		if (srv->clientcert == HARD)
			i |= SSL_VERIFY_CLIENT_ONCE;

		SSL_CTX_set_verify(ctx, i, verify_callback);
	}

	SSL_CTX_set_verify_depth(ctx, srv->sslverifydepth);

	SSL_CTX_set_options(ctx, SSL_OP_ALL | SSL_OP_NO_SSLv2);

	if (SSL_CTX_set_cipher_list(ctx, CIPHER_LIST) != 1) {
		LOG(SPOCP_ERR) traceLog(LOG_ERR,"No valid ciphers in cipherlist");
		SSL_CTX_free(ctx);
		return 0;
	}

	LOG(SPOCP_DEBUG) traceLog(LOG_DEBUG,"Initialised TLS");

	return ctx;
}