summaryrefslogtreecommitdiffstats
path: root/ipa-radius-server
diff options
context:
space:
mode:
authorKarl MacMillan <kmacmill@redhat.com>2007-12-12 18:06:39 -0500
committerKarl MacMillan <kmacmill@redhat.com>2007-12-12 18:06:39 -0500
commitcf595511ff9e55b5f10a3273575980d6bb39d67a (patch)
tree61e2f2e39ce7a15f219ce1c8037d1260d84b0da5 /ipa-radius-server
parentcecbca1a84579c6aaf20ab7979aee1ae483f32c6 (diff)
downloadfreeipa-cf595511ff9e55b5f10a3273575980d6bb39d67a.tar.gz
freeipa-cf595511ff9e55b5f10a3273575980d6bb39d67a.tar.xz
freeipa-cf595511ff9e55b5f10a3273575980d6bb39d67a.zip
Move radius server components into a separate package.
Diffstat (limited to 'ipa-radius-server')
-rw-r--r--ipa-radius-server/Makefile20
-rw-r--r--ipa-radius-server/ipa-radius-install73
-rwxr-xr-xipa-radius-server/ipa-radius-server.spec50
-rwxr-xr-xipa-radius-server/ipa-radius-server.spec.in50
-rw-r--r--ipa-radius-server/plugins/__init__.py1
-rw-r--r--ipa-radius-server/plugins/radiusinstance.py173
-rw-r--r--ipa-radius-server/share/radius.radiusd.conf.template285
7 files changed, 652 insertions, 0 deletions
diff --git a/ipa-radius-server/Makefile b/ipa-radius-server/Makefile
new file mode 100644
index 000000000..7de51b469
--- /dev/null
+++ b/ipa-radius-server/Makefile
@@ -0,0 +1,20 @@
+PLUGINS_SHARE = $(DESTDIR)/usr/share/ipa/plugins
+PLUGINS_PYTHON = $(DESTDIR)/usr/share/ipa/ipaserver/plugins
+SBINDIR = $(DESTDIR)/usr/sbin
+
+all:
+
+install:
+ -mkdir -p $(PLUGINS_SHARE)
+ -mkdir -p $(PLUGINS_PYTHON)
+ -mkdir -p $(PLUGINS_SBINDIR)
+ install -m 644 plugins/*.py $(PLUGINS_PYTHON)
+ install -m 644 share/*.template $(PLUGINS_SHARE)
+ install -m 755 ipa-radius-install $(SBINDIR)
+
+clean:
+ rm -fr *.pyc *~
+
+distclean: clean
+
+test: \ No newline at end of file
diff --git a/ipa-radius-server/ipa-radius-install b/ipa-radius-server/ipa-radius-install
new file mode 100644
index 000000000..3e759d8d2
--- /dev/null
+++ b/ipa-radius-server/ipa-radius-install
@@ -0,0 +1,73 @@
+#! /usr/bin/python -E
+# Authors: Karl MacMillan <kmacmillan@mentalrootkit.com>
+#
+# Copyright (C) 2007 Red Hat
+# see file 'COPYING' for use and warranty information
+#
+# 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 the Free Software Foundation; version 2 only
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+
+import sys
+sys.path.append("/usr/share/ipa")
+
+import traceback, logging, krbV
+
+from ipaserver import installutils
+from ipaserver.plugins import radiusinstance
+
+from ipa import ipautil
+
+def get_host_name():
+ hostname = installutils.get_fqdn()
+ try:
+ installutils.verify_fqdn(hostname)
+ except RuntimeError, e:
+ logging.error(str(e))
+ sys.exit(1)
+
+ return hostname
+
+def get_realm_name():
+ c = krbV.default_context()
+ return c.default_realm
+
+def main():
+ if not ipautil.file_exists("/etc/ipa/ipa.conf"):
+ print "This system does not appear to have IPA configured."
+ print "Has ipa-server-install been run?"
+ yesno = raw_input("Continue with radius install [y/N]? ")
+ if yesno.lower() != "y":
+ sys.exit(1)
+
+ installutils.standard_logging_setup("iparadius-install.log", False)
+
+ host_name = get_host_name()
+
+ realm_name = get_realm_name()
+
+ # Create a radius instance
+ radius = radiusinstance.RadiusInstance()
+ # FIXME: ldap_server should be derived, not hardcoded to localhost, also should it be a URL?
+ radius.create_instance(realm_name, host_name, 'localhost')
+
+
+try:
+ main()
+except Exception, e:
+ message = "Unexpected error - see iparadius-install.log for details:\n %s" % str(e)
+ print message
+ message = str(e)
+ for str in traceback.format_tb(sys.exc_info()[2]):
+ message = message + "\n" + str
+ logging.debug(message)
diff --git a/ipa-radius-server/ipa-radius-server.spec b/ipa-radius-server/ipa-radius-server.spec
new file mode 100755
index 000000000..2b8b61624
--- /dev/null
+++ b/ipa-radius-server/ipa-radius-server.spec
@@ -0,0 +1,50 @@
+Name: ipa-radius-server
+Version: 0.5.0
+Release: 1%{?dist}
+Summary: IPA authentication server - radius plugin
+
+Group: System Environment/Base
+License: GPL
+URL: http://www.freeipa.org
+Source0: %{name}-%{version}.tgz
+BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
+BuildArch: noarch
+
+Requires: python
+Requires: ipa-server
+Requires: freeradius
+
+%description
+Radius plugin for an IPA server
+
+%prep
+%setup -q
+
+%install
+rm -rf %{buildroot}
+mkdir -p %{buildroot}%{_sbindir}
+
+make install DESTDIR=%{buildroot}
+
+
+%clean
+rm -rf %{buildroot}
+
+
+%files
+%defattr(-,root,root,-)
+%{_sbindir}/ipa*
+
+%dir %{_usr}/share/ipa/plugins
+%{_usr}/share/ipa/plugins/*
+
+%dir %{_usr}/share/ipa/ipaserver/plugins
+%{_usr}/share/ipa/ipaserver/plugins/*
+
+%changelog
+* Wed Dec 12 2007 Karl MacMillan <kmacmill@redhat.com> - 0.5.0-1
+- Initial version
+
+
+
+
diff --git a/ipa-radius-server/ipa-radius-server.spec.in b/ipa-radius-server/ipa-radius-server.spec.in
new file mode 100755
index 000000000..5937d3b19
--- /dev/null
+++ b/ipa-radius-server/ipa-radius-server.spec.in
@@ -0,0 +1,50 @@
+Name: ipa-radius-server
+Version: VERSION
+Release: 1%{?dist}
+Summary: IPA authentication server - radius plugin
+
+Group: System Environment/Base
+License: GPL
+URL: http://www.freeipa.org
+Source0: %{name}-%{version}.tgz
+BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
+BuildArch: noarch
+
+Requires: python
+Requires: ipa-server
+Requires: freeradius
+
+%description
+Radius plugin for an IPA server
+
+%prep
+%setup -q
+
+%install
+rm -rf %{buildroot}
+mkdir -p %{buildroot}%{_sbindir}
+
+make install DESTDIR=%{buildroot}
+
+
+%clean
+rm -rf %{buildroot}
+
+
+%files
+%defattr(-,root,root,-)
+%{_sbindir}/ipa*
+
+%dir %{_usr}/share/ipa/plugins
+%{_usr}/share/ipa/plugins/*
+
+%dir %{_usr}/share/ipa/ipaserver/plugins
+%{_usr}/share/ipa/ipaserver/plugins/*
+
+%changelog
+* Wed Dec 12 2007 Karl MacMillan <kmacmill@redhat.com> - 0.5.0-1
+- Initial version
+
+
+
+
diff --git a/ipa-radius-server/plugins/__init__.py b/ipa-radius-server/plugins/__init__.py
new file mode 100644
index 000000000..636bc1a8a
--- /dev/null
+++ b/ipa-radius-server/plugins/__init__.py
@@ -0,0 +1 @@
+# intentionally empty
diff --git a/ipa-radius-server/plugins/radiusinstance.py b/ipa-radius-server/plugins/radiusinstance.py
new file mode 100644
index 000000000..743a1d8a2
--- /dev/null
+++ b/ipa-radius-server/plugins/radiusinstance.py
@@ -0,0 +1,173 @@
+#! /usr/bin/python -E
+# Authors: John Dennis <jdennis@redhat.com>
+#
+# Copyright (C) 2007 Red Hat
+# see file 'COPYING' for use and warranty information
+#
+# 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 the Free Software Foundation; version 2 or later
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+
+import sys
+sys.path.append("/usr/share/ipa")
+
+import subprocess
+import string
+import tempfile
+import shutil
+import logging
+import pwd
+import time
+import sys
+from ipa.ipautil import *
+from ipa import radius_util
+
+from ipaserver import service
+
+import os
+import re
+
+IPA_RADIUS_VERSION = '0.0.0'
+
+# FIXME there should a utility to get the user base dn
+from ipaserver.funcs import DefaultUserContainer, DefaultGroupContainer
+
+#-------------------------------------------------------------------------------
+
+def ldap_mod(fd, dn, pwd):
+ args = ["/usr/bin/ldapmodify", "-h", "127.0.0.1", "-xv", "-D", dn, "-w", pwd, "-f", fd.name]
+ run(args)
+
+def get_radius_version():
+ version = None
+ try:
+ p = subprocess.Popen([radius_util.RADIUSD, '-v'], stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE)
+ stdout, stderr = p.communicate()
+ status = p.returncode
+
+ if status == 0:
+ match = re.search("radiusd: FreeRADIUS Version (.+), for host", stdout)
+ if match:
+ version = match.group(1)
+ except Exception, e:
+ pass
+ return version
+
+
+#-------------------------------------------------------------------------------
+
+class RadiusInstance(service.Service):
+ def __init__(self):
+ service.Service.__init__(self, "radiusd")
+ self.fqdn = None
+ self.realm = None
+ self.principal = None
+
+ def create_instance(self, realm_name, host_name, ldap_server):
+ self.realm = realm_name.upper()
+ self.suffix = realm_to_suffix(self.realm)
+ self.fqdn = host_name
+ self.ldap_server = ldap_server
+ self.principal = "%s/%s@%s" % (radius_util.RADIUS_SERVICE_NAME, self.fqdn, self.realm)
+ self.basedn = self.suffix
+ self.user_basedn = "%s,%s" % (DefaultUserContainer, self.basedn) # FIXME, should be utility to get this
+ self.radius_version = get_radius_version()
+ self.start_creation(4, "Configuring radiusd")
+
+ try:
+ self.stop()
+ except:
+ # It could have been not running
+ pass
+
+ self.__create_radius_keytab()
+ self.__radiusd_conf()
+
+ try:
+ self.step("starting radiusd")
+ self.start()
+ except:
+ logging.error("radiusd service failed to start")
+
+ self.step("configuring radiusd to start on boot")
+ self.chkconfig_on()
+
+
+ def __radiusd_conf(self):
+ self.step('configuring radiusd.conf for radius instance')
+
+ version = 'IPA_RADIUS_VERSION=%s FREE_RADIUS_VERSION=%s' % (IPA_RADIUS_VERSION, self.radius_version)
+ sub_dict = {'CONFIG_FILE_VERSION_INFO' : version,
+ 'LDAP_SERVER' : self.ldap_server,
+ 'RADIUS_KEYTAB' : radius_util.RADIUS_IPA_KEYTAB_FILEPATH,
+ 'RADIUS_PRINCIPAL' : self.principal,
+ 'RADIUS_USER_BASE_DN' : self.user_basedn,
+ 'ACCESS_ATTRIBUTE' : '',
+ 'ACCESS_ATTRIBUTE_DEFAULT' : 'TRUE',
+ 'CLIENTS_BASEDN' : radius_util.radius_clients_basedn(None, self.suffix),
+ 'SUFFIX' : self.suffix,
+ }
+ try:
+ radiusd_conf = template_file(radius_util.RADIUSD_CONF_TEMPLATE_FILEPATH, sub_dict)
+ radiusd_fd = open(radius_util.RADIUSD_CONF_FILEPATH, 'w+')
+ radiusd_fd.write(radiusd_conf)
+ radiusd_fd.close()
+ except Exception, e:
+ logging.error("could not create %s: %s", radius_util.RADIUSD_CONF_FILEPATH, e)
+
+ def __create_radius_keytab(self):
+ self.step("creating a keytab for radiusd")
+ try:
+ if file_exists(radius_util.RADIUS_IPA_KEYTAB_FILEPATH):
+ os.remove(radius_util.RADIUS_IPA_KEYTAB_FILEPATH)
+ except os.error:
+ logging.error("Failed to remove %s", radius_util.RADIUS_IPA_KEYTAB_FILEPATH)
+
+ (kwrite, kread, kerr) = os.popen3("/usr/kerberos/sbin/kadmin.local")
+ kwrite.write("addprinc -randkey %s\n" % (self.principal))
+ kwrite.flush()
+ kwrite.write("ktadd -k %s %s\n" % (radius_util.RADIUS_IPA_KEYTAB_FILEPATH, self.principal))
+ kwrite.flush()
+ kwrite.close()
+ kread.close()
+ kerr.close()
+
+ # give kadmin time to actually write the file before we go on
+ retry = 0
+ while not file_exists(radius_util.RADIUS_IPA_KEYTAB_FILEPATH):
+ time.sleep(1)
+ retry += 1
+ if retry > 15:
+ print "Error timed out waiting for kadmin to finish operations\n"
+ sys.exit(1)
+ try:
+ pent = pwd.getpwnam(radius_util.RADIUS_USER)
+ os.chown(radius_util.RADIUS_IPA_KEYTAB_FILEPATH, pent.pw_uid, pent.pw_gid)
+ except Exception, e:
+ logging.error("could not chown on %s to %s: %s", radius_util.RADIUS_IPA_KEYTAB_FILEPATH, radius_util.RADIUS_USER, e)
+
+ #FIXME, should use IPAdmin method
+ def __set_ldap_encrypted_attributes(self):
+ ldif_file = 'encrypted_attribute.ldif'
+ self.step("setting ldap encrypted attributes")
+ ldif_txt = template_file(SHARE_DIR + ldif_file, {'ENCRYPTED_ATTRIBUTE':'radiusClientSecret'})
+ ldif_fd = write_tmp_file(ldif_txt)
+ try:
+ ldap_mod(ldif_fd, "cn=Directory Manager", self.dm_password)
+ except subprocess.CalledProcessError, e:
+ logging.critical("Failed to load %s: %s" % (ldif_file, str(e)))
+ ldif_fd.close()
+
+#-------------------------------------------------------------------------------
+
diff --git a/ipa-radius-server/share/radius.radiusd.conf.template b/ipa-radius-server/share/radius.radiusd.conf.template
new file mode 100644
index 000000000..3bc4927dd
--- /dev/null
+++ b/ipa-radius-server/share/radius.radiusd.conf.template
@@ -0,0 +1,285 @@
+#
+# WARNING: This file is automatically generated, do not edit
+#
+# $CONFIG_FILE_VERSION_INFO
+#
+prefix = /usr
+exec_prefix = /usr
+sysconfdir = /etc
+localstatedir = /var
+sbindir = /usr/sbin
+logdir = $${localstatedir}/log/radius
+raddbdir = $${sysconfdir}/raddb
+radacctdir = $${logdir}/radacct
+confdir = $${raddbdir}
+run_dir = $${localstatedir}/run/radiusd
+db_dir = $${localstatedir}/lib/radiusd
+log_file = $${logdir}/radius.log
+libdir = /usr/lib
+pidfile = $${run_dir}/radiusd.pid
+user = radiusd
+group = radiusd
+max_request_time = 30
+delete_blocked_requests = no
+cleanup_delay = 5
+max_requests = 1024
+bind_address = *
+port = 0
+hostname_lookups = no
+allow_core_dumps = no
+regular_expressions = yes
+extended_expressions = yes
+log_stripped_names = no
+log_auth = no
+log_auth_badpass = no
+log_auth_goodpass = no
+usercollide = no
+lower_user = no
+lower_pass = no
+nospace_user = no
+nospace_pass = no
+checkrad = $${sbindir}/checkrad
+security {
+ max_attributes = 200
+ reject_delay = 1
+ status_server = no
+}
+proxy_requests = yes
+$$INCLUDE $${confdir}/proxy.conf
+$$INCLUDE $${confdir}/clients.conf
+snmp = no
+$$INCLUDE $${confdir}/snmp.conf
+thread pool {
+ start_servers = 5
+ max_servers = 32
+ min_spare_servers = 3
+ max_spare_servers = 10
+ max_requests_per_server = 0
+}
+modules {
+ chap {
+ authtype = CHAP
+ }
+ pam {
+ pam_auth = radiusd
+ }
+ unix {
+ cache = no
+ cache_reload = 600
+ shadow = /etc/shadow
+ radwtmp = $${logdir}/radwtmp
+ }
+$$INCLUDE $${confdir}/eap.conf
+ mschap {
+ }
+ ldap {
+ server = "$LDAP_SERVER"
+ use_sasl = yes
+ sasl_mech = "GSSAPI"
+ krb_keytab = "$RADIUS_KEYTAB"
+ krb_principal = "$RADIUS_PRINCIPAL"
+ basedn = "$RADIUS_USER_BASE_DN"
+ filter = "(uid=%{Stripped-User-Name:-%{User-Name}})"
+ base_filter = "(objectclass=radiusprofile)"
+ start_tls = no
+ profile_attribute = "radiusProfileDn"
+ default_profile = "uid=ipa_default,cn=profiles,cn=radius,cn=services,cn=etc,$SUFFIX
+ # FIXME: we'll want to toggle the access_attr feature on/off,
+ # but it needs a control, so disable it for now.
+ #access_attr = "$ACCESS_ATTRIBUTE"
+ #access_attr_used_for_allow = "$ACCESS_ATTRIBUTE_DEFAULT"
+ dictionary_mapping = $${raddbdir}/ldap.attrmap
+ ldap_connections_number = 5
+ edir_account_policy_check=no
+ timeout = 4
+ timelimit = 3
+ net_timeout = 1
+ clients_basedn = "$CLIENTS_BASEDN"
+ }
+ realm IPASS {
+ format = prefix
+ delimiter = "/"
+ ignore_default = no
+ ignore_null = no
+ }
+ realm suffix {
+ format = suffix
+ delimiter = "@"
+ ignore_default = no
+ ignore_null = no
+ }
+ realm realmpercent {
+ format = suffix
+ delimiter = "%"
+ ignore_default = no
+ ignore_null = no
+ }
+ realm ntdomain {
+ format = prefix
+ delimiter = "\\"
+ ignore_default = no
+ ignore_null = no
+ }
+ checkval {
+ item-name = Calling-Station-Id
+ check-name = Calling-Station-Id
+ data-type = string
+ }
+ preprocess {
+ huntgroups = $${confdir}/huntgroups
+ hints = $${confdir}/hints
+ with_ascend_hack = no
+ ascend_channels_per_line = 23
+ with_ntdomain_hack = no
+ with_specialix_jetstream_hack = no
+ with_cisco_vsa_hack = no
+ }
+ files {
+ usersfile = $${confdir}/users
+ acctusersfile = $${confdir}/acct_users
+ preproxy_usersfile = $${confdir}/preproxy_users
+ compat = no
+ }
+ detail {
+ detailfile = $${radacctdir}/%{Client-IP-Address}/detail-%Y%m%d
+ detailperm = 0600
+ }
+ acct_unique {
+ key = "User-Name, Acct-Session-Id, NAS-IP-Address, Client-IP-Address, NAS-Port"
+ }
+ radutmp {
+ filename = $${logdir}/radutmp
+ username = %{User-Name}
+ case_sensitive = yes
+ check_with_nas = yes
+ perm = 0600
+ callerid = "yes"
+ }
+ radutmp sradutmp {
+ filename = $${logdir}/sradutmp
+ perm = 0644
+ callerid = "no"
+ }
+ attr_filter {
+ attrsfile = $${confdir}/attrs
+ }
+ counter daily {
+ filename = $${db_dir}/db.daily
+ key = User-Name
+ count-attribute = Acct-Session-Time
+ reset = daily
+ counter-name = Daily-Session-Time
+ check-name = Max-Daily-Session
+ allowed-servicetype = Framed-User
+ cache-size = 5000
+ }
+ sqlcounter dailycounter {
+ counter-name = Daily-Session-Time
+ check-name = Max-Daily-Session
+ reply-name = Session-Timeout
+ sqlmod-inst = sql
+ key = User-Name
+ reset = daily
+ query = "SELECT SUM(AcctSessionTime - \
+ GREATEST((%b - UNIX_TIMESTAMP(AcctStartTime)), 0)) \
+ FROM radacct WHERE UserName='%{%k}' AND \
+ UNIX_TIMESTAMP(AcctStartTime) + AcctSessionTime > '%b'"
+ }
+ sqlcounter monthlycounter {
+ counter-name = Monthly-Session-Time
+ check-name = Max-Monthly-Session
+ reply-name = Session-Timeout
+ sqlmod-inst = sql
+ key = User-Name
+ reset = monthly
+ query = "SELECT SUM(AcctSessionTime - \
+ GREATEST((%b - UNIX_TIMESTAMP(AcctStartTime)), 0)) \
+ FROM radacct WHERE UserName='%{%k}' AND \
+ UNIX_TIMESTAMP(AcctStartTime) + AcctSessionTime > '%b'"
+ }
+ always fail {
+ rcode = fail
+ }
+ always reject {
+ rcode = reject
+ }
+ always ok {
+ rcode = ok
+ simulcount = 0
+ mpp = no
+ }
+ expr {
+ }
+ digest {
+ }
+ exec {
+ wait = yes
+ input_pairs = request
+ }
+ exec echo {
+ wait = yes
+ program = "/bin/echo %{User-Name}"
+ input_pairs = request
+ output_pairs = reply
+ }
+ ippool main_pool {
+ range-start = 192.168.1.1
+ range-stop = 192.168.3.254
+ netmask = 255.255.255.0
+ cache-size = 800
+ session-db = $${db_dir}/db.ippool
+ ip-index = $${db_dir}/db.ipindex
+ override = no
+ maximum-timeout = 0
+ }
+ krb5 {
+ keytab = "$RADIUS_KEYTAB"
+ service_principal = "$RADIUS_PRINCIPAL"
+ }
+}
+instantiate {
+ exec
+ expr
+}
+authorize {
+ preprocess
+ chap
+ mschap
+ suffix
+ eap
+ #files
+ ldap
+}
+authenticate {
+ Auth-Type CHAP {
+ chap
+ }
+ Auth-Type MS-CHAP {
+ mschap
+ }
+ eap
+ Auth-Type Kerberos {
+ krb5
+ }
+}
+preacct {
+ preprocess
+ acct_unique
+ suffix
+ files
+}
+accounting {
+ detail
+ unix
+ radutmp
+}
+session {
+ radutmp
+}
+post-auth {
+}
+pre-proxy {
+}
+post-proxy {
+ eap
+}