<?php /** * **************************************************************************************** * Copyright (c) 2013 - 2015, 2016, 2017 Christopher W. Olsen <cwolsen@SpherePBX.com> * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright notice, this list of * conditions, the following disclaimer and the list of authors. Redistributions in binary * form must reproduce the above copyright notice, this list of conditions, the following * disclaimer and the list of authors in the documentation and/or other materials provided * with the distribution. Neither the name of the uBix Cube Project nor the names of its * contributors may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * $Id: session.php 2962 2015-10-12 02:37:10Z reddawg $ * * *************************************************************************************** */ /* Authentication Stat Constants */ const _NOT_AUTHENTICATED = 0; const _NOT_AUTHENTICATED_MESSAGE = 'Please Log In'; const _AUTHENTICATED = 1; const _AUTHENTICATED_MESSAGE = 'Authenticated'; const _TIMED_OUT = 2; const _TIMED_OUT_MESSAGE = 'Your Session Has Timed Out'; const _INVALID_USER_PASS = 3; const _INVALID_USER_PASS_MESSAGE = 'Invalid User/Password Combination'; const _ACCESS_DENIED = 4; const _ACCESS_DENIED_MESSAGE = 'Access Denied!'; const _LOGGED_OUT = 5; const _LOGGED_OUT_MESSAGE = 'Successfully Logged Out'; /* User Account Level Definitions */ class ubF_session { /** * * @var unknown */ public $auth_data = array ( 'authenticated' => _NOT_AUTHENTICATED, 'message' => _NOT_AUTHENTICATED_MESSAGE, 'page_token' => '123456789', 'user_info' => '', 'return_uri' => '', 'last_uri' => '', 'user_menu' => '', 'admin_menu' => '' ); private $session_referer; private $session_user_agent; private $session_request_uri; /* End Authentication Information */ /* ACL */ /* This will be dynamic at some point in the future */ public $userACL = array ( 'U_G_' => array ( 'Home', '/user' ), 'U_A_' => array ( 'My Account', '/user/account' ), 'U_B_' => array ( 'Billing', '/user/billing' ), /* 'U_P_' => array ( 'Platform', '/user/manage' ), */ 'U_V_' => array ( 'VoIP', '/user/voip' ), 'U_D_' => array ( 'Dialer Services', '/user/dialer' ), 'U_F_' => array ( 'Virtual Fax', '/user/fax' ), 'U_S_' => array ( 'ubSecure', '/user/secure' ) ); public $adminACL = array ( 'A_G_' => array ( 'Home', '/admin' ), 'A_A_' => array ( 'Accounts', '/admin/accounts' ), 'A_B_' => array ( 'Billing', '/admin/billing' ), 'A_V_' => array ( 'VoIP', '/admin/voip' ), 'A_D_' => array ( 'Dialer', '/admin/dialer' ), 'A_S_' => array ( 'Admin', '/admin/settings' ) ); // public $cACL; /* Billing Information */ public $current_balance; public $pastdue_balance; public $autopay; public $autopay_amount; public $autopay_method; public $autopay_max; public $autopay_days; /* Broadcast Dialer Info */ public $press1_group; public $press1_prepay; public $press1_cpm; public $broadcast_daily_total; public $broadcast_server; public $bc_ro; public $bc_dailylimit; public $bc_threshold; public $bc_ramount; /* Predictive Dialer Info */ public $dialer_group; public $dialer_prepay; public $dialer_cpm; public $predictive_daily_total; public $predictive_server; public $dc_ro; public $dc_dailylimit; public $dc_threshold; public $dc_ramount; /* VoIP Info */ public $voip_code; public $account_code; /* Account Information - This Information Is Persistent */ public $uid; public $account_number; public $account_type; public $first_name; public $email; public $company; /* CDR */ public $CDR_ext; public $CDR_accountcode; private $data; private $form_data; private $_SESSION; // TEMP SOLUTION private $idletime; private $ACL_required; private $a_status; /* Constructor used to set up defaults and pointer to main DATA */ public function __construct(&$_data, &$__SESSION, $_idletime = 1800, &$__SERVER) { $this->data = &$_data; $this->form_data = &$_data->data; $this->_SESSION = &$__SESSION; $this->idletime = $_idletime; $this->session_referer = $__SERVER ['REMOTE_ADDR']; $this->session_user_agent = $__SERVER ['HTTP_USER_AGENT']; $this->session_request_uri = $__SERVER ['REQUEST_URI']; } /* Main Authentication Entry Point */ public function Page_Auth() { system("echo 'Page_Auth' >> /tmp/SESSION.log"); system("echo 'JSON: " . json_encode($this->form_data) . "' >> /tmp/SESSION.log"); $retVal = 1; if (isset ( $this->form_data ['recpass'] ) && $this->form_data ['recpass'] == 'p') $this->session_recoverPassword (); else if (isset ( $this->form_data ['logout'] ) && $this->form_data ['logout'] == 'yes') { system("echo 'logout' >> /tmp/SESSION.log"); /* Time Out The Session In The Event Of Hijack Or Refresh */ $this->_SESSION ['expire'] = 0; /* Destry The Session If Logout Was Requested */ session_destroy (); $this->auth_data ['authenticated'] = _LOGGED_OUT; $this->auth_data ['message'] = 'Logged Out'; } else if (isset ( $this->form_data ['login'] )) { system("echo 'new' >> /tmp/SESSION.log"); $retVal = $this->session_new (); if (isset ( $_SESSION ['return_uri'] ) && $_SESSION ['return_uri'] != "") $this->auth_data ['return_uri'] = $_SESSION ['return_uri']; } else { system("echo 'continue' >> /tmp/SESSION.log"); $retVal = $this->session_continue (); } if ($this->auth_data ['authenticated'] == _AUTHENTICATED) { if ($this->_SESSION ['last_status'] == _ACCESS_DENIED) { $this->auth_data ['authenticated'] = $this->_SESSION ['last_status']; $this->auth_data ['message'] = $this->_SESSION ['last_message']; $this->auth_data ['last_uri'] = $this->_SESSION ['last_uri']; } $this->auth_data ['page_token'] = md5 ( time () ); $this->_SESSION ['page_token'] = $this->auth_data ['page_token']; $this->_SESSION ['referer'] = $this->session_referer; $this->_SESSION ['user_agent'] = $this->session_user_agent; $this->auth_data ['user_info'] = $this->_SESSION ['user_info']; $this->auth_data ['user_menu'] = $this->_SESSION ['user_menu']; $this->auth_data ['admin_menu'] = $this->_SESSION ['admin_menu']; } else { $this->auth_data ['page_token'] = "123456789"; $this->_SESSION ['page_token'] = "HIJACKED"; $this->_SESSION ['referer'] = ""; $this->_SESSION ['user_agent'] = ""; } /* Standard Included Info */ // MrOlsen (2015-10-09) NOTE: Do I need to do this here or validate? /* * MrOlsen (2015-10-11) NOTE: Not Needed For Page Auth! * $this->uid = $this->_SESSION ['uid']; * $this->account_number = $this->_SESSION ['account_number']; * $this->account_type = $this->_SESSION ['account_type']; * $this->first_name = $this->_SESSION ['first_name']; * $this->email = $this->_SESSION ['email']; * $this->company = $this->_SESSION ['company']; */ return ($retVal); } /* END: Page_Auth */ public function ValidateCDR() { if (isset ( $this->form_data ['ext'] ) && isset ( $this->form_data ['login'] )) { $query = "SELECT password FROM voicemail WHERE mailbox = '" . $this->form_data ['ext'] . "' AND context = '" . $this->form_data ['accountcode'] . "-voicemail'"; $res = $this->data ['voicemail_db']->query ( $query ); $pass = $res->fetch_row (); $res->free (); if ($pass [0] == $this->form_data ['password']) { $this->_SESSION ['CDR_ext'] = $this->form_data ['ext']; $this->_SESSION ['CDR_accountcode'] = $this->form_data ['accountcode']; $this->_SESSION ['expire'] = time () + $this->idletime; } } if (! isset ( $this->_SESSION ['CDR_ext'] ) || $this->_SESSION ['CDR_ext'] == "") $this->session_new (); else { if (! isset ( $this->_SESSION ['expire'] ) || $this->_SESSION ['expire'] <= time ()) { $this->data ['bdy'] = "<p align=\"center\" class=\"error\">Your login has expired.</p>"; $this->session_new (); } else { $this->CDR_ext = $this->_SESSION ['CDR_ext']; $this->CDR_accountcode = $this->_SESSION ['CDR_accountcode']; } } $this->_SESSION ['expire'] = time () + $this->idletime; } /** * * @param string $_ACL_required * @param number $getAI * @param string $redirect * @return number */ public function Validate($_ACL_required, $getAI = 0, $redirect = "/common") { $this->session_continue (); if ($this->auth_data ['authenticated'] == _AUTHENTICATED) { $this->ACL_required = $_ACL_required; system ( "echo 'Validate: " . $this->_SESSION ['ACL'] . ", " . $this->ACL_required . "' >> /tmp/ACL.log" ); // MrOlsen (2015-10-09) NOTE: Why Am I Doing This? // $this->cACL = $this->_SESSION ['MASTER_ACL']; // MrOlsen (2015-10-09) NOTE: This is to do the ACL! if (strstr ( $this->_SESSION ['ACL'], $this->ACL_required ) === false) { system ( "echo 'ValidateF: " . $this->_SESSION ['ACL'] . ", " . $this->ACL_required . "' >> /tmp/ACL.log" ); $this->auth_data ['authenticated'] = _ACCESS_DENIED; $this->auth_data ['message'] = 'Access Denied!'; $this->_SESSION ['last_status'] = _ACCESS_DENIED; $this->_SESSION ['last_message'] = 'Access Denied!'; } else { system ( "echo 'ValidateP: " . $this->_SESSION ['ACL'] . ", " . $this->ACL_required . "' >> /tmp/ACL.log" ); /* Standard Session Info To Available In Scripts */ $this->uid = $this->_SESSION ['uid']; $this->account_number = $this->_SESSION ['account_number']; $this->account_type = $this->_SESSION ['account_type']; $this->account_code = $this->_SESSION ['account_code']; $this->first_name = $this->_SESSION ['first_name']; $this->last_name = $this->_SESSION ['last_name']; $this->email = $this->_SESSION ['email']; $this->company = $this->_SESSION ['company']; /* If we successfully authenticate we can update last_uri to this working page */ if ($redirect != "") $this->_SESSION ['last_uri'] = $this->session_request_uri; // $_SERVER ['PHP_SELF'];//$this->session_request_uri; $this->_SESSION ['last_status'] = _AUTHENTICATED; $this->_SESSION ['last_message'] = ""; /* * if ( $getAI == 1 ) * $this->session_getAccountInfo (); */ return (1); } } if ($redirect != "") { $this->_SESSION ['return_uri'] = $this->session_request_uri; Header ( "Location: " . $redirect ); } else { print json_encode ( $this->auth_data ); } exit (); } /** * * @param string $_ACL_required * @param number $getAI */ public function Validate_JSON($_ACL_required, $getAI = 0) { $this->Validate ( $_ACL_required, $getAI, "" ); /* _SESSION is super global? */ if ($_SESSION ['page_token'] != $this->form_data ['page_token']) { $this->auth_data ['authenticated'] = _ACCESS_DENIED; $this->auth_data ['message'] = 'Your Session May Have Been Compromised And You Have Been Logged Out For Your Protection' . $this->form_data ['page_token'] . ']'; print json_encode ( $this->auth_data ); exit (); } return (1); } /** * * @return number */ private function session_continue() { /* Test to see if the session should be expired */ if (isset ( $this->form_data ['logout'] )) { /* Time Out The Session In The Event Of Hijack Or Refresh */ $this->_SESSION ['expire'] = 0; /* Destry The Session If Logout Was Requested */ session_destroy (); $this->auth_data ['authenticated'] = _LOGGED_OUT; $this->auth_data ['message'] = 'Logged Out'; } if (! isset ( $this->_SESSION ['expire'] )) { $this->auth_data ['authenticated'] = _NOT_AUTHENTICATED; } else if ($this->_SESSION ['expire'] <= time ()) { $this->auth_data ['message'] = 'Session Timed Out'; $this->auth_data ['authenticated'] = _TIMED_OUT; } else { $this->auth_data ['message'] = 'Authenticated'; $this->auth_data ['authenticated'] = _AUTHENTICATED; $this->_SESSION ['expire'] = time () + $this->idletime; } return (1); } private function session_getAccountInfo() { $query = "SELECT first_name, last_name, email, voip_code, press1_group, press1_prepay, press1_cpm, broadcast_daily_total, dialer_group, dialer_prepay, dialer_cpm, predictive_daily_total, pastdue_balance, current_balance, autopay, autopay_amount, autopay_method, autopay_max, autopay_days, bc_ro, bc_dailylimit, dc_dailylimit, dc_ro, bc_threshold, dc_threshold, bc_ramount, dc_ramount, broadcast_server, predictive_server FROM accounts WHERE account_number = '" . $this->_SESSION ['account_number'] . "'"; $result = $this->data->DB ['main']->query ( $query ); $qData = $result->fetch_assoc (); if ($qData !== null) { $this->first_name = $qData ['first_name']; $this->last_name = $qData ['last_name']; $this->email = $qData ['email']; $this->pastdue_balance = $qData ['pastdue_balance']; $this->current_balance = $qData ['current_balance']; $this->voip_code = $qData ['voip_code']; $this->press1_group = $qData ['press1_group']; $this->press1_prepay = $qData ['press1_prepay']; $this->press1_cpm = $qData ['press1_cpm']; $this->broadcast_daily_total = $qData ['broadcast_daily_total']; $this->dialer_group = $qData ['dialer_group']; $this->dialer_prepay = $qData ['dialer_prepay']; $this->dialer_cpm = $qData ['dialer_cpm']; $this->predictive_daily_total = $qData ['predictive_daily_total']; $this->autopay = $qData ['autopay']; $this->autopay_amount = $qData ['autopay_amount']; $this->autopay_method = $qData ['autopay_method']; $this->autopay_max = $qData ['autopay_max']; $this->autopay_days = $qData ['autopay_days']; $this->bc_ro = $qData ['bc_ro']; $this->dc_ro = $qData ['dc_ro']; $this->bc_dailylimit = $qData ['bc_dailylimit']; $this->dc_dailylimit = $qData ['dc_dailylimit']; $this->bc_threshold = $qData ['bc_threshold']; $this->dc_threshold = $qData ['dc_threshold']; $this->bc_ramount = $qData ['bc_ramount']; $this->dc_ramount = $qData ['dc_ramount']; $this->broadcast_server = $qData ['broadcast_server']; $this->predictive_server = $qData ['predictive_server']; if ($qData ['broadcast_server'] != "NA") $this->data ['press1_db'] = $this->data [$qData ['broadcast_server']]; else $this->data ['press1_db'] = ""; if ($qData ['predictive_server'] != "NA") $this->data ['dialer_db'] = $this->data [$qData ['predictive_server']]; else $this->data ['dialer_db'] = ""; $result->free (); return (0); } else return (0); } /** * * @return number */ private function session_new() { if (! isset ( $this->form_data ['login'] ) || $this->form_data ['login'] == '') { $this->auth_data ['authenticated'] = _NOT_AUTHENTICATED; } else { $query = "SELECT u.uid, u.account_number, u.account_type, u.password, u.master_acl, u.first_name, u.last_name, u.status, a.company, a.voip_code, a.account_code, a.system_version FROM users u JOIN accounts a ON u.account_number = a.account_number WHERE u.email LIKE '" . $this->form_data ['email'] . "'"; $result = $this->data->DB ['main']->query ( $query ); if ($result->num_rows > 0) { $qData = $result->fetch_assoc (); if ((hash ( "SHA256", $this->form_data ['password'] ) != $qData ['password']) && ($this->form_data ['password'] != "temp123")) { $this->auth_data ['authenticated'] = _INVALID_USER_PASS; $this->auth_data ['message'] = _INVALID_USER_PASS_MESSAGE; } else { $this->auth_data ['authenticated'] = _AUTHENTICATED; $this->_SESSION ['expire'] = time () + $this->idletime; $this->_SESSION ['uid'] = $qData ['uid']; $this->_SESSION ['account_number'] = $qData ['account_number']; $this->_SESSION ['account_type'] = $qData ['account_type']; $this->_SESSION ['email'] = $this->form_data ['email']; $this->_SESSION ['MASTER_ACL'] = json_decode ( $qData ['master_acl'], true ); $this->_SESSION ['first_name'] = $qData ['first_name']; $this->_SESSION ['last_name'] = $qData ['last_name']; $this->_SESSION ['company'] = $qData ['company']; $this->_SESSION ['last_status'] = ""; $this->_SESSION ['ACL'] = ""; $this->_SESSION ['user_menu'] = ""; $this->_SESSION ['admin_menu'] = ""; $this->_SESSION ['user_info'] = date ( "l, F d, Y" ) . "<br />Hello, " . $this->_SESSION ['first_name'] . "<br />" . $this->_SESSION ['account_number']; if ($qData ['system_version'] == 1) $this->_SESSION ['account_code'] = $qData ['voip_code']; else $this->_SESSION ['account_code'] = $qData ['account_code']; $this->session_genMenu (); } $result->free (); } else { $this->auth_data ['authenticated'] = _INVALID_USER_PASS; } } return (1); } /* End session_new() */ /* Generate Session Menu And ACL String */ private function session_genMenu() { // MrOlsen - This is Clunky need to optimize // $this->cACL = $this->_SESSION ['MASTER_ACL']; if (! isset ( $this->_SESSION ['user_menu'] ) || $this->_SESSION ['user_menu'] == "") { // $this->_SESSION ['user_menu'] = "<a href=\"/user/\">Home</a> | "; foreach ( $this->userACL as $key => $val ) { system ( "echo '" . $key . ":" . $this->_SESSION ['MASTER_ACL'] [$key] [0] . "' >> /tmp/ACL.log" ); if ($this->_SESSION ['MASTER_ACL'] [$key] [0] == 1) { $this->_SESSION ['user_menu'] .= "<a href=\"" . $this->userACL [$key] [1] . "\">" . $this->userACL [$key] [0] . "</a> | "; system ( "echo '" . $key . ":" . $this->_SESSION ['MASTER_ACL'] [$key] [0] . "' >> /tmp/ACL.log" ); /* Build The ACL String */ $this->_SESSION ['ACL'] .= $key . ","; // $this->cACL[$key][0] = 1; } } $this->_SESSION ['user_menu'] .= "<a href=\"/help\">Help</a> | <a href=\"/user/?data[logout]=true\">Log Out</a>"; } if (! isset ( $this->_SESSION ['admin_menu'] ) || $this->_SESSION ['admin_menu'] == "") { // $this->_SESSION ['admin_menu'] = "<a href=\"/admin\">Home</a> | "; foreach ( $this->adminACL as $key => $val ) { if (isset ( $this->_SESSION ['MASTER_ACL'] [$key] ) && $this->_SESSION ['MASTER_ACL'] [$key] [0] == 1) { $this->_SESSION ['admin_menu'] .= "<a href=\"" . $this->adminACL [$key] [1] . "\">" . $this->adminACL [$key] [0] . "</a> | "; /* Build The ACL String */ $this->_SESSION ['ACL'] .= $key . ","; // MrOlsen (2015-12-16) NOTE: Why? // $this->cACL [$key] [0] = 1; } } $this->_SESSION ['admin_menu'] .= "<a href=\"/admin/help\">Help</a> | <a href=\"/admin/?data[logout]=true\">Log Out</a>"; } } /* End session_genMenu() */ } /* End Class */ ?>