Merge tag 'release_3_0_14' into tr-integ
authorDan Breslau <dbreslau@painless-security.com>
Mon, 5 Jun 2017 20:58:36 +0000 (16:58 -0400)
committerDan Breslau <dbreslau@painless-security.com>
Mon, 5 Jun 2017 20:58:36 +0000 (16:58 -0400)
84 files changed:
VERSION
debian/changelog
debian/freeradius.logrotate
doc/ChangeLog
mibs/FREERADIUS-MGMT-MIB.mib
raddb/README.rst
raddb/certs/Makefile
raddb/mods-available/date
raddb/mods-available/eap
raddb/mods-available/moonshot-targeted-ids [new file with mode: 0644]
raddb/mods-available/otp
raddb/mods-config/files/accounting
raddb/mods-config/preprocess/huntgroups
raddb/mods-config/sql/moonshot-targeted-ids/mysql/queries.conf [new file with mode: 0644]
raddb/mods-config/sql/moonshot-targeted-ids/mysql/schema.sql [new file with mode: 0644]
raddb/mods-config/sql/moonshot-targeted-ids/postgresql/queries.conf [new file with mode: 0644]
raddb/mods-config/sql/moonshot-targeted-ids/postgresql/schema.sql [new file with mode: 0644]
raddb/mods-config/sql/moonshot-targeted-ids/sqlite/queries.conf [new file with mode: 0644]
raddb/mods-config/sql/moonshot-targeted-ids/sqlite/schema.sql [new file with mode: 0644]
raddb/policy.d/moonshot-targeted-ids
raddb/sites-available/abfab-tls
raddb/sites-available/abfab-tr-idp
raddb/sites-available/buffered-sql
raddb/sites-available/copy-acct-to-home-server
raddb/sites-available/decoupled-accounting
raddb/sites-available/default
raddb/sites-available/inner-tunnel
raddb/sites-available/tls
redhat/freeradius-logrotate
redhat/freeradius.spec-renamed
scripts/logrotate/freeradius
share/dictionary
share/dictionary.cisco.vpn3000
share/dictionary.dellemc [new file with mode: 0644]
share/dictionary.dhcp
share/dictionary.erx
share/dictionary.freeradius.internal
share/dictionary.patton
share/dictionary.ukerna
share/dictionary.zte
src/include/tls-h
src/lib/cbuff.c
src/lib/misc.c
src/lib/missing.c
src/lib/radius.c
src/main/auth.c
src/main/command.c
src/main/conffile.c
src/main/detail.c
src/main/evaluate.c
src/main/exec.c
src/main/listen.c
src/main/modcall.c
src/main/modules.c
src/main/pair.c
src/main/process.c
src/main/radtest.in
src/main/realms.c
src/main/state.c
src/main/tls.c
src/main/tls_listen.c
src/main/xlat.c
src/modules/proto_dhcp/dhcpd.c
src/modules/rlm_date/rlm_date.c
src/modules/rlm_eap/libeap/eap_chbind.c
src/modules/rlm_eap/libeap/eap_chbind.h
src/modules/rlm_eap/libeap/eap_tls.c
src/modules/rlm_eap/radeapclient.c
src/modules/rlm_eap/rlm_eap.c
src/modules/rlm_eap/types/rlm_eap_fast/eap_fast.c
src/modules/rlm_eap/types/rlm_eap_peap/peap.c
src/modules/rlm_eap/types/rlm_eap_peap/rlm_eap_peap.c
src/modules/rlm_eap/types/rlm_eap_pwd/rlm_eap_pwd.c
src/modules/rlm_eap/types/rlm_eap_ttls/ttls.c
src/modules/rlm_expr/paircmp.c
src/modules/rlm_ldap/groups.c
src/modules/rlm_mschap/rlm_mschap.c
src/modules/rlm_passwd/rlm_passwd.c
src/modules/rlm_realm/trustrouter.c
src/modules/rlm_sql/drivers/rlm_sql_iodbc/rlm_sql_iodbc.c
src/modules/rlm_sql/rlm_sql.c
src/modules/rlm_sqlcounter/rlm_sqlcounter.c
suse/freeradius.spec-renamed
suse/radiusd-logrotate

diff --git a/VERSION b/VERSION
index eea30e5..9bbe651 100644 (file)
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-3.0.13
+3.0.14
index ccb644d..3198b7a 100644 (file)
@@ -1,3 +1,9 @@
+freeradius (3.0.14+git) unstable; urgency=medium
+
+  * New upstream version.
+
+ -- Alan DeKok <aland@freeradius.org>  Tue, 07 Mar 2017 12:00:00 -0400
+
 freeradius (3.0.13+moonshot3-6) unstable; urgency=medium
 
   * Disabled session caching in EAP in response to CVE-2017-9148.
index 02f95c0..676f0c4 100644 (file)
@@ -26,13 +26,6 @@ notifempty
 }
 
 #
