Subversion Repositories oidplus

Rev

Rev 1426 | Rev 1428 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1426 daniel-mar 1
<?php
2
 
3
/*
4
 * OIDplus 2.0
5
 * Copyright 2019 - 2022 Daniel Marschall, ViaThinkSoft
6
 *
7
 * Licensed under the Apache License, Version 2.0 (the "License");
8
 * you may not use this file except in compliance with the License.
9
 * You may obtain a copy of the License at
10
 *
11
 *     http://www.apache.org/licenses/LICENSE-2.0
12
 *
13
 * Unless required by applicable law or agreed to in writing, software
14
 * distributed under the License is distributed on an "AS IS" BASIS,
15
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
 * See the License for the specific language governing permissions and
17
 * limitations under the License.
18
 */
19
 
20
/**
21
 * @param string &$outscript
22
 * @param string $dir_old
23
 * @param string $dir_new
24
 * @param string|null $basepath_old
25
 * @param string|null $basepath_new
26
 * @return void
27
 */
28
function getDirContents_del(string &$outscript, string $dir_old, string $dir_new, string $basepath_old=null, string $basepath_new=null) {
29
        if (is_null($basepath_old)) $basepath_old = $dir_old;
30
        $basepath_old = my_realpath($basepath_old) . DIRECTORY_SEPARATOR;
31
        if ($basepath_old == '/') {
32
                fwrite(STDERR, 'ARG');
33
                die();
34
        }
35
 
36
        $dir_old = my_realpath($dir_old) . DIRECTORY_SEPARATOR;
37
        $dir_new = my_realpath($dir_new) . DIRECTORY_SEPARATOR;
38
        $files_old = my_scandir($dir_old);
39
        //$files_new = my_scandir($dir_new);
40
 
41
        foreach ($files_old as $file_old) {
42
                if ($file_old === '.') continue;
43
                if ($file_old === '..') continue;
44
                if ($file_old === '.svn') continue;
45
                if ($file_old === '.git') continue;
46
 
47
                $path_old = my_realpath($dir_old . DIRECTORY_SEPARATOR . $file_old);
48
                $path_new = my_realpath($dir_new . DIRECTORY_SEPARATOR . $file_old);
49
 
50
                $xpath_old = substr($path_old, strlen($basepath_old));
51
 
52
                if (is_dir($path_old)) {
53
                        getDirContents_del($outscript, $path_old, $path_new, $basepath_old, $basepath_new);
54
                }
55
 
56
                // Note: We don't warn if a file-to-be-deleted has vanished. It would not be necessary to warn about it
57
                if (is_dir($path_old) && !is_dir($path_new)) {
58
                        $outscript .= "// Dir deleted: $xpath_old\n";
59
                        $outscript .= "@rmdir('$xpath_old');\n";
60
                        $outscript .= "if (is_dir('$xpath_old')) {\n";
61
                        $outscript .= "\twarn('Directory could not be deleted (was not empty?): $xpath_old');\n";
62
                        $outscript .= "}\n";
63
                        $outscript .= "\n";
64
                } else if (is_file($path_old) && !is_file($path_new)) {
65
                        $outscript .= "// File deleted: $xpath_old\n";
66
                        $outscript .= "@unlink('$xpath_old');\n";
67
                        $outscript .= "if (is_file('$xpath_old')) {\n";
68
                        $outscript .= "\twarn('File could not be deleted: $xpath_old');\n";
69
                        $outscript .= "}\n";
70
                        $outscript .= "\n";
71
                }
72
        }
73
}
74
 
75
/**
76
 * @param string &$outscript
77
 * @param string $dir_old
78
 * @param string $dir_new
79
 * @param string|null $basepath_old
80
 * @param string|null $basepath_new
81
 * @return void
82
 * @throws Exception
83
 */
