├── .gitignore ├── README.md ├── clientarea.tpl ├── config.php.example ├── cron.php ├── freeradius.php └── freeradiusapi.php /.gitignore: -------------------------------------------------------------------------------- 1 | config.php.example 2 | 3 | config.php 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # WHMCS Freeradius 2 | 3 | [![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/secondimpression/whmcs-freeradius?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) 4 | 5 | ## WHMCS 7.x 6 | 7 | The [refactor](https://github.com/eksoverzero/whmcs-freeradius/tree/refactor) branch contains a work in progress rewrite for WHMCS 7.x 8 | 9 | ### Installing 10 | 11 | ##### WHMCS 12 | 13 | - Create a folder called `freeradius` in `WHMCSROOT/modules/servers/` 14 | - Copy `freeradius.php` and `clientarea.tpl` into the newly created `WHMCSROOT/modules/servers/freeradius` folder 15 | - Copy `freeradiusapi.php` into the `WHMCSROOT/include/api/` folder 16 | 17 | ##### FreeRADIUS servers 18 | 19 | - Create a folder anywhere with whatever name you like. For example, on Linux `mkdir /opt/whmcs-freeradius` 20 | - Copy `cron.php` and `config.php.example` into this folder 21 | - Rename `config.php.example` to `config.php` 22 | - Edit `config.php` as per your needs/requirements 23 | - Create a Cron task for the `cron.php` file. If your `cron.php` file is in `/opt/whmcs-freeradius` then your cron task shold look something like this, if you want it to run every 5 minutes: 24 | 25 | ``` 26 | */5 * * * * PATH_TO_PHP/php -q /opt/whmcs-freeradius/cron.php 27 | ``` 28 | 29 | - On Linux, you can find the `PATH_TO_PHP` by running `which php` 30 | -------------------------------------------------------------------------------- /clientarea.tpl: -------------------------------------------------------------------------------- 1 |

2 |

Usage Stats for this Billing Period

3 | # of Logins: {$logins}
4 | Accumalated Hours Online: {$logintime}
5 | Total Usage: {$total}
6 | Uploads: {$uploads}
7 | Downloads: {$downloads}
8 | Usage Limit: {$limit}
9 | Status: {$status} 10 |

