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