84
function getDirContents_diff(string &$outscript, string $dir_old, string $dir_new, string $basepath_old=null, string $basepath_new=null) {
85
        if (is_null($basepath_old)) $basepath_old = $dir_old;
86
        $basepath_old = my_realpath($basepath_old) . DIRECTORY_SEPARATOR;
87
        if ($basepath_old == '/') {
88
                fwrite(STDERR, 'ARG');
89
                die();
90
        }
91
 
92
        $dir_old = my_realpath($dir_old) . DIRECTORY_SEPARATOR;
93
        $dir_new = my_realpath($dir_new) . DIRECTORY_SEPARATOR;
94
        $files_old = my_scandir($dir_old);
95
        $files_new = my_scandir($dir_new);
96
 
97
        foreach ($files_old as $file_old) {
98
                if ($file_old === '.') continue;
99
                if ($file_old === '..') continue;
100
                if ($file_old === '.svn') continue;
101
                if ($file_old === '.git') continue;
102
 
103
                $path_old = my_realpath($dir_old . DIRECTORY_SEPARATOR . $file_old);
104
                $path_new = my_realpath($dir_new . DIRECTORY_SEPARATOR . $file_old);
105
 
106
                $xpath_old = substr($path_old, strlen($basepath_old));
107
 
108
                if (is_file($path_old) && is_file($path_new)) {
109
                        if (file_get_contents($path_old) != file_get_contents($path_new)) {
110
                                $outscript .= "// Files different: $xpath_old\n";
111
 
112
                                global $func_idx;
113
                                $func_idx++;
114
                                $outscript .= "function writefile_".$func_idx."() {\n";
115
                                special_save_file($xpath_old, $path_new, $outscript, "\t@");
116
                                $outscript .= "\t@touch('$xpath_old',".filemtime($path_new).");\n";
117
                                $outscript .= "}\n";
118
 
119
                                $outscript .= "if (!is_file('$xpath_old')) {\n";
120
                                $outscript .= "\twarn('File has vanished! Will re-create it: $xpath_old');\n";
121
                                $outscript .= "\twritefile_".$func_idx."();\n";
122
                                $outscript .= "\tif (!is_file('$xpath_old')) {\n";
123
                                $outscript .= "\t\twarn('File cannot be created (not existing): $xpath_old');\n";
124
                                $outscript .= "\t} else if (sha1_file('$xpath_old') != '".sha1_file($path_new)."') {\n";
125
                                $outscript .= "\t\twarn('File cannot be created (checksum mismatch): $xpath_old');\n";
126
                                $outscript .= "\t} else if ((DIRECTORY_SEPARATOR === '/') && !@chmod('$xpath_old', 0".sprintf('%o', fileperms($path_new) & 0777).")) {\n";
127
                                $outscript .= "\t\twarn('Could not change file permissions of ".$xpath_old."');\n";
128
                                $outscript .= "\t}\n";
129
 
130
                                $outscript .= "} else {\n";
131
 
132
                                $outscript .= "\tif (@sha1_file('$xpath_old') !== '".sha1_file($path_new)."') {\n"; // it is possible that the file is already updated (e.g. by a manual hotfix)
133
                                $outscript .= "\t\tif (@sha1_file('$xpath_old') !== '".sha1_file($path_old)."') {\n";
134
                                $outscript .= "\t\t\twarn('File was modified. Will overwrite the changes now: $xpath_old');\n";
135
                                $outscript .= "\t\t\t\$tmp = pathinfo('$xpath_old');\n";
136
                                $outscript .= "\t\t\t\$backup_name = \$tmp['dirname'].DIRECTORY_SEPARATOR.\$tmp['filename'].'.'.date('Ymdhis',@filemtime('$xpath_old')).(isset(\$tmp['extension']) ? '.'.\$tmp['extension'] : '');\n";
137
                                $outscript .= "\t\t\twarn('Creating a backup as '.\$backup_name);\n";
138
                                $outscript .= "\t\t\tif (!@copy('$xpath_old', \$backup_name)) {\n";
139
                                $outscript .= "\t\t\t\twarn('Creation of backup failed');\n";
140
                                $outscript .= "\t\t\t}\n";
141
                                $outscript .= "\t\t}\n";
142
                                $outscript .= "\t\twritefile_".$func_idx."();\n";
143
                                $outscript .= "\t\tif (@sha1_file('$xpath_old') !== '".sha1_file($path_new)."') {\n";
144
                                $outscript .= "\t\t\twarn('File cannot be written (checksum mismatch): $xpath_old');\n";
145
                                $outscript .= "\t\t}\n";
146
                                $outscript .= "\t}\n";
147
 
148
                                $outscript .= "}\n";
149
                                $outscript .= "\n";
150
                        }
151
                        if ((fileperms($path_old) & 0777) != (fileperms($path_new) & 0777)) {
152
                                $outscript .= "// Different file chmod: $xpath_old\n";
153
                                $outscript .= "if ((DIRECTORY_SEPARATOR === '/') && !@chmod('$xpath_old', 0".sprintf('%o', fileperms($path_new) & 0777).")) {\n";
154
                                $outscript .= "\twarn('Could not change file permissions of ".$xpath_old."');\n";
155
                                $outscript .= "}\n";
156
                                $outscript .= "\n";
157
                        }
158
                } else if (is_dir($path_old) && is_dir($path_new)) {
159
                        /*
160
                        $outscript .= "// Verify that directory exists: $xpath_old\n";
161
                        $outscript .= "if (!is_dir('$xpath_old')) {\n";
162
                        $outscript .= "\twarn('Directory has vanished! Will re-create it: $xpath_old');\n";
163
                        $outscript .= "\t@mkdir('$xpath_old');\n";
164
                        $outscript .= "\tif (!is_dir('$xpath_old')) {\n";
165
                        $outscript .= "\t\twarn('Directory could not be created: $xpath_old');\n";
166
                        $outscript .= "\t}\n";
167
                        $outscript .= "}\n";
168
                        $outscript .= "\n";
169
                        */
170
 
171
                        if ((fileperms($path_old) & 0777) != (fileperms($path_new) & 0777)) {
172
                                $outscript .= "// Different dir chmod: $xpath_old\n";
173
                                $outscript .= "if ((DIRECTORY_SEPARATOR === '/') && !@chmod('$xpath_old', 0".sprintf('%o', fileperms($path_new) & 0777).")) {\n";
174
                                $outscript .= "\twarn('Could not change dir permissions of ".$xpath_old."');\n";
175
                                $outscript .= "}\n";
176
                                $outscript .= "\n";
177
                        }
178
                }
179
 
180
                if (is_dir($path_old)) {
181
                        getDirContents_diff($outscript, $path_old, $path_new, $basepath_old, $basepath_new);
182
                }
183
        }
184
}
185
 