11 | 12 | {php} 13 | /* 14 | 15 | As per the example output above: 16 | 17 | logins: Number of sessions 18 | logintime: Time spent online in this billing period. Convertered into a readable format 19 | total: Total usage for this billing period. Convertered into a readable format 20 | uploads: Upload usage for this billing period. Convertered into a readable format 21 | downloads: Download usage for this billing period. Convertered into a readable format 22 | limit: Usage Limit for this billing period. Convertered into a readable format 23 | status: Status on the radius server. Login time or Offline 24 | 25 | 26 | The following are also avaible in unconverted format. For use when creating a chart or using your own converstions 27 | 28 | logintime_seconds: Time spent online in this billing period. In seconds 29 | total_bytes: Total usage for this billing period. In Bytes 30 | uploads_bytes: Upload usage for this billing period. In Bytes 31 | downloads_bytes: Download usage for this billing period. In Bytes 32 | limit_bytes: Usage Limit for this billing period. In Bytes 33 | 34 | */ 35 | {/php} -------------------------------------------------------------------------------- /config.php.example: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /cron.php: -------------------------------------------------------------------------------- 1 | $v) $query_string .= "$k=".urlencode($v)."&"; 66 | 67 | $ch = curl_init(); 68 | curl_setopt($ch, CURLOPT_URL, $whmcs_api_url); 69 | curl_setopt($ch, CURLOPT_POST, 1); 70 | curl_setopt($ch, CURLOPT_TIMEOUT, 30); 71 | curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 72 | curl_setopt($ch, CURLOPT_POSTFIELDS, $query_string); 73 | curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0); 74 | curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); 75 | $jsondata = curl_exec($ch); 76 | if( curl_error($ch) ) { 77 | echo "WHMCS API Connection Error: " . curl_errno($ch) . " - " . curl_error($ch) . "\n"; 78 | curl_close($ch); 79 | continue; 80 | } 81 | 82 | curl_close($ch); 83 | $api_data = json_decode($jsondata, true); 84 | 85 | if( $api_data["result"] == 'error' ) { 86 | echo $user . ": " . $api_data["message"] . "\n"; 87 | continue; 88 | } 89 | 90 | $startdate = $api_data["startdate"]; 91 | $enddate = $api_data["enddate"]; 92 | $usagelimit = $api_data["usagelimit"]; 93 | 94 | if( $usagelimit == 0 ) { 95 | echo $user . ": No usage limit set\n"; 96 | continue; 97 | } 98 | 99 | $query = "SELECT SUM(radacct.AcctOutputOctets) + SUM(radacct.AcctInputOctets) AS total FROM radacct WHERE radacct.Username='$user' AND radacct.AcctStartTime>='".$startdate."'"; 100 | if ($enddate) $query .= " AND radacct.AcctStartTime<='".$startdate."'"; 101 | $result = mysql_query($query); 102 | $data = mysql_fetch_array($result); 103 | $usagetotal = $data[0]; 104 | if( ( $usagetotal == "" ) || ( $usagetotal == NULL ) ) { $usagetotal = 0; } 105 | 106 | if($usagetotal >= $usagelimit) { 107 | $result = mysql_query( "SELECT value FROM radcheck where username = '$user' and attribute = 'Expiration'" ); 108 | $row = mysql_fetch_array($result); 109 | if( !$row ) { 110 | $result = mysql_query( "INSERT into radcheck (username, attribute, op, value) values ('".$user."','Expiration',':=','".date("Y-d-m G:i:s")."')" ); 111 | echo $user . ": Account has reached its usage limit.\n"; 112 | disconnect($user); 113 | } 114 | } 115 | else { 116 | $result = mysql_query( "SELECT value FROM radcheck where username = '$user' and attribute = 'Expiration'" ); 117 | $row = mysql_fetch_array($result); 118 | if( $row ) { 119 | $result = mysql_query("DELETE from radcheck where username = '".$user."' and attribute = 'Expiration'"); 120 | echo $user . ": Account is within its usage limit. Removing suspension\n"; 121 | } 122 | } 123 | } 124 | //end 125 | 126 | //Functions 127 | function disconnect($username) { 128 | require( dirname(__FILE__) . '/config.php' ); 129 | 130 | $result = mysql_query("SELECT radacctid FROM radacct where username = '".$username."' and acctstoptime is null"); 131 | while( $row = mysql_fetch_array($result) ) { 132 | $result = mysql_query("SELECT * FROM radacct where radacctid = '".$row['radacctid']."'"); 133 | $radacct = mysql_fetch_array($result); 134 | 135 | $result = mysql_query("SELECT * FROM nas where nasname = '".$radacct['nasipaddress']."'"); 136 | $nas = mysql_fetch_array($result); 137 | if( $nas ) { 138 | $command = "echo \"User-Name='".$username."',Framed-IP-Address='".$radacct['framedipaddress']."',Acct-Session-Id='".$radacct['acctsessionid']."',NAS-IP-Address='".$radacct['nasipaddress']."'\"| ".$radclient_path." -r 3 -x ".$nas['nasname'].":".$nas['ports']." disconnect ".$nas['secret'].""; 139 | exec($command,$output,$rv); 140 | $podreply = end($output); 141 | if( strpos( $podreply, "Disconnect-ACK" ) === true ) { 142 | $message = $username.": Successfully disconnected session"; 143 | } 144 | else if( strpos($podreply, "Disconnect-NAK" ) === true ) { 145 | $message = "Failed to disconnected session. Device rejected the request."; 146 | } 147 | else { 148 | $message = $username.": Failed to disconnected session. Device time out."; 149 | } 150 | echo $message . "\n"; 151 | } 152 | } 153 | } 154 | //end 155 | 156 | //Close radius mysql connection 157 | mysql_close($mysql); 158 | //end 159 | 160 | ?> -------------------------------------------------------------------------------- /freeradius.php: -------------------------------------------------------------------------------- 1 | array ( 6 | "FriendlyName" => "Radius Group", 7 | "Type" => "text", 8 | "Size" => "25", 9 | "Description" => "FreeRADIUS group name" 10 | ), 11 | "usage_limit" => array ( 12 | "FriendlyName" => "Usage Limit", 13 | "Type" => "text", 14 | "Size" => "25", 15 | "Description" => "In bytes. 0 or blank to disable" 16 | ), 17 | "rate_limit" => array ( 18 | "FriendlyName" => "Rate Limit", 19 | "Type" => "text", 20 | "Size" => "25", 21 | "Description" => "Router specific. 0 or blank to disable" 22 | ), 23 | "session_limit" => array ( 24 | "FriendlyName" => "Session Limit", 25 | "Type" => "text", 26 | "Size" => "5", 27 | "Description" => "Fixed number. 0 or balnk to disable" 28 | ) 29 | ); 30 | return $configarray; 31 | } 32 | 33 | function freeradius_AdminServicesTabFields($params){ 34 | $username = $params["username"]; 35 | $serviceid = $params["serviceid"]; 36 | 37 | $collected = collect_usage($params); 38 | 39 | $fieldsarray = array( 40 | '# of Logins' => $collected['logins'], 41 | 'Accumalated Hours Online' => secs_to_h( $collected['logintime'] ), 42 | 'Total Usage' => byte_size( $collected['total'] ), 43 | 'Uploaded' => byte_size( $collected['uploads'] ), 44 | 'Downloaded' => byte_size( $collected['downloads'] ), 45 | 'Usage Limit' => byte_size( $collected['usage_limit'] ), 46 | 'Status' => $collected['status'] 47 | ); 48 | return $fieldsarray; 49 | } 50 | 51 | function freeradius_ClientArea($params){ 52 | $username = $params["username"]; 53 | $serviceid = $params["serviceid"]; 54 | 55 | $collected = collect_usage($params); 56 | 57 | return array( 58 | 'templatefile' => 'clientarea', 59 | 'vars' => array( 60 | 'logins' => $collected['logins'], 61 | 'logintime' => secs_to_h( $collected['logintime'] ), 62 | 'logintime_seconds' => $collected['logintime'], 63 | 'uploads' => byte_size( $collected['uploads'] ), 64 | 'uploads_bytes' => $collected['uploads'], 65 | 'downloads' => byte_size( $collected['downloads'] ), 66 | 'downloads_bytes' => $collected['downloads'], 67 | 'total' => byte_size( $collected['total'] ), 68 | 'total_bytes' => $collected['total'], 69 | 'limit' => byte_size( $collected['usage_limit']), 70 | 'limit_bytes' => $collected['usage_limit'], 71 | 'status' => $collected['status'], 72 | ), 73 | ); 74 | } 75 | 76 | function freeradius_username($email){ 77 | global $CONFIG; 78 | $emaillen = strlen($email); 79 | $result = select_query( 80 | "tblhosting", 81 | "COUNT(*)", 82 | array( 83 | "username" => $email 84 | ) 85 | ); 86 | $data = mysql_fetch_array($result); 87 | $username_exists = $data[0]; 88 | $suffix = 0; 89 | while( $username_exists > 0 ){ 90 | $suffix++; 91 | $email = substr( $email, 0, $emaillen ) . $suffix; 92 | $result = select_query( 93 | "tblhosting", 94 | "COUNT(*)", 95 | array( 96 | "username" => $email 97 | ) 98 | ); 99 | $data = mysql_fetch_array($result); 100 | $username_exists = $data[0]; 101 | } 102 | return $email; 103 | } 104 | 105 | function freeradius_CreateAccount($params){ 106 | $username = $params["username"]; 107 | $password = $params["password"]; 108 | $groupname = $params["configoption1"]; 109 | $firstname = $params["clientsdetails"]["firstname"]; 110 | $lastname = $params["clientsdetails"]["lastname"]; 111 | $email = $params["clientsdetails"]["email"]; 112 | $phonenumber = $params["clientsdetails"]["phonenumber"]; 113 | 114 | if( !$username ){ 115 | $username = freeradius_username( $email ); 116 | update_query( 117 | "tblhosting", 118 | array( 119 | "username" => $username 120 | ), 121 | array( 122 | "id" => $params["serviceid"] 123 | ) 124 | ); 125 | } 126 | 127 | $sqlhost = $params["serverip"]; 128 | $sqlusername = $params["serverusername"]; 129 | $sqlpassword = $params["serverpassword"]; 130 | $sqldbname = $params["serveraccesshash"]; 131 | $freeradiussql = mysql_connect($sqlhost,$sqlusername,$sqlpassword); 132 | mysql_select_db($sqldbname); 133 | 134 | $query = "SELECT COUNT(*) FROM radcheck WHERE username='$username'"; 135 | $result = mysql_query($query,$freeradiussql); 136 | if( !$result ){ 137 | $radiussqlerror = mysql_error(); 138 | freeradius_WHMCSReconnect(); 139 | return "FreeRadius Database Query Error: ".$radiussqlerror; 140 | } 141 | $data = mysql_fetch_array($result); 142 | if( $data[0] ){ 143 | freeradius_WHMCSReconnect(); 144 | return "Username Already Exists"; 145 | } 146 | $query = "INSERT INTO radcheck (username, attribute, value, op) VALUES ('$username', 'User-Password', '$password', ':=')"; 147 | $result = mysql_query($query,$freeradiussql); 148 | if( !$result ){ 149 | $radiussqlerror = mysql_error(); 150 | freeradius_WHMCSReconnect(); 151 | return "FreeRadius Database Query Error: " . $radiussqlerror; 152 | } 153 | $query = "INSERT INTO radusergroup(username, groupname) VALUES ('$username', '$groupname')"; 154 | $result = mysql_query( $query, $freeradiussql ); 155 | if( !$result ){ 156 | $radiussqlerror = mysql_error(); 157 | freeradius_WHMCSReconnect(); 158 | return "FreeRadius Database Query Error: " . $radiussqlerror; 159 | } 160 | 161 | $rate_limit = $params["configoption3"]; 162 | $session_limit = $params["configoption4"]; 163 | 164 | foreach( $params["configoptions"] as $key => $value ){ 165 | if( $key == 'Rate Limit' ){ 166 | $rate_limit = $value; 167 | } 168 | if( $key == 'Session Limit' ){ 169 | $session_limit = $value; 170 | } 171 | } 172 | 173 | if( $rate_limit ){ 174 | $query = "INSERT INTO radreply (username,attribute,value,op) VALUES ('$username','Mikrotik-Rate-Limit','$rate_limit',':=')"; 175 | $result = mysql_query($query,$freeradiussql); 176 | if (!$result) { 177 | $radiussqlerror = mysql_error(); 178 | freeradius_WHMCSReconnect(); 179 | return "FreeRadius Database Query Error: ".$radiussqlerror; 180 | } 181 | } 182 | 183 | if( $session_limit ){ 184 | $query = "INSERT INTO radcheck (username,attribute,value,op) VALUES ('$username','Simultaneous-Use','$session_limit',':=')"; 185 | $result = mysql_query($query,$freeradiussql); 186 | if (!$result) { 187 | $radiussqlerror = mysql_error(); 188 | freeradius_WHMCSReconnect(); 189 | return "FreeRadius Database Query Error: ".$radiussqlerror; 190 | } 191 | } 192 | 193 | freeradius_WHMCSReconnect(); 194 | return "success"; 195 | } 196 | 197 | function freeradius_SuspendAccount($params){ 198 | $username = $params["username"]; 199 | $password = $params["password"]; 200 | 201 | $sqlhost = $params["serverip"]; 202 | $sqlusername = $params["serverusername"]; 203 | $sqlpassword = $params["serverpassword"]; 204 | $sqldbname = $params["serveraccesshash"]; 205 | $freeradiussql = mysql_connect($sqlhost,$sqlusername,$sqlpassword); 206 | mysql_select_db($sqldbname); 207 | 208 | $query = "SELECT COUNT(*) FROM radcheck WHERE username='$username'"; 209 | $result = mysql_query($query,$freeradiussql); 210 | if (!$result) { 211 | freeradius_WHMCSReconnect(); 212 | return "FreeRadius Database Query Error: ".mysql_error(); 213 | } 214 | $data = mysql_fetch_array($result); 215 | $count = $data[0]; 216 | if (!$count) { 217 | freeradius_WHMCSReconnect(); 218 | return "User Not Found"; 219 | } 220 | $query = "SELECT COUNT(*) FROM radcheck WHERE username='$username' AND attribute='Expiration'"; 221 | $result = mysql_query($query,$freeradiussql); 222 | if (!$result) { 223 | freeradius_WHMCSReconnect(); 224 | return "FreeRadius Database Query Error: ".mysql_error(); 225 | } 226 | $data = mysql_fetch_array($result); 227 | $count = $data[0]; 228 | if (!$count) { 229 | $query = "INSERT INTO radcheck (username,attribute,value,op) VALUES ('$username','Expiration','".date("d F Y")."',':=')"; 230 | } else { 231 | $query = "UPDATE radcheck SET value='".date("d F Y")."' WHERE username='$username' AND attribute='Expiration'"; 232 | } 233 | $result = mysql_query($query,$freeradiussql); 234 | if (!$result) { 235 | freeradius_WHMCSReconnect(); 236 | return "FreeRadius Database Query Error: ".mysql_error(); 237 | } 238 | freeradius_WHMCSReconnect(); 239 | 240 | return "success"; 241 | } 242 | 243 | function freeradius_UnsuspendAccount($params){ 244 | $username = $params["username"]; 245 | $password = $params["password"]; 246 | 247 | $sqlhost = $params["serverip"]; 248 | $sqlusername = $params["serverusername"]; 249 | $sqlpassword = $params["serverpassword"]; 250 | $sqldbname = $params["serveraccesshash"]; 251 | $freeradiussql = mysql_connect($sqlhost,$sqlusername,$sqlpassword); 252 | mysql_select_db($sqldbname); 253 | 254 | $query = "SELECT COUNT(*) FROM radcheck WHERE username='$username' AND attribute='Expiration'"; 255 | $result = mysql_query($query,$freeradiussql); 256 | if (!$result) { 257 | freeradius_WHMCSReconnect(); 258 | return "FreeRadius Database Query Error: ".mysql_error(); 259 | } 260 | $data = mysql_fetch_array($result); 261 | $count = $data[0]; 262 | if (!$count) { 263 | freeradius_WHMCSReconnect(); 264 | return "User Not Currently Suspended"; 265 | } 266 | $query = "DELETE FROM radcheck WHERE username='$username' AND attribute='Expiration'"; 267 | $result = mysql_query($query,$freeradiussql); 268 | if (!$result) { 269 | freeradius_WHMCSReconnect(); 270 | return "FreeRadius Database Query Error: ".mysql_error(); 271 | } 272 | freeradius_WHMCSReconnect(); 273 | 274 | return "success"; 275 | } 276 | 277 | function freeradius_TerminateAccount($params){ 278 | $username = $params["username"]; 279 | $password = $params["password"]; 280 | 281 | $sqlhost = $params["serverip"]; 282 | $sqlusername = $params["serverusername"]; 283 | $sqlpassword = $params["serverpassword"]; 284 | $sqldbname = $params["serveraccesshash"]; 285 | $freeradiussql = mysql_connect($sqlhost,$sqlusername,$sqlpassword); 286 | mysql_select_db($sqldbname); 287 | 288 | $query = "DELETE FROM radreply WHERE username='$username'"; 289 | $result = mysql_query($query,$freeradiussql); 290 | if (!$result) { 291 | $radiussqlerror = mysql_error(); 292 | freeradius_WHMCSReconnect(); 293 | return "FreeRadius Database Query Error: ".$radiussqlerror; 294 | } 295 | $query = "DELETE FROM radusergroup WHERE username='$username'"; 296 | $result = mysql_query($query,$freeradiussql); 297 | if (!$result) { 298 | $radiussqlerror = mysql_error(); 299 | freeradius_WHMCSReconnect(); 300 | return "FreeRadius Database Query Error: ".$radiussqlerror; 301 | } 302 | $query = "DELETE FROM radcheck WHERE username='$username'"; 303 | $result = mysql_query($query,$freeradiussql); 304 | if (!$result) { 305 | $radiussqlerror = mysql_error(); 306 | freeradius_WHMCSReconnect(); 307 | return "FreeRadius Database Query Error: ".$radiussqlerror; 308 | } 309 | freeradius_WHMCSReconnect(); 310 | 311 | return "success"; 312 | } 313 | 314 | function freeradius_ChangePassword($params){ 315 | $username = $params["username"]; 316 | $password = $params["password"]; 317 | 318 | $sqlhost = $params["serverip"]; 319 | $sqlusername = $params["serverusername"]; 320 | $sqlpassword = $params["serverpassword"]; 321 | $sqldbname = $params["serveraccesshash"]; 322 | $freeradiussql = mysql_connect($sqlhost,$sqlusername,$sqlpassword); 323 | mysql_select_db($sqldbname); 324 | 325 | $query = "SELECT COUNT(*) FROM radcheck WHERE username='$username'"; 326 | $result = mysql_query($query,$freeradiussql); 327 | if (!$result) { 328 | $sqlerror = mysql_error(); 329 | freeradius_WHMCSReconnect(); 330 | return "FreeRadius Database Query Error: $sqlerror"; 331 | } 332 | $data = mysql_fetch_array($result); 333 | $count = $data[0]; 334 | if (!$count) { 335 | freeradius_WHMCSReconnect(); 336 | return "User Not Found"; 337 | } 338 | $query = "UPDATE radcheck SET value='$password' WHERE username='$username' AND attribute='User-Password'"; 339 | $result = mysql_query($query,$freeradiussql); 340 | if (!$result) { 341 | freeradius_WHMCSReconnect(); 342 | return "FreeRadius Database Query Error: ".mysql_error(); 343 | } 344 | freeradius_WHMCSReconnect(); 345 | 346 | return "success"; 347 | } 348 | 349 | function freeradius_ChangePackage($params){ 350 | $username = $params["username"]; 351 | $password = $params["password"]; 352 | $groupname = $params["configoption1"]; 353 | 354 | $sqlhost = $params["serverip"]; 355 | $sqlusername = $params["serverusername"]; 356 | $sqlpassword = $params["serverpassword"]; 357 | $sqldbname = $params["serveraccesshash"]; 358 | $freeradiussql = mysql_connect($sqlhost,$sqlusername,$sqlpassword); 359 | mysql_select_db($sqldbname); 360 | 361 | $query = "SELECT COUNT(*) FROM radusergroup WHERE username='$username'"; 362 | $result = mysql_query($query,$freeradiussql); 363 | if (!$result) { 364 | freeradius_WHMCSReconnect(); 365 | return "FreeRadius Database Query Error: ".mysql_error(); 366 | } 367 | $data = mysql_fetch_array($result); 368 | $count = $data[0]; 369 | if ( !$count ) { 370 | freeradius_WHMCSReconnect(); 371 | return "User Not Found"; 372 | } 373 | $query = "UPDATE radusergroup SET groupname='$groupname' WHERE username='$username'"; 374 | $result = mysql_query($query,$freeradiussql); 375 | if ( !$result ) { 376 | freeradius_WHMCSReconnect(); 377 | return "FreeRadius Database Query Error: ".mysql_error(); 378 | } 379 | 380 | $rate_limit = $params["configoption3"]; 381 | $session_limit = $params["configoption4"]; 382 | 383 | foreach ($params["configoptions"] as $key => $value) { 384 | if ($key == 'Rate Limit') { 385 | $rate_limit = $value; 386 | } 387 | if ($key == 'Session Limit') { 388 | $session_limit = $value; 389 | } 390 | } 391 | 392 | if( $rate_limit ) { 393 | $query = "UPDATE radreply SET value='$rate_limit' WHERE username='$username' AND attribute='Mikrotik-Rate-Limit'"; 394 | $result = mysql_query($query,$freeradiussql); 395 | if (!$result) { 396 | $radiussqlerror = mysql_error(); 397 | freeradius_WHMCSReconnect(); 398 | return "FreeRadius Database Query Error: ".$radiussqlerror; 399 | } 400 | } 401 | 402 | if( $session_limit ) { 403 | $query = "UPDATE radcheck SET value='$session_limit' WHERE username='$username' AND attribute='Simultaneous-Use'"; 404 | $result = mysql_query($query,$freeradiussql); 405 | if (!$result) { 406 | $radiussqlerror = mysql_error(); 407 | freeradius_WHMCSReconnect(); 408 | return "FreeRadius Database Query Error: ".$radiussqlerror; 409 | } 410 | } 411 | 412 | freeradius_WHMCSReconnect(); 413 | return "success"; 414 | } 415 | 416 | function freeradius_update_ip_address($params){ 417 | 418 | $username = $params["username"]; 419 | 420 | $result = select_query( 421 | 'tblhosting', 422 | "id,dedicatedip", 423 | array( 424 | "id"=>$params["serviceid"] 425 | ) 426 | ); 427 | $data = mysql_fetch_array($result); 428 | $id = $data['id']; 429 | $dedicatedip = $data['dedicatedip']; 430 | 431 | $sqlhost = $params["serverip"]; 432 | $sqlusername = $params["serverusername"]; 433 | $sqlpassword = $params["serverpassword"]; 434 | $sqldbname = $params["serveraccesshash"]; 435 | $freeradiussql = mysql_connect($sqlhost,$sqlusername,$sqlpassword); 436 | mysql_select_db($sqldbname); 437 | 438 | $query = "DELETE FROM radreply WHERE username='$username' AND attribute='Framed-IP-Address'"; 439 | $result = mysql_query($query,$freeradiussql); 440 | if (!$result) { 441 | $radiussqlerror = mysql_error(); 442 | freeradius_WHMCSReconnect(); 443 | return "FreeRadius Database Query Error: ".$radiussqlerror; 444 | } 445 | 446 | if( $dedicatedip ){ 447 | $query = "INSERT INTO radreply (username,attribute,value,op) VALUES ('$username','Framed-IP-Address','$dedicatedip',':=')"; 448 | $result = mysql_query($query,$freeradiussql); 449 | if (!$result) { 450 | $radiussqlerror = mysql_error(); 451 | freeradius_WHMCSReconnect(); 452 | return "FreeRadius Database Query Error: ".$radiussqlerror; 453 | } 454 | } 455 | freeradius_WHMCSReconnect(); 456 | return "success"; 457 | } 458 | 459 | function freeradius_AdminCustomButtonArray(){ 460 | $buttonarray = array( 461 | "Update IP Address" => "update_ip_address" 462 | ); 463 | return $buttonarray; 464 | } 465 | 466 | function date_range($nextduedate, $billingcycle) { 467 | $year = substr( $nextduedate, 0, 4 ); 468 | $month = substr( $nextduedate, 5, 2 ); 469 | $day = substr( $nextduedate, 8, 2 ); 470 | 471 | if( $billingcycle == "Monthly" ){ 472 | $new_time = mktime( 0, 0, 0, $month - 1, $day, $year ); 473 | } elseif( $billingcycle == "Quarterly" ){ 474 | $new_time = mktime( 0, 0, 0, $month - 3, $day, $year ); 475 | } elseif( $billingcycle == "Semi-Annually" ){ 476 | $new_time = mktime( 0, 0, 0, $month - 6, $day, $year ); 477 | } elseif( $billingcycle == "Annually" ){ 478 | $new_time = mktime( 0, 0, 0, $month, $day, $year - 1 ); 479 | } elseif( $billingcycle == "Biennially" ){ 480 | $new_time = mktime( 0, 0, 0, $month, $day, $year - 2 ); 481 | } 482 | $startdate = date( "Y-m-d", $new_time ); 483 | $enddate = ""; 484 | 485 | if( date( "Ymd", $new_time ) >= date( "Ymd" ) ){ 486 | if( $billingcycle == "Monthly" ){ 487 | $new_time = mktime( 0, 0, 0, $month - 2, $day, $year ); 488 | } elseif( $billingcycle == "Quarterly" ){ 489 | $new_time = mktime( 0, 0, 0, $month - 6, $day, $year ); 490 | } elseif( $billingcycle == "Semi-Annually" ){ 491 | $new_time = mktime( 0, 0, 0, $month - 12, $day, $year ); 492 | } elseif( $billingcycle == "Annually" ){ 493 | $new_time = mktime( 0, 0, 0, $month, $day, $year - 2 ); 494 | } elseif( $billingcycle == "Biennially" ){ 495 | $new_time = mktime( 0, 0, 0, $month, $day, $year - 4 ); 496 | } 497 | $startdate = date( "Y-m-d", $new_time ); 498 | if( $billingcycle == "Monthly" ){ 499 | $new_time = mktime( 0, 0, 0, $month - 1, $day, $year ); 500 | } elseif( $billingcycle == "Quarterly" ){ 501 | $new_time = mktime( 0, 0, 0, $month - 3, $day, $year ); 502 | } elseif( $billingcycle == "Semi-Annually" ){ 503 | $new_time = mktime( 0, 0, 0, $month - 6, $day, $year ); 504 | } elseif( $billingcycle == "Annually" ){ 505 | $new_time = mktime( 0, 0, 0, $month, $day, $year - 1 ); 506 | } elseif( $billingcycle == "Biennially" ){ 507 | $new_time = mktime( 0, 0, 0, $month, $day, $year - 2 ); 508 | } 509 | $enddate = date( "Y-m-d", $new_time ); 510 | } 511 | return array( 512 | "startdate" => $startdate, 513 | "enddate" => $enddate 514 | ); 515 | } 516 | 517 | function collect_usage($params){ 518 | $username = $params["username"]; 519 | $serviceid = $params["serviceid"]; 520 | 521 | $sqlhost = $params["serverip"]; 522 | $sqlusername = $params["serverusername"]; 523 | $sqlpassword = $params["serverpassword"]; 524 | $sqldbname = $params["serveraccesshash"]; 525 | 526 | $result = select_query("tblhosting","nextduedate,billingcycle",array("id"=>$serviceid)); 527 | $data = mysql_fetch_array($result); 528 | 529 | $date_range = date_range( $data["nextduedate"], $data["billingcycle"] ); 530 | 531 | $startdate = $date_range["startdate"]; 532 | $enddate = $date_range["enddate"]; 533 | 534 | $freeradiussql = mysql_connect($sqlhost,$sqlusername,$sqlpassword); 535 | mysql_select_db($sqldbname); 536 | 537 | $query = "SELECT COUNT(*) AS logins,SUM(radacct.AcctSessionTime) AS logintime,SUM(radacct.AcctInputOctets) AS uploads,SUM(radacct.AcctOutputOctets) AS downloads,SUM(radacct.AcctOutputOctets) + SUM(radacct.AcctInputOctets) AS total FROM radacct WHERE radacct.Username='$username' AND radacct.AcctStartTime>='".$startdate."'"; 538 | if ($enddate) $query .= " AND radacct.AcctStartTime<='".$startdate."'"; 539 | $query .= " ORDER BY AcctStartTime DESC"; 540 | $result = mysql_query($query,$freeradiussql); 541 | $data = mysql_fetch_array($result); 542 | $logins = $data[0]; 543 | $logintime = $data[1]; 544 | $uploads = $data[2]; 545 | $downloads = $data[3]; 546 | $total = $data[4]; 547 | 548 | $query = "SELECT radacct.AcctStartTime as start, radacct.AcctStopTime as stop FROM radacct WHERE radacct.Username='$username' ORDER BY AcctStartTime DESC LIMIT 0,1"; 549 | $result = mysql_query($query,$freeradiussql); 550 | $data = mysql_fetch_array($result); 551 | $sessions = mysql_num_rows($result); 552 | $start = $data[0]; 553 | $end = $data[1]; 554 | 555 | $status = "Offline"; 556 | if( $end ) { 557 | $status = "Logged in at ".$start; 558 | } 559 | if( $sessions < 1 ){ 560 | $status = "No logins"; 561 | } 562 | 563 | freeradius_WHMCSReconnect(); 564 | 565 | $usage_limit = 0; 566 | if( !empty( $params["configoption2"] ) ){ 567 | if( is_numeric($params["configoption2"]) ) { $usage_limit = $params["configoption2"]; } 568 | } 569 | 570 | foreach( $params["configoptions"] as $key => $value ){ 571 | $Megabytes = 0; 572 | $Gigabytes = 0; 573 | if( $key == 'Megabytes' ){ 574 | if( is_numeric($value) ){ 575 | $Gigabytes = $value * 1024 * 1024; 576 | } 577 | } 578 | if($key == 'Gigabytes'){ 579 | if( is_numeric($value) ){ 580 | $Gigabytes = $value * 1024 * 1024 * 1024; 581 | } 582 | } 583 | if( ( $Megabytes > 0 ) || ( $Gigabytes > 0 ) ){ 584 | $usage_limit = $Megabytes + $Gigabytes; 585 | } 586 | } 587 | 588 | return array( 589 | 'logins' => $logins, 590 | 'logintime' => $logintime, 591 | 'total' => $total, 592 | 'uploads' => $uploads, 593 | 'downloads' => $downloads, 594 | 'usage_limit' => $usage_limit, 595 | 'status' => $status, 596 | ); 597 | } 598 | 599 | function secs_to_h($secs){ 600 | $units = array( 601 | "week" => 7*24*3600, 602 | "day" => 24*3600, 603 | "hour" => 3600, 604 | "minute" => 60 605 | ); 606 | if ( $secs == 0 ) return "0 seconds"; 607 | if ( $secs < 60 ) return "{$secs} seconds"; 608 | $s = ""; 609 | 610 | foreach ( $units as $name => $divisor ) { 611 | if ( $quot = intval($secs / $divisor) ) { 612 | $s .= $quot." ".$name; 613 | $s .= (abs($quot) > 1 ? "s" : "") . ", "; 614 | $secs -= $quot * $divisor; 615 | } 616 | } 617 | return substr($s, 0, -2); 618 | } 619 | 620 | function byte_size($bytes){ 621 | $size = $bytes / 1024; 622 | if( $size < 1024 ) { 623 | $size = number_format( $size, 2 ); 624 | $size .= ' KB'; 625 | } 626 | else { 627 | if( $size / 1024 < 1024 ) { 628 | $size = number_format($size / 1024, 2); 629 | $size .= ' MB'; 630 | } 631 | else if ( $size / 1024 / 1024 < 1024 ) { 632 | $size = number_format($size / 1024 / 1024, 2); 633 | $size .= ' GB'; 634 | } 635 | } 636 | return $size; 637 | } 638 | 639 | function freeradius_WHMCSReconnect(){ 640 | require( ROOTDIR . "/configuration.php" ); 641 | $whmcsmysql = mysql_connect($db_host,$db_username,$db_password); 642 | mysql_select_db($db_name); 643 | } 644 | 645 | ?> 646 | -------------------------------------------------------------------------------- /freeradiusapi.php: -------------------------------------------------------------------------------- 1 | $username 25 | ) 26 | ); 27 | $tblhosting = mysql_fetch_array($result); 28 | if( !$tblhosting ) { 29 | $return["message"] = "Username not found in WHMCS"; 30 | echo json_encode( $return ); 31 | return; 32 | } 33 | 34 | #Don't bother going on if account is not active 35 | if( $tblhosting["domainstatus"] != "Active" ) { 36 | $return["message"] = "Account not active in WHMCS"; 37 | echo json_encode( $return ); 38 | return; 39 | } 40 | 41 | #Collect service details based on posted username 42 | $result = select_query( 43 | 'tblproducts', 44 | "*", 45 | array( 46 | "id" => $tblhosting["packageid"] 47 | ) 48 | ); 49 | $tblproducts = mysql_fetch_array($result); 50 | if( !$tblproducts ){ 51 | $return["message"] = "Package not found in WHMCS"; 52 | echo json_encode( $return ); 53 | return; 54 | } 55 | 56 | #Check account usage limit 57 | $Megabytes = 0; 58 | $Gigabytes = 0; 59 | $usage_limit = 0; 60 | $result = select_query( 61 | "tblhostingconfigoptions", 62 | "tblhostingconfigoptions.relid,tblhostingconfigoptions.configid,tblhostingconfigoptions.optionid,tblhostingconfigoptions.optionid,tblhostingconfigoptions.qty,tblproductconfigoptionssub.id,tblproductconfigoptionssub.optionname", 63 | array( 64 | "relid"=>$tblhosting["id"], 65 | ), 66 | "relid", 67 | "ASC", 68 | false, 69 | "tblproductconfigoptionssub ON tblproductconfigoptionssub.id=tblhostingconfigoptions.optionid" 70 | ); 71 | 72 | #Billing period dates for usage check 73 | $nextduedate = $tblhosting["nextduedate"]; 74 | $billingcycle = $tblhosting["billingcycle"]; 75 | $year = substr($nextduedate,0,4); 76 | $month = substr($nextduedate,5,2); 77 | $day = substr($nextduedate,8,2); 78 | 79 | if ($billingcycle=="Monthly") { 80 | $new_time=mktime(0,0,0,$month-1,$day,$year); 81 | } elseif ($billingcycle=="Quarterly") { 82 | $new_time=mktime(0,0,0,$month-3,$day,$year); 83 | } elseif ($billingcycle=="Semi-Annually") { 84 | $new_time=mktime(0,0,0,$month-6,$day,$year); 85 | } elseif ($billingcycle=="Annually") { 86 | $new_time=mktime(0,0,0,$month,$day,$year-1); 87 | } elseif ($billingcycle=="Biennially") { 88 | $new_time=mktime(0,0,0,$month,$day,$year-2); 89 | } 90 | $startdate = date("Y-m-d",$new_time); 91 | 92 | $enddate = ""; 93 | 94 | if (date("Ymd",$new_time)>=date("Ymd")) { 95 | if ($billingcycle=="Monthly") { 96 | $new_time=mktime(0,0,0,$month-2,$day,$year); 97 | } elseif ($billingcycle=="Quarterly") { 98 | $new_time=mktime(0,0,0,$month-6,$day,$year); 99 | } elseif ($billingcycle=="Semi-Annually") { 100 | $new_time=mktime(0,0,0,$month-12,$day,$year); 101 | } elseif ($billingcycle=="Annually") { 102 | $new_time=mktime(0,0,0,$month,$day,$year-2); 103 | } elseif ($billingcycle=="Biennially") { 104 | $new_time=mktime(0,0,0,$month,$day,$year-4); 105 | } 106 | $startdate = date("Y-m-d",$new_time); 107 | if ($billingcycle=="Monthly") { 108 | $new_time=mktime(0,0,0,$month-1,$day,$year); 109 | } elseif ($billingcycle=="Quarterly") { 110 | $new_time=mktime(0,0,0,$month-3,$day,$year); 111 | } elseif ($billingcycle=="Semi-Annually") { 112 | $new_time=mktime(0,0,0,$month-6,$day,$year); 113 | } elseif ($billingcycle=="Annually") { 114 | $new_time=mktime(0,0,0,$month,$day,$year-1); 115 | } elseif ($billingcycle=="Biennially") { 116 | $new_time=mktime(0,0,0,$month,$day,$year-2); 117 | } 118 | $enddate = date("Y-m-d",$new_time); 119 | } 120 | 121 | $return["startdate"] = $startdate; 122 | $return["enddate"] = $enddate; 123 | 124 | if( !$tblproducts["configoption2"] ){ 125 | $usage_limit =0; 126 | } 127 | else { 128 | if( is_numeric($tblproducts["configoption2"]) ) { $usage_limit = $tblproducts["configoption2"]; } 129 | } 130 | 131 | while ($data = mysql_fetch_array($result)) { 132 | $qty = $data['qty']; 133 | $optionname = $data['optionname']; 134 | if ($optionname == 'Megabytes') { 135 | if (is_numeric($qty)) { 136 | $Gigabytes = $qty * 1024 * 1024; 137 | } 138 | } 139 | if ($optionname == 'Gigabytes') { 140 | if (is_numeric($qty)) { 141 | $Gigabytes = $qty * 1024 * 1024 * 1024; 142 | } 143 | } 144 | if ( ( $Megabytes > 0 ) || ( $Gigabytes > 0 ) ) { 145 | $usage_limit = $Megabytes + $Gigabytes; 146 | } 147 | } 148 | 149 | $return["usagelimit"] = $usage_limit; 150 | 151 | $return["result"] = "success"; 152 | $return["message"] = "Success"; 153 | echo json_encode( $return ); 154 | return; 155 | 156 | ?> --------------------------------------------------------------------------------