MDL-16094 File storage conversion Quiz and Questions
[moodle.git] / mnet / peer.php
CommitLineData
1d422980 1<?php
71558f85 2/**
3 * An object to represent lots of information about an RPC-peer machine
4 *
5 * @author Donal McMullan donal@catalyst.net.nz
6 * @version 0.0.1
7 * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
8 * @package mnet
9 */
10
11class mnet_peer {
12
13 var $id = 0;
14 var $wwwroot = '';
15 var $ip_address = '';
16 var $name = '';
17 var $public_key = '';
18 var $public_key_expires = 0;
19 var $last_connect_time = 0;
20 var $last_log_id = 0;
22882b66 21 var $force_theme = 0;
22 var $theme = '';
25202581 23 var $applicationid = 1; // Default of 1 == Moodle
71558f85 24 var $keypair = array();
25 var $error = array();
96bd2921 26 var $bootstrapped = false; // set when the object is populated
71558f85 27
28 function mnet_peer() {
29 return true;
30 }
31
ea87ed52 32 /*
33 * Fetch information about a peer identified by wwwroot
34 * If information does not preexist in db, collect it together based on
35 * supplied information
36 *
37 * @param string $wwwroot - address of peer whose details we want
38 * @param string $pubkey - to use if we add a record to db for new peer
39 * @param int $application - table id - what kind of peer are we talking to
40 * @return bool - indication of success or failure
41 */
25202581 42 function bootstrap($wwwroot, $pubkey = null, $application) {
cc38ff5d 43 global $DB;
71558f85 44
b2d38907 45 if (substr($wwwroot, -1, 1) == '/') {
e931fedd 46 $wwwroot = substr($wwwroot, 0, -1);
47 }
48
aada58ea 49 // If a peer record already exists for this address,
50 // load that info and return
51 if ($this->set_wwwroot($wwwroot)) {
52 return true;
53 }
71558f85 54
aada58ea 55 $hostname = mnet_get_hostname_from_uri($wwwroot);
56 // Get the IP address for that host - if this fails, it will return the hostname string
57 $ip_address = gethostbyname($hostname);
71558f85 58
aada58ea 59 // Couldn't find the IP address?
60 if ($ip_address === $hostname && !preg_match('/^\d+\.\d+\.\d+.\d+$/',$hostname)) {
8fb18ca9 61 throw new moodle_exception('noaddressforhost', 'mnet', '', $hostname);
aada58ea 62 }
71558f85 63
aada58ea 64 $this->name = $wwwroot;
71558f85 65
aada58ea 66 // TODO: In reality, this will be prohibitively slow... need another
67 // default - maybe blank string
68 $homepage = download_file_content($wwwroot);
69 if (!empty($homepage)) {
70 $count = preg_match("@<title>(.*)</title>@siU", $homepage, $matches);
71 if ($count > 0) {
72 $this->name = $matches[1];
71558f85 73 }
aada58ea 74 }
71558f85 75
aada58ea 76 $this->wwwroot = $wwwroot;
77 $this->ip_address = $ip_address;
78 $this->deleted = 0;
25202581 79
aada58ea 80 $this->application = $DB->get_record('mnet_application', array('name'=>$application));
81 if (empty($this->application)) {
82 $this->application = $DB->get_record('mnet_application', array('name'=>'moodle'));
83 }
25202581 84
aada58ea 85 $this->applicationid = $this->application->id;
25202581 86
aada58ea 87 if(empty($pubkey)) {
88 $this->public_key = clean_param(mnet_get_public_key($this->wwwroot, $this->application), PARAM_PEM);
89 } else {
90 $this->public_key = clean_param($pubkey, PARAM_PEM);
91 }
92 $this->public_key_expires = $this->check_common_name($this->public_key);
93 $this->last_connect_time = 0;
94 $this->last_log_id = 0;
95 if ($this->public_key_expires == false) {
96 $this->public_key == '';
97 return false;
71558f85 98 }
96bd2921 99 $this->bootstrapped = true;
71558f85 100 }
101
fcb54be4 102 /*
5ac7a171 103 * Delete mnet peer
104 * the peer is marked as deleted in the database
105 * we delete current sessions.
fcb54be4 106 * @return bool - success
107 */
71558f85 108 function delete() {
c7da4357 109 global $DB;
110
fcb54be4 111 if ($this->deleted) {
112 return true;
113 }
71558f85 114
71558f85 115 $this->delete_all_sessions();
116
5ac7a171 117 $this->deleted = 1;
118 return $this->commit();
71558f85 119 }
120
121 function count_live_sessions() {
c7da4357 122 global $DB;
71558f85 123 $obj = $this->delete_expired_sessions();
c7da4357 124 return $DB->count_records('mnet_session', array('mnethostid'=>$this->id));
71558f85 125 }
126
127 function delete_expired_sessions() {
c7da4357 128 global $DB;
71558f85 129 $now = time();
c7da4357 130 return $DB->delete_records_select('mnet_session', " mnethostid = ? AND expires < ? ", array($this->id, $now));
71558f85 131 }
132
133 function delete_all_sessions() {
c7da4357 134 global $CFG, $DB;
71558f85 135 // TODO: Expires each PHP session individually
c7da4357 136 $sessions = $DB->get_records('mnet_session', array('mnethostid'=>$this->id));
71558f85 137
138 if (count($sessions) > 0 && file_exists($CFG->dirroot.'/auth/mnet/auth.php')) {
139 require_once($CFG->dirroot.'/auth/mnet/auth.php');
140 $auth = new auth_plugin_mnet();
141 $auth->end_local_sessions($sessions);
142 }
143
c7da4357 144 $deletereturn = $DB->delete_records('mnet_session', array('mnethostid'=>$this->id));
71558f85 145 return true;
146 }
147
148 function check_common_name($key) {
00d3c66b 149 $credentials = $this->check_credentials($key);
150 return $credentials['validTo_time_t'];
151 }
152
153 function check_credentials($key) {
71558f85 154 $credentials = openssl_x509_parse($key);
155 if ($credentials == false) {
156 $this->error[] = array('code' => 3, 'text' => get_string("nonmatchingcert", 'mnet', array('','')));
157 return false;
00d3c66b 158 } elseif (array_key_exists('subjectAltName', $credentials['subject']) && $credentials['subject']['subjectAltName'] != $this->wwwroot) {
29218f36
PS
159 $a['subject'] = $credentials['subject']['subjectAltName'];
160 $a['host'] = $this->wwwroot;
00d3c66b 161 $this->error[] = array('code' => 5, 'text' => get_string("nonmatchingcert", 'mnet', $a));
162 return false;
71558f85 163 } elseif ($credentials['subject']['CN'] != $this->wwwroot) {
29218f36
PS
164 $a['subject'] = $credentials['subject']['CN'];
165 $a['host'] = $this->wwwroot;
71558f85 166 $this->error[] = array('code' => 4, 'text' => get_string("nonmatchingcert", 'mnet', $a));
167 return false;
168 } else {
00d3c66b 169 if (array_key_exists('subjectAltName', $credentials['subject'])) {
170 $credentials['wwwroot'] = $credentials['subject']['subjectAltName'];
171 } else {
172 $credentials['wwwroot'] = $credentials['subject']['CN'];
173 }
174 return $credentials;
71558f85 175 }
176 }
177
178 function commit() {
c7da4357 179 global $DB;
71558f85 180 $obj = new stdClass();
181
182 $obj->wwwroot = $this->wwwroot;
183 $obj->ip_address = $this->ip_address;
184 $obj->name = $this->name;
185 $obj->public_key = $this->public_key;
186 $obj->public_key_expires = $this->public_key_expires;
187 $obj->deleted = $this->deleted;
188 $obj->last_connect_time = $this->last_connect_time;
189 $obj->last_log_id = $this->last_log_id;
22882b66 190 $obj->force_theme = $this->force_theme;
191 $obj->theme = $this->theme;
25202581 192 $obj->applicationid = $this->applicationid;
71558f85 193
194 if (isset($this->id) && $this->id > 0) {
195 $obj->id = $this->id;
c7da4357 196 return $DB->update_record('mnet_host', $obj);
71558f85 197 } else {
c7da4357 198 $this->id = $DB->insert_record('mnet_host', $obj);
71558f85 199 return $this->id > 0;
200 }
201 }
202
3e008de8 203 function touch() {
204 $this->last_connect_time = time();
205 $this->commit();
206 }
207
71558f85 208 function set_name($newname) {
209 if (is_string($newname) && strlen($newname <= 80)) {
210 $this->name = $newname;
211 return true;
212 }
213 return false;
214 }
215
25202581 216 function set_applicationid($applicationid) {
217 if (is_numeric($applicationid) && $applicationid == intval($applicationid)) {
218 $this->applicationid = $applicationid;
219 return true;
220 }
221 return false;
222 }
223
1d422980 224 /**
ea87ed52 225 * Load information from db about an mnet peer into this object's properties
1d422980 226 *
ea87ed52 227 * @param string $wwwroot - address of peer whose details we want to load
228 * @return bool - indication of success or failure
1d422980 229 */
71558f85 230 function set_wwwroot($wwwroot) {
c7da4357 231 global $CFG, $DB;
71558f85 232
c7da4357 233 $hostinfo = $DB->get_record('mnet_host', array('wwwroot'=>$wwwroot));
71558f85 234
235 if ($hostinfo != false) {
236 $this->populate($hostinfo);
237 return true;
238 }
239 return false;
240 }
241
242 function set_id($id) {
c7da4357 243 global $CFG, $DB;
71558f85 244
245 if (clean_param($id, PARAM_INT) != $id) {
246 $this->errno[] = 1;
247 $this->errmsg[] = 'Your id ('.$id.') is not legal';
248 return false;
249 }
250
251 $sql = "
252 SELECT
253 h.*
254 FROM
c7da4357 255 {mnet_host} h
71558f85 256 WHERE
c7da4357 257 h.id = ?";
71558f85 258
c7da4357 259 if ($hostinfo = $DB->get_record_sql($sql, array($id))) {
71558f85 260 $this->populate($hostinfo);
261 return true;
262 }
263 return false;
264 }
265
735c7beb 266 /**
267 * Several methods can be used to get an 'mnet_host' record. They all then
268 * send it to this private method to populate this object's attributes.
1d422980 269 *
735c7beb 270 * @param object $hostinfo A database record from the mnet_host table
271 * @return void
272 */
71558f85 273 function populate($hostinfo) {
c7da4357 274 global $DB;
71558f85 275 $this->id = $hostinfo->id;
276 $this->wwwroot = $hostinfo->wwwroot;
277 $this->ip_address = $hostinfo->ip_address;
278 $this->name = $hostinfo->name;
279 $this->deleted = $hostinfo->deleted;
280 $this->public_key = $hostinfo->public_key;
281 $this->public_key_expires = $hostinfo->public_key_expires;
282 $this->last_connect_time = $hostinfo->last_connect_time;
283 $this->last_log_id = $hostinfo->last_log_id;
22882b66 284 $this->force_theme = $hostinfo->force_theme;
285 $this->theme = $hostinfo->theme;
25202581 286 $this->applicationid = $hostinfo->applicationid;
c7da4357 287 $this->application = $DB->get_record('mnet_application', array('id'=>$this->applicationid));
96bd2921 288 $this->bootstrapped = true;
71558f85 289 }
290
291 function get_public_key() {
292 if (isset($this->public_key_ref)) return $this->public_key_ref;
293 $this->public_key_ref = openssl_pkey_get_public($this->public_key);
294 return $this->public_key_ref;
295 }
296}