From dc82da3d8caccbb97f96c00f54f8fb1b4c714e6b Mon Sep 17 00:00:00 2001
From: "Angel L. Mateo" <amateo@um.es>
Date: Mon, 30 Jan 2017 13:29:33 +0100
Subject: [PATCH] Add freeradius::listen to define listen directives

This is a way to configure listen directives not directly associated to
any specific virtual server
---
 manifests/init.pp          |   1 +
 manifests/listen.pp        |  46 ++++++++++++++
 templates/listen.erb       | 120 +++++++++++++++++++++++++++++++++++++
 templates/radiusd.conf.erb |   9 +++
 4 files changed, 176 insertions(+)
 create mode 100644 manifests/listen.pp
 create mode 100644 templates/listen.erb

diff --git a/manifests/init.pp b/manifests/init.pp
index 5ba393c..77e06e7 100644
--- a/manifests/init.pp
+++ b/manifests/init.pp
@@ -59,6 +59,7 @@ class freeradius (
   file { [
     "${freeradius::fr_basepath}/certs",
     "${freeradius::fr_basepath}/clients.d",
+    "${freeradius::fr_basepath}/listen.d",
     "${freeradius::fr_basepath}/sites-enabled",
     "${freeradius::fr_basepath}/mods-enabled",
     "${freeradius::fr_basepath}/instantiate",
diff --git a/manifests/listen.pp b/manifests/listen.pp
new file mode 100644
index 0000000..a0be39c
--- /dev/null
+++ b/manifests/listen.pp
@@ -0,0 +1,46 @@
+# == Define freeradius::listen
+#
+define freeradius::listen (
+  $ensure          = 'present',
+  Freeradius::Listen_type $type            = 'auth',
+  $ip          = undef,
+  $ip6        = undef,
+  Integer $port            = 0,
+  $interface       = undef,
+  Array $clients         = [],
+  Integer $max_connections = 16,
+  Integer $lifetime        = 0,
+  Integer $idle_timeout    = 30,
+) {
+  $fr_package  = $::freeradius::params::fr_package
+  $fr_service  = $::freeradius::params::fr_service
+  $fr_basepath = $::freeradius::params::fr_basepath
+  $fr_group    = $::freeradius::params::fr_group
+
+  #
+  # Parameters' validation
+  if $ip and $ip != '*' and !is_ip_address($ip) {
+    fail('ip must be a valid IP address or \'*\'')
+  }
+
+  if $ip6 and $ip6 != '::' and !is_ip_address($ip6) {
+    fail('ip6 must be a valid IP address or \'::\'')
+  }
+
+  if $ip and $ip6 {
+    fail('Only of ip and ip6 can be used')
+  }
+
+  file { "${fr_basepath}/listen.d/${name}.conf":
+    ensure  => $ensure,
+    owner   => 'root',
+    group   => $fr_group,
+    mode    => '0640',
+    content => template('freeradius/listen.erb'),
+    require => [
+      File["${fr_basepath}/listen.d"],
+      Group[$fr_group],
+    ],
+    notify  => Service[$fr_service],
+  }
+}
diff --git a/templates/listen.erb b/templates/listen.erb
new file mode 100644
index 0000000..6159417
--- /dev/null
+++ b/templates/listen.erb
@@ -0,0 +1,120 @@
+# This file is managed by Puppet. DO NOT EDIT.
+#
+listen {
+  #  Type of packets to listen for.
+  #  Allowed values are:
+  #  auth  listen for authentication packets
+  #  acct  listen for accounting packets
+  #  proxy   IP to use for sending proxied packets
+  #  detail  Read from the detail file.  For examples, see
+  #               raddb/sites-available/copy-acct-to-home-server
+  #  status  listen for Status-Server packets.  For examples,
+  #    see raddb/sites-available/status
+  #  coa     listen for CoA-Request and Disconnect-Request
+  #    packets.  For examples, see the file
+  #    raddb/sites-available/coa
+  #
+  type = <%= @type %>
+
+  #  Note: "type = proxy" lets you control the source IP used for
+  #        proxying packets, with some limitations:
+  #
+  #    * A proxy listener CANNOT be used in a virtual server section.
+  #    * You should probably set "port = 0".
+  #    * Any "clients" configuration will be ignored.
+  #
+  #  See also proxy.conf, and the "src_ipaddr" configuration entry
+  #  in the sample "home_server" section.  When you specify the
+  #  source IP address for packets sent to a home server, the
+  #  proxy listeners are automatically created.
+
+  #  IP address on which to listen.
+  #  Allowed values are:
+  #  dotted quad (1.2.3.4)
+  #       hostname    (radius.example.com)
+  #       wildcard    (*)
+<%- if !@ip6 and @ip -%>
+  ipaddr = <%= @ip %>
+<%- elsif !@ip6 -%>
+  ipaddr = *
+<%- end -%>
+
+  #  OR, you can use an IPv6 address, but not both
+  #  at the same time.
+#  ipv6addr = ::  # any.  ::1 == localhost
+<%- if !@ip and @ip6 -%>
+  ipv6addr = <%= @ip6 %>
+<%- end -%>
+
+  #  Port on which to listen.
+  #  Allowed values are:
+  #  integer port number (1812)
+  #  0 means "use /etc/services for the proper port"
+  port = <%= @port %>
+
+  #  Some systems support binding to an interface, in addition
+  #  to the IP address.  This feature isn't strictly necessary,
+  #  but for sites with many IP addresses on one interface,
+  #  it's useful to say "listen on all addresses for eth0".
+  #
+  #  If your system does not support this feature, you will
+  #  get an error if you try to use it.
+  #
+#  interface = eth0
+<%- if @interface -%>
+  interface = <%= @interface %>
+<%- end -%>
+
+  #  Per-socket lists of clients.  This is a very useful feature.
+  #
+  #  The name here is a reference to a section elsewhere in
+  #  radiusd.conf, or clients.conf.  Having the name as
+  #  a reference allows multiple sockets to use the same
+  #  set of clients.
+  #
+  #  If this configuration is used, then the global list of clients
+  #  is IGNORED for this "listen" section.  Take care configuring
+  #  this feature, to ensure you don't accidentally disable a
+  #  client you need.
+  #
+  #  See clients.conf for the configuration of "per_socket_clients".
+  #
+#  clients = per_socket_clients
+<%- if !@clients.empty? -%>
+  clients = <%= @clients.join(',') %>
+<%- end -%>
+
+  #
+  #  Connection limiting for sockets with "proto = tcp".
+  #
+  #  This section is ignored for other kinds of sockets.
+  #
+  limit {
+        #
+        #  Limit the number of simultaneous TCP connections to the socket
+        #
+        #  The default is 16.
+        #  Setting this to 0 means "no limit"
+        max_connections = <%= @max_connections %>
+
+        #  The per-socket "max_requests" option does not exist.
+
+        #
+        #  The lifetime, in seconds, of a TCP connection.  After
+        #  this lifetime, the connection will be closed.
+        #
+        #  Setting this to 0 means "forever".
+        lifetime = <%= @lifetime %>
+
+        #
+        #  The idle timeout, in seconds, of a TCP connection.
+        #  If no packets have been received over the connection for
+        #  this time, the connection will be closed.
+        #
+        #  Setting this to 0 means "no timeout".
+        #
+        #  We STRONGLY RECOMMEND that you set an idle timeout.
+        #
+        idle_timeout = <%= @idle_timeout %>
+  }
+}
diff --git a/templates/radiusd.conf.erb b/templates/radiusd.conf.erb
index 6f436c9..6c8046d 100644
--- a/templates/radiusd.conf.erb
+++ b/templates/radiusd.conf.erb
@@ -747,6 +747,15 @@ policy {
 	$INCLUDE policy.d/
 }
 
+######################################################################
+#
+# Listen directives not directly associated to any virtual server.
+# This way you could configure more than one virtual server sharing
+# ports.
+#
+#
+$INCLUDE listen.d/
+
 ######################################################################
 #
 #	Load virtual servers.
-- 
GitLab