public function get_content()
 {
     global $CFG, $USER, $OUTPUT;
     if (has_capability('block/papercut:view', $this->context)) {
         $this->content = new stdClass();
         $this->content->footer = '';
         $this->content->items = array();
         $this->content->icons = array();
         $serverip = explode('.', $_SERVER['SERVER_ADDR']);
         $internal = address_in_subnet(getremoteaddr(), $serverip[0] . '.' . $serverip[1]);
         $strnobalance = get_string('nobalance', 'block_papercut');
         $image = $OUTPUT->pix_icon('balance_not_available', $strnobalance, 'block_papercut');
         $http = $CFG->block_papercut_https ? 'https://' : 'http://';
         $serverurl = $http . $CFG->block_papercut_server_url . ':' . $CFG->block_papercut_server_port;
         $scriptattrs = array('type' => 'text/javascript');
         $wisgetsattrs = $scriptattrs;
         $widgetsattrs['src'] = $serverurl . '/content/widgets/widgets.js';
         $script1 = "var pcUsername = '******';" . "var pcServerURL = '{$serverurl}'; pcGetUserDetails();";
         $script2 = "pcInitUserEnvironmentalImpactWidget('widgetEnvironment');" . "pcInitUserBalanceWidget('widgetBalance');";
         if ($internal) {
             $this->content->text .= html_writer::tag('script', '', $widgetsattrs);
         }
         $this->content->text .= html_writer::tag('script', $script1, $scriptattrs);
         $this->content->text .= html_writer::tag('div', $image, array('id' => 'widgetBalance'));
         $this->content->text .= html_writer::tag('div', '', array('id' => 'widgetEnvironment'));
         if ($internal) {
             $this->content->text .= html_writer::tag('script', $script2, $scriptattrs);
         }
         return $this->content;
     }
 }
 function test_address_in_subnet()
 {
     $this->assertTrue(address_in_subnet('123.121.234.1', '123.121.234.1'));
     $this->assertFalse(address_in_subnet('123.121.234.2', '123.121.234.1'));
     $this->assertFalse(address_in_subnet('123.121.134.1', '123.121.234.1'));
     $this->assertFalse(address_in_subnet('113.121.234.1', '123.121.234.1'));
     $this->assertTrue(address_in_subnet('123.121.234.0', '123.121.234.2/28'));
     $this->assertTrue(address_in_subnet('123.121.234.15', '123.121.234.2/28'));
     $this->assertFalse(address_in_subnet('123.121.234.16', '123.121.234.2/28'));
     $this->assertFalse(address_in_subnet('123.121.234.255', '123.121.234.2/28'));
     $this->assertFalse(address_in_subnet('123.121.234.0', '123.121.234.0/'));
     $this->assertFalse(address_in_subnet('123.121.234.1', '123.121.234.0/'));
     $this->assertTrue(address_in_subnet('232.232.232.232', '123.121.234.0/0'));
     $this->assertFalse(address_in_subnet('123.122.234.1', '123.121.'));
     $this->assertFalse(address_in_subnet('223.121.234.1', '123.121.'));
     $this->assertTrue(address_in_subnet('123.121.234.1', '123.121'));
     $this->assertFalse(address_in_subnet('123.122.234.1', '123.121'));
     $this->assertFalse(address_in_subnet('223.121.234.1', '123.121'));
     $this->assertFalse(address_in_subnet('123.121.234.100', '123.121.234.10'));
     $this->assertFalse(address_in_subnet('123.121.234.9', '123.121.234.10-20'));
     $this->assertTrue(address_in_subnet('123.121.234.10', '123.121.234.10-20'));
     $this->assertTrue(address_in_subnet('123.121.234.15', '123.121.234.10-20'));
     $this->assertTrue(address_in_subnet('123.121.234.20', '123.121.234.10-20'));
     $this->assertFalse(address_in_subnet('123.121.234.21', '123.121.234.10-20'));
     $this->assertTrue(address_in_subnet('  123.121.234.1  ', '  123.121.234.1  , 1.1.1.1/16,2.2.,3.3.3.3-6  '));
     $this->assertTrue(address_in_subnet('  1.1.2.3 ', '  123.121.234.1  , 1.1.1.1/16,2.2.,3.3.3.3-6  '));
     $this->assertTrue(address_in_subnet('  2.2.234.1  ', '  123.121.234.1  , 1.1.1.1/16,2.2.,3.3.3.3-6  '));
     $this->assertTrue(address_in_subnet('  3.3.3.4  ', '  123.121.234.1  , 1.1.1.1/16,2.2.,3.3.3.3-6  '));
     $this->assertFalse(address_in_subnet('  123.121.234.2  ', '  123.121.234.1  , 1.1.1.1/16,2.2.,3.3.3.3-6  '));
     $this->assertFalse(address_in_subnet('  2.1.2.3 ', '  123.121.234.1  , 1.1.1.1/16,2.2.,3.3.3.3-6  '));
     $this->assertFalse(address_in_subnet('  2.3.234.1  ', '  123.121.234.1  , 1.1.1.1/16,2.2.,3.3.3.3-6  '));
     $this->assertFalse(address_in_subnet('  3.3.3.7  ', '  123.121.234.1  , 1.1.1.1/16,2.2.,3.3.3.3-6  '));
     $this->assertFalse(address_in_subnet('172.16.1.142', '172.16.1.143/148'));
 }
Example #3
0
 public function prevent_access()
 {
     if (address_in_subnet(getremoteaddr(), $this->quiz->subnet)) {
         return false;
     } else {
         return get_string('subnetwrong', 'quizaccess_ipaddress');
     }
 }
Example #4
0
 function plaintext_is_ok()
 {
     global $CFG;
     $trusted_hosts = explode(',', get_config('mnet', 'mnet_trusted_hosts'));
     foreach ($trusted_hosts as $host) {
         if (address_in_subnet(getremoteaddr(), $host)) {
             return true;
         }
     }
     return false;
 }