-#  Session database modules
-#
-/var/log/freeradius/radutmp /var/log/freeradius/radwtmp {
-       nocreate
-}
-
-#
 #  SQL log files
 #
 /var/log/freeradius/sqllog.sql {
index 51e6617..a26a7d1 100644 (file)
@@ -1,3 +1,56 @@
+FreeRADIUS 3.0.14 Mon 06 Mar 2017 13:00:00 EDT urgency=medium
+       Feature improvements
+       * Enforce TLS client certificate expiration on
+         session resumption, and Session-Timeout.
+         See CVE-2017-9148.
+       * Updated dictionary.cisco.vpn3000, dictionary.patton
+       * Added dictionary.dellemc
+       * Lowered the log output for failed PEAP sessions.
+       * ALlow utc in rlm_date.  Patch from
+         Peter Lambrechtsen.
+       * The internal OpenSSL session cache has been
+         disabled.  Please see mods-available/eap
+       * Update detail reader documentation.
+         Patch from Matthew Newton.  Fixes #1973.
+       * Make outgoing RadSec connections non-blocking.
+       * Add SQL backing to Moonshot-*-TargetedId
+         generation.  Patch from Stefan Paetow.
+
+       Bug fixes
+       * radtest uses Cleartext-Password for EAP, not
+         User-Password.
+       * Update documentation for mods-enabled/ linking.
+       * Enhanced checks for moonshot salt.  Fixes #1933.
+       * Allow session resumption for RadSec connections.
+         Fixes #1936.
+       * Update "huntgroups" file to note that port ranges
+         are not supported.
+       * Fix OpenSSL permissions issues on default key files.
+         Fixes #1941.
+       * Certificates are not required when PSK is used.
+       * Allow SubjectAltName as first extension in cert.
+         Fixes #1946.
+       * Fixed talloc issue with TLS session resumption.
+         Fixes #1980.
+       * "&Attr-26 := 0x01" now produces useful error messages.
+       * Handle connection error in rlm_ldap_cacheable_groupobj.
+         Fixes #1951.
+       * Fix endian issues in DHCP.
+       * Multiple minor fixes for Coverity complaints.
+       * Handle unexpected regex.  Fixes #1959.
+       * Fix minor issues in dictionaries.
+       * Fix typos and grammar.  Patches from Alan Buxey.
+       * Fix erroneous VP creation in rlm_preproces.
+       * Fix MIB.  Patch from Jeff Gehlbach.
+       * Trust router updates from Alejandro Perez.
+       * Allow build with LibreSSL.  Fixes #1989
+       * Use correct packet for channel bindings.  Fixes #1990.
+       * Many fixes found by PVS-Studio.  Thanks to PVS-Studio
+         for giving us a test license.  Please see the git commit
+         history for more information.
+       * Fix incorrect length check in EAP-PWD.  This may
+         be exploitable.
+
 FreeRADIUS 3.0.13 Mon 06 Mar 2017 13:00:00 EDT urgency=medium
        Feature improvements
        * Add dictionary.rfc7930.  Note that we do not implement
index a115711..8cb4009 100644 (file)
@@ -5,7 +5,9 @@ IMPORTS
        OBJECT-IDENTITY
                FROM SNMPv2-SMI
        freeRadiusMgmt
-               FROM FREERADIUS-SMI;
+               FROM FREERADIUS-SMI
+       SnmpAdminString
+               FROM SNMP-FRAMEWORK-MIB;
 
 freeradiusObjects MODULE-IDENTITY
        LAST-UPDATED "200712170000Z"
@@ -25,7 +27,9 @@ freeradiusObjects MODULE-IDENTITY
                "Generic objects used by notification MIBs"
        ::= { freeRadiusMgmt 1 }
 
-radiusObject OBJECT-IDENTITY
+radiusObject OBJECT-TYPE
+       SYNTAX  SnmpAdminString
+       MAX-ACCESS accessible-for-notify
        STATUS  current
        DESCRIPTION
                "A generic object"
index c77a95b..858a6d4 100644 (file)
@@ -76,8 +76,8 @@ ordering when the modules are loaded.
 
 Modules can be enabled by creating a soft link.  For module ``foo``, do::
 
-  $ cd raddb
-  $ ln -s mods-available/foo mods-enabled/foo
+  $ cd raddb/mods-enabled
+  $ ln -s ../mods-available/foo
 
 To create "local" versions of the modules, we suggest copying the file
 instead.  This leaves the original file (with documentation) in the
index 8141ae2..ef243c9 100644 (file)
@@ -62,6 +62,7 @@ ca.key ca.pem: ca.cnf
        @[ -f serial ] || $(MAKE) serial
        $(OPENSSL) req -new -x509 -keyout ca.key -out ca.pem \
                -days $(CA_DEFAULT_DAYS) -config ./ca.cnf
+       chmod g+r ca.key
 
 ca.der: ca.pem
        $(OPENSSL) x509 -inform PEM -outform DER -in ca.pem -out ca.der
@@ -73,15 +74,18 @@ ca.der: ca.pem
 ######################################################################
 server.csr server.key: server.cnf
        $(OPENSSL) req -new  -out server.csr -keyout server.key -config ./server.cnf
+       chmod g+r server.key
 
 server.crt: server.csr ca.key ca.pem
        $(OPENSSL) ca -batch -keyfile ca.key -cert ca.pem -in server.csr  -key $(PASSWORD_CA) -out server.crt -extensions xpserver_ext -extfile xpextensions -config ./server.cnf
 
 server.p12: server.crt
        $(OPENSSL) pkcs12 -export -in server.crt -inkey server.key -out server.p12  -passin pass:$(PASSWORD_SERVER) -passout pass:$(PASSWORD_SERVER)
+       chmod g+r server.p12
 
 server.pem: server.p12
        $(OPENSSL) pkcs12 -in server.p12 -out server.pem -passin pass:$(PASSWORD_SERVER) -passout pass:$(PASSWORD_SERVER)
+       chmod g+r server.pem
 
 .PHONY: server.vrfy
 server.vrfy: ca.pem
@@ -95,15 +99,18 @@ server.vrfy: ca.pem
 ######################################################################
 client.csr client.key: client.cnf
        $(OPENSSL) req -new  -out client.csr -keyout client.key -config ./client.cnf
+       chmod g+r client.key
 
 client.crt: client.csr ca.pem ca.key
        $(OPENSSL) ca -batch -keyfile ca.key -cert ca.pem -in client.csr  -key $(PASSWORD_CA) -out client.crt -extensions xpclient_ext -extfile xpextensions -config ./client.cnf
 
 client.p12: client.crt
        $(OPENSSL) pkcs12 -export -in client.crt -inkey client.key -out client.p12  -passin pass:$(PASSWORD_CLIENT) -passout pass:$(PASSWORD_CLIENT)
+       chmod g+r client.p12
 
 client.pem: client.p12
        $(OPENSSL) pkcs12 -in client.p12 -out client.pem -passin pass:$(PASSWORD_CLIENT) -passout pass:$(PASSWORD_CLIENT)
+       chmod g+r client.pem
        cp client.pem $(USER_NAME).pem
 
 .PHONY: client.vrfy
index bd4737d..2438b81 100644 (file)
@@ -11,4 +11,9 @@
 #
 date {
        format = "%b %e %Y %H:%M:%S %Z"
+
+       # Use UTC instead of local time.
+       #
+       #  default = no
+#      utc = yes
 }
index 427016c..04698ce 100644 (file)
@@ -382,6 +382,12 @@ eap {
                        #  Enable it.  The default is "no". Deleting the entire "cache"
                        #  subsection also disables caching.
                        #
+                       #  As of version 3.0.14, the session cache requires the use
+                       #  of the "name" and "persist_dir" configuration items, below.
+                       #
+                       #  The internal OpenSSL session cache has been permanently
+                       #  disabled.
+                       #
                        #  You can disallow resumption for a particular user by adding the
                        #  following attribute to the control item list:
                        #
@@ -390,7 +396,7 @@ eap {
                        #  If "enable = no" below, you CANNOT enable resumption for just one
                        #  user by setting the above attribute to "yes".
                        #
-                       enable = yes
+                       enable = no
 
                        #
                        #  Lifetime of the cached entries, in hours. The sessions will be
@@ -399,15 +405,6 @@ eap {
                        lifetime = 24 # hours
 
                        #
-                       #  The maximum number of entries in the
-                       #  cache.  Set to "0" for "infinite".
-                       #
-                       #  This could be set to the number of users
-                       #  who are logged in... which can be a LOT.
-                       #
-                       max_entries = 255
-
-                       #
                        #  Internal "name" of the session cache. Used to
                        #  distinguish which TLS context sessions belong to.
                        #
diff --git a/raddb/mods-available/moonshot-targeted-ids b/raddb/mods-available/moonshot-targeted-ids
new file mode 100644 (file)
index 0000000..bcf69bc
--- /dev/null
@@ -0,0 +1,57 @@
+# -*- text -*-
+#
+#  $Id$
+
+#
+#  Write Moonshot-*-TargetedId (MSTID) to the database.
+#
+#  Schema      raddb/sql/moonshot-targeted-ids/<DB>/schema.sql
+#  Queries     raddb/sql/moonshot-targeted-ids/<DB>/queries.conf
+#
+sql moonshot_tid_sql {
+
+       # The dialect of SQL you want to use, this should usually match
+       # the driver below.
+       #
+       # If you're using rlm_sql_null, then it should be the type of
+       # database the logged queries are going to be executed against.
+       dialect = "sqlite"
+
+       # The sub-module to use to execute queries. This should match
+       # the database you're attempting to connect to.
+       #
+       # There are MSTID queries available for:
+       #    * rlm_sql_mysql
+       #    * rlm_sql_postgresql
+       #    * rlm_sql_sqlite
+       #    * rlm_sql_null (log queries to disk)
+       #
+       driver = "rlm_sql_${dialect}"
+
+       sqlite {
+               filename = ${radacctdir}/moonshot-targeted-ids.sqlite
+               bootstrap = ${modconfdir}/${..:name}/moonshot-targeted-ids/sqlite/schema.sql
+       }
+
+       # Write MSTID queries to a logfile. Useful for debugging.
+#      logfile = ${logdir}/moonshot-targeted-id-log.sql
+
+       pool {
+               start = 5
+               min = 4
+               max = 10
+               spare = 3
+               uses = 0
+               lifetime = 0
+               idle_timeout = 60
+       }
+
+       #  If you adjust the table name here, you must also modify the table name in
+       #  the moonshot_get_targeted_id.post-auth policy in policy.d/moonshot-targeted-ids
+       #  and the schema.sql files in the mods-config/sql/moonshot-targeted-ids tree.
+       #
+       moonshot_tid_table = "moonshot_targeted_ids"
+       sql_user_name = "%{User-Name}"
+
+       $INCLUDE ${modconfdir}/${.:name}/moonshot-targeted-ids/${dialect}/queries.conf
+}
index 03d0262..aa5c612 100644 (file)
@@ -9,8 +9,6 @@
 #  It works in conjunction with otpd, which implements token
 #  management and OTP verification functions; and lsmd or gsmd,
 #  which implements synchronous state management functions.
-#  otpd, lsmd and gsmd are available from TRI-D Systems:
-#              <http://www.tri-dsystems.com/>
 
 #  You must list this module in BOTH the authorize and authenticate
 #  sections in order to use it.
index 322d33a..eaf952a 100644 (file)
@@ -9,13 +9,17 @@
 #  Realm, the Huntgroup-Name or any combinaison of the attribute/value
 #  pairs contained in an accounting packet.
 #
-#DEFAULT Realm == "foo.net", Acct-Type := sql_log.foo
+#  You will need to add an "Acct-Type foo {...}" subsection to the
+#  main "accounting" section in order for these sample configurations
+#  to work.
 #
-#DEFAULT Huntgroup-Name == "wifi", Acct-Type := sql_log.wifi
+#DEFAULT Realm == "foo.net", Acct-Type := foo
 #
-#DEFAULT Client-IP-Address == 10.0.0.1, Acct-Type := sql_log.other
+#DEFAULT Huntgroup-Name == "wifi", Acct-Type := wifi
 #
-#DEFAULT Acct-Status-Type == Start, Acct-Type := sql_log.start
+#DEFAULT Client-IP-Address == 10.0.0.1, Acct-Type := other
+#
+#DEFAULT Acct-Status-Type == Start, Acct-Type := start
 
 #  Replace the User-Name with the Stripped-User-Name, if it exists.
 #
index a937c8b..da28dba 100644 (file)
@@ -1,13 +1,10 @@
 #
 # huntgroups   This file defines the `huntgroups' that you have. A
 #              huntgroup is defined by specifying the IP address of
-#              the NAS and possibly a port range. Port can be identified
-#              as just one port, or a range (from-to), and multiple ports
-#              or ranges of ports must be separated by a comma. For
-#              example: 1,2,3-8
+#              the NAS and possibly a port.
 #
 #              Matching is done while RADIUS scans the user file; if it
-#              includes the selection criterium "Huntgroup-Name == XXX"
+#              includes the selection criteria "Huntgroup-Name == XXX"
 #              the huntgroup is looked up in this file to see if it
 #              matches. There can be multiple definitions of the same
 #              huntgroup; the first one that matches will be used.
 #delft         NAS-IP-Address == 198.51.100.5
 
 #
-# Ports 0-7 on the first terminal server in Alphen are connected to
+# Port 0 on the first terminal server in Alphen are connected to
 # a huntgroup that is for business users only. Note that only one
 # of the username or groupname has to match to get access (OR/OR).
 #
 # Note that this huntgroup is a subset of the "alphen" huntgroup.
 #
-#business      NAS-IP-Address == 198.51.100.5, NAS-Port-Id == 0-7
-#              User-Name = rogerl,
-#              User-Name = henks,
-#              Group = business,
-#              Group = staff
+#business      NAS-IP-Address == 198.51.100.5, NAS-Port-Id == 0
+#              User-Name == rogerl,
+#              User-Name == henks,
+#              Group == business,
+#              Group == staff
 
diff --git a/raddb/mods-config/sql/moonshot-targeted-ids/mysql/queries.conf b/raddb/mods-config/sql/moonshot-targeted-ids/mysql/queries.conf
new file mode 100644 (file)
index 0000000..68306db
--- /dev/null
@@ -0,0 +1,15 @@
+# -*- text -*-
+#
+#  moonshot-targeted-ids/mysql/queries.conf -- Queries to update a MySQL Moonshot-Targeted-Ids table.
+#
+#  $Id$
+
+post-auth {
+       #  Query to store the Moonshot-*-TargetedId
+       query = "\
+               INSERT IGNORE INTO ${..moonshot_tid_table} \
+                       (gss_acceptor, namespace, username, targeted_id) \
+               VALUES \
+                       ('%{control:Moonshot-MSTID-GSS-Acceptor}', '%{control:Moonshot-MSTID-Namespace}', \
+                       '%{tolower:%{User-Name}}', '%{control:Moonshot-MSTID-TargetedId}')"
+}
diff --git a/raddb/mods-config/sql/moonshot-targeted-ids/mysql/schema.sql b/raddb/mods-config/sql/moonshot-targeted-ids/mysql/schema.sql
new file mode 100644 (file)
index 0000000..8a33dc1
--- /dev/null
@@ -0,0 +1,8 @@
+CREATE TABLE `moonshot_targeted_ids` (
+  `gss_acceptor` varchar(254) NOT NULL default '',
+  `namespace` varchar(36) NOT NULL default '',
+  `username` varchar(64) NOT NULL default '',
+  `targeted_id` varchar(128) NOT NULL default '',
+  `creationdate` timestamp NOT NULL default CURRENT_TIMESTAMP,
+  PRIMARY KEY  (`username`,`gss_acceptor`,`namespace`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
diff --git a/raddb/mods-config/sql/moonshot-targeted-ids/postgresql/queries.conf b/raddb/mods-config/sql/moonshot-targeted-ids/postgresql/queries.conf
new file mode 100644 (file)
index 0000000..f757a87
--- /dev/null
@@ -0,0 +1,15 @@
+# -*- text -*-
+#
+#  moonshot-targeted-ids/postgresql/queries.conf -- Queries to update a PostgreSQL Moonshot-*-Targeted-Ids table.
+#
+#  $Id$
+
+post-auth {
+       #  Query to store the Moonshot-*-TargetedId
+       query = "\
+               INSERT INTO ${..moonshot_tid_table} \
+                       (gss_acceptor, namespace, username, targeted_id) \
+               VALUES \
+                       ('%{control:Moonshot-MSTID-GSS-Acceptor}', '%{control:Moonshot-MSTID-Namespace}', \
+                       '%{tolower:%{User-Name}}', '%{control:Moonshot-MSTID-TargetedId}')"
+}
diff --git a/raddb/mods-config/sql/moonshot-targeted-ids/postgresql/schema.sql b/raddb/mods-config/sql/moonshot-targeted-ids/postgresql/schema.sql
new file mode 100644 (file)
index 0000000..649c627
--- /dev/null
@@ -0,0 +1,8 @@
+CREATE TABLE moonshot_targeted_ids (
+  gss_acceptor varchar(254) NOT NULL DEFAULT '',
+  namespace varchar(36) NOT NULL DEFAULT '',
+  username varchar(64) NOT NULL DEFAULT '',
+  targeted_id varchar(128) NOT NULL DEFAULT '',
+  creationdate TIMESTAMP with time zone NOT NULL default 'now()',
+  PRIMARY KEY  (username, gss_acceptor, namespace)
+);
diff --git a/raddb/mods-config/sql/moonshot-targeted-ids/sqlite/queries.conf b/raddb/mods-config/sql/moonshot-targeted-ids/sqlite/queries.conf
new file mode 100644 (file)
index 0000000..8cdb803
--- /dev/null
@@ -0,0 +1,15 @@
+# -*- text -*-
+#
+#  moonshot-targeted-ids/sqlite/queries.conf -- Queries to update a sqlite Moonshot-*-Targeted-Ids table.
+#
+#  $Id$
+
+post-auth {
+       #  Query to store the Moonshot-*-TargetedId
+       query = "\
+               INSERT INTO ${..moonshot_tid_table} \
+                       (gss_acceptor, namespace, username, targeted_id) \
+               VALUES \
+                       ('%{control:Moonshot-MSTID-GSS-Acceptor}', '%{control:Moonshot-MSTID-Namespace}', \
+                       '%{tolower:%{User-Name}}', '%{control:Moonshot-MSTID-TargetedId}')"
+}
diff --git a/raddb/mods-config/sql/moonshot-targeted-ids/sqlite/schema.sql b/raddb/mods-config/sql/moonshot-targeted-ids/sqlite/schema.sql
new file mode 100644 (file)
index 0000000..71195ad
--- /dev/null
@@ -0,0 +1,8 @@
+CREATE TABLE `moonshot_targeted_ids` (
+  `gss_acceptor` varchar(254) NOT NULL default '',
+  `namespace` varchar(36) NOT NULL default '',
+  `username` varchar(64) NOT NULL default '',
+  `targeted_id` varchar(128) NOT NULL default '',
+  `creationdate` timestamp NOT NULL default CURRENT_TIMESTAMP,
+  PRIMARY KEY  (`username`,`gss_acceptor`,`namespace`)
+);
index e85b291..3198eba 100644 (file)
@@ -8,6 +8,9 @@
 #  Moonshot-Host-TargetedId (138)
 #  Moonshot-Realm-TargetedId (139)
 #  Moonshot-TR-COI-TargetedId (140)
+#  Moonshot-MSTID-GSS-Acceptor (141)
+#  Moonshot-MSTID-Namespace (142)
+#  Moonshot-MSTID-TargetedId (143)
 #
 #  These attributes should also be listed in the attr_filter policies
 #  post-proxy and pre-proxy when you use attribute filtering:
 #  dictionary attacks, therefore should be chosen as a "random"
 #  string and kept secret.
 #
-targeted_id_salt = "changeme"
+#  If you use special characters %, { and }, escape them with a \ first
+#
+targeted_id_salt = 'changeme'
+
 #
 #  Moonshot namespaces
 #  These namespaces are used for UUID generation.
 #  They should not be changed by implementors
 #
-moonshot_host_namespace = "a574a04e-b7ff-4850-aa24-a8599c7de1c6"
-moonshot_realm_namespace = "dea5f26d-a013-4444-977d-d09fc990d2e6"
-moonshot_coi_namespace = "145d7e7e-7d54-43ee-bbcb-3c6ad9428247"
-#  This policy generates a host-specific targeted ID
+moonshot_host_namespace = 'a574a04e-b7ff-4850-aa24-a8599c7de1c6'
+moonshot_realm_namespace = 'dea5f26d-a013-4444-977d-d09fc990d2e6'
+moonshot_coi_namespace = '145d7e7e-7d54-43ee-bbcb-3c6ad9428247'
+
+
+#  This policy generates a host-specific TargetedId
 #
 moonshot_host_tid.post-auth {
-       #  generate a UUID for Moonshot-Host-TargetedId
-       #  targeted id = (uuid -v 5 [namespace] [username][salt][RP host name])@[IdP realm name]
+       #  retrieve or generate a UUID for Moonshot-Host-TargetedId
        if (&outer.request:GSS-Acceptor-Host-Name) {
-               if ("%{echo:/usr/bin/uuid -v 5 ${policy.moonshot_host_namespace} %{tolower:%{User-Name}}${policy.targeted_id_salt}%{tolower:%{outer.request:GSS-Acceptor-Host-Name}}}" =~ /^([^ ]+)([ ]*)$/) {
+               # prep some variables (used regardless of SQL backing or not!)
+               update control {
+                       Moonshot-MSTID-GSS-Acceptor := "%{tolower:%{outer.request:GSS-Acceptor-Host-Name}}"
+                       Moonshot-MSTID-Namespace := "${policy.moonshot_host_namespace}"
+               }
+
+               #  if you want to use SQL-based backing, remove the comment from
+               #  this line. You also have to configure and enable the 
+               #  moonshot-targeted-ids sql module in mods-enabled. 
+               #
+#              moonshot_get_targeted_id
+
+               #  generate a UUID for Moonshot-Host-TargetedId
+               if (!&control:Moonshot-MSTID-TargetedId) {
+                       #  generate the TID
+                       moonshot_make_targeted_id
+
+                       #  if you want to store your TargetedId in SQL-based backing, 
+                       #  remove the comment from this line. You also have to configure 
+                       #  and enable the moonshot-targeted-ids sql module in mods-enabled.
+                       #
+#                      moonshot_tid_sql
+               }
+
+               #  set the actual TargetedId in the session-state list
+               if (&control:Moonshot-MSTID-TargetedId) {
                        update outer.session-state {
-                               Moonshot-Host-TargetedId := "%{1}@%{tolower:%{request:Realm}}"
+                               Moonshot-Host-TargetedId := &control:Moonshot-MSTID-TargetedId
+                       }
+                       update control {
+                               Moonshot-MSTID-TargetedId !* ANY
                        }
                }
        }
 }
-#  This policy generates a realm-specific targeted ID
+
+#  This policy generates a realm-specific TargetedId
 #
 moonshot_realm_tid.post-auth {
-       #  generate a UUID for Moonshot-Realm-TargetedId
-       #  targeted id = (uuid -v 5 [namespace] [username][salt][RP realm name])@[IdP realm name]
+       #  retrieve or generate a UUID for Moonshot-Realm-TargetedId
        if (&outer.request:GSS-Acceptor-Realm-Name) {
-               if ("%{echo:/usr/bin/uuid -v 5 ${policy.moonshot_realm_namespace} %{tolower:%{User-Name}}${policy.targeted_id_salt}%{tolower:%{outer.request:GSS-Acceptor-Realm-Name}}}" =~ /^([^ ]+)([ ]*)$/) {
+               # prep some variables (used regardless of SQL backing or not!)
+               update control {
+                       Moonshot-MSTID-GSS-Acceptor := "%{tolower:%{outer.request:GSS-Acceptor-Realm-Name}}"
+                       Moonshot-MSTID-Namespace := "${policy.moonshot_realm_namespace}"
+               }
+
+               #  if you want to use SQL-based backing, remove the comment from
+               #  this line. You also have to configure and enable the 
+               #  moonshot-targeted-ids sql module in mods-enabled. 
+               #
+#              moonshot_get_targeted_id
+
+               #  generate a UUID for Moonshot-Realm-TargetedId
+               if (!&control:Moonshot-MSTID-TargetedId) {
+                       #  generate the TID
+                       moonshot_make_targeted_id
+
+                       #  if you want to store your TargetedId in SQL-based backing, 
+                       #  remove the comment from this line. You also have to configure 
+                       #  and enable the moonshot-targeted-ids sql module in mods-enabled.
+                       #
+#                      moonshot_tid_sql
+               }
+
+               #  set the actual TargetedId in the session-state list
+               if (&control:Moonshot-MSTID-TargetedId) {
                        update outer.session-state {
-                               Moonshot-Realm-TargetedId := "%{1}@%{tolower:%{request:Realm}}"
+                               Moonshot-Realm-TargetedId := &control:Moonshot-MSTID-TargetedId
+                       }
+                       update control {
+                               Moonshot-MSTID-TargetedId !* ANY
                        }
                }
        }
 }
+
 #  This policy generates a COI-specific targeted ID
 #
 moonshot_coi_tid.post-auth {
-       #  generate a UUID for Moonshot-TR-COI-TargetedId
-       #  targeted id = (uuid -v 5 [namespace] [username][salt][RP COI name])@[IdP realm name]
+       #  retrieve or generate a UUID for Moonshot-TR-COI-TargetedId
        if (&outer.request:Trust-Router-COI) {
-               if ("%{echo:/usr/bin/uuid -v 5 ${policy.moonshot_coi_namespace} %{tolower:%{User-Name}}${policy.targeted_id_salt}%{tolower:%{outer.request:Trust-Router-COI}}}" =~ /^([^ ]+)([ ]*)$/) {
+               # prep some variables (used regardless of SQL backing or not!)
+               update control {
+                       Moonshot-MSTID-GSS-Acceptor := "%{tolower:%{outer.request:Trust-Router-COI}}"
+                       Moonshot-MSTID-Namespace := "${policy.moonshot_coi_namespace}"
+               }
+
+               #  if you want to use SQL-based backing, remove the comment from
+               #  this line. You also have to configure and enable the 
+               #  moonshot-targeted-ids sql module in mods-enabled. 
+               #
+#              moonshot_get_targeted_id
+
+               #  generate a UUID for Moonshot-TR-COI-TargetedId
+               if (!&control:Moonshot-MSTID-TargetedId) {
+                       #  generate the TID
+                       moonshot_make_targeted_id
+
+                       #  if you want to store your TargetedId in SQL-based backing, 
+                       #  remove the comment from this line. You also have to configure 
+                       #  and enable the moonshot-targeted-ids sql module in mods-enabled.
+                       #
+#                      moonshot_tid_sql
+               }
+
+               #  set the actual TargetedId in the session-state list
+               if (&control:Moonshot-MSTID-TargetedId) {
                        update outer.session-state {
-                               Moonshot-TR-COI-TargetedId := "%{1}@%{tolower:%{request:Realm}}"
+                               Moonshot-TR-COI-TargetedId := &control:Moonshot-MSTID-TargetedId
+                       }
+                       update control {
+                               Moonshot-MSTID-TargetedId !* ANY
+                       }
+               }
+       }
+}
+
+#  This is the generic generation policy. It requires moonshot_host_tid, moonshot_realm_tid, or moonshot_coi_tid to set variables
+#
+moonshot_make_targeted_id.post-auth {
+       #  uses variables set in the control list
+       #
+       if (&control:Moonshot-MSTID-Namespace && &control:Moonshot-MSTID-GSS-Acceptor) {
+               #  targeted id = (uuid -v 5 [namespace] [username][salt][GSS acceptor value])@[IdP realm name]
+               #
+               if ("%{echo:/usr/bin/uuid -v 5 %{control:Moonshot-MSTID-Namespace} %{tolower:%{User-Name}}${policy.targeted_id_salt}%{control:Moonshot-MSTID-GSS-Acceptor}}" =~ /^([^ ]+)([ ]*)$/) {
+                       update control {
+                               Moonshot-MSTID-TargetedId := "%{1}@%{tolower:%{request:Realm}}"
+                       }
+                       if (&control:Moonshot-MSTID-TargetedId =~ /([\%\{\}]+)/) {
+                               update control {
+                                       Moonshot-MSTID-TargetedId !* ANY
+                               }
+                               update outer.session-state {
+                                       Module-Failure-Message = 'Invalid TargetedId generated, check your targeted_id_salt!'
+                               }
+                               reject
+                       }
+               }
+               else {
+                       #  we simply return the 'echo' error message as the Module-Failure-Message, usually a lack of 'uuid'
+                       reject
+               }
+       }
+       else {
+               #  Our variables were not set, so we'll throw an error because there's no point in continuing!
+               update outer.session-state {
+                       Module-Failure-Message = 'Required variables for moonshot_make_targeted_id not set!'
+               }
+               reject
+       }
+}
+
+#  This is the generic retrieval policy. It requires moonshot_host_tid, moonshot_realm_tid, or moonshot_coi_tid to set variables
+#
+moonshot_get_targeted_id.post-auth {
+       #  uses variables set in the control list
+       #
+       if (&control:Moonshot-MSTID-Namespace && &control:Moonshot-MSTID-GSS-Acceptor) {
+               #  retrieve the TargetedId
+               #
+               update control {
+                       Moonshot-MSTID-TargetedId := "%{moonshot_tid_sql:\
+                               SELECT targeted_id FROM moonshot_targeted_ids \
+                               WHERE gss_acceptor = '%{control:Moonshot-MSTID-GSS-Acceptor}' \
+                               AND namespace = '%{control:Moonshot-MSTID-Namespace}' \
+                               AND username = '%{tolower:%{User-Name}}'}"
+               }
+
+               #  if the value is empty, there's no point in setting it and delete it from the control list!
+               if (&control:Moonshot-MSTID-TargetedId == '') {
+                       update control {
+                               Moonshot-MSTID-TargetedId !* ANY
                        }
                }
        }
+       else {
+               #  Our variables were not set, so we'll throw an error because there's no point in continuing!
+               update outer.session-state {
+                       Module-Failure-Message = 'Required variables for moonshot_get_targeted_id not set!'
+               }
+               reject
+       }
 }
index 79d74e6..5dbe143 100644 (file)
@@ -24,7 +24,8 @@ listen {
                cache {
                        enable = no
                        lifetime = 24 # hours
-                       max_entries = 255
+                       name = "abfab-tls"
+#                      persist_dir = ${logdir}/abfab-tls
                }
 
                require_client_cert = yes
index 61bc9e4..f1466da 100644 (file)
@@ -81,12 +81,6 @@ post-auth {
        -sql
 
        #
-       #  Instead of sending the query to the SQL server,
-       #  write it into a log file.
-       #
-#      sql_log
-
-       #
        #  Un-comment the following if you want to modify the user's object
        #  in LDAP after a successful login.
        #
index ba71ea5..8115044 100644 (file)
@@ -43,6 +43,16 @@ server buffered-sql {
                #  The location where the detail file is located.
                #  This should be on local disk, and NOT on an NFS
                #  mounted location!
+               #
+               #  On most systems, this should support file globbing
+               #  e.g. "${radacctdir}/detail-*:*"
+               #  This lets you write many smaller detail files as in
+               #  the example in radiusd.conf: ".../detail-%Y%m%d:%H"
+               #  Writing many small files is often better than writing
+               #  one large file.  File globbing also means that with
+               #  a common naming scheme for detail files, then you can
+               #  have many detail file writers, and only one reader.
+               #
                filename = "${radacctdir}/detail-*"
 
                #
@@ -78,6 +88,7 @@ server buffered-sql {
                #  wake up, and poll for it every N seconds.
                #
                #  Useful range of values: 1 to 60
+               #
                poll_interval = 1
 
                #
@@ -87,6 +98,7 @@ server buffered-sql {
                #  home server responds.
                #
                #  Useful range of values: 5 to 30
+               #
                retry_interval = 30
 
                #
@@ -98,6 +110,17 @@ server buffered-sql {
                #  have already been processed.  The default is "no".
                #
        #       track = yes
+
+               #
+               #  In some circumstances it may be desirable for the
+               #  server to start up, process a detail file, and
+               #  immediately quit. To do this enable the "one_shot"
+               #  option below.
+               #
+               #  Do not enable this for normal server operation. The
+               #  default is "no".
+               #
+       #       one_shot = no
        }
 
        #
index 3c38550..ea39098 100644 (file)
@@ -29,6 +29,11 @@ server copy-acct-to-home-server {
        listen {
                type = detail
 
+               #
+               #  See sites-available/buffered-sql for more details on
+               #  all the options available for the detail reader.
+               #
+
                ######################################################
                #
                #  !!!! WARNING !!!!
@@ -63,6 +68,7 @@ server copy-acct-to-home-server {
                #  one large file.  File globbing also means that with
                #  a common naming scheme for detail files, then you can
                #  have many detail file writers, and only one reader.
+               #
                filename = ${radacctdir}/detail
 
                #
index a440e77..6b1b5b3 100644 (file)
@@ -119,12 +119,6 @@ accounting {
        #  See "Accounting queries" in sql.conf
 #      sql
 
-       #
-       #  Instead of sending the query to the SQL server,
-       #  write it into a log file.
-       #
-#      sql_log
-
        #  Cisco VoIP specific bulk accounting
 #      pgsql-voip
 
index 292abcc..3616050 100644 (file)
@@ -577,7 +577,7 @@ preacct {
        #
 
 #      update request {
-#              FreeRADIUS-Acct-Session-Start-Time = "%{expr: %l - %{%{Acct-Session-Time}:-0} - %{%{Acct-Delay-Time}:-0}}"
+#              &FreeRADIUS-Acct-Session-Start-Time = "%{expr: %l - %{%{Acct-Session-Time}:-0} - %{%{Acct-Delay-Time}:-0}}"
 #      }
 
 
@@ -653,12 +653,6 @@ accounting {
 #              ok
 #      }
 
-       #
-       #  Instead of sending the query to the SQL server,
-       #  write it into a log file.
-       #
-#      sql_log
-
        #  Cisco VoIP specific bulk accounting
 #      pgsql-voip
 
@@ -738,12 +732,6 @@ post-auth {
        -sql
 
        #
-       #  Instead of sending the query to the SQL server,
-       #  write it into a log file.
-       #
-#      sql_log
-
-       #
        #  Un-comment the following if you want to modify the user's object
        #  in LDAP after a successful login.
        #
index b4d26cf..de184a1 100644 (file)
@@ -302,12 +302,6 @@ post-auth {
        -sql
 
        #
-       #  Instead of sending the query to the SQL server,
-       #  write it into a log file.
-       #
-#      sql_log
-
-       #
        #  Un-comment the following if you have set
        #  'edir_account_policy_check = yes' in the ldap module sub-section of
        #  the 'modules' section.
@@ -317,7 +311,14 @@ post-auth {
 
        #
        #  Un-comment the following if you want to generate Moonshot (ABFAB) TargetedIds
-       #  IMPORTANT: This requires the UUID package to be installed!
+       #
+       #  IMPORTANT: This requires the UUID package to be installed, and a targeted_id_salt
+       #             to be configured.
+       #
+       #  This functionality also supports SQL backing. To use this functionality, enable
+       #  and configure the moonshot-targeted-ids SQL module in the mods-enabled directory.
+       #  Then remove the comments from the appropriate lines in each of the below
+       #  policies in the policy.d/moonshot-targeted-ids file.
        #
 #      moonshot_host_tid
 #      moonshot_realm_tid
index c9555e1..cf1cd7a 100644 (file)
@@ -239,6 +239,13 @@ listen {
                      #  Deleting the entire "cache" subsection
                      #  Also disables caching.
                      #
+                       #
+                       #  As of version 3.0.14, the session cache requires the use
+                       #  of the "name" and "persist_dir" configuration items, below.
+                       #
+                       #  The internal OpenSSL session cache has been permanently
+                       #  disabled.
+                       #
                      #  You can disallow resumption for a
                      #  particular user by adding the following
                      #  attribute to the control item list:
@@ -259,15 +266,6 @@ listen {
                      lifetime = 24 # hours
 
                      #
-                     #  The maximum number of entries in the
-                     #  cache.  Set to "0" for "infinite".
-                     #
-                     #  This could be set to the number of users
-                     #  who are logged in... which can be a LOT.
-                     #
-                     max_entries = 255
-
-                     #
                      #  Internal "name" of the session cache.
                      #  Used to distinguish which TLS context
                      #  sessions belong to.
index 6faf336..360765d 100644 (file)
@@ -25,13 +25,6 @@ delaycompress
 }
 
 #
-#  Session database modules
-#
-/var/log/radius/radutmp /var/log/radius/radwtmp {
-       nocreate
-}
-
-#
 #  SQL log files
 #
 /var/log/radius/sqllog.sql {
index ff98677..eb32165 100644 (file)
@@ -26,7 +26,7 @@
 
 Summary: High-performance and highly configurable free RADIUS server
 Name: freeradius
-Version: 3.0.13
+Version: 3.0.14
 Release: 2%{?dist}
 License: GPLv2+ and LGPLv2+
 Group: System Environment/Daemons
@@ -665,6 +665,8 @@ fi
 %attr(640,root,radiusd) %config(noreplace) /etc/raddb/mods-config/sql/main/mysql/*
 %dir %attr(750,root,radiusd) /etc/raddb/mods-config/sql/main/ndb
 %attr(640,root,radiusd) %config(noreplace) /etc/raddb/mods-config/sql/main/ndb/*
+%dir %attr(750,root,radiusd) /etc/raddb/mods-config/sql/moonshot-targeted-ids/mysql
+%attr(640,root,radiusd) %config(noreplace) /etc/raddb/mods-config/sql/moonshot-targeted-ids/mysql/*
 # postgres
 %dir %attr(750,root,radiusd) /etc/raddb/mods-config/sql/counter/postgresql
 %attr(640,root,radiusd) %config(noreplace) /etc/raddb/mods-config/sql/counter/postgresql/*
@@ -674,6 +676,8 @@ fi
 %attr(640,root,radiusd) %config(noreplace) /etc/raddb/mods-config/sql/ippool/postgresql/*
 %dir %attr(750,root,radiusd) /etc/raddb/mods-config/sql/main/postgresql
 %attr(640,root,radiusd) %config(noreplace) /etc/raddb/mods-config/sql/main/postgresql/*
+%dir %attr(750,root,radiusd) /etc/raddb/mods-config/sql/moonshot-targeted-ids/postgresql
+%attr(640,root,radiusd) %config(noreplace) /etc/raddb/mods-config/sql/moonshot-targeted-ids/postgresql/*
 # sqlite
 %dir %attr(750,root,radiusd) /etc/raddb/mods-config/sql/counter/sqlite
 %attr(640,root,radiusd) %config(noreplace) /etc/raddb/mods-config/sql/counter/sqlite/*
@@ -686,6 +690,8 @@ fi
 %attr(640,root,radiusd) %config(noreplace) /etc/raddb/mods-config/sql/ippool/sqlite/*
 %dir %attr(750,root,radiusd) /etc/raddb/mods-config/sql/main/sqlite
 %attr(640,root,radiusd) %config(noreplace) /etc/raddb/mods-config/sql/main/sqlite/*
+%dir %attr(750,root,radiusd) /etc/raddb/mods-config/sql/moonshot-targeted-ids/sqlite
+%attr(640,root,radiusd) %config(noreplace) /etc/raddb/mods-config/sql/moonshot-targeted-ids/sqlite/*
 # ruby
 %if %{?_with_rlm_ruby:1}%{!?_with_rlm_ruby:0}
 %dir %attr(750,root,radiusd) /etc/raddb/mods-config/ruby
index cbeeb5f..e8cf706 100644 (file)
@@ -29,13 +29,6 @@ notifempty
 }
 
 #
-#  Session database modules
-#
-/var/log/radius/radutmp /var/log/radius/radwtmp {
-       nocreate
-}
-
-#
 #  SQL log files
 #
 /var/log/radius/sqllog.sql {
index 03da5d7..fe89609 100644 (file)
@@ -176,6 +176,7 @@ $INCLUDE dictionary.colubris
 $INCLUDE dictionary.compatible
 $INCLUDE dictionary.cosine
 $INCLUDE dictionary.dante
+$INCLUDE dictionary.dellemc
 $INCLUDE dictionary.dlink
 $INCLUDE dictionary.digium
 $INCLUDE dictionary.dragonwave
index ae3f0d7..1d9dfbf 100644 (file)
@@ -1,5 +1,5 @@
 # -*- text -*-
-# Copyright (C) 2015 The FreeRADIUS Server project and contributors
+# Copyright (C) 2017 The FreeRADIUS Server project and contributors
 #
 #       Cisco VPN 3000 Concentrator Dictionary
 #
@@ -84,6 +84,33 @@ ATTRIBUTE    CVPN3000-WebVPN-Exchange-Addr           74      string
 ATTRIBUTE      CVPN3000-LEAP-Bypass                    75      integer
 ATTRIBUTE      CVPN3000-WebVPN-Exchange-NETBIOS-name   78      string
 ATTRIBUTE      CVPN3000-Port-Forwarding-Name           79      string
+ATTRIBUTE      CVPN3000-IE-Proxy-Server                80      string
+ATTRIBUTE      CVPN3000-IE-Proxy-Server-Policy         81      integer
+ATTRIBUTE      CVPN3000-IE-Proxy-Exception-List        82      string
+ATTRIBUTE      CVPN3000-IE-Proxy-Bypass-Local          83      integer
+ATTRIBUTE      CVPN3000-IKE-Keepalive-Retry-Interval   84      integer
+ATTRIBUTE      CVPN3000-Tunnel-Group-Lock              85      string
+ATTRIBUTE      Cisco-VPN3000-Access-List-Inbound       86      string
+ATTRIBUTE      Cisco-VPN3000-Access-List-Outbound      87      string
+ATTRIBUTE      Cisco-VPN3000-Perfect-Forward-Secrecy-Enable 88 integer
+ATTRIBUTE      Cisco-VPN3000-NAC-Enable                89      integer
+ATTRIBUTE      Cisco-VPN3000-NAC-Status-Query-Timer    90      integer
+ATTRIBUTE      Cisco-VPN3000-NAC-Revalidation-Timer    91      integer
+ATTRIBUTE      Cisco-VPN3000-NAC-Default-ACL           92      integer
+ATTRIBUTE      Cisco-VPN3000-WebVPN-URL-Entry-Enable   93      integer
+ATTRIBUTE      Cisco-VPN3000-WebVPN-File-Access-Enable 94      integer
+ATTRIBUTE      Cisco-VPN3000-WebVPN-File-Server-Entry-Enable 95        integer
+ATTRIBUTE      Cisco-VPN3000-WebVPN-File-Server-Browsing-Enable 96     integer
+ATTRIBUTE      Cisco-VPN3000-WebVPN-Port-Forwarding-Enable 97  integer
+ATTRIBUTE      Cisco-VPN3000-WebVPN-Outlook-Exchange-Proxy-Enable 98   integer
+ATTRIBUTE      Cisco-VPN3000-WebVPN-Outlook-Exchange-Proxy-Enable 99   integer
+ATTRIBUTE      Cisco-VPN3000-WebVPN-Auto-Applet-Download-Enable 100    integer
+ATTRIBUTE      Cisco-VPN3000-WebVPN-Citrix-MetaFrame-Enable 101        integer
+ATTRIBUTE      Cisco-VPN3000-WebVPN-Apply-ACL          102     integer
+ATTRIBUTE      Cisco-VPN3000-WebVPN-SSL-VPN-Client-Enable 103  integer
+ATTRIBUTE      Cisco-VPN3000-WebVPN-SSL-VPN-Client-Required 104        integer
+ATTRIBUTE      Cisco-VPN3000-WebVPN-SSL-VPN-Client-Keep-Installation 105       integer
+
 ATTRIBUTE      CVPN3000-Partition-Primary-DHCP         128     ipaddr
 ATTRIBUTE      CVPN3000-Partition-Secondary-DHCP       129     ipaddr
 ATTRIBUTE      CVPN3000-Partition-Premise-Router       131     ipaddr
diff --git a/share/dictionary.dellemc b/share/dictionary.dellemc
new file mode 100644 (file)
index 0000000..68c2758
--- /dev/null
@@ -0,0 +1,18 @@
+# -*- text -*-
+# Copyright (C) 2017 The FreeRADIUS Server project and contributors
+#
+#   Dell Inc.
+#
+#   DellEMC-AVpair      Attribute-Value Pair.
+#   DellEMC-Group-Name  The Linux primary group name associated with the user.
+#                       This must be an existing group in /etc/groups.
+
+VENDOR         DellEMC                         674
+
+BEGIN-VENDOR   DellEMC
+
+ATTRIBUTE      DellEMC-AVpair                          1       string
+ATTRIBUTE      DellEMC-Group-Name                      2       string
+
+END-VENDOR DellEMC
+
index cf79ae1..9744211 100644 (file)
@@ -332,8 +332,8 @@ ATTRIBUTE   DHCP-Call-Server-IP-address             129     octets
 ATTRIBUTE      DHCP-Ethernet-Interface                 130     octets
 ATTRIBUTE      DHCP-Vendor-Discrimination-Str          130     octets
 ATTRIBUTE      DHCP-Remote-Stats-Svr-IP-Address        131     octets
-ATTRIBUTE      DHCP-IEEE-802.1P-VLAN-ID                132     octets
-ATTRIBUTE      DHCP-IEEE-802.1Q-L2-Priority            133     octets
+ATTRIBUTE      DHCP-IEEE-802.1Q-VLAN-ID                132     octets
+ATTRIBUTE      DHCP-IEEE-802.1P-L2-Priority            133     octets
 ATTRIBUTE      DHCP-Diffserv-Code-Point                134     octets
 ATTRIBUTE      DHCP-HTTP-Proxy                         135     octets
 
index 965702c..98ea04f 100644 (file)
@@ -59,8 +59,8 @@ ATTRIBUTE     ERX-Primary-Dns                         4       ipaddr
 ATTRIBUTE      ERX-Secondary-Dns                       5       ipaddr
 ATTRIBUTE      ERX-Primary-Wins                        6       ipaddr
 ATTRIBUTE      ERX-Secondary-Wins                      7       ipaddr
-ATTRIBUTE      ERX-Tunnel-Virtual-Router               8       string
-ATTRIBUTE      ERX-Tunnel-Password                     9       string
+ATTRIBUTE      ERX-Tunnel-Virtual-Router               8       string  has_tag
+ATTRIBUTE      ERX-Tunnel-Password                     9       string  has_tag
 ATTRIBUTE      ERX-Ingress-Policy-Name                 10      string
 ATTRIBUTE      ERX-Egress-Policy-Name                  11      string
 ATTRIBUTE      ERX-Ingress-Statistics                  12      integer
index 390bd57..30baba1 100644 (file)
@@ -743,15 +743,18 @@ VALUE     EAP-Type                        Identity                1
 VALUE  EAP-Type                        Notification            2
 VALUE  EAP-Type                        NAK                     3
 VALUE  EAP-Type                        MD5-Challenge           4
+VALUE  EAP-Type                        EAP-MD5                 4
 VALUE  EAP-Type                        MD5                     4
 VALUE  EAP-Type                        One-Time-Password       5
 VALUE  EAP-Type                        OTP                     5
 VALUE  EAP-Type                        Generic-Token-Card      6
+VALUE  EAP-Type                        EAP-GTC                 6
 VALUE  EAP-Type                        GTC                     6
 VALUE  EAP-Type                        RSA-Public-Key          9
 VALUE  EAP-Type                        DSS-Unilateral          10
 VALUE  EAP-Type                        KEA                     11
 VALUE  EAP-Type                        KEA-Validate            12
+VALUE  EAP-Type                        EAP-TLS                 13
 VALUE  EAP-Type                        TLS                     13
 VALUE  EAP-Type                        Defender-Token          14
 VALUE  EAP-Type                        RSA-SecurID-EAP         15
@@ -759,11 +762,14 @@ VALUE     EAP-Type                        Arcot-Systems-EAP       16
 VALUE  EAP-Type                        Cisco-LEAP              17
 VALUE  EAP-Type                        LEAP                    17
 VALUE  EAP-Type                        Nokia-IP-Smart-Card     18
+VALUE  EAP-Type                        EAP-SIM                 18
 VALUE  EAP-Type                        SIM                     18
 VALUE  EAP-Type                        SRP-SHA1                19
 # 20 is unassigned
+VALUE  EAP-Type                        EAP-TTLS                21
 VALUE  EAP-Type                        TTLS                    21
 VALUE  EAP-Type                        Remote-Access-Service   22
+VALUE  EAP-Type                        EAP-AKA                 23
 VALUE  EAP-Type                        AKA                     23
 VALUE  EAP-Type                        3Com-Wireless           24
 VALUE  EAP-Type                        PEAP                    25
@@ -785,12 +791,14 @@ VALUE     EAP-Type                        SecuriSuite-EAP         39
 VALUE  EAP-Type                        DeviceConnect-EAP       40
 VALUE  EAP-Type                        SPEKE                   41
 VALUE  EAP-Type                        MOBAC                   42
+VALUE  EAP-Type                        EAP-FAST                43
 VALUE  EAP-Type                        FAST                    43
 VALUE  EAP-Type                        Zonelabs                44
 VALUE  EAP-Type                        Link                    45
 VALUE  EAP-Type                        PAX                     46
 VALUE  EAP-Type                        PSK                     47
 VALUE  EAP-Type                        SAKE                    48
+VALUE  EAP-Type                        EAP-IKEv2               49
 VALUE  EAP-Type                        IKEv2                   49
 VALUE  EAP-Type                        AKA2                    50
 VALUE  EAP-Type                        GPSK                    51
@@ -800,6 +808,7 @@ VALUE       EAP-Type                        EKEv1                   53
 #
 #      And this is what most people mean by MS-CHAPv2
 #
+VALUE  EAP-Type                        EAP-MSCHAPv2            26
 VALUE  EAP-Type                        MSCHAPv2                26
 
 #
index d330259..a24cdf7 100644 (file)
@@ -14,6 +14,7 @@ VENDOR                Patton                          1768
 
 BEGIN-VENDOR   Patton
 
+ATTRIBUTE      Patton-Protocol                 16      string
 ATTRIBUTE      Patton-Setup-Time                       32      string
 ATTRIBUTE      Patton-Connect-Time                     33      string
 ATTRIBUTE      Patton-Disconnect-Time                  34      string
@@ -24,6 +25,7 @@ ATTRIBUTE     Patton-Called-IP-Address                49      ipaddr
 ATTRIBUTE      Patton-Called-Numbering-Plan            50      string
 ATTRIBUTE      Patton-Called-Type-Of-Number            51      string
 ATTRIBUTE      Patton-Called-Name                      52      string
+ATTRIBUTE Patton-Called-Station-Id                     53      string
 ATTRIBUTE      Patton-Called-Rx-Octets                 64      integer
 ATTRIBUTE      Patton-Called-Tx-Octets                 65      integer
 ATTRIBUTE      Patton-Called-Rx-Packets                66      integer
@@ -33,6 +35,10 @@ ATTRIBUTE    Patton-Called-Tx-Lost-Packets           69      integer
 ATTRIBUTE      Patton-Called-Rx-Jitter                 70      integer
 ATTRIBUTE      Patton-Called-Tx-Jitter                 71      integer
 ATTRIBUTE      Patton-Called-Codec                     72      string
+ATTRIBUTE      Patton-Called-Remote-Ip                 73      integer
+ATTRIBUTE      Patton-Called-Remote-Udp-Port                   74      integer
+ATTRIBUTE      Patton-Called-Local-Udp-Port                    75      integer
+ATTRIBUTE      Patton-Called-Qos                       76      integer
 ATTRIBUTE      Patton-Called-MOS                       77      integer
 ATTRIBUTE      Patton-Called-Round-Trip-Time           78      integer
 ATTRIBUTE      Patton-Calling-Unique-Id                80      string
@@ -42,6 +48,7 @@ ATTRIBUTE     Patton-Calling-Type-Of-Number           83      string
 ATTRIBUTE      Patton-Calling-Presentation-Indicator   88      string
 ATTRIBUTE      Patton-Calling-Screening-Indicator      89      string
 ATTRIBUTE      Patton-Calling-Name                     84      string
+ATTRIBUTE      Patton-Calling-Station-Id                       85      string
 ATTRIBUTE      Patton-Calling-Rx-Octets                96      integer
 ATTRIBUTE      Patton-Calling-Tx-Octets                97      integer
 ATTRIBUTE      Patton-Calling-Rx-Packets               98      integer
@@ -51,6 +58,10 @@ ATTRIBUTE    Patton-Calling-Lost-Rx-Packets          101     integer
 ATTRIBUTE      Patton-Calling-Rx-Jitter                102     integer
 ATTRIBUTE      Patton-Calling-Tx-Jitter                103     integer
 ATTRIBUTE      Patton-Calling-Codec                    104     string
+ATTRIBUTE      Patton-Calling-Remote-Ip                        105     integer
+ATTRIBUTE      Patton-Calling-Remote-Udp-Port                  106     integer
+ATTRIBUTE      Patton-Calling-Local-Udp-Port                   107     integer
+ATTRIBUTE      Patton-Calling-Qos                      108     integer
 ATTRIBUTE      Patton-Calling-MOS                      109     integer
 ATTRIBUTE      Patton-Calling-Round-Trip-Time          110     integer
 
index 54f7d3e..201d8a9 100644 (file)
@@ -21,5 +21,8 @@ ATTRIBUTE     Trust-Router-APC                        137     string
 ATTRIBUTE      Moonshot-Host-TargetedId                138     string
 ATTRIBUTE      Moonshot-Realm-TargetedId               139     string
 ATTRIBUTE      Moonshot-TR-COI-TargetedId              140     string
+ATTRIBUTE      Moonshot-MSTID-GSS-Acceptor             141     string
+ATTRIBUTE      Moonshot-MSTID-Namespace                142     string
+ATTRIBUTE      Moonshot-MSTID-TargetedId               143     string
 
 END-VENDOR UKERNA
index df5eb02..844ad2f 100644 (file)
@@ -45,6 +45,7 @@ ATTRIBUTE     ZTE-TCP-Limit-Num                       95      integer
 ATTRIBUTE      ZTE-TCP-Limit-Mode                      96      integer
 ATTRIBUTE      ZTE-IGMP-Service-Profile-Num            97      integer
 ATTRIBUTE      ZTE-PPP-Sservice-Type                   101     integer
+ATTRIBUTE      ZTE-SW-Privilege                        104     integer
 ATTRIBUTE      ZTE-Access-Domain                       151     string
 ATTRIBUTE      ZTE-VPN-ID                              190     string
 
index 520553b..6c4629b 100644 (file)
@@ -137,6 +137,7 @@ typedef struct _tls_session_t {
        unsigned int    (*record_minus)(record_t *buf, void *ptr, unsigned int size);
 
        bool            invalid_hb_used;                //!< Whether heartbleed attack was detected.
+       bool            connected;                      //!< whether the outgoing socket is connected
 
        /*
         *      Framed-MTU attribute in RADIUS, if present, can also be used to set this
@@ -308,6 +309,7 @@ tls_session_t       *tls_new_session(TALLOC_CTX *ctx, fr_tls_server_conf_t *conf, REQU
 tls_session_t  *tls_new_client_session(TALLOC_CTX *ctx, fr_tls_server_conf_t *conf, int fd);
 fr_tls_server_conf_t *tls_server_conf_parse(CONF_SECTION *cs);
 fr_tls_server_conf_t *tls_client_conf_parse(CONF_SECTION *cs);
+fr_tls_server_conf_t *tls_server_conf_alloc(TALLOC_CTX *ctx);
 SSL_CTX                *tls_init_ctx(fr_tls_server_conf_t *conf, int client);
 int            tls_handshake_recv(REQUEST *, tls_session_t *ssn);
 int            tls_handshake_send(REQUEST *, tls_session_t *ssn);
index 7f447e3..c547ed8 100644 (file)
@@ -104,7 +104,7 @@ fr_cbuff_t *fr_cbuff_alloc(TALLOC_CTX *ctx, uint32_t size, UNUSED bool lock)
 void fr_cbuff_rp_insert(fr_cbuff_t *cbuff, void *obj)
 {
 #ifdef HAVE_PTHREAD_H
-       if (cbuff->lock) PTHREAD_MUTEX_LOCK(cbuff);
+       PTHREAD_MUTEX_LOCK(cbuff);
 #endif
 
        if (cbuff->elem[cbuff->in]) {
@@ -121,7 +121,7 @@ void fr_cbuff_rp_insert(fr_cbuff_t *cbuff, void *obj)
        }
 
 #ifdef HAVE_PTHREAD_H
-       if (cbuff->lock) PTHREAD_MUTEX_UNLOCK(cbuff);
+       PTHREAD_MUTEX_UNLOCK(cbuff);
 #endif
 }
 
@@ -136,7 +136,7 @@ void *fr_cbuff_rp_next(fr_cbuff_t *cbuff, TALLOC_CTX *ctx)
        void *obj = NULL;
 
 #ifdef HAVE_PTHREAD_H
-       if (cbuff->lock) PTHREAD_MUTEX_LOCK(cbuff);
+       PTHREAD_MUTEX_LOCK(cbuff);
 #endif
 
        /* Buffer is empty */
@@ -147,7 +147,7 @@ void *fr_cbuff_rp_next(fr_cbuff_t *cbuff, TALLOC_CTX *ctx)
 
 done:
 #ifdef HAVE_PTHREAD_H
-       if (cbuff->lock) PTHREAD_MUTEX_UNLOCK(cbuff);
+       PTHREAD_MUTEX_UNLOCK(cbuff);
 #endif
        return obj;
 }
index 587482f..6449b29 100644 (file)
@@ -1871,7 +1871,7 @@ static char *mystrtok(char **ptr, char const *sep)
  */
 int fr_get_time(char const *date_str, time_t *date)
 {
-       int             i;
+       int             i, j;
        time_t          t;
        struct tm       *tm, s_tm;
        char            buf[64];
@@ -1928,9 +1928,9 @@ int fr_get_time(char const *date_str, time_t *date)
                        f[0] = f[i];
                        f[i] = p;
 
-                       for (i = 0; i < 12; i++) {
-                               if (strncasecmp(months[i], f[0], 3) == 0) {
-                                       tm->tm_mon = i;
+                       for (j = 0; j < 12; j++) {
+                               if (strncasecmp(months[j], f[0], 3) == 0) {
+                                       tm->tm_mon = j;
                                        break;
                                }
                        }
index 22fea07..95b8c54 100644 (file)
@@ -321,10 +321,9 @@ HMAC_CTX *HMAC_CTX_new(void)
 {
        HMAC_CTX *ctx;
        ctx = OPENSSL_malloc(sizeof(*ctx));
+       if (!ctx) return NULL;
+
        memset(ctx, 0, sizeof(*ctx));
-       if (ctx == NULL) {
-                return NULL;
-        }
         HMAC_CTX_init(ctx);
        return ctx;
 }
index ad6b15b..245b86c 100644 (file)
@@ -1606,7 +1606,7 @@ int rad_vp2rfc(RADIUS_PACKET const *packet,
        /*
         *      Message-Authenticator is hard-coded.
         */
-       if (!vp->da->vendor && (vp->da->attr == PW_MESSAGE_AUTHENTICATOR)) {
+       if (vp->da->attr == PW_MESSAGE_AUTHENTICATOR) {
                if (room < 18) return -1;
 
                ptr[0] = PW_MESSAGE_AUTHENTICATOR;
index ecf42ed..79e639e 100644 (file)
@@ -197,7 +197,7 @@ static int CC_HINT(nonnull) rad_check_password(REQUEST *request)
         *      Warn if more than one Auth-Type was found, because only the last
         *      one found will actually be used.
         */
-       if ((auth_type_count > 1) && (rad_debug_lvl)) {
+       if ((auth_type_count > 1) && (rad_debug_lvl) && request->username) {
                RERROR("Warning:  Found %d auth-types on request for user '%s'",
                        auth_type_count, request->username->vp_strvalue);
        }
index d3b729f..34c5268 100644 (file)
@@ -345,7 +345,7 @@ static int fr_server_domain_socket_perm(UNUSED char const *path, UNUSED uid_t ui
  */
 static int fr_server_domain_socket_perm(char const *path, uid_t uid, gid_t gid)
 {
-       int                     dir_fd = -1, path_fd = -1, sock_fd = -1, parent_fd = -1;
+       int                     dir_fd = -1, sock_fd = -1, parent_fd = -1;
        char const              *name;
        char                    *buff = NULL, *dir = NULL, *p;
 
@@ -392,8 +392,9 @@ static int fr_server_domain_socket_perm(char const *path, uid_t uid, gid_t gid)
                fr_strerror_printf("Failed determining parent directory");
        error:
                talloc_free(dir);
-               close(dir_fd);
-               close(path_fd);
+               if (sock_fd >= 0) close(sock_fd);
+               if (dir_fd >= 0) close(dir_fd);
+               if (parent_fd >= 0) close(parent_fd);
                return -1;
        }
 
@@ -459,7 +460,7 @@ static int fr_server_domain_socket_perm(char const *path, uid_t uid, gid_t gid)
                if (ret < 0) {
                        fr_strerror_printf("Failed changing ownership of control socket directory: %s",
                                           fr_syserror(errno));
-                       return -1;
+                       goto error;
                }
        /*
         *      Control socket dir already exists, but we still need to
@@ -527,7 +528,7 @@ static int fr_server_domain_socket_perm(char const *path, uid_t uid, gid_t gid)
                if (client_fd >= 0) {
                        fr_strerror_printf("Control socket '%s' is already in use", path);
                        close(client_fd);
-                       return -1;
+                       goto error;
                }
        }
 
@@ -676,8 +677,8 @@ static int fr_server_domain_socket_perm(char const *path, uid_t uid, gid_t gid)
        if (uid != (uid_t)-1) rad_seuid(euid);
        if (gid != (gid_t)-1) rad_segid(egid);
 
-       close(dir_fd);
-       close(path_fd);
+       if (dir_fd >= 0) close(dir_fd);
+       if (parent_fd >= 0) close(parent_fd);
 
        return sock_fd;
 }
index df78184..5f4c722 100644 (file)
@@ -1393,10 +1393,12 @@ int cf_item_parse(CONF_SECTION *cs, char const *name, unsigned int type, void *d
        CONF_PAIR *cp = NULL;
        fr_ipaddr_t *ipaddr;
        char buffer[8192];
-       CONF_ITEM *c_item = &cs->item;
+       CONF_ITEM *c_item;
 
        if (!cs) return -1;
 
+       c_item = &cs->item;
+
        deprecated = (type & PW_TYPE_DEPRECATED);
        required = (type & PW_TYPE_REQUIRED);
        attribute = (type & PW_TYPE_ATTRIBUTE);
@@ -1474,7 +1476,6 @@ int cf_item_parse(CONF_SECTION *cs, char const *name, unsigned int type, void *d
 
        if (!value) {
                if (required) {
-               is_required:
                        cf_log_err(c_item, "Configuration item \"%s\" must have a value", name);
 
                        return -1;
@@ -1620,7 +1621,6 @@ int cf_item_parse(CONF_SECTION *cs, char const *name, unsigned int type, void *d
                        }
                }
 
-               if (required && !value) goto is_required;
                if (cant_be_empty && (value[0] == '\0')) goto cant_be_empty;
 
                if (attribute) {
index 633364f..3c0e95c 100644 (file)
@@ -385,6 +385,8 @@ int detail_recv(rad_listen_t *listener)
        rcode = read(data->master_pipe[0], &packet, sizeof(packet));
        if (rcode <= 0) return rcode;
 
+       rad_assert(packet != NULL);
+
        if (DEBUG_ENABLED2) {
                VALUE_PAIR *vp;
                vp_cursor_t cursor;
@@ -396,7 +398,6 @@ int detail_recv(rad_listen_t *listener)
                        debug_pair(vp);
                }
        }
-       rad_assert(packet != NULL);
 
        switch (packet->code) {
        case PW_CODE_ACCOUNTING_REQUEST:
index f01eeec..a8ef5d9 100644 (file)
@@ -164,8 +164,7 @@ static int cond_do_regex(REQUEST *request, fr_cond_t const *c,
        regmatch_t      rxmatch[REQUEST_MAX_REGEX + 1]; /* +1 for %{0} (whole match) capture group */
        size_t          nmatch = sizeof(rxmatch) / sizeof(regmatch_t);
 
-       rad_assert(lhs_type == PW_TYPE_STRING);
-       rad_assert(lhs != NULL);
+       if (!lhs || (lhs_type != PW_TYPE_STRING)) return -1;
 
        EVAL_DEBUG("CMP WITH REGEX %s %s",
                   map->rhs->tmpl_iflag ? "CASE INSENSITIVE" : "CASE SENSITIVE",
@@ -363,8 +362,6 @@ static size_t regex_escape(UNUSED REQUEST *request, char *out, size_t outlen, ch
                case '[':       /* we don't list close braces */
                case '{':
                case '(':
-                       if (outlen < 3) goto done;
-
                        *(p++) = '\\';
                        outlen--;
                        /* FALL-THROUGH */
@@ -376,7 +373,6 @@ static size_t regex_escape(UNUSED REQUEST *request, char *out, size_t outlen, ch
                }
        }
 
-done:
        *(p++) = '\0';
        return p - out;
 }
index 77fdd2e..d5b3a9a 100644 (file)
@@ -86,7 +86,6 @@ pid_t radius_start_program(char const *cmd, REQUEST *request, bool exec_wait,
                           VALUE_PAIR *input_pairs, bool shell_escape)
 {
 #ifndef __MINGW32__
-       char *p;
        VALUE_PAIR *vp;
        int n;
        int to_child[2] = {-1, -1};
@@ -169,6 +168,8 @@ pid_t radius_start_program(char const *cmd, REQUEST *request, bool exec_wait,
                         */
                        snprintf(buffer, sizeof(buffer), "%s=", vp->da->name);
                        if (shell_escape) {
+                               char *p;
+
                                for (p = buffer; *p != '='; p++) {
                                        if (*p == '-') {
                                                *p = '_';
index b277c6b..61c299e 100644 (file)
@@ -2623,18 +2623,11 @@ static int listen_bind(rad_listen_t *this)
 #ifdef WITH_TCP
        if (sock->proto == IPPROTO_TCP) {
                /*
-                *      If there are hard-coded worker threads, OR
-                *      it's a TLS connection, it's blocking.
+                *      Woker threads are blocking.
                 *
                 *      Otherwise, they're non-blocking.
                 */
-               if (!this->workers
-#ifdef WITH_PROXY
-#ifdef WITH_TLS
-                   && (this->type == RAD_LISTEN_PROXY) && !this->tls
-#endif
-#endif
-                       ) {
+               if (!this->workers) {
                        if (fr_nonblock(this->fd) < 0) {
                                close(this->fd);
                                ERROR("Failed setting non-blocking on socket: %s",
index 312b1bb..c385db2 100644 (file)
@@ -1664,7 +1664,7 @@ int modcall_fixup_update(vp_map_t *map, UNUSED void *ctx)
 
                                if (!map_cast_from_hex(map, T_BARE_WORD, vpt->name)) {
                                        map->rhs = vpt;
-                                       cf_log_err(map->ci, "%s", fr_strerror());
+                                       cf_log_err(map->ci, "Cannot parse RHS hex as the data type of the attribute %s", map->lhs->tmpl_da->name);
                                        return -1;
                                }
                                talloc_free(vpt);
@@ -1684,9 +1684,9 @@ int modcall_fixup_update(vp_map_t *map, UNUSED void *ctx)
                                da = dict_attrbytype(map->lhs->tmpl_da->attr, map->lhs->tmpl_da->vendor,
                                                     map->rhs->tmpl_data_type);
                                if (!da) {
-                                       fr_strerror_printf("Cannot find %s variant of attribute \"%s\"",
-                                                          fr_int2str(dict_attr_types, map->rhs->tmpl_data_type,
-                                                          "<INVALID>"), map->lhs->tmpl_da->name);
+                                       cf_log_err(map->ci, "Cannot find %s variant of attribute \"%s\"",
+                                                  fr_int2str(dict_attr_types, map->rhs->tmpl_data_type,
+                                                             "<INVALID>"), map->lhs->tmpl_da->name);
                                        return -1;
                                }
                                map->lhs->tmpl_da = da;
@@ -2095,7 +2095,12 @@ static modcallable *do_compile_modxlat(modcallable *parent,
        memcpy(csingle->actions, defaultactions[component][GROUPTYPE_SIMPLE],
               sizeof(csingle->actions));
 
-       mx->xlat_name = strdup(fmt);
+       mx->xlat_name = talloc_strdup(mx, fmt);
+       if (!mx->xlat_name) {
+               talloc_free(mx);
+               return NULL;
+       }
+
        if (fmt[0] != '%') {
                char *p;
                mx->exec = true;
@@ -3324,7 +3329,7 @@ static bool pass2_callback(void *ctx, fr_cond_t *c)
 
                                        if (!map_cast_from_hex(map, T_BARE_WORD, vpt->name)) {
                                                map->rhs = vpt;
-                                               cf_log_err(map->ci, "%s", fr_strerror());
+                                               cf_log_err(map->ci, "Cannot parse RHS hex as the data type of the attribute %s", map->lhs->tmpl_da->name);
                                                return -1;
                                        }
                                        talloc_free(vpt);
index 91218dd..749c07e 100644 (file)
@@ -578,7 +578,7 @@ static int module_conf_parse(module_instance_t *node, void **handle)
         */
        if (node->entry->module->inst_size) {
                *handle = talloc_zero_array(node, uint8_t, node->entry->module->inst_size);
-               rad_assert(handle);
+               rad_assert(*handle);
 
                talloc_set_name(*handle, "rlm_%s_t",
                                node->entry->module->name ? node->entry->module->name : "config");
@@ -1248,7 +1248,8 @@ static int load_component_section(CONF_SECTION *cs,
 
 static int load_byserver(CONF_SECTION *cs)
 {
-       rlm_components_t comp, found;
+       rlm_components_t comp;
+       bool found;
        char const *name = cf_section_name2(cs);
        rbtree_t *components;
        virtual_server_t *server = NULL;
@@ -1286,7 +1287,7 @@ static int load_byserver(CONF_SECTION *cs)
         *      Loop over all of the known components, finding their
         *      configuration section, and loading it.
         */
-       found = 0;
+       found = false;
        for (comp = 0; comp < MOD_COUNT; ++comp) {
                CONF_SECTION *subcs;
 
@@ -1346,7 +1347,7 @@ static int load_byserver(CONF_SECTION *cs)
 
                server->subcs[comp] = subcs;
 
-               found = 1;
+               found = true;
        } /* loop over components */
 
        /*
index fea349e..f679ade 100644 (file)
@@ -79,6 +79,8 @@ int radius_compare_vps(UNUSED REQUEST *request, VALUE_PAIR *check, VALUE_PAIR *v
                char *expr = NULL, *value = NULL;
                char const *expr_p, *value_p;
 
+               if (!vp) return -2;
+
                if (check->da->type == PW_TYPE_STRING) {
                        expr_p = check->vp_strvalue;
                } else {
index c5a6906..e3e32f4 100644 (file)
@@ -485,6 +485,8 @@ static struct timeval *request_response_window(REQUEST *request)
 {
        VERIFY_REQUEST(request);
 
+       rad_assert(request->home_server != NULL);
+
        if (request->client) {
                /*
                 *      The client hasn't set the response window.  Return
@@ -500,7 +502,6 @@ static struct timeval *request_response_window(REQUEST *request)
                }
        }
 
-       rad_assert(request->home_server != NULL);
        return &request->home_server->response_window;
 }
 
@@ -2122,8 +2123,9 @@ static void remove_from_proxy_hash_nl(REQUEST *request, bool yank)
        }
 
 #ifdef WITH_TCP
-       rad_assert(request->proxy_listener != NULL);
-       request->proxy_listener->count--;
+       if (request->proxy_listener) {
+               request->proxy_listener->count--;
+       }
 #endif
        request->proxy_listener = NULL;
 
@@ -2569,8 +2571,6 @@ int request_proxy_reply(RADIUS_PACKET *packet)
 
 #ifdef WITH_ACCOUNTING
        case PW_CODE_ACCOUNTING_REQUEST:
-               proxy_acct_stats.last_packet = packet->timestamp.tv_sec;
-
                request->proxy_listener->stats.total_responses++;
                proxy_acct_stats.last_packet = packet->timestamp.tv_sec;
                break;
index 7f009ae..38b1ba9 100644 (file)
@@ -81,7 +81,7 @@ do
                                PASSWORD="MS-CHAP-Password"
                                ;;
                        eap-md5)
-                               PASSWORD="User-Password"
+                               PASSWORD="Cleartext-Password"
                                if [ ! -x "$radeapclient" ]
                                then
                                    echo "radtest: No 'radeapclient' program was found.  Cannot perform EAP-MD5." >&1
index 2a047e0..d1fafcf 100644 (file)
@@ -1156,7 +1156,7 @@ void realm_pool_free(home_pool_t *pool)
        }
 
        this->next = NULL;
-       this->when = now + 60;
+       this->when = now + 300;
        this->pool = pool;
        pthread_mutex_unlock(&pool_free_mutex);
 }
index 161834e..b195a7c 100644 (file)
@@ -479,7 +479,6 @@ bool fr_state_put_vps(REQUEST *request, RADIUS_PACKET *original, RADIUS_PACKET *
 
        PTHREAD_MUTEX_UNLOCK(&state->mutex);
 
-       rad_assert(request->state == NULL);
        VERIFY_REQUEST(request);
        return true;
 }
index 05cb577..753bf2d 100644 (file)
@@ -505,6 +505,7 @@ tls_session_t *tls_new_client_session(TALLOC_CTX *ctx, fr_tls_server_conf_t *con
        talloc_set_destructor(ssn, _tls_session_free);
 
        ssn->ctx = conf->ctx;
+       ssn->mtu = conf->fragment_size;
 
        SSL_CTX_set_mode(ssn->ctx, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER | SSL_MODE_AUTO_RETRY);
 
@@ -537,6 +538,21 @@ tls_session_t *tls_new_client_session(TALLOC_CTX *ctx, fr_tls_server_conf_t *con
        SSL_set_ex_data(ssn->ssl, FR_TLS_EX_INDEX_SSN, (void *)ssn);
        SSL_set_fd(ssn->ssl, fd);
        ret = SSL_connect(ssn->ssl);
+
+       if (ret < 0) {
+               switch (SSL_get_error(ssn->ssl, ret)) {
+                       default:
+                               break;
+
+
+
+               case SSL_ERROR_WANT_READ:
+               case SSL_ERROR_WANT_WRITE:
+                       ssn->connected = false;
+                       return ssn;
+               }
+       }
+
        if (ret <= 0) {
                tls_error_io_log(NULL, ssn, ret, "Failed in " STRINGIFY(__FUNCTION__) " (SSL_connect)");
                talloc_free(ssn);
@@ -544,8 +560,7 @@ tls_session_t *tls_new_client_session(TALLOC_CTX *ctx, fr_tls_server_conf_t *con
                return NULL;
        }
 
-       ssn->mtu = conf->fragment_size;
-
+       ssn->connected = true;
        return ssn;
 }
 
@@ -822,10 +837,10 @@ static void session_init(tls_session_t *ssn)
 
 static void session_close(tls_session_t *ssn)
 {
-       SSL_set_quiet_shutdown(ssn->ssl, 1);
-       SSL_shutdown(ssn->ssl);
-
        if (ssn->ssl) {
+               SSL_set_quiet_shutdown(ssn->ssl, 1);
+               SSL_shutdown(ssn->ssl);
+
                SSL_free(ssn->ssl);
                ssn->ssl = NULL;
        }
@@ -1359,7 +1374,7 @@ static int cbtls_new_session(SSL *ssl, SSL_SESSION *sess)
                blob_len = i2d_SSL_SESSION(sess, NULL);
                if (blob_len < 1) {
                        /* something went wrong */
-                       RWDEBUG("Session serialisation failed, couldn't determine required buffer length");
+                       if (request) RWDEBUG("Session serialisation failed, couldn't determine required buffer length");
                        return 0;
                }
 
@@ -1374,17 +1389,17 @@ static int cbtls_new_session(SSL *ssl, SSL_SESSION *sess)
                p = sess_blob;
                rv = i2d_SSL_SESSION(sess, &p);
                if (rv != blob_len) {
-                       RWDEBUG("Session serialisation failed");
+                       if (request) RWDEBUG("Session serialisation failed");
                        goto error;
                }
 
                /* open output file */
                snprintf(filename, sizeof(filename), "%s%c%s.asn1",
                         conf->session_cache_path, FR_DIR_SEP, buffer);
-               fd = open(filename, O_RDWR|O_CREAT|O_EXCL, 0600);
+               fd = open(filename, O_RDWR|O_CREAT|O_EXCL, S_IWUSR);
                if (fd < 0) {
-                       RERROR("Session serialisation failed, failed opening session file %s: %s",
-                             filename, fr_syserror(errno));
+                       if (request) RERROR("Session serialisation failed, failed opening session file %s: %s",
+                                           filename, fr_syserror(errno));
                        goto error;
                }
 
@@ -1399,8 +1414,6 @@ static int cbtls_new_session(SSL *ssl, SSL_SESSION *sess)
                                fr_pair_value_strcpy(vp, filename);
                                fr_pair_add(&request->state, vp);
                        }
-
-                       (void) fchmod(fd, S_IWUSR);
                }
 
                todo = blob_len;
@@ -1408,7 +1421,7 @@ static int cbtls_new_session(SSL *ssl, SSL_SESSION *sess)
                while (todo > 0) {
                        rv = write(fd, p, todo);
                        if (rv < 1) {
-                               RWDEBUG("Failed writing session: %s", fr_syserror(errno));
+                               if (request) RWDEBUG("Failed writing session: %s", fr_syserror(errno));
                                close(fd);
                                goto error;
                        }
@@ -1416,7 +1429,7 @@ static int cbtls_new_session(SSL *ssl, SSL_SESSION *sess)
                        todo -= rv;
                }
                close(fd);
-               RWDEBUG("Wrote session %s to %s (%d bytes)", buffer, filename, blob_len);
+               if (request) RWDEBUG("Wrote session %s to %s (%d bytes)", buffer, filename, blob_len);
        }
 
 error:
@@ -1425,6 +1438,61 @@ error:
        return 0;
 }
 
+/** Convert OpenSSL's ASN1_TIME to an epoch time
+ *
+ * @param[out] out     Where to write the time_t.
+ * @param[in] asn1     The ASN1_TIME to convert.
+ * @return
+ *     - 0 success.
+ *     - -1 on failure.
+ */
+static int ocsp_asn1time_to_epoch(time_t *out, char const *asn1)
+{
+       struct          tm t;
+       char const      *p = asn1, *end = p + strlen(p);
+
+       memset(&t, 0, sizeof(t));
+
+       if ((end - p) <= 12) {
+               if ((end - p) < 2) {
+                       fr_strerror_printf("ASN1 date string too short, expected 2 additional bytes, got %zu bytes",
+                                          end - p);
+                       return -1;
+               }
+
+               t.tm_year = (*(p++) - '0') * 10;
+               t.tm_year += (*(p++) - '0');
+               if (t.tm_year < 70) t.tm_year += 100;
+       } else {
+               t.tm_year = (*(p++) - '0') * 1000;
+               t.tm_year += (*(p++) - '0') * 100;
+               t.tm_year += (*(p++) - '0') * 10;
+               t.tm_year += (*(p++) - '0');
+               t.tm_year -= 1900;
+       }
+
+       if ((end - p) < 10) {
+               fr_strerror_printf("ASN1 string too short, expected 10 additional bytes, got %zu bytes",
+                                  end - p);
+               return -1;
+       }
+
+       t.tm_mon = (*(p++) - '0') * 10;
+       t.tm_mon += (*(p++) - '0') - 1; // -1 since January is 0 not 1.
+       t.tm_mday = (*(p++) - '0') * 10;
+       t.tm_mday += (*(p++) - '0');
+       t.tm_hour = (*(p++) - '0') * 10;
+       t.tm_hour += (*(p++) - '0');
+       t.tm_min = (*(p++) - '0') * 10;
+       t.tm_min += (*(p++) - '0');
+       t.tm_sec = (*(p++) - '0') * 10;
+       t.tm_sec += (*(p++) - '0');
+
+       /* Apparently OpenSSL converts all timestamps to UTC? Maybe? */
+       *out = timegm(&t);
+       return 0;
+}
+
 #if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
 static SSL_SESSION *cbtls_get_session(SSL *ssl, unsigned char *data, int len, int *copy)
 #else
@@ -1471,27 +1539,28 @@ static SSL_SESSION *cbtls_get_session(SSL *ssl, const unsigned char *data, int l
 
                struct stat     st;
                VALUE_PAIR      *vps = NULL;
+               VALUE_PAIR      *vp;
 
                /* load the actual SSL session */
                snprintf(filename, sizeof(filename), "%s%c%s.asn1", conf->session_cache_path, FR_DIR_SEP, buffer);
                fd = open(filename, O_RDONLY);
                if (fd < 0) {
                        RWDEBUG("No persisted session file %s: %s", filename, fr_syserror(errno));
-                       goto err;
+                       goto error;
                }
 
                rv = fstat(fd, &st);
                if (rv < 0) {
                        RWDEBUG("Failed stating persisted session file %s: %s", filename, fr_syserror(errno));
                        close(fd);
-                       goto err;
+                       goto error;
                }
 
                sess_data = talloc_array(NULL, unsigned char, st.st_size);
                if (!sess_data) {
                        RWDEBUG("Failed allocating buffer for persisted session (%d bytes)", (int) st.st_size);
                        close(fd);
-                       goto err;
+                       goto error;
                }
 
                q = sess_data;
@@ -1501,7 +1570,7 @@ static SSL_SESSION *cbtls_get_session(SSL *ssl, const unsigned char *data, int l
                        if (rv < 1) {
                                RWDEBUG("Failed reading persisted session: %s", fr_syserror(errno));
                                close(fd);
-                               goto err;
+                               goto error;
                        }
                        todo -= rv;
                        q += rv;
@@ -1524,7 +1593,7 @@ static SSL_SESSION *cbtls_get_session(SSL *ssl, const unsigned char *data, int l
                sess = d2i_SSL_SESSION(NULL, o, st.st_size);
                if (!sess) {
                        RWDEBUG("Failed loading persisted session: %s", ERR_error_string(ERR_get_error(), NULL));
-                       goto err;
+                       goto error;
                }
 
                /* read in the cached VPs from the .vps file */
@@ -1534,7 +1603,40 @@ static SSL_SESSION *cbtls_get_session(SSL *ssl, const unsigned char *data, int l
                if (rv < 0) {
                        /* not safe to un-persist a session w/o VPs */
                        RWDEBUG("Failed loading persisted VPs for session %s", buffer);
-                       goto err;
+                       SSL_SESSION_free(sess);
+                       goto error;
+               }
+
+               /*
+                *      Enforce client certificate expiration.
+                */
+               vp = fr_pair_find_by_num(pairlist->reply, PW_TLS_CLIENT_CERT_EXPIRATION, 0, TAG_ANY);
+               if (vp) {
+                       time_t expires;
+
+                       if (ocsp_asn1time_to_epoch(&expires, vp->vp_strvalue) < 0) {
+                               RDEBUG2("Failed getting certificate expiration, removing cache entry for session %s", buffer);
+                               SSL_SESSION_free(sess);
+                               goto error;
+                       }
+
+                       if (expires <= request->timestamp) {
+                               RDEBUG2("Certificate has expired, removing cache entry for session %s", buffer);
+                               SSL_SESSION_free(sess);
+                               goto error;
+                       }
+
+                       /*
+                        *      Account for Session-Timeout, if it's available.
+                        */
+                       vp = fr_pair_find_by_num(request->reply->vps, PW_SESSION_TIMEOUT, 0, TAG_ANY);
+                       if (vp) {
+                               if ((request->timestamp + vp->vp_integer) > expires) {
+                                       vp->vp_integer = expires - request->timestamp;
+                                       RWDEBUG2("Updating Session-Timeout to %u, due to impending certificate expiration",
+                                                vp->vp_integer);
+                               }
+                       }
                }
 
                /* move the cached VPs into the session */
@@ -1544,7 +1646,7 @@ static SSL_SESSION *cbtls_get_session(SSL *ssl, const unsigned char *data, int l
                RWDEBUG("Successfully restored session %s", buffer);
                rdebug_pair_list(L_DBG_LVL_2, request, vps, "reply:");
        }
-err:
+error:
        if (sess_data) talloc_free(sess_data);
        if (pairlist) pairlist_free(&pairlist);
 
@@ -2059,7 +2161,7 @@ int cbtls_verify(int ok, X509_STORE_CTX *ctx)
        /*
         *      Get the RFC822 Subject Alternative Name
         */
-       loc = X509_get_ext_by_NID(client_cert, NID_subject_alt_name, 0);
+       loc = X509_get_ext_by_NID(client_cert, NID_subject_alt_name, -1);
        if (certs && (lookup <= 1) && (loc >= 0)) {
                X509_EXTENSION *ext = NULL;
                GENERAL_NAMES *names = NULL;
@@ -2130,7 +2232,7 @@ int cbtls_verify(int ok, X509_STORE_CTX *ctx)
        }
 
        if (lookup == 0) {
-#if OPENSSL_VERSION_NUMBER >= 0x10100000L
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)
                ext_list = X509_get0_extensions(client_cert);
 #else
                X509_CINF       *client_inf;
@@ -2339,7 +2441,8 @@ int cbtls_verify(int ok, X509_STORE_CTX *ctx)
                                                true, true, EXEC_TIMEOUT) != 0) {
                                AUTH(LOG_PREFIX ": Certificate CN (%s) fails external verification!", common_name);
                                my_ok = 0;
-                       } else {
+
+                       } else  if (request) {
                                RDEBUG("Client certificate CN %s passed external validation", common_name);
                        }
 
@@ -2435,6 +2538,38 @@ static int set_ecdh_curve(SSL_CTX *ctx, char const *ecdh_curve, bool disable_sin
 #endif
 #endif
 
+/*
+ * DIE OPENSSL DIE DIE DIE
+ *
+ * What a palaver, just to free some data attached the
+ * session. We need to do this because the "remove" callback
+ * is called when refcount > 0 sometimes, if another thread
+ * is using the session
+ */
+static void sess_free_vps(UNUSED void *parent, void *data_ptr,
+                                UNUSED CRYPTO_EX_DATA *ad, UNUSED int idx,
+                                UNUSED long argl, UNUSED void *argp)
+{
+        VALUE_PAIR *vp = data_ptr;
+        if (!vp) return;
+
+        DEBUG2(LOG_PREFIX ": Freeing cached session VPs");
+
+        fr_pair_list_free(&vp);
+}
+
+static void sess_free_certs(UNUSED void *parent, void *data_ptr,
+                                UNUSED CRYPTO_EX_DATA *ad, UNUSED int idx,
+                                UNUSED long argl, UNUSED void *argp)
+{
+        VALUE_PAIR **certs = data_ptr;
+        if (!certs) return;
+
+        DEBUG2(LOG_PREFIX ": Freeing cached session Certificates");
+
+        fr_pair_list_free(certs);
+}
+
 /** Add all the default ciphers and message digests reate our context.
  *
  * This should be called exactly once from main, before reading the main config
@@ -2450,7 +2585,7 @@ void tls_global_init(void)
        /*
         *      Initialize the index for the certificates.
         */
-       fr_tls_ex_index_certs = SSL_SESSION_get_ex_new_index(0, NULL, NULL, NULL, NULL);
+       fr_tls_ex_index_certs = SSL_SESSION_get_ex_new_index(0, NULL, NULL, NULL, sess_free_certs);
 }
 
 #ifdef ENABLE_OPENSSL_VERSION_CHECK
@@ -2867,7 +3002,7 @@ post_ca:
 
                SSL_CTX_set_quiet_shutdown(ctx, 1);
                if (fr_tls_ex_index_vps < 0)
-                       fr_tls_ex_index_vps = SSL_SESSION_get_ex_new_index(0, NULL, NULL, NULL, NULL);
+                       fr_tls_ex_index_vps = SSL_SESSION_get_ex_new_index(0, NULL, NULL, NULL, sess_free_vps);
        }
 
        /*
@@ -2936,9 +3071,9 @@ post_ca:
                }
 
                /*
-                *      Cache it, and DON'T auto-clear it.
+                *      Cache it, DON'T auto-clear it, and disable the internal OpenSSL session cache.
                 */
-               SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_SERVER | SSL_SESS_CACHE_NO_AUTO_CLEAR);
+               SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_SERVER | SSL_SESS_CACHE_NO_AUTO_CLEAR | SSL_SESS_CACHE_NO_INTERNAL);
 
                SSL_CTX_set_session_id_context(ctx,
                                               (unsigned char *) conf->session_context_id,
@@ -2984,7 +3119,7 @@ static int _tls_server_conf_free(fr_tls_server_conf_t *conf)
        return 0;
 }
 
-static fr_tls_server_conf_t *tls_server_conf_alloc(TALLOC_CTX *ctx)
+fr_tls_server_conf_t *tls_server_conf_alloc(TALLOC_CTX *ctx)
 {
        fr_tls_server_conf_t *conf;
 
@@ -3026,14 +3161,29 @@ fr_tls_server_conf_t *tls_server_conf_parse(CONF_SECTION *cs)
         */
        if (conf->fragment_size < 100) conf->fragment_size = 100;
 
-       if (!conf->private_key_file) {
-               ERROR(LOG_PREFIX ": TLS Server requires a private key file");
-               goto error;
-       }
+       /*
+        *      Only check for certificate things if we don't have a
+        *      PSK query.
+        */
+       if (conf->psk_identity) {
+               if (conf->private_key_file) {
+                       WARN(LOG_PREFIX ": Ignoring private key file due to psk_identity being used");
+               }
 
-       if (!conf->certificate_file) {
-               ERROR(LOG_PREFIX ": TLS Server requires a certificate file");
-               goto error;
+               if (conf->certificate_file) {
+                       WARN(LOG_PREFIX ": Ignoring certificate file due to psk_identity being used");
+               }
+
+       } else {
+               if (!conf->private_key_file) {
+                       ERROR(LOG_PREFIX ": TLS Server requires a private key file");
+                       goto error;
+               }
+
+               if (!conf->certificate_file) {
+                       ERROR(LOG_PREFIX ": TLS Server requires a certificate file");
+                       goto error;
+               }
        }
 
        /*
@@ -3138,6 +3288,7 @@ fr_tls_server_conf_t *tls_client_conf_parse(CONF_SECTION *cs)
        return conf;
 }
 
+
 int tls_success(tls_session_t *ssn, REQUEST *request)
 {
        VALUE_PAIR *vp, *vps = NULL;
@@ -3215,6 +3366,35 @@ int tls_success(tls_session_t *ssn, REQUEST *request)
                         *      Save the certs in the packet, so that we can see them.
                         */
                        fr_pair_add(&request->packet->vps, fr_pair_list_copy(request->packet, *certs));
+
+                       vp = fr_pair_find_by_num(request->packet->vps, PW_TLS_CLIENT_CERT_EXPIRATION, 0, TAG_ANY);
+                       if (vp) {
+                               time_t expires;
+
+                               if (ocsp_asn1time_to_epoch(&expires, vp->vp_strvalue) < 0) {
+                                       RDEBUG2("Failed getting certificate expiration, removing cache entry for session %s", buffer);
+                                       SSL_CTX_remove_session(ssn->ctx, ssn->ssl_session);
+                                       return -1;
+                               }
+
+                               if (expires <= request->timestamp) {
+                                       RDEBUG2("Certificate has expired, removing cache entry for session %s", buffer);
+                                       SSL_CTX_remove_session(ssn->ctx, ssn->ssl_session);
+                                       return -1;
+                               }
+
+                               /*
+                                *      Account for Session-Timeout, if it's available.
+                                */
+                               vp = fr_pair_find_by_num(request->reply->vps, PW_SESSION_TIMEOUT, 0, TAG_ANY);
+                               if (vp) {
+                                       if ((request->timestamp + vp->vp_integer) > expires) {
+                                               vp->vp_integer = expires - request->timestamp;
+                                               RWDEBUG2("Updating Session-Timeout to %u, due to impending certificate expiration",
+                                                        vp->vp_integer);
+                                       }
+                               }
+                       }
                }
 
                if (vps) {
index 32cf564..4f52df4 100644 (file)
@@ -157,7 +157,6 @@ static int tls_socket_recv(rad_listen_t *listener)
                rad_assert(sock->packet != NULL);
                request->packet = talloc_steal(request, sock->packet);
 
-               request->component = "<core>";
                request->component = "<tls-connect>";
 
                request->reply = rad_alloc(request, false);
@@ -175,7 +174,7 @@ static int tls_socket_recv(rad_listen_t *listener)
 
                SSL_set_ex_data(sock->ssn->ssl, FR_TLS_EX_INDEX_REQUEST, (void *)request);
                SSL_set_ex_data(sock->ssn->ssl, fr_tls_ex_index_certs, (void *) &sock->certs);
-               SSL_set_ex_data(sock->ssn->ssl, FR_TLS_EX_INDEX_TALLOC, sock);
+               SSL_set_ex_data(sock->ssn->ssl, FR_TLS_EX_INDEX_TALLOC, NULL);
 
                doing_init = true;
        }
@@ -480,6 +479,34 @@ int dual_tls_send(rad_listen_t *listener, REQUEST *request)
        return 0;
 }
 
+static int try_connect(tls_session_t *ssn)
+{
+       int ret;
+       ret = SSL_connect(ssn->ssl);
+       if (ret < 0) {
+               switch (SSL_get_error(ssn->ssl, ret)) {
+                       default:
+                               break;
+
+
+
+               case SSL_ERROR_WANT_READ:
+               case SSL_ERROR_WANT_WRITE:
+                       ssn->connected = false;
+                       return 0;
+               }
+       }
+
+       if (ret <= 0) {
+               tls_error_io_log(NULL, ssn, ret, "Failed in " STRINGIFY(__FUNCTION__) " (SSL_connect)");
+               talloc_free(ssn);
+
+               return -1;
+       }
+
+       return 1;
+}
+
 
 #ifdef WITH_PROXY
 /*
@@ -501,6 +528,18 @@ static ssize_t proxy_tls_read(rad_listen_t *listener)
        uint8_t *data;
        listen_socket_t *sock = listener->data;
 
+       if (!sock->ssn->connected) {
+               rcode = try_connect(sock->ssn);
+               if (rcode == 0) return 0;
+
+               if (rcode < 0) {
+                       SSL_shutdown(sock->ssn->ssl);
+                       return -1;
+               }
+
+               sock->ssn->connected = true;
+       }
+
        /*
         *      Get the maximum size of data to receive.
         */
@@ -694,6 +733,20 @@ int proxy_tls_send(rad_listen_t *listener, REQUEST *request)
                                                request);
        }
 
+       if (!sock->ssn->connected) {
+               PTHREAD_MUTEX_LOCK(&sock->mutex);
+               rcode = try_connect(sock->ssn);
+               PTHREAD_MUTEX_UNLOCK(&sock->mutex);
+               if (rcode == 0) return 0;
+
+               if (rcode < 0) {
+                       SSL_shutdown(sock->ssn->ssl);
+                       return -1;
+               }
+
+               sock->ssn->connected = true;
+       }
+
        DEBUG3("Proxy is writing %u bytes to SSL",
               (unsigned int) request->proxy->data_len);
        PTHREAD_MUTEX_LOCK(&sock->mutex);
index 3198728..59fb6b9 100644 (file)
@@ -1787,7 +1787,10 @@ static ssize_t xlat_tokenize_request(REQUEST *request, char const *fmt, xlat_exp
         *      much faster.
         */
        tokens = talloc_typed_strdup(request, fmt);
-       if (!tokens) return -1;
+       if (!tokens) {
+               error = "Out of memory";
+               return -1;
+       }
 
        slen = xlat_tokenize_literal(request, tokens, head, false, &error);
 
@@ -1806,7 +1809,8 @@ static ssize_t xlat_tokenize_request(REQUEST *request, char const *fmt, xlat_exp
         */
        if (slen < 0) {
                talloc_free(tokens);
-               rad_assert(error != NULL);
+
+               if (!error) error = "Unknown error";
 
                REMARKER(fmt, -slen, error);
                return slen;
@@ -2197,15 +2201,14 @@ static char *xlat_aprint(TALLOC_CTX *ctx, REQUEST *request, xlat_exp_t const * c
 
                case 'S': /* request timestamp in SQL format*/
                        if (!localtime_r(&when, &ts)) goto error;
-                       nl = str + strftime(str, freespace, "%Y-%m-%d %H:%M:%S", &ts);
-                       rad_assert(((str + freespace) - nl) >= 8);
-                       snprintf(nl, (str + freespace) - nl, ".%06d",  usec);
+                       strftime(str, freespace, "%Y-%m-%d %H:%M:%S", &ts);
                        break;
 
                case 'T': /* request timestamp */
                        if (!localtime_r(&when, &ts)) goto error;
-                       strftime(str, freespace, "%Y-%m-%d-%H.%M.%S", &ts);
-                       
+                       nl = str + strftime(str, freespace, "%Y-%m-%d-%H.%M.%S", &ts);
+                       rad_assert(((str + freespace) - nl) >= 8);
+                       snprintf(nl, (str + freespace) - nl, ".%06d",  usec);
                        break;
 
                case 'Y': /* request year */
index b6aeee5..218198c 100644 (file)
@@ -105,12 +105,12 @@ static int dhcprelay_process_client_request(REQUEST *request)
        }
        vp = fr_pair_find_by_num(request->packet->vps, 259, DHCP_MAGIC_VENDOR, TAG_ANY); /* DHCP-Hop-Count */
        rad_assert(vp != NULL);
-       if (vp->vp_integer > maxhops) {
+       if (vp->vp_byte > maxhops) {
                DEBUG("DHCP: Number of hops is greater than %d: not relaying\n", maxhops);
                return 1;
        } else {
-           /* Increment hop count */
-           vp->vp_integer++;
+               /* Increment hop count */
+               vp->vp_byte++;
        }
 
        sock = request->listener->data;
@@ -301,10 +301,10 @@ static int dhcp_process(REQUEST *request)
 
        vp = fr_pair_find_by_num(request->packet->vps, 53, DHCP_MAGIC_VENDOR, TAG_ANY); /* DHCP-Message-Type */
        if (vp) {
-               DICT_VALUE *dv = dict_valbyattr(53, DHCP_MAGIC_VENDOR, vp->vp_integer);
+               DICT_VALUE *dv = dict_valbyattr(53, DHCP_MAGIC_VENDOR, vp->vp_byte);
                DEBUG("Trying sub-section dhcp %s {...}",
                      dv ? dv->name : "<unknown>");
-               rcode = process_post_auth(vp->vp_integer, request);
+               rcode = process_post_auth(vp->vp_byte, request);
        } else {
                DEBUG("DHCP: Failed to find DHCP-Message-Type in packet!");
                rcode = RLM_MODULE_FAIL;
@@ -312,7 +312,7 @@ static int dhcp_process(REQUEST *request)
 
        vp = fr_pair_find_by_num(request->reply->vps, 53, DHCP_MAGIC_VENDOR, TAG_ANY); /* DHCP-Message-Type */
        if (vp) {
-               request->reply->code = vp->vp_integer;
+               request->reply->code = vp->vp_byte;
                if ((request->reply->code != 0) &&
                    (request->reply->code < PW_DHCP_OFFSET)) {
                        request->reply->code += PW_DHCP_OFFSET;
@@ -366,7 +366,7 @@ static int dhcp_process(REQUEST *request)
        }
 
        /* BOOTREPLY received on port 67 (i.e. from a server) */
-       if (vp->vp_integer == 2) {
+       if (vp->vp_byte == 2) {
                return dhcprelay_process_server_reply(request);
        }
 
@@ -376,7 +376,7 @@ static int dhcp_process(REQUEST *request)
        }
 
        /* else it's a packet from a client, without relaying */
-       rad_assert(vp->vp_integer == 1); /* BOOTREQUEST */
+       rad_assert(vp->vp_byte == 1); /* BOOTREQUEST */
 
        sock = request->listener->data;
 
@@ -414,7 +414,7 @@ static int dhcp_process(REQUEST *request)
 
        vp = fr_pair_find_by_num(request->reply->vps, 256, DHCP_MAGIC_VENDOR, TAG_ANY); /* DHCP-Opcode */
        rad_assert(vp != NULL);
-       vp->vp_integer = 2; /* BOOTREPLY */
+       vp->vp_byte = 2; /* BOOTREPLY */
 
        /*
         *      Allow NAKs to be delayed for a short period of time.
index d8278cc..86a7d62 100644 (file)
 typedef struct rlm_date_t {
        char const *xlat_name;
        char const *fmt;
+       bool utc;
 } rlm_date_t;
 
 static const CONF_PARSER module_config[] = {
        { "format", FR_CONF_OFFSET(PW_TYPE_STRING, rlm_date_t, fmt), "%b %e %Y %H:%M:%S %Z" },
+       { "utc", FR_CONF_OFFSET(PW_TYPE_BOOLEAN, rlm_date_t, utc), "no" },
        CONF_PARSER_TERMINATOR
 };
 
@@ -69,9 +71,16 @@ static ssize_t xlat_date_convert(void *instance, REQUEST *request, char const *f
                date = (time_t) vp->vp_integer;
 
        encode:
-               if (localtime_r(&date, &tminfo) == NULL) {
-                       REDEBUG("Failed converting time string to localtime");
-                       goto error;
+               if (!inst->utc) {
+                       if (localtime_r(&date, &tminfo) == NULL) {
+                               REDEBUG("Failed converting time string to localtime");
+                               goto error;
+                       }
+               } else {
+                       if (gmtime_r(&date, &tminfo) == NULL) {
+                               REDEBUG("Failed converting time string to gmtime");
+                               goto error;
+                       }
                }
                return strftime(out, outlen, inst->fmt, &tminfo);
 
index 3f0fd73..a8ecb51 100644 (file)
@@ -207,9 +207,7 @@ PW_CODE chbind_process(REQUEST *request, CHBIND_REQ *chbind)
        fake->server = "channel_bindings";
        fake->packet->code = PW_CODE_ACCESS_REQUEST;
 
-       rcode = rad_virtual_server(fake);
-
-       switch (rcode) {
+       switch (rad_virtual_server(fake)) {
                /* If rad_authenticate succeeded, build a reply */
        case RLM_MODULE_OK:
        case RLM_MODULE_HANDLED:
@@ -280,15 +278,15 @@ chbind_packet_t *eap_chbind_vp2packet(TALLOC_CTX *ctx, VALUE_PAIR *vps)
        return packet;
 }
 
-VALUE_PAIR *eap_chbind_packet2vp(REQUEST *request, chbind_packet_t *packet)
+VALUE_PAIR *eap_chbind_packet2vp(RADIUS_PACKET *packet, chbind_packet_t *chbind)
 {
        VALUE_PAIR      *vp;
 
-       if (!packet) return NULL; /* don't produce garbage */
+       if (!chbind) return NULL; /* don't produce garbage */
 
-       vp = fr_pair_afrom_num(request->packet, PW_UKERNA_CHBIND, VENDORPEC_UKERNA);
+       vp = fr_pair_afrom_num(packet, VENDORPEC_UKERNA, PW_UKERNA_CHBIND);
        if (!vp) return NULL;
-       fr_pair_value_memcpy(vp, (uint8_t *) packet, talloc_array_length((uint8_t *)packet));
+       fr_pair_value_memcpy(vp, (uint8_t *) chbind, talloc_array_length((uint8_t *)chbind));
 
        return vp;
 }
index 914e364..346b712 100644 (file)
@@ -58,7 +58,7 @@ typedef struct CHBIND_REQ {
 /* Channel binding function prototypes */
 PW_CODE chbind_process(REQUEST *request, CHBIND_REQ *chbind_req);
 
-VALUE_PAIR *eap_chbind_packet2vp(REQUEST *request, chbind_packet_t *packet);
+VALUE_PAIR *eap_chbind_packet2vp(RADIUS_PACKET *packet, chbind_packet_t *chbind);
 chbind_packet_t *eap_chbind_vp2packet(TALLOC_CTX *ctx, VALUE_PAIR *vps);
 
 #endif /*_EAP_CHBIND_H*/
index 9cff1d4..a08cd50 100644 (file)
@@ -96,7 +96,7 @@ tls_session_t *eaptls_session(eap_handler_t *handler, fr_tls_server_conf_t *tls_
        SSL_set_ex_data(ssn->ssl, FR_TLS_EX_INDEX_STORE, (void *)tls_conf->ocsp_store);
 #endif
        SSL_set_ex_data(ssn->ssl, FR_TLS_EX_INDEX_SSN, (void *)ssn);
-       SSL_set_ex_data(ssn->ssl, FR_TLS_EX_INDEX_TALLOC, handler);
+       SSL_set_ex_data(ssn->ssl, FR_TLS_EX_INDEX_TALLOC, NULL);
 
        return talloc_steal(handler, ssn); /* ssn */
 }
@@ -325,13 +325,15 @@ static fr_tls_status_t eaptls_verify(eap_handler_t *handler)
        if (prev_eap_ds && prev_eap_ds->response)
                eaptls_prev = (eaptls_packet_t *)prev_eap_ds->response->type.data;
 
-       /*
-        *      First output the flags (for debugging)
-        */
-       RDEBUG3("Peer sent flags %c%c%c",
-               TLS_START(eaptls_packet->flags) ? 'S' : '-',
-               TLS_MORE_FRAGMENTS(eaptls_packet->flags) ? 'M' : '-',
-               TLS_LENGTH_INCLUDED(eaptls_packet->flags) ? 'L' : '-');
+       if (eaptls_packet) {
+               /*
+                *      First output the flags (for debugging)
+                */
+               RDEBUG3("Peer sent flags %c%c%c",
+                       TLS_START(eaptls_packet->flags) ? 'S' : '-',
+                       TLS_MORE_FRAGMENTS(eaptls_packet->flags) ? 'M' : '-',
+                       TLS_LENGTH_INCLUDED(eaptls_packet->flags) ? 'L' : '-');
+       }
 
        /*
         *      check for ACK
index 020d252..ff69361 100644 (file)
@@ -468,6 +468,7 @@ static int rc_init_packet(rc_transaction_t *trans)
                /*
                 *      Keep a copy of the the password attribute.
                 */
+               case PW_CLEARTEXT_PASSWORD:
                case PW_USER_PASSWORD:
                case PW_CHAP_PASSWORD:
                case PW_MS_CHAP_PASSWORD:
index 356038a..14265ee 100644 (file)
@@ -453,17 +453,28 @@ static rlm_rcode_t CC_HINT(nonnull) mod_authenticate(void *instance, REQUEST *re
 
                /*
                 *      Cisco AP1230 has a bug and needs a zero
-                *      terminated string in Access-Accept.
+                *      terminated string in Access-Accept.  This
+                *      means it requires 2 trailing zeros.  One to
+                *      send in the RADIUS packet, and the other to
+                *      convince the rest of the server that
+                *      vp->vp_strvalue is still a NUL-terminated C
+                *      string.
                 */
                if (inst->mod_accounting_username_bug) {
                        char const *old = vp->vp_strvalue;
-                       char *new = talloc_zero_array(vp, char, vp->vp_length + 1);
+                       char *new;
+
+                       vp->vp_length++; /* account for an additional zero */
+
+                       new = talloc_array(vp, char, vp->vp_length + 1);
 
                        memcpy(new, old, vp->vp_length);
+                       new[vp->length] = '\0';
+                       new[vp->length + 1] = '\0';
                        vp->vp_strvalue = new;
-                       vp->vp_length++;
 
                        rad_const_free(old);
+                       VERIFY_VP(vp);
                }
        }
 
index dba2c14..95e5217 100644 (file)
@@ -1235,9 +1235,6 @@ PW_CODE eap_fast_process(eap_handler_t *eap_session, tls_session_t *tls_session)
 
                eap_fast_append_result(tls_session, code);
 
-               if (code == PW_CODE_ACCESS_REJECT)
-                       break;
-
                if (t->pac.send) {
                        RDEBUG("Peer requires new PAC");
                        eap_fast_send_pac_tunnel(request, tls_session);
index cc0927e..801bd7c 100644 (file)
@@ -207,12 +207,17 @@ static void eapsoh_verify(REQUEST *request, RADIUS_PACKET *packet,
  *     Verify the tunneled EAP message.
  */
 static int eapmessage_verify(REQUEST *request,
-                            uint8_t const *data, unsigned int data_len)
+                            uint8_t const *data, unsigned int data_len, int peap_version)
 {
        eap_packet_raw_t const *eap_packet = (eap_packet_raw_t const *) data;
        eap_type_t eap_method;
 
        /*
+        *      Hack for now.
+        */
+       if (peap_version == 1) return 1;
+
+       /*
         *      No data, OR only 1 byte of EAP type.
         */
        if (!data || (data_len == 0) ||
@@ -241,7 +246,7 @@ static int eapmessage_verify(REQUEST *request,
                        RDEBUG2("Received EAP-TLV response");
                        return 1;
                }
-               RDEBUG2("Got something weird");
+               RDEBUG2("Received unexpected EAP-Response, rejecting the session.");
                break;
 
 
@@ -264,7 +269,7 @@ static int eapmessage_verify(REQUEST *request,
  */
 static VALUE_PAIR *eap2vp(UNUSED REQUEST *request, RADIUS_PACKET *packet,
                          EAP_DS *eap_ds,
-                         uint8_t const *data, size_t data_len)
+                         uint8_t const *data, size_t data_len, int peap_version)
 {
        size_t total;
        uint8_t *p;
@@ -281,18 +286,25 @@ static VALUE_PAIR *eap2vp(UNUSED REQUEST *request, RADIUS_PACKET *packet,
        total = data_len;
        if (total > 249) total = 249;
 
-       /*
-        *      Hand-build an EAP packet from the crap in PEAP version 0.
-        */
-       vp->vp_length = EAP_HEADER_LEN + total;
-       vp->vp_octets = p = talloc_array(vp, uint8_t, vp->vp_length);
+       if (peap_version == 0) {
+               /*
+                *      Hand-build an EAP packet from the crap in PEAP version 0.
+                */
+               vp->vp_length = EAP_HEADER_LEN + total;
+               vp->vp_octets = p = talloc_array(vp, uint8_t, vp->vp_length);
+
+               p[0] = PW_EAP_RESPONSE;
+               p[1] = eap_ds->response->id;
+               p[2] = (data_len + EAP_HEADER_LEN) >> 8;
+               p[3] = (data_len + EAP_HEADER_LEN) & 0xff;
 
-       p[0] = PW_EAP_RESPONSE;
-       p[1] = eap_ds->response->id;
-       p[2] = (data_len + EAP_HEADER_LEN) >> 8;
-       p[3] = (data_len + EAP_HEADER_LEN) & 0xff;
+               memcpy(p + EAP_HEADER_LEN, data, total);
 
-       memcpy(p + EAP_HEADER_LEN, data, total);
+       } else {                /* peapv1 */
+               vp->vp_length = total;
+               vp->vp_octets = p = talloc_array(vp, uint8_t, vp->vp_length);
+               memcpy(p, data, total);
+       }
 
        fr_cursor_init(&cursor, &head);
        fr_cursor_insert(&cursor, vp);
@@ -323,6 +335,9 @@ static int vp2eap(REQUEST *request, tls_session_t *tls_session, VALUE_PAIR *vp)
        rad_assert(vp != NULL);
        VALUE_PAIR *this;
        vp_cursor_t cursor;
+       size_t header = EAP_HEADER_LEN;
+
+       if (tls_session->peap_flag > 0) header = 0;
 
        /*
         *      Skip the id, code, and length.  Just write the EAP
@@ -330,7 +345,7 @@ static int vp2eap(REQUEST *request, tls_session_t *tls_session, VALUE_PAIR *vp)
         */
 #ifndef NDEBUG
        if ((rad_debug_lvl > 2) && fr_log_fp) {
-               size_t i, total, start = EAP_HEADER_LEN;
+               size_t i, total, start = header;
                total = 0;
 
                for (this = fr_cursor_init(&cursor, &vp); this; this = fr_cursor_next(&cursor)) {
@@ -360,7 +375,7 @@ static int vp2eap(REQUEST *request, tls_session_t *tls_session, VALUE_PAIR *vp)
         *      Send the EAP data in the first attribute, WITHOUT the
         *      header.
         */
-       (tls_session->record_plus)(&tls_session->clean_in, vp->vp_octets + EAP_HEADER_LEN, vp->vp_length - EAP_HEADER_LEN);
+       (tls_session->record_plus)(&tls_session->clean_in, vp->vp_octets + header, vp->vp_length - header);
 
        /*
         *      Send the rest of the EAP data, but skipping the first VP.
@@ -730,6 +745,7 @@ rlm_rcode_t eappeap_process(eap_handler_t *handler, tls_session_t *tls_session,
        rlm_rcode_t     rcode = RLM_MODULE_REJECT;
        uint8_t const   *data;
        unsigned int    data_len;
+       size_t          header = 0;
 
        REQUEST *request = handler->request;
        EAP_DS *eap_ds = handler->eap_ds;
@@ -745,12 +761,14 @@ rlm_rcode_t eappeap_process(eap_handler_t *handler, tls_session_t *tls_session,
        RDEBUG2("PEAP state %s", peap_state(t));
 
        if ((t->status != PEAP_STATUS_TUNNEL_ESTABLISHED) &&
-           !eapmessage_verify(request, data, data_len)) {
+           !eapmessage_verify(request, data, data_len, tls_session->peap_flag)) {
                REDEBUG("Tunneled data is invalid");
                if (rad_debug_lvl > 2) print_tunneled_data(data, data_len);
                return RLM_MODULE_REJECT;
        }
 
+       if (tls_session->peap_flag > 0) header = EAP_HEADER_LEN;
+
        switch (t->status) {
        case PEAP_STATUS_TUNNEL_ESTABLISHED:
                /* FIXME: should be no data in the buffer here, check & assert? */
@@ -778,7 +796,7 @@ rlm_rcode_t eappeap_process(eap_handler_t *handler, tls_session_t *tls_session,
 
        case PEAP_STATUS_INNER_IDENTITY_REQ_SENT:
                /* we're expecting an identity response */
-               if (data[0] != PW_EAP_IDENTITY) {
+               if (data[header] != PW_EAP_IDENTITY) {
                        REDEBUG("Expected EAP-Identity, got something else");
                        return RLM_MODULE_REJECT;
                }
@@ -789,7 +807,7 @@ rlm_rcode_t eappeap_process(eap_handler_t *handler, tls_session_t *tls_session,
                t->username = fr_pair_make(t, NULL, "User-Name", NULL, T_OP_EQ);
                rad_assert(t->username != NULL);
 
-               fr_pair_value_bstrncpy(t->username, data + 1, data_len - 1);
+               fr_pair_value_bstrncpy(t->username, data + header + 1, data_len - header - 1);
 
                RDEBUG("Got inner identity '%s'", t->username->vp_strvalue);
                if (t->soh) {
@@ -804,7 +822,7 @@ rlm_rcode_t eappeap_process(eap_handler_t *handler, tls_session_t *tls_session,
        case PEAP_STATUS_WAIT_FOR_SOH_RESPONSE:
                fake = request_alloc_fake(request);
                rad_assert(!fake->packet->vps);
-               eapsoh_verify(fake, fake->packet, data, data_len);
+               eapsoh_verify(fake, fake->packet, data + header, data_len - header);
                setup_fake_request(request, fake, t);
 
                if (t->soh_virtual_server) {
@@ -842,7 +860,7 @@ rlm_rcode_t eappeap_process(eap_handler_t *handler, tls_session_t *tls_session,
         *      If we authenticated the user, then it's OK.
         */
        case PEAP_STATUS_SENT_TLV_SUCCESS:
-               if (eappeap_check_tlv(request, data, data_len)) {
+               if (eappeap_check_tlv(request, data + header, data_len - header)) {
                        RDEBUG2("Success");
                        return RLM_MODULE_OK;
                }
@@ -937,7 +955,7 @@ rlm_rcode_t eappeap_process(eap_handler_t *handler, tls_session_t *tls_session,
 
        case PEAP_STATUS_PHASE2:
                fake->packet->vps = eap2vp(request, fake->packet,
-                                          eap_ds, data, data_len);
+                                          eap_ds, data, data_len, tls_session->peap_flag);
                if (!fake->packet->vps) {
                        talloc_free(fake);
                        RDEBUG2("Unable to convert tunneled EAP packet to internal server data structures");
@@ -962,11 +980,11 @@ rlm_rcode_t eappeap_process(eap_handler_t *handler, tls_session_t *tls_session,
                 *      so we add one here, by pulling it out of the
                 *      EAP-Identity packet.
                 */
-               if ((data[0] == PW_EAP_IDENTITY) && (data_len > 1)) {
+               if ((data[header] == PW_EAP_IDENTITY) && (data_len > (1 + header))) {
                        t->username = fr_pair_make(t, NULL, "User-Name", NULL, T_OP_EQ);
                        rad_assert(t->username != NULL);
 
-                       fr_pair_value_bstrncpy(t->username, data + 1, data_len - 1);
+                       fr_pair_value_bstrncpy(t->username, data + header + 1, data_len - header - 1);
 
                        RDEBUG2("Got tunneled identity of %s", t->username->vp_strvalue);
 
index e43c9c7..5bf7c96 100644 (file)
@@ -262,6 +262,13 @@ static int mod_process(void *arg, eap_handler_t *handler)
                peap = tls_session->opaque = peap_alloc(tls_session, inst);
        }
 
+       /*
+        *      Negotiate PEAP versions down.
+        */
+       if ((handler->eap_ds->response->type.data[0] & 0x03) < tls_session->peap_flag) {
+               tls_session->peap_flag = handler->eap_ds->response->type.data[0] & 0x03;
+       }
+
        status = eaptls_process(handler);
        if ((status == FR_TLS_INVALID) || (status == FR_TLS_FAIL)) {
                REDEBUG("[eaptls process] = %s", fr_int2str(fr_tls_status_table, status, "<INVALID>"));
index 9abae5c..3c043f7 100644 (file)
@@ -386,8 +386,8 @@ static int mod_process(void *arg, eap_handler_t *handler)
                }
 
                packet = (pwd_id_packet_t *) in;
-               if (in_len < sizeof(packet)) {
-                       RDEBUG("Packet is too small (%zd < %zd).", in_len, sizeof(packet));
+               if (in_len < sizeof(*packet)) {
+                       RDEBUG("Packet is too small (%zd < %zd).", in_len, sizeof(*packet));
                        return 0;
                }
 
index 912060f..524e874 100644 (file)
@@ -1183,7 +1183,7 @@ int eapttls_process(eap_handler_t *handler, tls_session_t *tls_session)
                if (req->response) {
                        RDEBUG("sending chbind response");
                        fr_pair_add(&fake->reply->vps,
-                               eap_chbind_packet2vp(fake, req->response));
+                                   eap_chbind_packet2vp(fake->reply, req->response));
                } else {
                        RDEBUG("no chbind response");
                }
index 5d6f626..8d3dde9 100644 (file)
@@ -217,7 +217,7 @@ static int genericcmp(UNUSED void *instance,
        /*
         *      Will do the xlat for us
         */
-       return radius_compare_vps(request, check, NULL);
+       return radius_compare_vps(request, check, req);
 }
 
 static int generic_attrs[] = {
index 12f34da..5e0a181 100644 (file)
@@ -461,8 +461,10 @@ rlm_rcode_t rlm_ldap_cacheable_groupobj(rlm_ldap_t const *inst, REQUEST *request
 
        case LDAP_PROC_NO_RESULT:
                RDEBUG2("No cacheable group memberships found in group objects");
+               goto finish;
 
        default:
+               rcode = RLM_MODULE_FAIL;
                goto finish;
        }
 
index aba15f8..c702f1b 100644 (file)
@@ -1471,7 +1471,7 @@ static rlm_rcode_t mschap_error(rlm_mschap_t *inst, REQUEST *request, unsigned c
                break;
 
        default:
-               rad_assert(0);
+               return RLM_MODULE_FAIL;
        }
        mschap_add_reply(request, ident, "MS-CHAP-Error", buffer, strlen(buffer));
 
index e8cd8af..b6b9ba0 100644 (file)
@@ -134,10 +134,11 @@ static void release_hash_table(struct hashtable * ht){
        int i;
 
        if (!ht) return;
-       for (i = 0; i < ht->tablesize; i++)
-               if (ht->table[i])
-                       destroy_password(ht->table[i]);
        if (ht->table) {
+               for (i = 0; i < ht->tablesize; i++) {
+                       if (ht->table[i])
+                               destroy_password(ht->table[i]);
+               }
                free(ht->table);
                ht->table = NULL;
        }
index 1636a4b..338fa49 100644 (file)
@@ -70,7 +70,7 @@ static fr_tls_server_conf_t *construct_tls(TIDC_INSTANCE *inst,
        char *hexbuf = NULL;
        DH *aaa_server_dh;
 
-       tls = talloc_zero( hs, fr_tls_server_conf_t);
+       tls = tls_server_conf_alloc(hs);
        if (!tls) return NULL;
 
        aaa_server_dh = tid_srvr_get_dh(server);
@@ -181,7 +181,12 @@ static home_server_t *srvr_blk_to_home_server(TALLOC_CTX *ctx,
        hs->secret = talloc_strdup(hs, "radsec");
        hs->response_window.tv_sec = 30;
        hs->last_packet_recv = time(NULL);
-
+       /* 
+        *  We want sockets using these servers to close as soon as possible, 
+        *  to make sure that whenever a pool is replaced, sockets using old ones 
+        *  will not last long (hopefully less than 300s).
+        */
+       hs->limit.idle_timeout = 5;
        hs->tls = construct_tls(inst, hs, blk);
        if (!hs->tls) goto error;
 
@@ -321,14 +326,6 @@ static bool update_required(REALM const *r)
                }
 
                /*
-                *      This server has received a packet in the last
-                *      5 minutes.  It doesn't need an update.
-                */
-               if ((now - server->last_packet_recv) < 300) {
-                       return false;
-               }
-
-               /*
                 *      If we've opened in the last 10 minutes, then
                 *      open rather than update.
                 */
index 4a4ae5c..c15664c 100644 (file)
@@ -259,6 +259,7 @@ static sql_rcode_t sql_free_result(rlm_sql_handle_t *handle, rlm_sql_config_t *c
        conn->row = NULL;
 
        SQLFreeStmt(conn->stmt, SQL_DROP);
+       conn->stmt = NULL;
 
        return 0;
 }
index 3a032d3..3bf9be2 100644 (file)
@@ -586,7 +586,7 @@ static int sql_get_grouplist(rlm_sql_t *inst, rlm_sql_handle_t **handle, REQUEST
 
 /*
  * sql groupcmp function. That way we can do group comparisons (in the users file for example)
- * with the group memberships reciding in sql
+ * with the group memberships residing in sql
  * The group membership query should only return one element which is the username. The returned
  * username will then be checked with the passed check string.
  */
@@ -1234,7 +1234,7 @@ static rlm_rcode_t mod_authorize(void *instance, REQUEST *request)
        }
 
        /*
-        *      Neither group checks or profiles will work without
+        *      Neither group checks nor profiles will work without
         *      a group membership query.
         */
        if (!inst->config->groupmemb_query) goto release;
@@ -1327,7 +1327,7 @@ skipreply:
        }
 
        /*
-        *      At this point the key (user) hasn't be found in the check table, the reply table
+        *      At this point the key (user) hasn't been found in the check table, the reply table
         *      or the group mapping table, and there was no matching profile.
         */
 release:
@@ -1463,7 +1463,7 @@ static int acct_redundant(rlm_sql_t *inst, REQUEST *request, sql_acct_section_t
                case RLM_SQL_ERROR:
                /*
                 *  If we get RLM_SQL_RECONNECT it means all connections in the pool
-                *  were exhausted, and we couldn't create a new connection,
+                *  were exhausted and we couldn't create a new connection,
                 *  so we do not need to call fr_connection_release.
                 */
                case RLM_SQL_RECONNECT:
@@ -1495,7 +1495,7 @@ static int acct_redundant(rlm_sql_t *inst, REQUEST *request, sql_acct_section_t
                (inst->module->sql_finish_query)(handle, inst->config);
                RDEBUG("%i record(s) updated", numaffected);
 
-               if (numaffected > 0) break;     /* A query succeeded, were done! */
+               if (numaffected > 0) break;     /* A query succeeded, we're done! */
        next:
                /*
                 *  We assume all entries with the same name form a redundant
index 7fdcb3a..8d43e73 100644 (file)
@@ -103,7 +103,7 @@ static const CONF_PARSER module_config[] = {
        CONF_PARSER_TERMINATOR
 };
 
-static int find_next_reset(rlm_sqlcounter_t *inst, time_t timeval)
+static int find_next_reset(rlm_sqlcounter_t *inst, REQUEST *request, time_t timeval)
 {
        int ret = 0;
        size_t len;
@@ -113,28 +113,33 @@ static int find_next_reset(rlm_sqlcounter_t *inst, time_t timeval)
        char sCurrentTime[40], sNextTime[40];
 
        tm = localtime_r(&timeval, &s_tm);
-       len = strftime(sCurrentTime, sizeof(sCurrentTime), "%Y-%m-%d %H:%M:%S", tm);
-       if (len == 0) *sCurrentTime = '\0';
        tm->tm_sec = tm->tm_min = 0;
 
        rad_assert(inst->reset != NULL);
 
+       /*
+        *      Reset every N hours, days, weeks, months.
+        */
        if (isdigit((int) inst->reset[0])){
                len = strlen(inst->reset);
-               if (len == 0)
-                       return -1;
+               if (len == 0) return -1;
+
                last = inst->reset[len - 1];
-               if (!isalpha((int) last))
+               if (!isalpha((int) last)) {
                        last = 'd';
+               }
+
                num = atoi(inst->reset);
                DEBUG("rlm_sqlcounter: num=%d, last=%c",num,last);
        }
+
        if (strcmp(inst->reset, "hourly") == 0 || last == 'h') {
                /*
                 *  Round up to the next nearest hour.
                 */
                tm->tm_hour += num;
                inst->reset_time = mktime(tm);
+
        } else if (strcmp(inst->reset, "daily") == 0 || last == 'd') {
                /*
                 *  Round up to the next nearest day.
@@ -142,6 +147,7 @@ static int find_next_reset(rlm_sqlcounter_t *inst, time_t timeval)
                tm->tm_hour = 0;
                tm->tm_mday += num;
                inst->reset_time = mktime(tm);
+
        } else if (strcmp(inst->reset, "weekly") == 0 || last == 'w') {
                /*
                 *  Round up to the next nearest week.
@@ -149,21 +155,29 @@ static int find_next_reset(rlm_sqlcounter_t *inst, time_t timeval)
                tm->tm_hour = 0;
                tm->tm_mday += (7 - tm->tm_wday) +(7*(num-1));
                inst->reset_time = mktime(tm);
+
        } else if (strcmp(inst->reset, "monthly") == 0 || last == 'm') {
                tm->tm_hour = 0;
                tm->tm_mday = 1;
                tm->tm_mon += num;
                inst->reset_time = mktime(tm);
+
        } else if (strcmp(inst->reset, "never") == 0) {
                inst->reset_time = 0;
+
        } else {
                return -1;
        }
 
+       if (!request || (rad_debug_lvl < 2)) return ret;
+
+       len = strftime(sCurrentTime, sizeof(sCurrentTime), "%Y-%m-%d %H:%M:%S", tm);
+       if (len == 0) *sCurrentTime = '\0';
+
        len = strftime(sNextTime, sizeof(sNextTime),"%Y-%m-%d %H:%M:%S",tm);
        if (len == 0) *sNextTime = '\0';
-       DEBUG2("rlm_sqlcounter: Current Time: %" PRId64 " [%s], Next reset %" PRId64 " [%s]",
-              (int64_t) timeval, sCurrentTime, (int64_t) inst->reset_time, sNextTime);
+       RDEBUG2("rlm_sqlcounter: Current Time: %" PRId64 " [%s], Next reset %" PRId64 " [%s]",
+               (int64_t) timeval, sCurrentTime, (int64_t) inst->reset_time, sNextTime);
 
        return ret;
 }
@@ -205,6 +219,7 @@ static int find_prev_reset(rlm_sqlcounter_t *inst, time_t timeval)
                 */
                tm->tm_hour -= num - 1;
                inst->last_reset = mktime(tm);
+
        } else if (strcmp(inst->reset, "daily") == 0 || last == 'd') {
                /*
                 *  Round down to the prev nearest day.
@@ -212,6 +227,7 @@ static int find_prev_reset(rlm_sqlcounter_t *inst, time_t timeval)
                tm->tm_hour = 0;
                tm->tm_mday -= num - 1;
                inst->last_reset = mktime(tm);
+
        } else if (strcmp(inst->reset, "weekly") == 0 || last == 'w') {
                /*
                 *  Round down to the prev nearest week.
@@ -219,13 +235,16 @@ static int find_prev_reset(rlm_sqlcounter_t *inst, time_t timeval)
                tm->tm_hour = 0;
                tm->tm_mday -= tm->tm_wday +(7*(num-1));
                inst->last_reset = mktime(tm);
+
        } else if (strcmp(inst->reset, "monthly") == 0 || last == 'm') {
                tm->tm_hour = 0;
                tm->tm_mday = 1;
                tm->tm_mon -= num - 1;
                inst->last_reset = mktime(tm);
+
        } else if (strcmp(inst->reset, "never") == 0) {
                inst->reset_time = 0;
+
        } else {
                return -1;
        }
@@ -463,7 +482,7 @@ static int mod_instantiate(CONF_SECTION *conf, void *instance)
        now = time(NULL);
        inst->reset_time = 0;
 
-       if (find_next_reset(inst, now) == -1) {
+       if (find_next_reset(inst, NULL, now) < 0) {
                cf_log_err_cs(conf, "Invalid reset '%s'", inst->reset);
                return -1;
        }
@@ -511,7 +530,7 @@ static rlm_rcode_t CC_HINT(nonnull) mod_authorize(void *instance, REQUEST *reque
                 *      Re-set the next time and prev_time for this counters range
                 */
                inst->last_reset = inst->reset_time;
-               find_next_reset(inst,request->timestamp);
+               find_next_reset(inst, request, request->timestamp);
        }
 
        /*
index 1868bca..1fb3c14 100644 (file)
@@ -1,5 +1,5 @@
 Name:         freeradius-server
-Version: 3.0.13
+Version: 3.0.14
 Release:      0
 License:      GPLv2 ; LGPLv2.1
 Group:        Productivity/Networking/Radius/Servers
index b72267b..24d56be 100644 (file)
@@ -28,14 +28,6 @@ notifempty
 }
 
 #
-#  Session database modules
-#
-/var/log/radius/radutmp /var/log/radius/radwtmp {
-       nocreate
-       size=+2048k
-}
-
-#
 #  SQL log files
 #
 /var/log/radius/sqllog.sql {