From dad7dae8885edeed6bc4891d6d8945383cda3294 Mon Sep 17 00:00:00 2001 From: Ad Schellevis Date: Wed, 21 Oct 2015 11:01:15 +0200 Subject: [PATCH] (auth) add radius authenticator (framework, currently only pap support) --- .../OPNsense/Auth/AuthenticationFactory.php | 3 + .../mvc/app/library/OPNsense/Auth/Radius.php | 175 ++++++++++++++++++ 2 files changed, 178 insertions(+) create mode 100644 src/opnsense/mvc/app/library/OPNsense/Auth/Radius.php diff --git a/src/opnsense/mvc/app/library/OPNsense/Auth/AuthenticationFactory.php b/src/opnsense/mvc/app/library/OPNsense/Auth/AuthenticationFactory.php index 82b907c90..0dd7fd650 100644 --- a/src/opnsense/mvc/app/library/OPNsense/Auth/AuthenticationFactory.php +++ b/src/opnsense/mvc/app/library/OPNsense/Auth/AuthenticationFactory.php @@ -98,6 +98,9 @@ class AuthenticationFactory $authObject = new LDAP(); $localUserMap = $this->fetchUserDNs(); break; + case 'radius': + $authObject = new Radius(); + break; default: $authObject = null; } diff --git a/src/opnsense/mvc/app/library/OPNsense/Auth/Radius.php b/src/opnsense/mvc/app/library/OPNsense/Auth/Radius.php new file mode 100644 index 000000000..995387bd2 --- /dev/null +++ b/src/opnsense/mvc/app/library/OPNsense/Auth/Radius.php @@ -0,0 +1,175 @@ + 'radiusHost', + 'radius_secret' => 'sharedSecret', + 'radius_timeout' => 'timeout', + 'radius_auth_port' => 'authPort', + 'radius_acct_port' => 'acctPort', + 'radius_protocol' => 'protocol', + 'refid' => 'nasIdentifier' + ) ; + + // map properties 1-on-1 + foreach ($confMap as $confSetting => $objectProperty) { + if (!empty($config[$confSetting]) && property_exists($this, $objectProperty)) { + $this->$objectProperty = $config[$confSetting]; + } + } + } + + /** + * authenticate user against radius + * @param $username username to authenticate + * @param $password user password + * @return bool authentication status + */ + public function authenticate($username, $password) + { + $radius = radius_auth_open(); + + $error = null; + if (!radius_add_server( + $radius, + $this->radiusHost, + $this->authPort, + $this->sharedSecret, + $this->timeout, + $this->maxRetries + )) { + $error = radius_strerror($radius); + } elseif (!radius_create_request($radius, RADIUS_ACCESS_REQUEST)) { + $error = radius_strerror($radius); + } elseif (!radius_put_string($radius, RADIUS_USER_NAME, $username)) { + $error = radius_strerror($radius); + } elseif (!radius_put_int($radius, RADIUS_SERVICE_TYPE, RADIUS_LOGIN)) { + $error = radius_strerror($radius); + } elseif (!radius_put_int($radius, RADIUS_FRAMED_PROTOCOL, RADIUS_ETHERNET)) { + $error = radius_strerror($radius); + } elseif (!radius_put_string($radius, RADIUS_NAS_IDENTIFIER, $this->nasIdentifier)) { + $error = radius_strerror($radius); + } elseif (!radius_put_int($radius, RADIUS_NAS_PORT_TYPE, RADIUS_ETHERNET)) { + $error = radius_strerror($radius); + } else { + // Implement extra protocols in this section. + switch ($this->protocol) { + case 'PAP': + // do PAP authentication + if (!radius_put_string($radius, RADIUS_USER_PASSWORD, $password)) { + $error = radius_strerror($radius); + } + break; + default: + syslog(LOG_ERR, 'Unsupported protocol '.$this->protocol); + return false; + } + } + + // log errors and perform actual authentication request + if ($error != null) { + syslog(LOG_ERR, 'RadiusError:' . radius_strerror($error)); + } else { + $request = radius_send_request($radius); + if (!$request) { + syslog(LOG_ERR, 'RadiusError:' . radius_strerror($error)); + } else { + switch($request) { + case RADIUS_ACCESS_ACCEPT: + return true; + break; + case RADIUS_ACCESS_REJECT: + return false; + break; + default: + // unexpected result, log + syslog(LOG_ERR, 'Radius unexpected response:' . $request); + } + } + } + return false; + } +}