Search moodle.org's
Developer Documentation

See Release Notes
Long Term Support Release

  • Bug fixes for general core bugs in 4.1.x will end 13 November 2023 (12 months).
  • Bug fixes for security issues in 4.1.x will end 10 November 2025 (36 months).
  • PHP version: minimum PHP 7.4.0 Note: minimum PHP version has increased since Moodle 4.0. PHP 8.0.x is supported too.

Differences Between: [Versions 310 and 401] [Versions 39 and 401] [Versions 400 and 401] [Versions 401 and 402] [Versions 401 and 403]

   1  <?php
   2  /**
   3   * Info about the local environment, wrt RPC
   4   *
   5   * This should really be a singleton. A PHP5 Todo I guess.
   6   */
   7  
   8  class mnet_environment {
   9  
  10      var $id                 = 0;
  11      var $wwwroot            = '';
  12      var $ip_address         = '';
  13      var $public_key         = '';
  14      var $public_key_expires = 0;
  15      var $last_connect_time  = 0;
  16      var $last_log_id        = 0;
  17      var $keypair            = array();
  18      var $deleted            = 0;
  19  
  20      function init() {
  21          global $CFG, $DB;
  22  
  23          // Bootstrap the object data on first load.
  24          if (!$hostobject = $DB->get_record('mnet_host', array('id'=>$CFG->mnet_localhost_id))) {
  25              return false;
  26          }
  27          $temparr = get_object_vars($hostobject);
  28          foreach($temparr as $key => $value) {
  29              $this->$key = $value;
  30          }
  31          unset($hostobject, $temparr);
  32  
  33          // Unless this is an install/upgrade, generate the SSL keys.
  34          if (empty($this->public_key)) {
  35              $this->get_keypair();
  36          }
  37  
  38          // We need to set up a record that represents 'all hosts'. Any rights
  39          // granted to this host will be conferred on all hosts.
  40          if (empty($CFG->mnet_all_hosts_id) ) {
  41              $hostobject                     = new stdClass();
  42              $hostobject->wwwroot            = '';
  43              $hostobject->ip_address         = '';
  44              $hostobject->public_key         = '';
  45              $hostobject->public_key_expires = 0;
  46              $hostobject->last_connect_time  = 0;
  47              $hostobject->last_log_id        = 0;
  48              $hostobject->deleted            = 0;
  49              $hostobject->name               = 'All Hosts';
  50  
  51              $hostobject->id = $DB->insert_record('mnet_host',$hostobject);
  52              set_config('mnet_all_hosts_id', $hostobject->id);
  53              $CFG->mnet_all_hosts_id = $hostobject->id;
  54              unset($hostobject);
  55          }
  56      }
  57  
  58      function get_keypair() {
  59          global $DB, $CFG;
  60  
  61          // We don't generate keys on install/upgrade because we want the USER
  62          // record to have an email address, city and country already.
  63          if (during_initial_install()) return true;
  64          if ($CFG->mnet_dispatcher_mode == 'off') return true;
  65          if (!extension_loaded("openssl")) return true;
  66          if (!empty($this->keypair)) return true;
  67  
  68          $this->keypair = array();
  69          $keypair = get_config('mnet', 'openssl');
  70  
  71          if (!empty($keypair)) {
  72              // Explode/Implode is faster than Unserialize/Serialize
  73              list($this->keypair['certificate'], $this->keypair['keypair_PEM']) = explode('@@@@@@@@', $keypair);
  74          }
  75  
  76          if ($this->public_key_expires <= time()) {
  77              // Key generation/rotation
  78  
  79              // 1. Archive the current key (if there is one).
  80              $result = get_config('mnet', 'openssl_history');
  81              if(empty($result)) {
  82                  set_config('openssl_history', serialize(array()), 'mnet');
  83                  $openssl_history = array();
  84              } else {
  85                  $openssl_history = unserialize($result);
  86              }
  87  
  88              if(count($this->keypair)) {
  89                  $this->keypair['expires'] = $this->public_key_expires;
  90                  array_unshift($openssl_history, $this->keypair);
  91              }
  92  
  93              // 2. How many old keys do we want to keep? Use array_slice to get
  94              // rid of any we don't want
  95              $openssl_generations = get_config('mnet', 'openssl_generations');
  96              if(empty($openssl_generations)) {
  97                  set_config('openssl_generations', 3, 'mnet');
  98                  $openssl_generations = 3;
  99              }
 100  
 101              if(count($openssl_history) > $openssl_generations) {
 102                  $openssl_history = array_slice($openssl_history, 0, $openssl_generations);
 103              }
 104  
 105              set_config('openssl_history', serialize($openssl_history), 'mnet');
 106  
 107              // 3. Generate fresh keys
 108              $this->replace_keys();
 109          }
 110          return true;
 111      }
 112  
 113      function replace_keys() {
 114          global $DB, $CFG;
 115  
 116          $keypair = mnet_generate_keypair();
 117          if (empty($keypair)) {
 118              error_log('Can not generate keypair, sorry');
 119              return;
 120          }
 121  
 122          $this->keypair = array();
 123          $this->keypair            = $keypair;
 124          $this->public_key         = $this->keypair['certificate'];
 125          $details                  = openssl_x509_parse($this->public_key);
 126          $this->public_key_expires = $details['validTo_time_t'];
 127  
 128          $this->wwwroot            = $CFG->wwwroot;
 129          if (empty($_SERVER['SERVER_ADDR'])) {
 130              // SERVER_ADDR is only returned by Apache-like webservers
 131              $my_hostname = mnet_get_hostname_from_uri($CFG->wwwroot);
 132              $my_ip       = gethostbyname($my_hostname);  // Returns unmodified hostname on failure. DOH!
 133              if ($my_ip == $my_hostname) {
 134                  $this->ip_address = 'UNKNOWN';
 135              } else {
 136                  $this->ip_address = $my_ip;
 137              }
 138          } else {
 139              $this->ip_address = $_SERVER['SERVER_ADDR'];
 140          }
 141  
 142          set_config('openssl', implode('@@@@@@@@', $this->keypair), 'mnet');
 143  
 144          $DB->update_record('mnet_host', $this);
 145          error_log('New public key has been generated. It expires ' . date('Y/m/d h:i:s', $this->public_key_expires));
 146      }
 147  
 148      function get_private_key() {
 149          if (empty($this->keypair)) $this->get_keypair();
 150          return openssl_pkey_get_private($this->keypair['keypair_PEM']);
 151      }
 152  
 153      function get_public_key() {
 154          if (!isset($this->keypair)) $this->get_keypair();
 155          return openssl_pkey_get_public($this->keypair['certificate']);
 156      }
 157  }