Index: raddb/eap.conf
===================================================================
RCS file: /cvs/meta/freeradius-tls/raddb/eap.conf,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -I\$Id: -u -r1.1.1.1 -r1.2
--- raddb/eap.conf	11 May 2006 12:22:57 -0000	1.1.1.1
+++ raddb/eap.conf	11 May 2006 13:14:52 -0000	1.2
@@ -176,7 +176,16 @@
 		       #  will fail rejecting the user.
 		       #
 		#	check_cert_cn = %{User-Name}
-		#}
+		
+                # Check the subject and issuer of the client certificate by
+                # the script.  Script is invoked after successful TLS
+                # authentication.  X509_SUBJECT and X509_ISSUER environ
+                # variables are passed to the script. Return value of the
+                # script decide if the request is discarded (return 0) or
+                # allowed (return != 0)
+                #
+        #   check_script = /usr/local/etc/raddb/check_script
+        #}
 
 		#  The TTLS module implements the EAP-TTLS protocol,
 		#  which can be described as EAP inside of Diameter,
Index: share/dictionary.freeradius.internal
===================================================================
RCS file: /cvs/meta/freeradius-tls/share/dictionary.freeradius.internal,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -I\$Id: -u -r1.1.1.1 -r1.2
--- share/dictionary.freeradius.internal	11 May 2006 12:22:57 -0000	1.1.1.1
+++ share/dictionary.freeradius.internal	11 May 2006 12:46:10 -0000	1.2
@@ -126,6 +126,8 @@
 ATTRIBUTE	Packet-Src-IPv6-Address			1097	ipv6addr
 ATTRIBUTE	Packet-Dst-IPv6-Address			1098	ipv6addr
 ATTRIBUTE	Server-Identity				1099	string
+ATTRIBUTE	X509-Subject				1100	string
+ATTRIBUTE	X509-Issuer				1101	string
 
 #
 #	Range:	1200-1279
Index: src/include/radius.h
===================================================================
RCS file: /cvs/meta/freeradius-tls/src/include/radius.h,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -I\$Id: -u -r1.1.1.1 -r1.2
--- src/include/radius.h	11 May 2006 12:22:57 -0000	1.1.1.1
+++ src/include/radius.h	11 May 2006 12:46:10 -0000	1.2
@@ -187,6 +187,12 @@
 #define PW_MS_CHAP_USE_NTLM_AUTH	1082
 
 /*
+ * X509 client Subject and Issuer
+ */
+#define PW_X509_SUBJECT			1100
+#define PW_X509_ISSUER			1101
+
+/*
  *	Integer Translations
  */
 
Index: src/modules/rlm_eap/types/rlm_eap_tls/Makefile.in
===================================================================
RCS file: /cvs/meta/freeradius-tls/src/modules/rlm_eap/types/rlm_eap_tls/Makefile.in,v
retrieving revision 1.1.1.1
retrieving revision 1.3
diff -I\$Id: -u -r1.1.1.1 -r1.3
--- src/modules/rlm_eap/types/rlm_eap_tls/Makefile.in	11 May 2006 12:22:57 -0000	1.1.1.1
+++ src/modules/rlm_eap/types/rlm_eap_tls/Makefile.in	12 May 2006 07:25:00 -0000	1.3
@@ -2,7 +2,7 @@
 SRCS        = rlm_eap_tls.c eap_tls.c cb.c tls.c mppe_keys.c
 RLM_CFLAGS  = $(INCLTDL) -I@srcdir@/../.. -I@srcdir@/../../libeap @eap_tls_cflags@ -DOPENSSL_NO_KRB5 
 HEADERS     = rlm_eap_tls.h eap_tls.h ../../eap.h ../../rlm_eap.h
-RLM_INSTALL = 
+RLM_INSTALL = install-scripts 
 RLM_LIBS    += @eap_tls_ldflags@
 
 $(STATIC_OBJS): $(HEADERS)
@@ -11,3 +11,6 @@
 
 RLM_DIR=../../
 include ${RLM_DIR}../rules.mak
+
+install-scripts:
+	$(INSTALL) -m 755 check_script $(R)$(raddbdir)
Index: src/modules/rlm_eap/types/rlm_eap_tls/check_script
===================================================================
RCS file: src/modules/rlm_eap/types/rlm_eap_tls/check_script
diff -N src/modules/rlm_eap/types/rlm_eap_tls/check_script
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ src/modules/rlm_eap/types/rlm_eap_tls/check_script	12 May 2006 08:36:14 -0000	1.3
@@ -0,0 +1,27 @@
+#!/bin/sh
+
+# File containing subjects + issuers which are allowed
+ALLOWED_CERTS_FILE=/usr/local/etc/raddb/radius_allowed_certs
+LOG_FILE=/usr/local/var/log/radius/radtls.log
+
+# Get values from env variables
+SUBJECT=$X509_SUBJECT
+ISSUER=$X509_ISSUER
+
+
+# Get the number of occurrence of the ISSUER - SUBJECT in the
+# ALLOWED_CERTS_FILE.
+# This grep expression getting only exact match.
+# !!! Keep in mind that issuer and subject is covered by double quotes !!!
+
+RESULT=`grep -x -c "$ISSUER - $SUBJECT" $ALLOWED_CERTS_FILE`
+
+# If one or more line matched log it else log unauthorize access
+if [ $RESULT -ge 1 ]; then
+    echo -e `date` " $ISSUER - $SUBJECT - successfull" >> $LOG_FILE
+    exit 0
+else
+    echo -e `date` " $ISSUER - $SUBJECT - unatuhorized" >> $LOG_FILE
+    exit 1
+fi
+
Index: src/modules/rlm_eap/types/rlm_eap_tls/eap_tls.h
===================================================================
RCS file: /cvs/meta/freeradius-tls/src/modules/rlm_eap/types/rlm_eap_tls/eap_tls.h,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -I\$Id: -u -r1.1.1.1 -r1.2
--- src/modules/rlm_eap/types/rlm_eap_tls/eap_tls.h	11 May 2006 12:22:57 -0000	1.1.1.1
+++ src/modules/rlm_eap/types/rlm_eap_tls/eap_tls.h	11 May 2006 12:46:10 -0000	1.2
@@ -200,6 +200,7 @@
 	int		fragment_size;
 	int		check_crl;
 	char		*check_cert_cn;