186
/**
187
 * @param string &$outscript
188
 * @param string $dir_old
189
 * @param string $dir_new
190
 * @param string|null $basepath_old
191
 * @param string|null $basepath_new
192
 * @return void
193
 * @throws Exception
194
 */
195
function getDirContents_add(string &$outscript, string $dir_old, string $dir_new, string $basepath_old=null, string $basepath_new=null) {
196
        if (is_null($basepath_new)) $basepath_new = $dir_new;
197
        $basepath_new = my_realpath($basepath_new) . DIRECTORY_SEPARATOR;
198
        if ($basepath_new == '/') {
199
                fwrite(STDERR, 'ARG');
200
                die();
201
        }
202
 
203
        $dir_old = my_realpath($dir_old) . DIRECTORY_SEPARATOR;
204
        $dir_new = my_realpath($dir_new) . DIRECTORY_SEPARATOR;
205
        //$files_old = my_scandir($dir_old);
206
        $files_new = my_scandir($dir_new);
207
 
208
        foreach ($files_new as $file_new) {
209
                if ($file_new === '.') continue;
210
                if ($file_new === '..') continue;
211
                if ($file_new === '.svn') continue;
212
                if ($file_new === '.git') continue;
213
 
214
                $path_old = my_realpath($dir_old . DIRECTORY_SEPARATOR . $file_new);
215
                $path_new = my_realpath($dir_new . DIRECTORY_SEPARATOR . $file_new);
216
 
217
                $xpath_new = substr($path_new, strlen($basepath_new));
218
 
219
                if (is_dir($path_new) && !is_dir($path_old)) {
220
                        // Note: We are not warning if the dir was already created by the user
221
                        $outscript .= "// Dir added: $xpath_new\n";
222
                        $outscript .= "@mkdir('$xpath_new');\n";
223
                        $outscript .= "if (!is_dir('$xpath_new')) {\n";
224
                        $outscript .= "\twarn('Directory could not be created: $xpath_new');\n";
225
                        $outscript .= "} else if ((DIRECTORY_SEPARATOR === '/') && !@chmod('$xpath_new', 0".sprintf('%o', fileperms($path_new) & 0777).")) {\n";
226
                        $outscript .= "\twarn('Could not change directory permissions of ".$xpath_new."');\n";
227
                        $outscript .= "}\n";
228
                        $outscript .= "\n";
229
 
230
                        // we create it locally, so that the recursive code still works
231
                        mkdir($dir_old . DIRECTORY_SEPARATOR . $file_new);
232
                        $path_old = my_realpath($dir_old . DIRECTORY_SEPARATOR . $file_new);
233
 
234
                } else if (is_file($path_new) && !is_file($path_old)) {
235
                        $outscript .= "// File added: $xpath_new\n";
236
 
237
                        global $func_idx;
238
                        $func_idx++;
239
                        $outscript .= "function writefile_".$func_idx."() {\n";
240
                        special_save_file($xpath_new, $path_new, $outscript, "\t@");
241
                        $outscript .= "\t@touch('$xpath_new',".filemtime($path_new).");\n";
242
                        $outscript .= "}\n";
243
 
244
                        // Note: We will not warn if the file was created and is exactly the file we want
245
                        $outscript .= "if (is_file('$xpath_new') && (sha1_file('$xpath_new') != '".sha1_file($path_new)."')) {\n";
246
                        $outscript .= "\twarn('File was created by someone else. Will overwrite the changes now: $xpath_new');\n";
247
                        $outscript .= "\t\$tmp = pathinfo('$xpath_new');\n";
248
                        $outscript .= "\t\$backup_name = \$tmp['dirname'].DIRECTORY_SEPARATOR.\$tmp['filename'].'.'.date('Ymdhis',@filemtime('$xpath_new')).(isset(\$tmp['extension']) ? '.'.\$tmp['extension'] : '');\n";
249
                        $outscript .= "\twarn('Creating a backup as '.\$backup_name);\n";
250
                        $outscript .= "\tif (!@copy('$xpath_new', \$backup_name)) {\n";
251
                        $outscript .= "\t\twarn('Creation of backup failed');\n";
252
                        $outscript .= "\t}\n";
253
                        $outscript .= "}\n";
254
 
255
                        $outscript .= "writefile_".$func_idx."();\n";
256
                        $outscript .= "if (!is_file('$xpath_new')) {\n";
257
                        $outscript .= "\twarn('File cannot be created (not existing): $xpath_new');\n";
258
                        $outscript .= "} else if (sha1_file('$xpath_new') != '".sha1_file($path_new)."') {\n";
259
                        $outscript .= "\twarn('File cannot be created (checksum mismatch): $xpath_new');\n";
260
                        $outscript .= "} else if ((DIRECTORY_SEPARATOR === '/') && !@chmod('$xpath_new', 0".sprintf('%o', fileperms($path_new) & 0777).")) {\n";
261
                        $outscript .= "\twarn('Could not change file permissions of ".$xpath_new."');\n";
262
                        $outscript .= "}\n";
263
                        $outscript .= "\n";
264
                }
265
 
266
                if (is_dir($path_new)) {
267
                        getDirContents_add($outscript, $path_old, $path_new, $basepath_old, $basepath_new);
268
                }
269
        }
270
}
271
 
