mnet: We now keep several generations of SSL keys
[moodle.git] / mnet / environment.php
CommitLineData
71558f85 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
8class 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();
f32689ad 18 var $deleted = 0;
71558f85 19
20 function mnet_environment() {
21 return true;
22 }
23
24 function init() {
25 global $CFG;
26
27 // Bootstrap the object data on first load.
28 if (empty($CFG->mnet_localhost_id) ) {
71558f85 29
f32689ad 30 $this->wwwroot = $CFG->wwwroot;
31 $this->ip_address = $_SERVER['SERVER_ADDR'];
32 $this->id = insert_record('mnet_host', $this, true);
71558f85 33
34 set_config('mnet_localhost_id', $this->id);
f32689ad 35 $this->get_keypair();
71558f85 36 } else {
37 $hostobject = get_record('mnet_host','id', $CFG->mnet_localhost_id);
f32689ad 38 if(is_object($hostobject)) {
39 $temparr = get_object_vars($hostobject);
40 foreach(get_object_vars($temparr) as $key => $value) {
41 $this->$key = $value;
42 }
43 unset($hostobject, $temparr);
44 } else {
45 return false;
71558f85 46 }
47
f32689ad 48 // Unless this is an install/upgrade, generate the SSL keys.
49 if(empty($this->public_key)) {
50 $this->get_keypair();
51 }
71558f85 52 }
53
54 // We need to set up a record that represents 'all hosts'. Any rights
55 // granted to this host will be conferred on all hosts.
56 if (empty($CFG->mnet_all_hosts_id) ) {
57 $hostobject = new stdClass();
58 $hostobject->wwwroot = '';
59 $hostobject->ip_address = '';
60 $hostobject->public_key = '';
61 $hostobject->public_key_expires = '';
62 $hostobject->last_connect_time = '0';
63 $hostobject->last_log_id = '0';
64 $hostobject->deleted = 0;
65 $hostobject->name = 'All Hosts';
66
67 $hostobject->id = insert_record('mnet_host',$hostobject, true);
68 set_config('mnet_all_hosts_id', $hostobject->id);
69 $CFG->mnet_all_hosts_id = $hostobject->id;
70 unset($hostobject);
71 }
72 }
73
74 function get_keypair() {
735c7beb 75 // We don't generate keys on install/upgrade because we want the USER
76 // record to have an email address, city and country already.
77 if (!empty($_SESSION['upgraderunning'])) return true;
71558f85 78 if (!empty($this->keypair)) return true;
735c7beb 79
80 $this->keypair = array();
81 $keypair = get_field('config_plugins', 'value', 'plugin', 'mnet', 'name', 'openssl');
82
83 if (!empty($keypair)) {
84 // Explode/Implode is faster than Unserialize/Serialize
85 $this->keypair = explode('@@@@@@@@', $keypair);
86 }
87
88 if ($this->public_key_expires > time()) {
71558f85 89 $this->keypair['privatekey'] = openssl_pkey_get_private($this->keypair['keypair_PEM']);
90 $this->keypair['publickey'] = openssl_pkey_get_public($this->keypair['certificate']);
91 } else {
735c7beb 92 // Key generation/rotation
93
94 // 1. Archive the current key (if there is one).
95 $result = get_field('config_plugins', 'value', 'plugin', 'mnet', 'name', 'openssl_history');
96 if(empty($result)) {
97 set_config('openssl_history', serialize(array()), 'mnet');
98 $openssl_history = array();
99 } else {
100 $openssl_history = unserialize($result);
101 }
102
103 if(count($this->keypair)) {
104 $this->keypair['expires'] = $this->public_key_expires;
105 array_unshift($openssl_history, $this->keypair);
106 }
107
108 // 2. How many old keys do we want to keep? Use array_slice to get
109 // rid of any we don't want
110 $openssl_generations = get_field('config_plugins', 'value', 'plugin', 'mnet', 'name', 'openssl_generations');
111 if(empty($openssl_generations)) {
112 set_config('openssl_generations', 3, 'mnet');
113 $openssl_generations = 3;
114 }
115
116 if(count($openssl_history) > $openssl_generations) {
117 $openssl_history = array_slice($openssl_history, 0, $openssl_generations);
118 }
119
120 set_config('openssl_history', serialize($openssl_history), 'mnet');
121
122 // 3. Generate fresh keys
123 $this->keypair = array();
71558f85 124 $this->keypair = mnet_generate_keypair();
f32689ad 125 $this->public_key = $this->keypair['certificate'];
126 $details = openssl_x509_parse($this->public_key);
127 $this->public_key_expires = $details['validTo_time_t'];
128
735c7beb 129 set_config('openssl', implode('@@@@@@@@', $this->keypair);
130
f32689ad 131 update_record('mnet_host', $this);
71558f85 132 }
133 return true;
134 }
135
136 function get_private_key() {
137 if (empty($this->keypair)) $this->get_keypair();
138 if (isset($this->keypair['privatekey'])) return $this->keypair['privatekey'];
139 $this->keypair['privatekey'] = openssl_pkey_get_private($this->keypair['keypair_PEM']);
140 return $this->keypair['privatekey'];
141 }
142
143 function get_public_key() {
144 if (!isset($this->keypair)) $this->get_keypair();
145 if (isset($this->keypair['publickey'])) return $this->keypair['publickey'];
146 $this->keypair['publickey'] = openssl_pkey_get_public($this->keypair['certificate']);
147 return $this->keypair['publickey'];
148 }
149
150 /**
151 * Note that the openssl_sign function computes the sha1 hash, and then
152 * signs the hash.
153 */
154 function sign_message($message) {
155 $bool = openssl_sign($message, $signature, $this->get_private_key());
156 return $signature;
157 }
158}
159
160?>