Index: raddb/Makefile
===================================================================
RCS file: /home/michalp/cvsroot/freeradius-tls/raddb/Makefile,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -u -r1.1.1.1 -r1.2
--- raddb/Makefile	28 May 2007 07:17:06 -0000	1.1.1.1
+++ raddb/Makefile	28 May 2007 11:36:56 -0000	1.2
@@ -1,7 +1,7 @@
 #
 # Makefile
 #
-# Version:      $Id: Makefile,v 1.1.1.1 2007/05/28 07:17:06 michalp Exp $
+# Version:      $Id: Makefile,v 1.2 2007/05/28 11:36:56 michalp Exp $
 #
 
 include ../Make.inc
@@ -13,7 +13,7 @@
 	  experimental.conf hints huntgroups ldap.attrmap \
 	  mssql.conf naslist naspasswd oraclesql.conf postgresql.conf \
 	  preproxy_users proxy.conf radiusd.conf realms snmp.conf \
-	  sql.conf sqlippool.conf users otp.conf
+	  sql.conf sqlippool.conf users otp.conf check_tls_script
 
 all:
 
Index: raddb/check_tls_script
===================================================================
RCS file: raddb/check_tls_script
diff -N raddb/check_tls_script
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ raddb/check_tls_script	28 May 2007 11:36:56 -0000	1.1
@@ -0,0 +1,27 @@
+#!/bin/sh
+
+# File containing subjects + issuers which are allowed
+ALLOWED_CERTS_FILE=/etc/raddb/radius_allowed_certs
+LOG_FILE=/var/log/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: raddb/eap.conf
===================================================================
RCS file: /home/michalp/cvsroot/freeradius-tls/raddb/eap.conf,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -u -r1.1.1.1 -r1.2
--- raddb/eap.conf	28 May 2007 07:17:06 -0000	1.1.1.1
+++ raddb/eap.conf	28 May 2007 07:23:47 -0000	1.2
@@ -5,7 +5,7 @@
 #  common side effect of setting 'Auth-Type := EAP' is that the
 #  users then cannot use ANY other authentication method.
 #