272
/**
273
 * @param string &$outscript
274
 * @param string $dir_old
275
 * @param string $dir_new
276
 * @return void
277
 * @throws Exception
278
 */
279
function getDirContents(string &$outscript, string $dir_old, string $dir_new) {
280
        global $func_idx;
281
        $func_idx = 0;
282
        getDirContents_add($outscript, $dir_old, $dir_new);
283
        getDirContents_diff($outscript, $dir_old, $dir_new);
284
        getDirContents_del($outscript, $dir_old, $dir_new);
285
}
286
 
287
/**
288
 * @param string $version
289
 * @param string $dir
290
 * @return void
291
 */
292
function hotfix_dir(string $version, string $dir) {
293
        if ($version == "2.0.0.699") {
294
                // Fix syntax error that lead to a stalled update!
295
                $file = $dir.'/plugins/viathinksoft/adminPages/900_software_update/OIDplusPageAdminSoftwareUpdate.class.php';
296
                $cont = file_get_contents($file);
297
                $cont = str_replace("urlencode('oidplus:system_file_check',OIDplus::getEditionInfo()['downloadpage']))",
298
                                    "urlencode('oidplus:system_file_check'),OIDplus::getEditionInfo()['downloadpage'])",
299
                                    $cont);
300
                file_put_contents($file, $cont);
301
 
302
                // Fix syntax error that lead to a stalled update!
303
                $file = $dir.'/plugins/viathinksoft/adminPages/901_vnag_version_check/vnag.php';
304
                $cont = file_get_contents($file);
305
                $cont = str_replace("\t\tOIDplus::getEditionInfo()", "", $cont);
306
                file_put_contents($file, $cont);
307
        }
308
        if ($version == "2.0.0.830") {
309
                // Fix bug that caused system ID to get lost
310
                $file = $dir.'/includes/classes/OIDplus.class.php';
311
                $cont = file_get_contents($file);
312
                $cont = str_replace("if ((\$passphrase === false) || !is_privatekey_encrypted(\$privKey)) {",
313
                                    "if ((\$passphrase === false) || !is_privatekey_encrypted(OIDplus::config()->getValue('oidplus_private_key'))) {",
314
                                    $cont);
315
                file_put_contents($file, $cont);
316
        }
317
        if ($version == "2.0.0.856") {
318
                // Fix runtime error that lead to a stalled update!
319
                $file = $dir.'/includes/classes/OIDplus.class.php';
320
                $cont = file_get_contents($file);
321
                $cont = str_replace('$this->recanonizeObjects();', '', $cont);
322
                file_put_contents($file, $cont);
323
        }
324
        if ($version == "2.0.0.1108") {
325
                // Fix runtime error that lead to a stalled update!
326
                $file = $dir.'/vendor/danielmarschall/php_utils/vts_crypt.inc.php';
327
                $cont = file_get_contents($file);
328
                $cont = str_replace('echo "OK, password $password\n";', '', $cont);
329
                file_put_contents($file, $cont);
330
        }
331
        if ($version == "2.0.0.1186") {
332
                // Fix runtime error that lead to a stalled update!
333
                $file = $dir.'/includes/classes/OIDplusGui.class.php';
334
                $cont = file_get_contents($file);
335
                $cont = str_replace('public function html_exception_handler', 'public static function html_exception_handler', $cont);
336
                file_put_contents($file, $cont);
337
        }
338
        if ($version == "2.0.0.1248") {
339
                // Possible error message that interrupts AJAX contents if error output is enabled
340
                $file = $dir.'/vendor/danielmarschall/uuid_mac_utils/includes/mac_utils.inc.php';
341
                $cont = file_get_contents($file);
342
                $cont = str_replace(' inet_pton', ' @inet_pton', $cont);
343
                file_put_contents($file, $cont);
344
 
345
                // A PHP 8 function was used, making the update impossible on PHP 7.x systems
346
                $file = $dir.'/plugins/viathinksoft/objectTypes/mac/OIDplusObjectTypePluginMac.class.php';
347
                $cont = file_get_contents($file);
348
                $cont = str_replace("str_contains(\$static_node_id, ':')", "(strpos(\$static_node_id, ':') !== false)", $cont);
349
                $cont = str_replace("str_contains(\$static_node_id, '-')", "(strpos(\$static_node_id, '-') !== false)", $cont);
350
                file_put_contents($file, $cont);
351
        }
352
        if ($version == "2.0.0.1317") {
353
                // Exception is thrown when audience is wrong; therefore the user must clear their browset cache after update to get rid of the error message
354
                $file = $dir.'/includes/classes/OIDplusAuthContentStoreJWT.class.php';
355
                $cont = file_get_contents($file);
356
                $wrong = 'throw new OIDplusException(_L(\'Token has wrong audience: Given %1 but expected %2.\'), $contentProvider->getValue(\'aud\',\'\'), $contentProvider->getAudIss());';
357
                $correct = 'throw new OIDplusException(_L(\'Token has wrong audience: Given %1 but expected %2.\', $contentProvider->getValue(\'aud\',\'\'), $contentProvider->getAudIss()));';
358
                $cont = str_replace($wrong, $correct, $cont);
359
                file_put_contents($file, $cont);
360
        }
361
}
362
 
