#
ecdh_curve = "prime256v1"
+ #
+ # As part of checking a client certificate, the EAP-TLS
+ # sets some attributes such as TLS-Client-Cert-CN. This
+ # virtual server has access to these attributes, and can
+ # be used to accept or reject the request.
+ #
+ # virtual_server = check-eap-tls
+
#
# Session resumption / fast reauthentication
# cache.
--- /dev/null
+# This virtual server allows EAP-TLS to reject access requests
+# based on some certificate attributes.
+
+# Value-pairs that are available for checking include:
+#
+# TLS-Client-Cert-Subject
+# TLS-Client-Cert-Issuer
+# TLS-Client-Cert-Common-Name
+# TLS-Client-Cert-Subject-Alt-Name-Email
+#
+# To see a full list of attributes, run the server in debug mode
+# with this virtual server configured, and look at the attributes
+# passed in to this virtual server.
+
+server check-eap-tls {
+
+
+# Authorize - this is the only section required.
+#
+# To accept the access request, set Auth-Type = Accept, otherwise
+# set it to Reject.
+
+authorize {
+ if ("%{TLS-Client-Cert-Common-Name}" == "client.example.com") {
+ update config {
+ Auth-Type = Accept
+ }
+ }
+ else {
+ update config {
+ Auth-Type = Reject
+ }
+ update reply {
+ Reply-Message = "Your certificate is not valid."
+ }
+ }
+
+# if ("host/%{TLS-Client-Cert-Common-Name}" == "%{User-Name}") {
+# update config {
+# Auth-Type = Accept
+# }
+# }
+# else {
+# update config {
+# Auth-Type = Reject
+# }
+# }
+
+}
+
+
+
+}
+
char *verify_client_cert_cmd;
int require_client_cert;
+ char *virtual_server; /* for processing certificates */
+
#ifdef HAVE_OPENSSL_OCSP_H
/*
* OCSP Configuration
offsetof(fr_tls_server_conf_t, make_cert_command), NULL, NULL},
{ "require_client_cert", PW_TYPE_BOOLEAN,
offsetof(fr_tls_server_conf_t, require_client_cert), NULL, NULL },
+ { "virtual_server", PW_TYPE_STRING_PTR,
+ offsetof(fr_tls_server_conf_t, virtual_server), NULL, NULL},
#if OPENSSL_VERSION_NUMBER >= 0x0090800fL
#ifndef OPENSSL_NO_ECDH
fr_tls_status_t status;
tls_session_t *tls_session = (tls_session_t *) handler->opaque;
REQUEST *request = handler->request;
+ fr_tls_server_conf_t *conf;
RDEBUG2("Authenticate");
/*
* EAP-TLS handshake was successful, return an
* EAP-TLS-Success packet here.
+ *
+ * If a virtual server was configured, check that
+ * it accepts the certificates, too.
*/
case FR_TLS_SUCCESS:
+ conf = SSL_get_ex_data(tls_session->ssl, FR_TLS_EX_INDEX_CONF);
+ if (conf && conf->virtual_server) {
+ VALUE_PAIR *vp;
+ REQUEST *fake;
+
+ /* create a fake request */
+ fake = request_alloc_fake(request);
+ rad_assert(fake->packet->vps == NULL);
+
+ fake->packet->vps = paircopy(request->packet->vps);
+
+ /* set the virtual server to use */
+ if ((vp = pairfind(request->config_items,
+ PW_VIRTUAL_SERVER, 0)) != NULL) {
+ fake->server = vp->vp_strvalue;
+ } else {
+ fake->server = conf->virtual_server;
+ }
+
+ RDEBUG("Processing EAP-TLS Certificate check:");
+ debug_pair_list(fake->packet->vps);
+
+ RDEBUG("server %s {", fake->server);
+
+ rad_authenticate(fake);
+
+ RDEBUG("} # server %s", fake->server);
+
+ /* copy the reply vps back to our reply */
+ pairadd(&request->reply->vps, fake->reply->vps);
+ fake->reply->vps = NULL;
+
+ /* reject if virtual server didn't return accept */
+ if (fake->reply->code != PW_AUTHENTICATION_ACK) {
+ RDEBUG2("Certifictes were rejected by the virtual server");
+ request_free(&fake);
+ eaptls_fail(handler, 0);
+ return 0;
+ }
+
+ request_free(&fake);
+ /* success */
+ }
break;
/*