Example #5
0
function find_lms_user($installid, $username, $signature, $confirmaction = null, $firstname = null, $lastname = null, $email = null)
{
    global $CFG;
    // find this host from the installid
    if (empty($CFG->lmshosts) || !is_array($CFG->lmshosts) || !array_key_exists($installid, $CFG->lmshosts)) {
        return LMS_NO_SUCH_HOST;
    }
    $host = $CFG->lmshosts[$installid];
    // validate our md5 hash
    if ($confirmaction == 'signupconfirmation') {
        $stringtohash = $installid . '|' . $username . '|' . $firstname . '|' . $lastname . '|' . $email . '|' . $host['token'];
    } else {
        $stringtohash = $installid . '|' . $username . '|' . $host['token'];
        // firstname, lastname and email cannot be relied upon not to change
        // so we only want to add them to the hash on signup, not for auth or anything else.
    }
    $checksig = md5($stringtohash);
    if ($checksig != $signature) {
        return LMS_INVALID_HASH;
    }
    // if we have an ip address, check it.
    if (array_key_exists('networkaddress', $host) && empty($confirmaction)) {
        if (!address_in_subnet(getremoteaddr(), $host['networkaddress'])) {
            return LMS_INVALID_NETWORK;
        }
    }
    if (!empty($confirmaction) && !empty($host['confirmurl'])) {
        $client = new Snoopy();
        $client->agent = LMS_SNOOPY_USER_AGENT;
        $client->read_timeout = 5;
        $client->use_gzip = true;
        $postdata = array('action' => $confirmaction, 'username' => $username, 'signature' => $signature);
        @$client->submit($host['confirmurl'], $postdata);
        if ($client->results != 'OK') {
            return clean_param($client->results, PARAM_CLEAN);
        }
    }
    // find our user (we only want to check username and installid, the others could potentially change..
    if (!($user = get_record_sql('SELECT u.* FROM ' . $CFG->prefix . 'users u 
                        JOIN ' . $CFG->prefix . 'users_alias ua ON ua.user_id = u.ident
                        WHERE ua.installid = ? AND ua.username = ?', array($installid, $username)))) {
        return LMS_NO_SUCH_USER;
    }
    return $user;
}
Example #6
0
 /**
  * Will get called before the login page is shown, if NTLM SSO
  * is enabled, and the user is in the right network, we'll redirect
  * to the magic NTLM page for SSO...
  *
  */
 function loginpage_hook()
 {
     global $CFG;
     if ($_SERVER['REQUEST_METHOD'] === 'GET' && !empty($this->config->ntlmsso_enabled) && !empty($this->config->ntlmsso_subnet) && empty($_GET['authldap_skipntlmsso']) && (isguestuser() || !isloggedin()) && address_in_subnet($_SERVER['REMOTE_ADDR'], $this->config->ntlmsso_subnet)) {
         redirect("{$CFG->wwwroot}/auth/ldap/ntlmsso_attempt.php");
     }
 }
Example #7
0
/**
 * Is current ip in give list?
 *
 * @param string $list
 * @return bool
 */
function remoteip_in_list($list)
{
    $inlist = false;
    $clientip = getremoteaddr(null);
    if (!$clientip) {
        // Ensure access on cli.
        return true;
    }
    $list = explode("\n", $list);
    foreach ($list as $subnet) {
        $subnet = trim($subnet);
        if (address_in_subnet($clientip, $subnet)) {
            $inlist = true;
            break;
        }
    }
    return $inlist;
}
         $session = session_get_instance();
         if (!$session->session_exists($token->sid)) {
             //this token will never be valid anymore, delete it
             $DB->delete_records('external_tokens', array('sid' => $token->sid));
             $unsettoken = true;
         }
     }
     //remove token if no valid anymore
     //Also delete this wrong token (similar logic to the web service servers
     //    /webservice/lib.php/webservice_server::authenticate_by_token())
     if (!empty($token->validuntil) and $token->validuntil < time()) {
         $DB->delete_records('external_tokens', array('token' => $token->token, 'tokentype' => EXTERNAL_TOKEN_PERMANENT));
         $unsettoken = true;
     }
     // remove token if its ip not in whitelist
     if (isset($token->iprestriction) and !address_in_subnet(getremoteaddr(), $token->iprestriction)) {
         $unsettoken = true;
     }
     if ($unsettoken) {
         unset($tokens[$key]);
     }
 }
 // if some valid tokens exist then use the most recent
 if (count($tokens) > 0) {
     $token = array_pop($tokens);
 } else {
     if (has_capability('moodle/webservice:createmobiletoken', get_system_context()) or !is_siteadmin($user) && has_capability('moodle/webservice:createtoken', get_system_context())) {
         // if service doesn't exist, dml will throw exception
         $service_record = $DB->get_record('external_services', array('shortname' => $serviceshortname, 'enabled' => 1), '*', MUST_EXIST);
         // create a new token
         $token = new stdClass();
 public function __authenticate($username, $password, $serviceshortname)
 {
     global $CFG, $DB;
     //echo $OUTPUT->header();
     if (!$CFG->enablewebservices) {
         throw new moodle_exception('enablewsdescription', 'webservice');
     }
     $username = trim(textlib::strtolower($username));
     if (is_restored_user($username)) {
         throw new moodle_exception('restoredaccountresetpassword', 'webservice');
     }
     $user = authenticate_user_login($username, $password);
     if (!empty($user)) {
         //Non admin can not authenticate if maintenance mode
         $hassiteconfig = has_capability('moodle/site:config', context_system::instance(), $user);
         if (!empty($CFG->maintenance_enabled) and !$hassiteconfig) {
             throw new moodle_exception('sitemaintenance', 'admin');
         }
         if (isguestuser($user)) {
             throw new moodle_exception('noguest');
         }
         if (empty($user->confirmed)) {
             throw new moodle_exception('usernotconfirmed', 'moodle', '', $user->username);
         }
         // check credential expiry
         $userauth = get_auth_plugin($user->auth);
         if (!empty($userauth->config->expiration) and $userauth->config->expiration == 1) {
             $days2expire = $userauth->password_expire($user->username);
             if (intval($days2expire) < 0) {
                 throw new moodle_exception('passwordisexpired', 'webservice');
             }
         }
         // let enrol plugins deal with new enrolments if necessary
         enrol_check_plugins($user);
         // setup user session to check capability
         session_set_user($user);
         //check if the service exists and is enabled
         $service = $DB->get_record('external_services', array('shortname' => $serviceshortname, 'enabled' => 1));
         if (empty($service)) {
             // will throw exception if no token found
             throw new moodle_exception('servicenotavailable', 'webservice');
         }
         //check if there is any required system capability
         if ($service->requiredcapability and !has_capability($service->requiredcapability, context_system::instance(), $user)) {
             throw new moodle_exception('missingrequiredcapability', 'webservice', '', $service->requiredcapability);
         }
         //specific checks related to user restricted service
         if ($service->restrictedusers) {
             $authoriseduser = $DB->get_record('external_services_users', array('externalserviceid' => $service->id, 'userid' => $user->id));
             if (empty($authoriseduser)) {
                 throw new moodle_exception('usernotallowed', 'webservice', '', $serviceshortname);
             }
             if (!empty($authoriseduser->validuntil) and $authoriseduser->validuntil < time()) {
                 throw new moodle_exception('invalidtimedtoken', 'webservice');
             }
             if (!empty($authoriseduser->iprestriction) and !address_in_subnet(getremoteaddr(), $authoriseduser->iprestriction)) {
                 throw new moodle_exception('invalidiptoken', 'webservice');
             }
         }
         //Check if a token has already been created for this user and this service
         //Note: this could be an admin created or an user created token.
         //      It does not really matter we take the first one that is valid.
         $tokenssql = "SELECT t.id, t.sid, t.token, t.validuntil, t.iprestriction\n              FROM {external_tokens} t\n             WHERE t.userid = ? AND t.externalserviceid = ? AND t.tokentype = ?\n          ORDER BY t.timecreated ASC";
         $tokens = $DB->get_records_sql($tokenssql, array($user->id, $service->id, EXTERNAL_TOKEN_PERMANENT));
         //A bit of sanity checks
         foreach ($tokens as $key => $token) {
             /// Checks related to a specific token. (script execution continue)
             $unsettoken = false;
             //if sid is set then there must be a valid associated session no matter the token type
             if (!empty($token->sid)) {
                 $session = session_get_instance();
                 if (!$session->session_exists($token->sid)) {
                     //this token will never be valid anymore, delete it
                     $DB->delete_records('external_tokens', array('sid' => $token->sid));
                     $unsettoken = true;
                 }
             }
             //remove token if no valid anymore
             //Also delete this wrong token (similar logic to the web service servers
             //    /webservice/lib.php/webservice_server::authenticate_by_token())
             if (!empty($token->validuntil) and $token->validuntil < time()) {
                 $DB->delete_records('external_tokens', array('token' => $token->token, 'tokentype' => EXTERNAL_TOKEN_PERMANENT));
                 $unsettoken = true;
             }
             // remove token if its ip not in whitelist
             if (isset($token->iprestriction) and !address_in_subnet(getremoteaddr(), $token->iprestriction)) {
                 $unsettoken = true;
             }
             if ($unsettoken) {
                 unset($tokens[$key]);
             }
         }
         // if some valid tokens exist then use the most recent
         if (count($tokens) > 0) {
             $token = array_pop($tokens);
         } else {
             if ($serviceshortname == MOODLE_OFFICIAL_MOBILE_SERVICE and has_capability('moodle/webservice:createmobiletoken', get_system_context()) or !is_siteadmin($user) && has_capability('moodle/webservice:createtoken', get_system_context())) {
                 // if service doesn't exist, dml will throw exception
                 $service_record = $DB->get_record('external_services', array('shortname' => $serviceshortname, 'enabled' => 1), '*', MUST_EXIST);
                 // create a new token
                 $token = new stdClass();
                 $token->token = md5(uniqid(rand(), 1));
                 $token->userid = $user->id;
                 $token->tokentype = EXTERNAL_TOKEN_PERMANENT;
                 $token->contextid = context_system::instance()->id;
                 $token->creatorid = $user->id;
                 $token->timecreated = time();
                 $token->externalserviceid = $service_record->id;
                 $tokenid = $DB->insert_record('external_tokens', $token);
                 add_to_log(SITEID, 'webservice', 'automatically create user token', '', 'User ID: ' . $user->id);
                 $token->id = $tokenid;
             } else {
                 throw new moodle_exception('cannotcreatetoken', 'webservice', '', $serviceshortname);
             }
         }
         // log token access
         $DB->set_field('external_tokens', 'lastaccess', time(), array('id' => $token->id));
         add_to_log(SITEID, 'webservice', 'sending requested user token', '', 'User ID: ' . $user->id);
         $usertoken = new stdClass();
         $usertoken->token = $token->token;
         //complete login process by activating session.
         // To restrict the admin user to login into application
         if (is_siteadmin($user)) {
             $heIsAdmin = new stdClass();
             $heIsAdmin->error = 'admin_user';
             echo json_encode($heIsAdmin);
             die;
         }
         Login::__app_complete_user_login($user);
         $forcePasswordChangesql = "SELECT up.userid\n              FROM {user_preferences} up\n             WHERE up.userid = ? AND up.name = ? AND up.value = ?";
         $forcePasswordChange = $DB->get_records_sql($forcePasswordChangesql, array($user->id, 'auth_forcepasswordchange', 1));
         //User Update Profile starts here
         $admins = get_admins();
         $currentAdmin = end($admins);
         $admintokensql = "SELECT et.token\n              FROM {external_tokens} et\n             WHERE et.userid = ?";
         $currrentAdminToken = $DB->get_records_sql($admintokensql, array($currentAdmin->id), 0, 1);
         $unique_key = substr(md5(mt_rand(0, 1000000)), 0, 7);
         $keys = array_keys($currrentAdminToken);
         $appuser = new stdClass();
         $user->token = $token->token;
         $user->forcePasswordChange = !empty($forcePasswordChange) ? true : false;
         $user->updateProfile = substr($unique_key, 0, 3) . $keys[0] . substr($unique_key, 3, 7);
         //Get User role
         $rolesql = "SELECT id\n              FROM {role} \n             WHERE shortname = ?";
         $roleid = array_values($DB->get_records_sql($rolesql, array('reportuser')));
         $reportuser = array_values($DB->get_records_sql("SELECT id FROM {role_assignments} WHERE roleid=" . $roleid[0]->id . " AND userid=" . $user->id . ""));
         if ($reportuser[0]->id != '') {
             $user->role = 'reportuser';
         } else {
             $user->role = '';
         }
         //User Update Profile ends here
         unset($user->password);
         $appuser->USER = $user;
         $user->country_value = $user->country;
         $user->country = get_string($user->country, 'countries');
         echo json_encode($appuser);
     } else {
         throw new moodle_exception('usernamenotfound', 'moodle');
     }
 }
Example #10
0
    /**
     * Load the virtual class needed for the web service.
     *
     * Initialises the virtual class that contains the web service functions that the user is allowed to use.
     * The web service function will be available if the user:
     * - is validly registered in the external_services_users table.
     * - has the required capability.
     * - meets the IP restriction requirement.
     * This virtual class can be used by web service protocols such as SOAP, especially when generating WSDL.
     * NOTE: The implementation of this method has been mostly copied from webservice_zend_server::init_server_class().
     */
    protected function init_service_class()
    {
        global $USER, $DB;
        // Initialise service methods and struct classes.
        $this->servicemethods = array();
        $this->servicestructs = array();
        $params = array();
        $wscond1 = '';
        $wscond2 = '';
        if ($this->restricted_serviceid) {
            $params = array('sid1' => $this->restricted_serviceid, 'sid2' => $this->restricted_serviceid);
            $wscond1 = 'AND s.id = :sid1';
            $wscond2 = 'AND s.id = :sid2';
        }
        $sql = "SELECT s.*, NULL AS iprestriction\n                  FROM {external_services} s\n                  JOIN {external_services_functions} sf ON (sf.externalserviceid = s.id AND s.restrictedusers = 0)\n                 WHERE s.enabled = 1 {$wscond1}\n\n                 UNION\n\n                SELECT s.*, su.iprestriction\n                  FROM {external_services} s\n                  JOIN {external_services_functions} sf ON (sf.externalserviceid = s.id AND s.restrictedusers = 1)\n                  JOIN {external_services_users} su ON (su.externalserviceid = s.id AND su.userid = :userid)\n                 WHERE s.enabled = 1 AND (su.validuntil IS NULL OR su.validuntil < :now) {$wscond2}";
        $params = array_merge($params, array('userid' => $USER->id, 'now' => time()));
        $serviceids = array();
        $remoteaddr = getremoteaddr();
        // Query list of external services for the user.
        $rs = $DB->get_recordset_sql($sql, $params);
        // Check which service ID to include.
        foreach ($rs as $service) {
            if (isset($serviceids[$service->id])) {
                continue;
                // Service already added.
            }
            if ($service->requiredcapability and !has_capability($service->requiredcapability, $this->restricted_context)) {
                continue;
                // Cap required, sorry.
            }
            if ($service->iprestriction and !address_in_subnet($remoteaddr, $service->iprestriction)) {
                continue;
                // Wrong request source ip, sorry.
            }
            $serviceids[$service->id] = $service->id;
        }
        $rs->close();
        // Generate the virtual class name.
        $classname = 'webservices_virtual_class_000000';
        while (class_exists($classname)) {
            $classname++;
        }
        $this->serviceclass = $classname;
        // Get the list of all available external functions.
        $wsmanager = new webservice();
        $functions = $wsmanager->get_external_functions($serviceids);
        // Generate code for the virtual methods for this web service.
        $methods = '';
        foreach ($functions as $function) {
            $methods .= $this->get_virtual_method_code($function);
        }
        $code = <<<EOD
/**
 * Virtual class web services for user id {$USER->id} in context {$this->restricted_context->id}.
 */
class {$classname} {
{$methods}
}
EOD;
        // Load the virtual class definition into memory.
        eval($code);
    }
Example #11
0
 /**
  * Fetches the function description from database,
  * verifies user is allowed to use this function and
  * loads all paremeters and return descriptions.
  * @return void
  */
 protected function load_function_info()
 {
     global $DB, $USER, $CFG;
     if (empty($this->functionname)) {
         throw new invalid_parameter_exception('Missing function name');
     }
     // function must exist
     $function = external_function_info($this->functionname);
     if ($this->restricted_serviceid) {
         $params = array('sid1' => $this->restricted_serviceid, 'sid2' => $this->restricted_serviceid);
         $wscond1 = 'AND s.id = :sid1';
         $wscond2 = 'AND s.id = :sid2';
     } else {
         $params = array();
         $wscond1 = '';
         $wscond2 = '';
     }
     // now let's verify access control
     // now make sure the function is listed in at least one service user is allowed to use
     // allow access only if:
     //  1/ entry in the external_services_users table if required
     //  2/ validuntil not reached
     //  3/ has capability if specified in service desc
     //  4/ iprestriction
     $sql = "SELECT s.*, NULL AS iprestriction\n                  FROM {external_services} s\n                  JOIN {external_services_functions} sf ON (sf.externalserviceid = s.id AND s.restrictedusers = 0 AND sf.functionname = :name1)\n                 WHERE s.enabled = 1 {$wscond1}\n\n                 UNION\n\n                SELECT s.*, su.iprestriction\n                  FROM {external_services} s\n                  JOIN {external_services_functions} sf ON (sf.externalserviceid = s.id AND s.restrictedusers = 1 AND sf.functionname = :name2)\n                  JOIN {external_services_users} su ON (su.externalserviceid = s.id AND su.userid = :userid)\n                 WHERE s.enabled = 1 AND su.validuntil IS NULL OR su.validuntil < :now {$wscond2}";
     $params = array_merge($params, array('userid' => $USER->id, 'name1' => $function->name, 'name2' => $function->name, 'now' => time()));
     $rs = $DB->get_recordset_sql($sql, $params);
     // now make sure user may access at least one service
     $remoteaddr = getremoteaddr();
     $allowed = false;
     foreach ($rs as $service) {
         if ($service->requiredcapability and !has_capability($service->requiredcapability, $this->restricted_context)) {
             continue;
             // cap required, sorry
         }
         if ($service->iprestriction and !address_in_subnet($remoteaddr, $service->iprestriction)) {
             continue;
             // wrong request source ip, sorry
         }
         $allowed = true;
         break;
         // one service is enough, no need to continue
     }
     $rs->close();
     if (!$allowed) {
         throw new webservice_access_exception('Access to external function not allowed');
     }
     // we have all we need now
     $this->function = $function;
 }
Example #12
0
 /**
  * require_subnet
  *
  * @return xxx
  */
 function require_subnet()
 {
     if (!$this->subnet) {
         return false;
     }
     if (address_in_subnet(getremoteaddr(), $this->subnet)) {
         return false;
     }
     // user's IP address is missing or does not match required subnet mask
     return get_string('subnetwrong', 'quiz');
 }
Example #13
0
 /**
  * Fetches the function description from database,
  * verifies user is allowed to use this function and
  * loads all paremeters and return descriptions.
  * @return void
  */
 protected function load_function_info()
 {
     global $USER;
     if (empty($this->functionname)) {
         throw new WebserviceInvalidParameterException(get_string('missingfuncname', 'webserivce'));
     }
     // function must exist
     $function = webservice_function_info($this->functionname);
     if (!$function) {
         throw new WebserviceAccessException(get_string('accessextfunctionnotconf', 'auth.webservice'));
     }
     // first ofall get a complete list of services user is allowed to access
     if ($this->restricted_serviceid) {
         $wscond1 = 'AND s.id = ? ';
         $wscond2 = 'AND s.id = ? ';
     } else {
         $wscond1 = '';
         $wscond2 = '';
     }
     // now let's verify access control
     // now make sure the function is listed in at least one service user is allowed to use
     // allow access only if:
     //  1/ entry in the external_services_users table if required
     //  2/ validuntil not reached
     //  3/ has capability if specified in service desc
     //  4/ iprestriction
     $sql = "SELECT s.*, NULL AS iprestriction\n                  FROM {external_services} s\n                  JOIN {external_services_functions} sf ON (sf.externalserviceid = s.id AND (s.restrictedusers = ? OR s.tokenusers = ?) AND sf.functionname = ?)\n                 WHERE s.enabled = ? {$wscond1}\n\n                 UNION\n\n                SELECT s.*, su.iprestriction\n                  FROM {external_services} s\n                  JOIN {external_services_functions} sf ON (sf.externalserviceid = s.id AND s.restrictedusers = ? AND sf.functionname = ?)\n                  JOIN {external_services_users} su ON (su.externalserviceid = s.id AND su.userid = ?)\n                 WHERE s.enabled = ? AND su.validuntil IS NULL OR su.validuntil < ? {$wscond2}";
     $params = array(0, 1, $function->name, 1);
     $wscond1 && ($params[] = $this->restricted_serviceid);
     $params[] = 1;
     $params[] = $function->name;
     $params[] = $USER->get('id');
     $params[] = 1;
     $params[] = time();
     $wscond2 && ($params[] = $this->restricted_serviceid);
     $rs = get_recordset_sql($sql, $params);
     // now make sure user may access at least one service
     $remoteaddr = getremoteaddr();
     $allowed = false;
     $serviceids = array();
     foreach ($rs as $service) {
         $serviceids[] = $service['id'];
         if ($service['iprestriction'] and !address_in_subnet($remoteaddr, $service['iprestriction'])) {
             // wrong request source ip, sorry
             continue;
         }
         $allowed = true;
         // one service is enough, no need to continue
         break;
     }
     $rs->close();
     if (!$allowed) {
         throw new WebserviceAccessException(get_string('accesstofunctionnotallowed', 'auth.webservice', $this->functionname));
     }
     // now get the list of all functions - this triggers the stashing of
     // functions in the context
     $wsmanager = new webservice();
     $functions = $wsmanager->get_external_functions($serviceids);
     // we have all we need now
     $this->function = $function;
 }
Example #14
0
/**
 * Generate or return an existing token for the current authenticated user.
 * This function is used for creating a valid token for users authenticathing via login/token.php or admin/tool/mobile/launch.php.
 *
 * @param stdClass $service external service object
 * @return stdClass token object
 * @since Moodle 3.2
 * @throws moodle_exception
 */
function external_generate_token_for_current_user($service)
{
    global $DB, $USER;
    core_user::require_active_user($USER, true, true);
    // Check if there is any required system capability.
    if ($service->requiredcapability and !has_capability($service->requiredcapability, context_system::instance())) {
        throw new moodle_exception('missingrequiredcapability', 'webservice', '', $service->requiredcapability);
    }
    // Specific checks related to user restricted service.
    if ($service->restrictedusers) {
        $authoriseduser = $DB->get_record('external_services_users', array('externalserviceid' => $service->id, 'userid' => $USER->id));
        if (empty($authoriseduser)) {
            throw new moodle_exception('usernotallowed', 'webservice', '', $service->shortname);
        }
        if (!empty($authoriseduser->validuntil) and $authoriseduser->validuntil < time()) {
            throw new moodle_exception('invalidtimedtoken', 'webservice');
        }
        if (!empty($authoriseduser->iprestriction) and !address_in_subnet(getremoteaddr(), $authoriseduser->iprestriction)) {
            throw new moodle_exception('invalidiptoken', 'webservice');
        }
    }
    // Check if a token has already been created for this user and this service.
    $conditions = array('userid' => $USER->id, 'externalserviceid' => $service->id, 'tokentype' => EXTERNAL_TOKEN_PERMANENT);
    $tokens = $DB->get_records('external_tokens', $conditions, 'timecreated ASC');
    // A bit of sanity checks.
    foreach ($tokens as $key => $token) {
        // Checks related to a specific token. (script execution continue).
        $unsettoken = false;
        // If sid is set then there must be a valid associated session no matter the token type.
        if (!empty($token->sid)) {
            if (!\core\session\manager::session_exists($token->sid)) {
                // This token will never be valid anymore, delete it.
                $DB->delete_records('external_tokens', array('sid' => $token->sid));
                $unsettoken = true;
            }
        }
        // Remove token is not valid anymore.
        if (!empty($token->validuntil) and $token->validuntil < time()) {
            $DB->delete_records('external_tokens', array('token' => $token->token, 'tokentype' => EXTERNAL_TOKEN_PERMANENT));
            $unsettoken = true;
        }
        // Remove token if its ip not in whitelist.
        if (isset($token->iprestriction) and !address_in_subnet(getremoteaddr(), $token->iprestriction)) {
            $unsettoken = true;
        }
        if ($unsettoken) {
            unset($tokens[$key]);
        }
    }
    // If some valid tokens exist then use the most recent.
    if (count($tokens) > 0) {
        $token = array_pop($tokens);
    } else {
        $context = context_system::instance();
        $isofficialservice = $service->shortname == MOODLE_OFFICIAL_MOBILE_SERVICE;
        if ($isofficialservice and has_capability('moodle/webservice:createmobiletoken', $context) or !is_siteadmin($USER) && has_capability('moodle/webservice:createtoken', $context)) {
            // Create a new token.
            $token = new stdClass();
            $token->token = md5(uniqid(rand(), 1));
            $token->userid = $USER->id;
            $token->tokentype = EXTERNAL_TOKEN_PERMANENT;
            $token->contextid = context_system::instance()->id;
            $token->creatorid = $USER->id;
            $token->timecreated = time();
            $token->externalserviceid = $service->id;
            // MDL-43119 Token valid for 3 months (12 weeks).
            $token->validuntil = $token->timecreated + 12 * WEEKSECS;
            $token->iprestriction = null;
            $token->sid = null;
            $token->lastaccess = null;
            // Generate the private token, it must be transmitted only via https.
            $token->privatetoken = random_string(64);
            $token->id = $DB->insert_record('external_tokens', $token);
            $eventtoken = clone $token;
            $eventtoken->privatetoken = null;
            $params = array('objectid' => $eventtoken->id, 'relateduserid' => $USER->id, 'other' => array('auto' => true));
            $event = \core\event\webservice_token_created::create($params);
            $event->add_record_snapshot('external_tokens', $eventtoken);
            $event->trigger();
        } else {
            throw new moodle_exception('cannotcreatetoken', 'webservice', '', $service->shortname);
        }
    }
    return $token;
}
Example #15
0
 /**
  * Fetches the function description from database,
  * verifies user is allowed to use this function and
  * loads all paremeters and return descriptions.
  */
 protected function load_function_info()
 {
     global $DB, $USER, $CFG;
     if (empty($this->functionname)) {
         throw new invalid_parameter_exception('Missing function name');
     }
     // function must exist
     $function = external_function_info($this->functionname);
     if ($this->restricted_serviceid) {
         $params = array('sid1' => $this->restricted_serviceid, 'sid2' => $this->restricted_serviceid);
         $wscond1 = 'AND s.id = :sid1';
         $wscond2 = 'AND s.id = :sid2';
     } else {
         $params = array();
         $wscond1 = '';
         $wscond2 = '';
     }
     // now let's verify access control
     // now make sure the function is listed in at least one service user is allowed to use
     // allow access only if:
     //  1/ entry in the external_services_users table if required
     //  2/ validuntil not reached
     //  3/ has capability if specified in service desc
     //  4/ iprestriction
     $sql = "SELECT s.*, NULL AS iprestriction\n                  FROM {external_services} s\n                  JOIN {external_services_functions} sf ON (sf.externalserviceid = s.id AND s.restrictedusers = 0 AND sf.functionname = :name1)\n                 WHERE s.enabled = 1 {$wscond1}\n\n                 UNION\n\n                SELECT s.*, su.iprestriction\n                  FROM {external_services} s\n                  JOIN {external_services_functions} sf ON (sf.externalserviceid = s.id AND s.restrictedusers = 1 AND sf.functionname = :name2)\n                  JOIN {external_services_users} su ON (su.externalserviceid = s.id AND su.userid = :userid)\n                 WHERE s.enabled = 1 AND (su.validuntil IS NULL OR su.validuntil < :now) {$wscond2}";
     $params = array_merge($params, array('userid' => $USER->id, 'name1' => $function->name, 'name2' => $function->name, 'now' => time()));
     $rs = $DB->get_recordset_sql($sql, $params);
     // now make sure user may access at least one service
     $remoteaddr = getremoteaddr();
     $allowed = false;
     foreach ($rs as $service) {
         if ($service->requiredcapability and !has_capability($service->requiredcapability, $this->restricted_context)) {
             continue;
             // cap required, sorry
         }
         if ($service->iprestriction and !address_in_subnet($remoteaddr, $service->iprestriction)) {
             continue;
             // wrong request source ip, sorry
         }
         $allowed = true;
         break;
         // one service is enough, no need to continue
     }
     $rs->close();
     if (!$allowed) {
         throw new webservice_access_exception('Access to the function ' . $this->functionname . '() is not allowed.
                  There could be multiple reasons for this:
                  1. The service linked to the user token does not contain the function.
                  2. The service is user-restricted and the user is not listed.
                  3. The service is IP-restricted and the user IP is not listed.
                  4. The service is time-restricted and the time has expired.
                  5. The token is time-restricted and the time has expired.
                  6. The service requires a specific capability which the user does not have.
                  7. The function is called with username/password (no user token is sent)
                  and none of the services has the function to allow the user.
                  These settings can be found in Administration > Site administration
                  > Plugins > Web services > External services and Manage tokens.');
     }
     // we have all we need now
     $this->function = $function;
 }
Example #16
0
$navigation = build_navigation('', $cm);
$button = update_module_button($cm->id, $course->id, get_string("modulename", "hotpot"));
$button = '<div style="font-size:0.75em;">' . $button . '</div>';
$loggedinas = '<span class="logininfo">' . user_login_string($course, $USER) . '</span>';
$time = time();
$hppassword = optional_param('hppassword', '');
if (HOTPOT_FIRST_ATTEMPT && !has_capability('mod/hotpot:grade', $context)) {
    // check this quiz is available to this student
    // error message, if quiz is unavailable
    $error = '';
    // check quiz is visible
    if (!hotpot_is_visible($cm)) {
        $error = get_string("activityiscurrentlyhidden");
        // check network address
    } else {
        if ($hotpot->subnet && !address_in_subnet(getremoteaddr(), $hotpot->subnet)) {
            $error = get_string("subneterror", "quiz");
            // check number of attempts
        } else {
            if ($hotpot->attempts && $hotpot->attempts <= $DB->count_records_select('hotpot_attempts', 'hotpot=? AND userid=?', array($hotpot->id, $USER->id), 'COUNT(DISTINCT clickreportid)')) {
                $error = get_string("nomoreattempts", "quiz");
                // get password
            } else {
                if ($hotpot->password && empty($hppassword)) {
                    print_header($title, $heading, $navigation, "", "", true, $button, $loggedinas, false);
                    echo $OUTPUT->heading($hotpot->name);
                    $boxalign = 'center';
                    $boxwidth = 500;
                    if (trim(strip_tags($hotpot->summary))) {
                        echo $OUTPUT->box_start("generalbox boxalign{$boxalign}");
                        print '<div class="mdl-align">' . format_text($hotpot->summary) . "</div>\n";
Example #17
0
/*
* Check time [open/close]
*/
$timenow = time();
if (!empty($reader->timeopen) && $reader->timeopen > $timenow) {
    error(get_string('quizopens', 'quiz') . ': ' . userdate($reader->timeopen));
}
if (!empty($reader->timeclose) && $reader->timeclose < $timenow) {
    error(get_string('quizcloses', 'quiz') . ': ' . userdate($reader->timeclose));
}
$alreadyansweredbooksid = array();
if (has_capability('mod/reader:manage', $contextmodule)) {
    require_once 'tabs.php';
} else {
    /// Check subnet access
    if ($reader->subnet && !address_in_subnet(getremoteaddr(), $reader->subnet)) {
        error(get_string("subneterror", "quiz"), "view.php?id=" . $id);
    }
}
$leveldata = reader_get_stlevel_data($reader);
echo $OUTPUT->box_start('generalbox');
$table = new html_table();
if ($reader->pointreport == 1) {
    if ($reader->reportwordspoints != 1) {
        //1 - only points
        $table->head = array("Date", "Book Title", "Level", "Words", "Percent Correct", "Total Points");
        $table->align = array("left", "left", "left", "center", "center", "center");
    } else {
        $table->head = array("Date", "Book Title", "Level", "Percent Correct", "Total Points");
        $table->align = array("left", "left", "left", "center", "center");
    }
Example #18
0
 /**
  * Check netword restriction and return true o false
  * Network field may be a combination of ip, netmask and domain
  * comma separated to check.
  **/
 function pass_network_check($netreq = null, $ip = null)
 {
     if ($netreq === null) {
         $netreq = $this->instance->requirednet;
     }
     $netreq = trim($netreq);
     if ($netreq == '') {
         // No net required
         return true;
     }
     if ($ip === null) {
         $ip = getremoteaddr();
     }
     return address_in_subnet($ip, $netreq);
 }
    admin_externalpage_print_header();
    print_error('nosite', '', '', NULL, true);
}
$trusted_hosts = '';
//array();
$old_trusted_hosts = get_config('mnet', 'mnet_trusted_hosts');
if (!empty($old_trusted_hosts)) {
    $old_trusted_hosts = explode(',', $old_trusted_hosts);
} else {
    $old_trusted_hosts = array();
}
$test_ip_address = optional_param('testipaddress', NULL, PARAM_HOST);
$in_range = false;
if (!empty($test_ip_address)) {
    foreach ($old_trusted_hosts as $host) {
        if (address_in_subnet($test_ip_address, $host)) {
            $in_range = true;
            $validated_by = $host;
            break;
        }
    }
}
/// If data submitted, process and store
if (($form = data_submitted()) && confirm_sesskey()) {
    $hostlist = preg_split("/[\\s,]+/", $form->hostlist);
    foreach ($hostlist as $host) {
        list($address, $mask) = explode('/', $host . '/');
        if (empty($address)) {
            continue;
        }
        if (strlen($mask) == 0) {
Example #20
0
 /**
  * See if the request has the proper remote address
  *
  * @param  Zend_Controller_Request_Http $request The request to check
  * @return boolean
  */
 public function isValid($request)
 {
     if (!empty($this->_ipAddresses)) {
         $remoteaddr = getremoteaddr();
         // Check for localhost IPv6
         if (empty($remoteaddr) and $request->getServer('REMOTE_ADDR') == '::1') {
             $remoteaddr = '127.0.0.1';
         }
         // Can get get the remote address ?
         if (empty($remoteaddr)) {
             $this->_setValue($request->getServer('REMOTE_ADDR'));
             $this->_error(self::NOT_FOUND);
             return false;
         }
         // Address valid ?
         if (!address_in_subnet($remoteaddr, $this->_ipAddresses)) {
             $this->_setValue($remoteaddr);
             $this->_error(self::NOT_VALID);
             return false;
         }
     }
     return true;
 }
Example #21
0
    /**
     * Will get called before the login page is shownr. Ff NTLM SSO
     * is enabled, and the user is in the right network, we'll redirect
     * to the magic NTLM page for SSO...
     *
     */
    function loginpage_hook() {
        global $CFG, $SESSION;

        // HTTPS is potentially required
        //httpsrequired(); - this must be used before setting the URL, it is already done on the login/index.php

        if (($_SERVER['REQUEST_METHOD'] === 'GET'         // Only on initial GET of loginpage
             || ($_SERVER['REQUEST_METHOD'] === 'POST'
                 && (get_referer() != strip_querystring(qualified_me()))))
                                                          // Or when POSTed from another place
                                                          // See MDL-14071
            && !empty($this->config->ntlmsso_enabled)     // SSO enabled
            && !empty($this->config->ntlmsso_subnet)      // have a subnet to test for
            && empty($_GET['authldap_skipntlmsso'])       // haven't failed it yet
            && (isguestuser() || !isloggedin())           // guestuser or not-logged-in users
            && address_in_subnet(getremoteaddr(), $this->config->ntlmsso_subnet)) {

            // First, let's remember where we were trying to get to before we got here
            if (empty($SESSION->wantsurl)) {
                $SESSION->wantsurl = (array_key_exists('HTTP_REFERER', $_SERVER) &&
                                      $_SERVER['HTTP_REFERER'] != $CFG->wwwroot &&
                                      $_SERVER['HTTP_REFERER'] != $CFG->wwwroot.'/' &&
                                      $_SERVER['HTTP_REFERER'] != $CFG->httpswwwroot.'/login/' &&
                                      $_SERVER['HTTP_REFERER'] != $CFG->httpswwwroot.'/login/index.php')
                    ? $_SERVER['HTTP_REFERER'] : NULL;
            }

            // Now start the whole NTLM machinery.
            if(!empty($this->config->ntlmsso_ie_fastpath)) {
                // Shortcut for IE browsers: skip the attempt page
                if(check_browser_version('MSIE')) {
                    $sesskey = sesskey();
                    redirect($CFG->wwwroot.'/auth/ldap/ntlmsso_magic.php?sesskey='.$sesskey);
                } else {
                    redirect($CFG->httpswwwroot.'/login/index.php?authldap_skipntlmsso=1');
                }
            } else {
                redirect($CFG->wwwroot.'/auth/ldap/ntlmsso_attempt.php');
            }
        }

        // No NTLM SSO, Use the normal login page instead.

        // If $SESSION->wantsurl is empty and we have a 'Referer:' header, the login
        // page insists on redirecting us to that page after user validation. If
        // we clicked on the redirect link at the ntlmsso_finish.php page (instead
        // of waiting for the redirection to happen) then we have a 'Referer:' header
        // we don't want to use at all. As we can't get rid of it, just point
        // $SESSION->wantsurl to $CFG->wwwroot (after all, we came from there).
        if (empty($SESSION->wantsurl)
            && (get_referer() == $CFG->httpswwwroot.'/auth/ldap/ntlmsso_finish.php')) {

            $SESSION->wantsurl = $CFG->wwwroot;
        }
    }
 /**
  * Checks whether the input address is blocked by at any of the IPv4 or IPv6 address rules.
  *
  * @param string $addr the ip address to check.
  * @return bool true if the address is covered by an entry in the blacklist, false otherwise.
  */
 protected function address_explicitly_blocked($addr)
 {
     $blockedhosts = $this->get_blacklisted_hosts_by_category();
     $iphostsblocked = array_merge($blockedhosts['ipv4'], $blockedhosts['ipv6']);
     return address_in_subnet($addr, implode(',', $iphostsblocked));
 }
Example #23
0
/**
 * Require key login. Function terminates with error if key not found or incorrect.
 * @param string $script unique script identifier
 * @param int $instance optional instance id
 */
function require_user_key_login($script, $instance = null)
{
    global $nomoodlecookie, $USER, $SESSION, $CFG;
    if (empty($nomoodlecookie)) {
        error('Incorrect use of require_key_login() - session cookies must be disabled!');
    }
    /// extra safety
    @session_write_close();
    $keyvalue = required_param('key', PARAM_ALPHANUM);
    if (!($key = get_record('user_private_key', 'script', $script, 'value', $keyvalue, 'instance', $instance))) {
        error('Incorrect key');
    }
    if (!empty($key->validuntil) and $key->validuntil < time()) {
        error('Expired key');
    }
    if ($key->iprestriction) {
        $remoteaddr = getremoteaddr();
        if ($remoteaddr == '' or !address_in_subnet($remoteaddr, $key->iprestriction)) {
            error('Client IP address mismatch');
        }
    }
    if (!($user = get_record('user', 'id', $key->userid))) {
        error('Incorrect user record');
    }
    /// emulate normal session
    $SESSION = new object();
    $USER = $user;
    /// note we are not using normal login
    if (!defined('USER_KEY_LOGIN')) {
        define('USER_KEY_LOGIN', true);
    }
    load_all_capabilities();
    /// return isntance id - it might be empty
    return $key->instance;
}
 /**
  * Check if a server is located in a private network
  * @return true == private
  */
 static function is_private_host($URL)
 {
     $host_name = parse_url($URL, PHP_URL_HOST);
     if ($host_name === false) {
         return true;
     }
     $private = '10., 127., 172.16.0.0/12, 192.168., 169.254.';
     $name = $host_name . '.';
     $IP = gethostbyname($name);
     if ($IP != $name) {
         return address_in_subnet($IP, $private);
         // IPv6 not implemented
         // fc00::/7
         // fe80::/10
     }
     return true;
 }
Example #25
0
 /**
  * Will get called before the login page is shownr. Ff NTLM SSO
  * is enabled, and the user is in the right network, we'll redirect
  * to the magic NTLM page for SSO...
  *
  */
 function loginpage_hook()
 {
     global $CFG, $SESSION;
     // HTTPS is potentially required
     //httpsrequired(); - this must be used before setting the URL, it is already done on the login/index.php
     if (($_SERVER['REQUEST_METHOD'] === 'GET' || $_SERVER['REQUEST_METHOD'] === 'POST' && get_local_referer() != strip_querystring(qualified_me())) && !empty($this->config->ntlmsso_enabled) && !empty($this->config->ntlmsso_subnet) && empty($_GET['authldap_skipntlmsso']) && (isguestuser() || !isloggedin()) && address_in_subnet(getremoteaddr(), $this->config->ntlmsso_subnet)) {
         // First, let's remember where we were trying to get to before we got here
         if (empty($SESSION->wantsurl)) {
             $SESSION->wantsurl = null;
             $referer = get_local_referer(false);
             if ($referer && $referer != $CFG->wwwroot && $referer != $CFG->wwwroot . '/' && $referer != $CFG->httpswwwroot . '/login/' && $referer != $CFG->httpswwwroot . '/login/index.php') {
                 $SESSION->wantsurl = $referer;
             }
         }
         // Now start the whole NTLM machinery.
         if ($this->config->ntlmsso_ie_fastpath == AUTH_NTLM_FASTPATH_YESATTEMPT || $this->config->ntlmsso_ie_fastpath == AUTH_NTLM_FASTPATH_YESFORM) {
             if (core_useragent::is_ie()) {
                 $sesskey = sesskey();
                 redirect($CFG->wwwroot . '/auth/ldap/ntlmsso_magic.php?sesskey=' . $sesskey);
             } else {
                 if ($this->config->ntlmsso_ie_fastpath == AUTH_NTLM_FASTPATH_YESFORM) {
                     redirect($CFG->httpswwwroot . '/login/index.php?authldap_skipntlmsso=1');
                 }
             }
         }
         redirect($CFG->wwwroot . '/auth/ldap/ntlmsso_attempt.php');
     }
     // No NTLM SSO, Use the normal login page instead.
     // If $SESSION->wantsurl is empty and we have a 'Referer:' header, the login
     // page insists on redirecting us to that page after user validation. If
     // we clicked on the redirect link at the ntlmsso_finish.php page (instead
     // of waiting for the redirection to happen) then we have a 'Referer:' header
     // we don't want to use at all. As we can't get rid of it, just point
     // $SESSION->wantsurl to $CFG->wwwroot (after all, we came from there).
     if (empty($SESSION->wantsurl) && get_local_referer() == $CFG->httpswwwroot . '/auth/ldap/ntlmsso_finish.php') {
         $SESSION->wantsurl = $CFG->wwwroot;
     }
 }
Example #26
0
}
$button = update_module_button($cm->id, $course->id, get_string("modulename", "hotpot"));
$button = '<div style="font-size:0.75em;">' . $button . '</div>';
$loggedinas = '<span class="logininfo">' . user_login_string($course, $USER) . '</span>';
$time = time();
$hppassword = optional_param('hppassword', '');
if (HOTPOT_FIRST_ATTEMPT && !has_capability('mod/hotpot:grade', $context)) {
    // check this quiz is available to this student
    // error message, if quiz is unavailable
    $error = '';
    // check quiz is visible
    if (!hotpot_is_visible($cm)) {
        $error = get_string("activityiscurrentlyhidden");
        // check network address
    } else {
        if ($hotpot->subnet && !address_in_subnet($_SERVER['REMOTE_ADDR'], $hotpot->subnet)) {
            $error = get_string("subneterror", "quiz");
            // check number of attempts
        } else {
            if ($hotpot->attempts && $hotpot->attempts <= count_records_select('hotpot_attempts', 'hotpot=' . $hotpot->id . ' AND userid=' . $USER->id, 'COUNT(DISTINCT clickreportid)')) {
                $error = get_string("nomoreattempts", "quiz");
                // get password
            } else {
                if ($hotpot->password && empty($hppassword)) {
                    print_header($title, $heading, $navigation, "", "", true, $button, $loggedinas, false);
                    print_heading($hotpot->name);
                    $boxalign = 'center';
                    $boxwidth = 500;
                    if (trim(strip_tags($hotpot->summary))) {
                        print_simple_box_start($boxalign, $boxwidth);
                        print '<div align="center">' . format_text($hotpot->summary) . "</div>\n";
Example #27
0
    $buttonoptions['forcenew'] = true;
    echo '<div class="controls">';
    print_single_button($CFG->wwwroot . '/mod/quiz/attempt.php', $buttonoptions, get_string('startagain', 'quiz'));
    echo '</div>';
    /// Notices about restrictions that would affect students.
    if ($quiz->popup == 1) {
        notify(get_string('popupnotice', 'quiz'));
    } else {
        if ($quiz->popup == 2) {
            notify(get_string('safebrowsernotice', 'quiz'));
        }
    }
    if ($timestamp < $quiz->timeopen || $quiz->timeclose && $timestamp > $quiz->timeclose) {
        notify(get_string('notavailabletostudents', 'quiz'));
    }
    if ($quiz->subnet && !address_in_subnet(getremoteaddr(), $quiz->subnet)) {
        notify(get_string('subnetnotice', 'quiz'));
    }
} else {
    if ($quiz->attempts != 1) {
        print_heading(format_string($quiz->name) . ' - ' . $strattemptnum);
    } else {
        print_heading(format_string($quiz->name));
    }
}
// Start the form
$quiz->thispageurl = $CFG->wwwroot . '/mod/quiz/attempt.php?q=' . s($quiz->id) . '&amp;page=' . s($page);
$quiz->cmid = $cm->id;
echo '<form id="responseform" method="post" action="', $quiz->thispageurl . '" enctype="multipart/form-data"' . ' onkeypress="return check_enter(event);" accept-charset="utf-8">', "\n";
echo '<script type="text/javascript">', "\n", 'document.getElementById("responseform").setAttribute("autocomplete", "off")', "\n", "</script>\n";
if ($quiz->timelimit > 0) {
Example #28
0
/**
 * Is current ip in give list?
 *
 * @param string $list
 * @return bool
 */
function remoteip_in_list($list)
{
    $inlist = false;
    $client_ip = getremoteaddr();
    $list = explode("\n", $list);
    foreach ($list as $subnet) {
        $subnet = trim($subnet);
        if (address_in_subnet($client_ip, $subnet)) {
            $inlist = true;
            break;
        }
    }
    return $inlist;
}
 public function test_address_in_subnet()
 {
     // 1: xxx.xxx.xxx.xxx/nn or xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx/nnn (number of bits in net mask).
     $this->assertTrue(address_in_subnet('123.121.234.1', '123.121.234.1/32'));
     $this->assertFalse(address_in_subnet('123.121.23.1', '123.121.23.0/32'));
     $this->assertTrue(address_in_subnet('10.10.10.100', '123.121.23.45/0'));
     $this->assertTrue(address_in_subnet('123.121.234.1', '123.121.234.0/24'));
     $this->assertFalse(address_in_subnet('123.121.34.1', '123.121.234.0/24'));
     $this->assertTrue(address_in_subnet('123.121.234.1', '123.121.234.0/30'));
     $this->assertFalse(address_in_subnet('123.121.23.8', '123.121.23.0/30'));
     $this->assertTrue(address_in_subnet('baba:baba::baba', 'baba:baba::baba/128'));
     $this->assertFalse(address_in_subnet('bab:baba::baba', 'bab:baba::cece/128'));
     $this->assertTrue(address_in_subnet('baba:baba::baba', 'cece:cece::cece/0'));
     $this->assertTrue(address_in_subnet('baba:baba::baba', 'baba:baba::baba/128'));
     $this->assertTrue(address_in_subnet('baba:baba::00ba', 'baba:baba::/120'));
     $this->assertFalse(address_in_subnet('baba:baba::aba', 'baba:baba::/120'));
     $this->assertTrue(address_in_subnet('baba::baba:00ba', 'baba::baba:0/112'));
     $this->assertFalse(address_in_subnet('baba::aba:00ba', 'baba::baba:0/112'));
     $this->assertFalse(address_in_subnet('aba::baba:0000', 'baba::baba:0/112'));
     // Fixed input.
     $this->assertTrue(address_in_subnet('123.121.23.1   ', ' 123.121.23.0 / 24'));
     $this->assertTrue(address_in_subnet('::ffff:10.1.1.1', ' 0:0:0:000:0:ffff:a1:10 / 126'));
     // Incorrect input.
     $this->assertFalse(address_in_subnet('123.121.234.1', '123.121.234.1/-2'));
     $this->assertFalse(address_in_subnet('123.121.234.1', '123.121.234.1/64'));
     $this->assertFalse(address_in_subnet('123.121.234.x', '123.121.234.1/24'));
     $this->assertFalse(address_in_subnet('123.121.234.0', '123.121.234.xx/24'));
     $this->assertFalse(address_in_subnet('123.121.234.1', '123.121.234.1/xx0'));
     $this->assertFalse(address_in_subnet('::1', '::aa:0/xx0'));
     $this->assertFalse(address_in_subnet('::1', '::aa:0/-5'));
     $this->assertFalse(address_in_subnet('::1', '::aa:0/130'));
     $this->assertFalse(address_in_subnet('x:1', '::aa:0/130'));
     $this->assertFalse(address_in_subnet('::1', '::ax:0/130'));
     // 2: xxx.xxx.xxx.xxx-yyy or  xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx::xxxx-yyyy (a range of IP addresses in the last group).
     $this->assertTrue(address_in_subnet('123.121.234.12', '123.121.234.12-14'));
     $this->assertTrue(address_in_subnet('123.121.234.13', '123.121.234.12-14'));
     $this->assertTrue(address_in_subnet('123.121.234.14', '123.121.234.12-14'));
     $this->assertFalse(address_in_subnet('123.121.234.1', '123.121.234.12-14'));
     $this->assertFalse(address_in_subnet('123.121.234.20', '123.121.234.12-14'));
     $this->assertFalse(address_in_subnet('123.121.23.12', '123.121.234.12-14'));
     $this->assertFalse(address_in_subnet('123.12.234.12', '123.121.234.12-14'));
     $this->assertTrue(address_in_subnet('baba:baba::baba', 'baba:baba::baba-babe'));
     $this->assertTrue(address_in_subnet('baba:baba::babc', 'baba:baba::baba-babe'));
     $this->assertTrue(address_in_subnet('baba:baba::babe', 'baba:baba::baba-babe'));
     $this->assertFalse(address_in_subnet('bab:baba::bab0', 'bab:baba::baba-babe'));
     $this->assertFalse(address_in_subnet('bab:baba::babf', 'bab:baba::baba-babe'));
     $this->assertFalse(address_in_subnet('bab:baba::bfbe', 'bab:baba::baba-babe'));
     $this->assertFalse(address_in_subnet('bfb:baba::babe', 'bab:baba::baba-babe'));
     // Fixed input.
     $this->assertTrue(address_in_subnet('123.121.234.12', '123.121.234.12 - 14 '));
     $this->assertTrue(address_in_subnet('bab:baba::babe', 'bab:baba::baba - babe  '));
     // Incorrect input.
     $this->assertFalse(address_in_subnet('123.121.234.12', '123.121.234.12-234.14'));
     $this->assertFalse(address_in_subnet('123.121.234.12', '123.121.234.12-256'));
     $this->assertFalse(address_in_subnet('123.121.234.12', '123.121.234.12--256'));
     // 3: xxx.xxx or xxx.xxx. or xxx:xxx:xxxx or xxx:xxx:xxxx. (incomplete address, a bit non-technical ;-).
     $this->assertTrue(address_in_subnet('123.121.234.12', '123.121.234.12'));
     $this->assertFalse(address_in_subnet('123.121.23.12', '123.121.23.13'));
     $this->assertTrue(address_in_subnet('123.121.234.12', '123.121.234.'));
     $this->assertTrue(address_in_subnet('123.121.234.12', '123.121.234'));
     $this->assertTrue(address_in_subnet('123.121.234.12', '123.121'));
     $this->assertTrue(address_in_subnet('123.121.234.12', '123'));
     $this->assertFalse(address_in_subnet('123.121.234.1', '12.121.234.'));
     $this->assertFalse(address_in_subnet('123.121.234.1', '12.121.234'));
     $this->assertTrue(address_in_subnet('baba:baba::bab', 'baba:baba::bab'));
     $this->assertFalse(address_in_subnet('baba:baba::ba', 'baba:baba::bc'));
     $this->assertTrue(address_in_subnet('baba:baba::bab', 'baba:baba'));
     $this->assertTrue(address_in_subnet('baba:baba::bab', 'baba:'));
     $this->assertFalse(address_in_subnet('bab:baba::bab', 'baba:'));
     // Multiple subnets.
     $this->assertTrue(address_in_subnet('123.121.234.12', '::1/64, 124., 123.121.234.10-30'));
     $this->assertTrue(address_in_subnet('124.121.234.12', '::1/64, 124., 123.121.234.10-30'));
     $this->assertTrue(address_in_subnet('::2', '::1/64, 124., 123.121.234.10-30'));
     $this->assertFalse(address_in_subnet('12.121.234.12', '::1/64, 124., 123.121.234.10-30'));
     // Other incorrect input.
     $this->assertFalse(address_in_subnet('123.123.123.123', ''));
 }
Example #30
0
/**
 * Function to check the passed address is within the passed subnet
 *
 * The parameter is a comma separated string of subnet definitions.
 * Subnet strings can be in one of three formats:
 *   1: xxx.xxx.xxx.xxx/nn or xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx/nnn          (number of bits in net mask)
 *   2: xxx.xxx.xxx.xxx-yyy or  xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx::xxxx-yyyy (a range of IP addresses in the last group)
 *   3: xxx.xxx or xxx.xxx. or xxx:xxx:xxxx or xxx:xxx:xxxx.                  (incomplete address, a bit non-technical ;-)
 * Code for type 1 modified from user posted comments by mediator at
 * {@link http://au.php.net/manual/en/function.ip2long.php}
 *
 * @param string $addr    The address you are checking
 * @param string $subnetstr    The string of subnet addresses
 * @return bool
 */
function address_in_subnet($addr, $subnetstr)
{
    if ($addr == '0.0.0.0') {
        return false;
    }
    $subnets = explode(',', $subnetstr);
    $found = false;
    $addr = trim($addr);
    // normalise
    $addr = cleanremoteaddr($addr, false);
    if ($addr === null) {
        return false;
    }
    $addrparts = explode(':', $addr);
    $ipv6 = strpos($addr, ':');
    foreach ($subnets as $subnet) {
        $subnet = trim($subnet);
        if ($subnet === '') {
            continue;
        }
        if (strpos($subnet, '/') !== false) {
            ///1: xxx.xxx.xxx.xxx/nn or xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx/nnn
            list($ip, $mask) = explode('/', $subnet);
            $mask = trim($mask);
            if (!is_number($mask)) {
                // incorect mask number, eh?
                continue;
            }
            // normalise
            $ip = cleanremoteaddr($ip, false);
            if ($ip === null) {
                continue;
            }
            if (strpos($ip, ':') !== false) {
                // IPv6
                if (!$ipv6) {
                    continue;
                }
                if ($mask > 128 or $mask < 0) {
                    // nonsense
                    continue;
                }
                if ($mask == 0) {
                    // any address
                    return true;
                }
                if ($mask == 128) {
                    if ($ip === $addr) {
                        return true;
                    }
                    continue;
                }
                $ipparts = explode(':', $ip);
                $modulo = $mask % 16;
                $ipnet = array_slice($ipparts, 0, ($mask - $modulo) / 16);
                $addrnet = array_slice($addrparts, 0, ($mask - $modulo) / 16);
                if (implode(':', $ipnet) === implode(':', $addrnet)) {
                    if ($modulo == 0) {
                        return true;
                    }
                    $pos = ($mask - $modulo) / 16;
                    $ipnet = hexdec($ipparts[$pos]);
                    $addrnet = hexdec($addrparts[$pos]);
                    $mask = 0xffff << 16 - $modulo;
                    if (($addrnet & $mask) == ($ipnet & $mask)) {
                        return true;
                    }
                }
            } else {
                // IPv4
                if ($ipv6) {
                    continue;
                }
                if ($mask > 32 or $mask < 0) {
                    // nonsense
                    continue;
                }
                if ($mask == 0) {
                    return true;
                }
                if ($mask == 32) {
                    if ($ip === $addr) {
                        return true;
                    }
                    continue;
                }
                $mask = 4294967295.0 << 32 - $mask;
                if ((ip2long($addr) & $mask) == (ip2long($ip) & $mask)) {
                    return true;
                }
            }
        } else {
            if (strpos($subnet, '-') !== false) {
                /// 2: xxx.xxx.xxx.xxx-yyy or  xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx::xxxx-yyyy ...a range of IP addresses in the last group.
                $parts = explode('-', $subnet);
                if (count($parts) != 2) {
                    continue;
                }
                if (strpos($subnet, ':') !== false) {
                    // IPv6
                    if (!$ipv6) {
                        continue;
                    }
                    // normalise
                    $ipstart = cleanremoteaddr(trim($parts[0]), false);
                    if ($ipstart === null) {
                        continue;
                    }
                    $ipparts = explode(':', $ipstart);
                    $start = hexdec(array_pop($ipparts));
                    $ipparts[] = trim($parts[1]);
                    // normalise
                    $ipend = cleanremoteaddr(implode(':', $ipparts), false);
                    if ($ipend === null) {
                        continue;
                    }
                    $ipparts[7] = '';
                    $ipnet = implode(':', $ipparts);
                    if (strpos($addr, $ipnet) !== 0) {
                        continue;
                    }
                    $ipparts = explode(':', $ipend);
                    $end = hexdec($ipparts[7]);
                    $addrend = hexdec($addrparts[7]);
                    if ($addrend >= $start and $addrend <= $end) {
                        return true;
                    }
                } else {
                    // IPv4
                    if ($ipv6) {
                        continue;
                    }
                    // normalise
                    $ipstart = cleanremoteaddr(trim($parts[0]), false);
                    if ($ipstart === null) {
                        continue;
                    }
                    $ipparts = explode('.', $ipstart);
                    $ipparts[3] = trim($parts[1]);
                    // normalise
                    $ipend = cleanremoteaddr(implode('.', $ipparts), false);
                    if ($ipend === null) {
                        continue;
                    }
                    if (ip2long($addr) >= ip2long($ipstart) and ip2long($addr) <= ip2long($ipend)) {
                        return true;
                    }
                }
            } else {
                /// 3: xxx.xxx or xxx.xxx. or xxx:xxx:xxxx or xxx:xxx:xxxx.
                if (strpos($subnet, ':') !== false) {
                    // IPv6
                    if (!$ipv6) {
                        continue;
                    }
                    $parts = explode(':', $subnet);
                    $count = count($parts);
                    if ($parts[$count - 1] === '') {
                        // trim trailing :
                        unset($parts[$count - 1]);
                        $count--;
                        $subnet = implode('.', $parts);
                    }
                    // normalise
                    $isip = cleanremoteaddr($subnet, false);
                    if ($isip !== null) {
                        if ($isip === $addr) {
                            return true;
                        }
                        continue;
                    } else {
                        if ($count > 8) {
                            continue;
                        }
                    }
                    $zeros = array_fill(0, 8 - $count, '0');
                    $subnet = $subnet . ':' . implode(':', $zeros) . '/' . $count * 16;
                    if (address_in_subnet($addr, $subnet)) {
                        return true;
                    }
                } else {
                    // IPv4
                    if ($ipv6) {
                        continue;
                    }
                    $parts = explode('.', $subnet);
                    $count = count($parts);
                    if ($parts[$count - 1] === '') {
                        // trim trailing .
                        unset($parts[$count - 1]);
                        $count--;
                        $subnet = implode('.', $parts);
                    }
                    if ($count == 4) {
                        // normalise
                        $subnet = cleanremoteaddr($subnet, false);
                        if ($subnet === $addr) {
                            return true;
                        }
                        continue;
                    } else {
                        if ($count > 4) {
                            continue;
                        }
                    }
                    $zeros = array_fill(0, 4 - $count, '0');
                    $subnet = $subnet . '.' . implode('.', $zeros) . '/' . $count * 8;
                    if (address_in_subnet($addr, $subnet)) {
                        return true;
                    }
                }
            }
        }
    }
    return false;
}