/*
 *	Send an initial eap-tls request to the peer, using the libeap functions.
 */
static int eapttls_initiate(void *type_arg, EAP_HANDLER *handler)
{
	int		status;
	tls_session_t	*ssn;
	rlm_eap_ttls_t	*inst;
	VALUE_PAIR	*vp;
	int		client_cert = FALSE;
	REQUEST		*request = handler->request;

	inst = type_arg;

	handler->tls = TRUE;
	handler->finished = FALSE;

	/*
	 *	Check if we need a client certificate.
	 */
	client_cert = inst->req_client_cert;

	/*
	 * EAP-TLS-Require-Client-Cert attribute will override
	 * the require_client_cert configuration option.
	 */
	vp = pairfind(handler->request->config_items, PW_EAP_TLS_REQUIRE_CLIENT_CERT, 0, TAG_ANY);
	if (vp) {
		client_cert = vp->vp_integer;
	}

	ssn = eaptls_session(inst->tls_conf, handler, client_cert);
	if (!ssn) {
		return 0;
	}

	handler->opaque = ((void *)ssn);
	handler->free_opaque = session_free;

	/*
	 *	Set up type-specific information.
	 */
	ssn->prf_label = "ttls keying material";

	/*
	 *	TLS session initialization is over.  Now handle TLS
	 *	related handshaking or application data.
	 */
	status = eaptls_start(handler->eap_ds, ssn->peap_flag);
	RDEBUG2("Start returned %d", status);
	if (status == 0) {
		return 0;
	}

	/*
	 *	The next stage to process the packet.
	 */
	handler->stage = AUTHENTICATE;

	return 1;
}
/*
 *	Send an initial eap-tls request to the peer, using the libeap functions.
 */
static int eaptls_initiate(void *type_arg, eap_handler_t *handler)
{
	int		status;
	tls_session_t	*ssn;
	rlm_eap_tls_t	*inst;
	REQUEST		*request = handler->request;

	inst = type_arg;

	handler->tls = true;
	handler->finished = false;

	/*
	 *	EAP-TLS always requires a client certificate.
	 */
	ssn = eaptls_session(inst->tls_conf, handler, true);
	if (!ssn) {
		return 0;
	}

	handler->opaque = ((void *)ssn);
	handler->free_opaque = session_free;

	/*
	 *	Set up type-specific information.
	 */
	ssn->prf_label = "client EAP encryption";

	/*
	 *	TLS session initialization is over.  Now handle TLS
	 *	related handshaking or application data.
	 */
	status = eaptls_start(handler->eap_ds, ssn->peap_flag);
	RDEBUG2("Start returned %d", status);
	if (status == 0) {
		return 0;
	}

	/*
	 *	The next stage to process the packet.
	 */
	handler->stage = AUTHENTICATE;

	return 1;
}
/*
 *	Send an initial eap-tls request to the peer, using the libeap functions.
 */
static int eappeap_initiate(void *type_arg, eap_handler_t *handler)
{
    int		status;
    tls_session_t	*ssn;
    rlm_eap_peap_t	*inst;
    VALUE_PAIR	*vp;
    bool		client_cert;
    REQUEST		*request = handler->request;

    inst = type_arg;

    handler->tls = true;
    handler->finished = false;

    /*
     *	Check if we need a client certificate.
     */

    /*
     * EAP-TLS-Require-Client-Cert attribute will override
     * the require_client_cert configuration option.
     */
    vp = pairfind(handler->request->config_items, PW_EAP_TLS_REQUIRE_CLIENT_CERT, 0, TAG_ANY);
    if (vp) {
        client_cert = vp->vp_integer ? true : false;
    } else {
        client_cert = inst->req_client_cert;
    }

    ssn = eaptls_session(handler, inst->tls_conf, client_cert);
    if (!ssn) {
        return 0;
    }

    handler->opaque = ((void *)ssn);

    /*
     *	Set up type-specific information.
     */
    ssn->prf_label = "client EAP encryption";

    /*
     *	As it is a poorly designed protocol, PEAP uses
     *	bits in the TLS header to indicate PEAP
     *	version numbers.  For now, we only support
     *	PEAP version 0, so it doesn't matter too much.
     *	However, if we support later versions of PEAP,
     *	we will need this flag to indicate which
     *	version we're currently dealing with.
     */
    ssn->peap_flag = 0x00;

    /*
     *	PEAP version 0 requires 'include_length = no',
     *	so rather than hoping the user figures it out,
     *	we force it here.
     */
    ssn->length_flag = 0;

    /*
     *	TLS session initialization is over.  Now handle TLS
     *	related handshaking or application data.
     */
    status = eaptls_start(handler->eap_ds, ssn->peap_flag);
    RDEBUG2("Start returned %d", status);
    if (status == 0) {
        return 0;
    }

    /*
     *	The next stage to process the packet.
     */
    handler->stage = AUTHENTICATE;

    return 1;
}