From 321a46b71f6f3cf2325a72cd37c15fba5fc0c1b3 Mon Sep 17 00:00:00 2001
From: phpipam <miha.petkovsek@telemach.si>
Date: Wed, 20 Dec 2023 15:24:27 +0100
Subject: [PATCH] Changed from propriatary to dapphp/radius for radius auth
 #3986

---
 functions/classes/class.User.php | 92 +++++++++++++++++++++++++++++++-
 functions/composer.json          |  3 +-
 functions/composer.lock          | 71 +++++++++++++++++++++++-
 3 files changed, 163 insertions(+), 3 deletions(-)

diff --git a/functions/classes/class.User.php b/functions/classes/class.User.php
index 6e858b42..e2d023cc 100644
--- a/functions/classes/class.User.php
+++ b/functions/classes/class.User.php
@@ -1174,7 +1174,7 @@ class User extends Common_functions {
      * @param mixed $password
      * @return void
      */
-    private function auth_radius ($username, $password) {
+    private function auth_radius_legacy ($username, $password) {
         # decode radius parameters
         $params = pf_json_decode($this->authmethodparams);
 
@@ -1223,6 +1223,96 @@ class User extends Common_functions {
         }
     }
 
+    /**
+     * Authenticates user on radius server
+     *
+     * GH: https://github.com/dapphp/radius
+     *
+     * @access private
+     * @param mixed $username
+     * @param mixed $password
+     * @return void
+     */
+    private function auth_radius ($username, $password) {
+        # decode radius parameters
+        $params = pf_json_decode($this->authmethodparams);
+
+        # Valdate composer
+        if($this->composer_has_errors(["dapphp/radius"])) {
+            $this->Result->show("danger", $this->composer_err, true);
+        }
+
+        # Composer
+        require __DIR__ . '/../vendor/autoload.php';
+
+        // init client
+        $client = new Radius();
+        // set params
+        $client->setServer($params->hostname)
+               ->setSecret($params->secret)
+               ->setNasIpAddress(gethostbyname(gethostname()))
+               ->setAttribute(32, 'login');
+
+        // fake type for testing
+        $params->authType = "pap";
+
+        // pap
+        if(!isset($params->authType) || @$params->authType=="pap") {
+            $authenticated = $client->accessRequest($username, $password);
+        }
+        // chap-md5
+        elseif ($params->authType == "chap") {
+            $client->setChapPassword($password);
+            $authenticated = $client->accessRequest($username);
+        }
+        // mschapv1
+        elseif ($params->authType == "mschapv1") {
+            $client->setMSChapPassword($password);
+            $authenticated = $client->accessRequest($username);
+        }
+        // mschapv2
+        elseif($params->authType == "mschapv2") {
+            $authenticated = $client->accessRequestEapMsChapV2($username, $password);
+        }
+        // fault
+        else {
+            $this->Result->show("danger", _("Invalid radius authentication method"), true);
+        }
+
+        # debug?
+        if($this->debugging)
+        $client->setDebug(true);
+
+        # authenticate user
+        if($authenticated === true) {
+            # check login restrictions for authenticated user
+            $this->check_login_restrictions ($username);
+            # save to session
+            $this->write_session_parameters ();
+
+            $this->Log->write( _("Radius login"), _("User")." ".$this->user->real_name." "._("logged in via radius"), 0, $username );
+            $this->Result->show("success", _("Radius login successful"));
+
+            # write last logintime
+            $this->update_login_time ();
+            # remove possible blocked IP
+            $this->block_remove_entry ();
+        }
+        else {
+            # add blocked count
+            $this->block_ip ();
+            $this->log_failed_access ($username);
+            $this->Log->write( _("Radius login"), _("Failed to authenticate user on radius server"), 2, $username );
+            $this->Result->show("danger", _("Invalid username or password"), true);
+            # debug ?
+            if($this->debugging) {
+                print "<pre style='width:700px;margin:auto;margin-top:10px;'>";
+                print "Access-Request failed with error ".$client->getErrorMessage()." (".$client->getErrorCode().")";
+                print "</pre>";
+            }
+        }
+    }
+
     /**
      * SAML2 auth
      *
diff --git a/functions/composer.json b/functions/composer.json
index 98208ceb..1fa21abd 100644
--- a/functions/composer.json
+++ b/functions/composer.json
@@ -1,6 +1,7 @@
 {
     "require": {
         "firehed/webauthn": "dev-main",
-        "firehed/cbor": "^0.1.0"
+        "firehed/cbor": "^0.1.0",
+        "dapphp/radius": "^3.0"
     }
 }
diff --git a/functions/composer.lock b/functions/composer.lock
index df24dd56..33a26a30 100644
--- a/functions/composer.lock
+++ b/functions/composer.lock
@@ -4,8 +4,77 @@
         "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
         "This file is @generated automatically"
     ],
-    "content-hash": "b0a7a5cc1994c275013de9975a5f2675",
+    "content-hash": "23e5bbc9dd993a1c1824330765401dfd",
     "packages": [
+        {
+            "name": "dapphp/radius",
+            "version": "v3.0.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/dapphp/radius.git",
+                "reference": "023f538e46d20fa285f55dd65d7054fb9b370a82"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/dapphp/radius/zipball/023f538e46d20fa285f55dd65d7054fb9b370a82",
+                "reference": "023f538e46d20fa285f55dd65d7054fb9b370a82",
+                "shasum": ""
+            },
+            "require": {
+                "php": "^7.3 || ^8.0"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "^9.5.13"
+            },
+            "suggest": {
+                "ext-openssl": "To support hashing required by Pear_CHAP"
+            },
+            "type": "library",
+            "autoload": {
+                "psr-0": {
+                    "Crypt_CHAP_": "lib/"
+                },
+                "psr-4": {
+                    "Dapphp\\Radius\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "LGPL-3.0-or-later"
+            ],
+            "authors": [
+                {
+                    "name": "Drew Phillips",
+                    "email": "drew@drew-phillips.com",
+                    "homepage": "https://drew-phillips.com/"
+                },
+                {
+                    "name": "SysCo/al",
+                    "homepage": "http://developer.sysco.ch/php/"
+                }
+            ],
+            "description": "A pure PHP RADIUS client based on the SysCo/al implementation",
+            "homepage": "https://github.com/dapphp/radius",
+            "keywords": [
+                "Authentication",
+                "authorization",
+                "chap",
+                "ms-chap",
+                "ms-chap v2",
+                "pap",
+                "radius",
+                "rfc1994",
+                "rfc2284",
+                "rfc2759",
+                "rfc2865",
+                "rfc2869"
+            ],
+            "support": {
+                "issues": "https://github.com/dapphp/radius/issues",
+                "source": "https://github.com/dapphp/radius/tree/v3.0.0"
+            },
+            "time": "2022-01-26T04:33:16+00:00"
+        },
         {
             "name": "firehed/cbor",
             "version": "0.1.0",
-- 
GitLab