363
/**
364
 * @param string $data
365
 * @param int $width
366
 * @return string
367
 */
368
function split_equal_length(string $data, int $width=65): string {
369
        $res = '';
370
        for ($i=0; $i<strlen($data); $i+=$width) {
371
                $res .= substr($data, $i, $width)."\n";
372
        }
373
        return $res;
374
}
375
 
376
/**
377
 * @param string $out_file
378
 * @param string $in_file
379
 * @param string $res
380
 * @param string $line_prefix
381
 * @param int $width
382
 * @return void
383
 * @throws Exception
384
 */
385
function special_save_file(string $out_file, string $in_file, string &$res, string $line_prefix, int $width=50) {
386
        $handle = @fopen($in_file, "rb");
387
        if (!$handle) {
388
                throw new Exception("Cannot open file $in_file");
389
        }
390
        $res .= $line_prefix."\$fp = fopen('$out_file', 'w');\n";
391
 
392
        while (!feof($handle)) {
393
                // important: must be a multiple of 3, otherwise we have base64 paddings!
394
                $buffer = fread($handle, $width*3);
395
                $base64 = base64_encode($buffer);
396
                $res .= $line_prefix."fwrite(\$fp, base64_decode('".$base64."'));\n";
397
        }
398
 
399
        $res .= $line_prefix."fclose(\$fp);\n";
400
        fclose($handle);
401
}
402
 