+	char		*check_script;
 } EAP_TLS_CONF;
 
 
Index: src/modules/rlm_eap/types/rlm_eap_tls/rlm_eap_tls.c
===================================================================
RCS file: /cvs/meta/freeradius-tls/src/modules/rlm_eap/types/rlm_eap_tls/rlm_eap_tls.c,v
retrieving revision 1.1.1.1
retrieving revision 1.4
diff -I\$Id: -u -r1.1.1.1 -r1.4
--- src/modules/rlm_eap/types/rlm_eap_tls/rlm_eap_tls.c	11 May 2006 12:22:57 -0000	1.1.1.1
+++ src/modules/rlm_eap/types/rlm_eap_tls/rlm_eap_tls.c	11 May 2006 13:28:09 -0000	1.4
@@ -63,7 +63,9 @@
 	  offsetof(EAP_TLS_CONF, check_crl), NULL, "no"},
 	{ "check_cert_cn", PW_TYPE_STRING_PTR,
 	  offsetof(EAP_TLS_CONF, check_cert_cn), NULL, NULL},
-
+	{ "check_script", PW_TYPE_STRING_PTR,
+          offsetof(EAP_TLS_CONF, check_script), NULL, NULL},
+	
  	{ NULL, -1, 0, NULL, NULL }           /* end the list */
 };
 
@@ -496,11 +498,14 @@
 /*
  *	Do authentication, by letting EAP-TLS do most of the work.
  */
-static int eaptls_authenticate(void *arg UNUSED, EAP_HANDLER *handler)
+static int eaptls_authenticate(void *arg, EAP_HANDLER *handler)
 {
 	eaptls_status_t	status;
 	tls_session_t *tls_session = (tls_session_t *) handler->opaque;
+	eap_tls_t        *inst;
 
+	inst = (eap_tls_t *) arg;
+    
 	DEBUG2("  rlm_eap_tls: Authenticate");
 
 	status = eaptls_process(handler);
@@ -511,6 +516,66 @@
 		 *	EAP-TLS-Success packet here.
 		 */
 	case EAPTLS_SUCCESS:
+		/*
+		 * 	When EAPTLS successed and if check_script is defined
+		 * 	add X509 subject and issuer from client certificate
+		 * 	to the packet and send it to the defined script by 
+		 * 	radius_exec_program.
+		 */
+        
+        
+		if (inst->conf->check_script != NULL) {
+			VALUE_PAIR *vp = NULL;
+		        char x509_subject[256];
+		        char x509_issuer[256];
+		        int result;
+
+		        if (access(inst->conf->check_script, X_OK) != 0) {
+			        DEBUG2("  eaptls_check_script: file %s not found or it is not executable\n", inst->conf->check_script);
+                                return 0;
+                        }
+
+                       DEBUG2("  eaptls_check_script: processing script %s\n", inst->conf->check_script);
+
+		       
+		       x509_subject[0] = x509_issuer[0] = '\0';
+                       X509_NAME_oneline(X509_get_subject_name(tls_session->ssl->session->peer), x509_subject, 256);
+                       X509_NAME_oneline(X509_get_issuer_name(tls_session->ssl->session->peer), x509_issuer, 256);
+
+		       /* 
+			* Create X509_Subject pair 
+			*/
+                       vp = paircreate(PW_X509_SUBJECT, PW_TYPE_OCTETS);
+                       memcpy(vp->strvalue, x509_subject, strlen(x509_subject));
+                       vp->length = strlen(x509_subject);
+                       pairadd(&(handler->request->packet->vps), vp);
+                       vp = NULL;
+
+		       /*
+			* Create X509_Issuer pair
+			*/
+                       vp = paircreate(PW_X509_ISSUER, PW_TYPE_OCTETS);
+                       memcpy(vp->strvalue, x509_issuer, strlen(x509_issuer));
+                       vp->length = strlen(x509_issuer);
+                       pairadd(&(handler->request->packet->vps), vp);
+                       vp = NULL;
+
+		       /*
+			* Run the script and get the result of the script
+			*/
+                       result = radius_exec_program( inst->conf->check_script, handler->request,
+	                                             1, NULL, 0,
+                                                     handler->request->packet->vps, NULL);
+                       if (result != 0) {
+                                radlog(L_ERR, "  eaptls_check_script: rlm_exec (%s): External script failed",
+	                               inst->conf->check_script);
+                                return 0;
+                       }
+
+		       pairdelete(&(handler->request->packet->vps), PW_X509_SUBJECT);
+		       pairdelete(&(handler->request->packet->vps), PW_X509_ISSUER);
+		       
+                }
 		break;
 
 		/*

