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