403
/**
404
 * @param string $name
405
 * @return string
406
 */
407
function my_realpath(string $name): string {
408
        $ret = realpath($name);
409
        return ($ret === false) ? $name : $ret;
410
}
411
 
412
/**
413
 * @param string $dir
414
 * @return array
415
 */
416
function my_scandir(string $dir): array {
417
        $ret = @scandir($dir);
418
        if ($ret === false) return array();
419
        return $ret;
420
}
421
 
422
/**
423
 * @param string $outdir_old
424
 * @param string $outdir_new
425
 * @param string $outfile
426
 * @param string $version
427
 * @param string $prev_version
428
 * @param string $priv_key
429
 * @return void
430
 */
431
function oidplus_create_changescript($outdir_old, $outdir_new, $outfile, $prev_version, $version, $priv_key) {
432
        $outscript  = "<?php\n";
433
        $outscript .= "\n";
434
        $outscript .= "/*\n";
435
        $outscript .= " * OIDplus 2.0\n";
436
        $outscript .= " * Copyright 2019 - ".date('Y')." Daniel Marschall, ViaThinkSoft\n";
437
        $outscript .= " *\n";
438
        $outscript .= " * Licensed under the Apache License, Version 2.0 (the \"License\");\n";
439
        $outscript .= " * you may not use this file except in compliance with the License.\n";
440
        $outscript .= " * You may obtain a copy of the License at\n";
441
        $outscript .= " *\n";
442
        $outscript .= " *     http://www.apache.org/licenses/LICENSE-2.0\n";
443
        $outscript .= " *\n";
444
        $outscript .= " * Unless required by applicable law or agreed to in writing, software\n";
445
        $outscript .= " * distributed under the License is distributed on an \"AS IS\" BASIS,\n";
446
        $outscript .= " * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n";
447
        $outscript .= " * See the License for the specific language governing permissions and\n";
448
        $outscript .= " * limitations under the License.\n";
449
        $outscript .= " */\n";
450
        $outscript .= "\n";
451
        $outscript .= "function info(\$str) { echo \"INFO: \$str\\n\"; }\n";
452
        $outscript .= "function warn(\$str) { echo \"WARNING: \$str\\n\"; }\n";
453
        $outscript .= "function err(\$str) { die(\"FATAL ERROR: \$str\\n\"); }\n";
454
        $outscript .= "\n";
455
        $outscript .= "@set_time_limit(0);\n";
456
        $outscript .= "\n";
457
        $outscript .= "@header('Content-Type: text/plain');\n";
458
        $outscript .= "\n";
459
        $outscript .= "chdir(__DIR__);\n";
460
        if (version_compare($version,"2.0.1") >= 0) {
461
                // Version check see also OIDplus::getVersion()
462
                $outscript .= "\$cont = @file_get_contents('changelog.json.php');\n";
463
                $outscript .= "if (\$cont === false) err('Cannot read changelog.json.php');\n";
464
                $outscript .= "\$json = @json_decode(\$cont, true);\n";
465
                $outscript .= "if (\$json === null) err('Cannot parse changelog.json.php');\n";
466
                $outscript .= "\$latest_version = false;\n";
467
                $outscript .= "foreach (\$json as \$v) {\n";
468
                $outscript .= "\tif (isset(\$v['version'])) {\n";
469
                $outscript .= "\t\t\$latest_version = \$v['version'];\n";
470
                $outscript .= "\t\tbreak; // the first item is the latest version\n";
471
                $outscript .= "\t}\n";
472
                $outscript .= "}\n";
473
                $outscript .= "if (\$latest_version != '$prev_version') err('This update can only be applied to OIDplus version $prev_version!');\n";
474
        } else if (version_compare($version, "2.0.0.662") >= 0) {
475
                $rev = str_replace('2.0.0.', '', $version);
476
                $prev_rev = str_replace('2.0.0.', '', $prev_version);
477
                $outscript .= "if (trim(@file_get_contents('.version.php')) !== '<?php // Revision $prev_rev') {\n";
478
                $outscript .= "\terr('This update can only be applied to OIDplus version 2.0.0.$prev_rev!');\n";
479
                $outscript .= "}\n";
480
        } else {
481
                $rev = str_replace('2.0.0.', '', $version);
482
                $prev_rev = str_replace('2.0.0.', '', $prev_version);
483
                $outscript .= "if (trim(@file_get_contents('oidplus_version.txt')) !== 'Revision $prev_rev') {\n";
484
                $outscript .= "\terr('This update can only be applied to OIDplus version 2.0.0.$prev_rev!');\n";
485
                $outscript .= "}\n";
486
        }
487
        $outscript .= "\n";
488
        /*
489
        if (version_compare($version,"2.0.999.999") >= 0) {
490
                ... once we require PHP 7.1, we add the requirement here
491
                ... also if we require fancy new PHP modules, we must add it here
492
                ... the checks avoid that someone breaks their OIDplus installation if they update
493
        } else
494
        */if (version_compare($version,"2.0.0.2") >= 0) {
495
                // Version 2.0.0.2 (SVN Revision 2) requires PHP 7.0.0
496
                $outscript .= "if (version_compare(PHP_VERSION, '7.0.0') < 0) {\n";
497
                $outscript .= "\terr('You need PHP Version 7.0 to update to this version');\n";
498
                $outscript .= "}\n";
499
        }
500
        $outscript .= "\n";
501
        //$outscript .= "info('Update to OIDplus version $version running...');\n";
502
        //$outscript .= "\n";
503
        getDirContents($outscript, $outdir_old, $outdir_new);
504
        $outscript .= "\n";
505
        if (version_compare($version,"2.0.1") >= 0) {
506
                // Nothing to do in order to set the version, because changelog.json.php contains this information
507
                if (version_compare($version, "2.0.1") == 0) {
508
                        $outscript .= "@unlink('.version.php');\n";
509
                        $outscript .= "if (is_file('.version.php')) err('Could not delete .version.php! Please delete it manually');\n";
510
                }
511
        } else if (version_compare($version, "2.0.0.661") >= 0) {
512
                $rev = str_replace('2.0.0.', '', $version);
513
                $outscript .= "file_put_contents('.version.php', \"<?php // Revision $rev\\n\");\n";
514
                $outscript .= "if (trim(@file_get_contents('.version.php')) !== '<?php // Revision $rev') err('Could not write to .version.php!');\n";
515
                if (version_compare($version, "2.0.0.661") == 0) {
516
                        $outscript .= "@unlink('oidplus_version.txt');\n";
517
                        $outscript .= "if (is_file('oidplus_version.txt')) err('Could not delete oidplus_version.txt! Please delete it manually');\n";
518
                }
519
        } else {
520
                $rev = str_replace('2.0.0.', '', $version);
521
                $outscript .= "file_put_contents('oidplus_version.txt', \"Revision $rev\\n\");\n";
522
                $outscript .= "if (trim(@file_get_contents('oidplus_version.txt')) !== 'Revision $rev') err('Could not write to oidplus_version.txt!');\n";
523
        }
524
        $outscript .= "\n";
525
        $outscript .= "\n";
526
        //$outscript .= "info('Update to OIDplus version $version done!');\n";
1427 daniel-mar 527
        $outscript .= "echo 'DONE'; // This exact string will be compared in Update v3\n";
1426 daniel-mar 528
        $outscript .= "\n";
529
        $outscript .= "unlink(__FILE__);\n";
530
        $outscript .= "\n";
531
 
532
        // Now add digital signature
533
 
534
        if (strpos($outscript, '<?php') === false) {
535
                echo "Not a PHP file\n"; // Should not happen
536
                return;
537
        }
538
 
539
        $naked = preg_replace('@<\?php /\* <ViaThinkSoftSignature>(.+)</ViaThinkSoftSignature> \*/ \?>\n@ismU', '', $outscript);
540
 
541
        $hash = hash("sha256", $naked.basename($outfile));
542
 
543
        $pkeyid = openssl_pkey_get_private('file://'.$priv_key);
544
        openssl_sign($hash, $signature, $pkeyid, OPENSSL_ALGO_SHA256);
545
        openssl_free_key($pkeyid);
546
 
547
        if (!$signature) {
548
                echo "ERROR: Signature failed\n";
549
                return;
550
        }
551
 
552
        $sign_line = '<?php /* <ViaThinkSoftSignature>'."\n".split_equal_length(base64_encode($signature),65).'</ViaThinkSoftSignature> */ ?>';
553
 
554
        // We have to put the signature at the beginning, because we don't know if the end of the file lacks a PHP closing tag
555
        if (substr($outscript,0,2) === '#!') {
556
                // Preserve shebang
557
                $shebang_pos = strpos($naked, "\n");
558
                $shebang = substr($naked, 0, $shebang_pos);
559
                $rest = substr($naked, $shebang_pos+1);
560
                $outscript = $shebang."\n".$sign_line."\n".$rest;
561
        } else {
562
                $outscript = $sign_line."\n".$naked;
563
        }
564
 
565
        // Write the file
566
 
567
        file_put_contents($outfile, $outscript);
568
 
569
        $ec = -1;
570
        $out = array();
571
        exec('php -l '.escapeshellarg($outfile), $out, $ec);
572
        if ($ec != 0) {
573
                fwrite(STDERR, "STOP! $outfile PHP syntax error!\n");
1427 daniel-mar 574
                @unlink($outfile);
1426 daniel-mar 575
                return;
576
        }
577
        file_put_contents($outfile.'.gz', gzencode($outscript));
578
}