-#	$Id: eap.conf,v 1.1.1.1 2007/05/28 07:17:06 michalp Exp $
+#	$Id: eap.conf,v 1.2 2007/05/28 07:23:47 michalp Exp $
 #
 	eap {
 		#  Invoke the default supported EAP type when
@@ -189,7 +189,16 @@
 		       #  the check succeeds.
 		       #
 		#	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_tls_script
+
 			# Set this option to specify the allowed
 			# TLS cipher suites.  The format is listed
 			# in "man 1 ciphers".
Index: share/dictionary.freeradius.internal
===================================================================
RCS file: /home/michalp/cvsroot/freeradius-tls/share/dictionary.freeradius.internal,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -u -r1.1.1.1 -r1.2
--- share/dictionary.freeradius.internal	28 May 2007 07:17:06 -0000	1.1.1.1
+++ share/dictionary.freeradius.internal	28 May 2007 07:23:47 -0000	1.2
@@ -2,7 +2,7 @@
 #
 #	Non Protocol Attributes used by FreeRADIUS
 #
-#	$Id: dictionary.freeradius.internal,v 1.1.1.1 2007/05/28 07:17:06 michalp Exp $
+#	$Id: dictionary.freeradius.internal,v 1.2 2007/05/28 07:23:47 michalp Exp $
 #
 
 #	The attributes number ranges are allocates as follows:
@@ -128,6 +128,8 @@
 ATTRIBUTE	Server-Identity				1099	string
 ATTRIBUTE	Cleartext-Password			1100	string
 ATTRIBUTE	Password-With-Header			1101	string
+ATTRIBUTE       X509-Subject                            1102    string
+ATTRIBUTE       X509-Issuer                             1103    string
 
 #
 #	Range:	1200-1279
Index: src/include/radius.h
===================================================================
RCS file: /home/michalp/cvsroot/freeradius-tls/src/include/radius.h,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -u -r1.1.1.1 -r1.2
--- src/include/radius.h	28 May 2007 07:17:06 -0000	1.1.1.1
+++ src/include/radius.h	28 May 2007 07:23:47 -0000	1.2
@@ -1,7 +1,7 @@
 /*
  * radius.h	Constants of the radius protocol.
  *
- * Version:	$Id: radius.h,v 1.1.1.1 2007/05/28 07:17:06 michalp Exp $
+ * Version:	$Id: radius.h,v 1.2 2007/05/28 07:23:47 michalp Exp $
  *
  */
 
@@ -201,7 +201,11 @@
 #define PW_SMD5_PASSWORD		1096
 #define PW_CLEARTEXT_PASSWORD		1100
 #define PW_PASSWORD_WITH_HEADER		1101
-
+/*
+* X509 client Subject and Issuer
+*/
+#define PW_X509_SUBJECT                 1102
+#define PW_X509_ISSUER                  1103
 
 /*
  *	Integer Translations
Index: src/modules/rlm_eap/types/rlm_eap_tls/Makefile.in
===================================================================
RCS file: /home/michalp/cvsroot/freeradius-tls/src/modules/rlm_eap/types/rlm_eap_tls/Makefile.in,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 Makefile.in
--- src/modules/rlm_eap/types/rlm_eap_tls/Makefile.in	28 May 2007 07:17:06 -0000	1.1.1.1
+++ src/modules/rlm_eap/types/rlm_eap_tls/Makefile.in	28 May 2007 11:41:52 -0000
@@ -1,5 +1,5 @@
 #
-# $Id: Makefile.in,v 1.1.1.1 2007/05/28 07:17:06 michalp Exp $
+# $Id: Makefile.in,v 1.2 2007/05/28 07:23:47 michalp Exp $
 #
 
 TARGET      = @targetname@
@@ -7,7 +7,7 @@
 HEADERS     = rlm_eap_tls.h ../../eap.h ../../rlm_eap.h
 RLM_CFLAGS  = -I../.. -I../../libeap $(INCLTDL) $(OPENSSL_INCLUDE) @eap_tls_cflags@
 RLM_LIBS    = @eap_tls_ldflags@ ../../libeap/libeap.la $(OPENSSL_LIBS)
-RLM_INSTALL =
+RLM_INSTALL = 
 
 RLM_DIR=../../
 include ${RLM_DIR}../rules.mak
Index: src/modules/rlm_eap/types/rlm_eap_tls/check_tls_script.in
===================================================================
RCS file: src/modules/rlm_eap/types/rlm_eap_tls/check_tls_script.in
diff -N src/modules/rlm_eap/types/rlm_eap_tls/check_tls_script.in
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ src/modules/rlm_eap/types/rlm_eap_tls/check_tls_script.in	28 May 2007 08:05:34 -0000	1.1
@@ -0,0 +1,27 @@
+#!/bin/sh
+
+# File containing subjects + issuers which are allowed
+ALLOWED_CERTS_FILE=@sysconfdir@/radius_allowed_certs
+LOG_FILE=@logdir@/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/rlm_eap_tls.c
===================================================================
RCS file: /home/michalp/cvsroot/freeradius-tls/src/modules/rlm_eap/types/rlm_eap_tls/rlm_eap_tls.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -u -r1.1.1.1 -r1.2
--- src/modules/rlm_eap/types/rlm_eap_tls/rlm_eap_tls.c	28 May 2007 07:17:06 -0000	1.1.1.1
+++ src/modules/rlm_eap/types/rlm_eap_tls/rlm_eap_tls.c	28 May 2007 07:23:47 -0000	1.2
@@ -1,7 +1,7 @@
 /*
  * rlm_eap_tls.c  contains the interfaces that are called from eap
  *
- * Version:     $Id: rlm_eap_tls.c,v 1.1.1.1 2007/05/28 07:17:06 michalp Exp $
+ * Version:     $Id: rlm_eap_tls.c,v 1.2 2007/05/28 07:23:47 michalp Exp $
  *
  *   This program is free software; you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License as published by
@@ -68,6 +68,8 @@
 	  offsetof(EAP_TLS_CONF, cipher_list), NULL, NULL},
 	{ "check_cert_issuer", PW_TYPE_STRING_PTR,
 	  offsetof(EAP_TLS_CONF, check_cert_issuer), NULL, NULL},
+	{ "check_script", PW_TYPE_STRING_PTR,
+	  offsetof(EAP_TLS_CONF, check_script), NULL, NULL},
 
  	{ NULL, -1, 0, NULL, NULL }           /* end the list */
 };
@@ -698,11 +700,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);
@@ -713,6 +718,71 @@
 		 *	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;
 
 		/*
@@ -722,7 +792,6 @@
 		 */
 	case EAPTLS_HANDLED:
 		return 1;
-
 		/*
 		 *	Handshake is done, proceed with decoding tunneled
 		 *	data.
Index: src/modules/rlm_eap/types/rlm_eap_tls/rlm_eap_tls.h
===================================================================
RCS file: /home/michalp/cvsroot/freeradius-tls/src/modules/rlm_eap/types/rlm_eap_tls/rlm_eap_tls.h,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -u -r1.1.1.1 -r1.2
--- src/modules/rlm_eap/types/rlm_eap_tls/rlm_eap_tls.h	28 May 2007 07:17:06 -0000	1.1.1.1
+++ src/modules/rlm_eap/types/rlm_eap_tls/rlm_eap_tls.h	28 May 2007 07:23:47 -0000	1.2
@@ -1,7 +1,7 @@
 /*
  * rlm_eap_tls.h
  *
- * Version:     $Id: rlm_eap_tls.h,v 1.1.1.1 2007/05/28 07:17:06 michalp Exp $
+ * Version:     $Id: rlm_eap_tls.h,v 1.2 2007/05/28 07:23:47 michalp Exp $
  *
  *   This program is free software; you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License as published by
@@ -54,6 +54,7 @@
 	char		*check_cert_cn;
 	char		*cipher_list;
 	char		*check_cert_issuer;
+	char		*check_script;
 } EAP_TLS_CONF;
 
 /* This structure gets stored in arg */
