Subversion Repositories oidplus

Rev

Rev 1278 | Rev 1375 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 1278 Rev 1293
Line 47... Line 47...
47
        private function getSvnCommand(): string {
47
        private function getSvnCommand(): string {
48
                return 'svn update --accept theirs-full';
48
                return 'svn update --accept theirs-full';
49
        }
49
        }
50
 
50
 
51
        /**
51
        /**
52
         * @param string $actionID
-
 
53
         * @param array $params
52
         * @param array $params
54
         * @return array
53
         * @return array
55
         * @throws OIDplusException
54
         * @throws OIDplusException
56
         */
55
         */
57
        public function action(string $actionID, array $params): array {
56
        private function action_Update(array $params): array {
58
                if ($actionID == 'update_now') {
-
 
59
                        @set_time_limit(0);
57
                @set_time_limit(0);
60
 
-
 
61
                        if (!OIDplus::authUtils()->isAdminLoggedIn()) {
-
 
62
                                throw new OIDplusHtmlException(_L('You need to <a %1>log in</a> as administrator.',OIDplus::gui()->link('oidplus:login$admin')), null, 401);
-
 
63
                        }
-
 
64
 
58
 
65
                        if (OIDplus::getInstallType() === 'git-wc') {
59
                if (!OIDplus::authUtils()->isAdminLoggedIn()) {
66
                                $cmd = $this->getGitCommand().' 2>&1';
60
                        throw new OIDplusHtmlException(_L('You need to <a %1>log in</a> as administrator.',OIDplus::gui()->link('oidplus:login$admin')), null, 401);
-
 
61
                }
67
 
62
 
68
                                $ec = -1;
-
 
69
                                $out = array();
63
                if (OIDplus::getInstallType() === 'git-wc') {
70
                                exec($cmd, $out, $ec);
64
                        $cmd = $this->getGitCommand().' 2>&1';
71
 
65
 
-
 
66
                        $ec = -1;
-
 
67
                        $out = array();
-
 
68
                        exec($cmd, $out, $ec);
-
 
69
 
72
                                $res = _L('Execute command:').' '.$cmd."\n\n".trim(implode("\n",$out));
70
                        $res = _L('Execute command:').' '.$cmd."\n\n".trim(implode("\n",$out));
73
                                if ($ec === 0) {
71
                        if ($ec === 0) {
74
                                        $rev = 'HEAD'; // do not translate
72
                                $rev = 'HEAD'; // do not translate
75
                                        return array("status" => 0, "content" => $res, "rev" => $rev);
73
                                return array("status" => 0, "content" => $res, "rev" => $rev);
76
                                } else {
74
                        } else {
77
                                        return array("status" => -1, "error" => $res, "content" => "");
75
                                return array("status" => -1, "error" => $res, "content" => "");
78
                                }
-
 
79
                        }
76
                        }
-
 
77
                }
80
                        else if (OIDplus::getInstallType() === 'svn-wc') {
78
                else if (OIDplus::getInstallType() === 'svn-wc') {
81
                                $cmd = $this->getSvnCommand().' 2>&1';
79
                        $cmd = $this->getSvnCommand().' 2>&1';
82
 
80
 
83
                                $ec = -1;
81
                        $ec = -1;
84
                                $out = array();
82
                        $out = array();
85
                                exec($cmd, $out, $ec);
83
                        exec($cmd, $out, $ec);
86
 
84
 
87
                                $res = _L('Execute command:').' '.$cmd."\n\n".trim(implode("\n",$out));
85
                        $res = _L('Execute command:').' '.$cmd."\n\n".trim(implode("\n",$out));
88
                                if ($ec === 0) {
86
                        if ($ec === 0) {
89
                                        $rev = 'HEAD'; // do not translate
87
                                $rev = 'HEAD'; // do not translate
90
                                        return array("status" => 0, "content" => $res, "rev" => $rev);
88
                                return array("status" => 0, "content" => $res, "rev" => $rev);
91
                                } else {
89
                        } else {
92
                                        return array("status" => -1, "error" => $res, "content" => "");
90
                                return array("status" => -1, "error" => $res, "content" => "");
93
                                }
-
 
94
                        }
91
                        }
-
 
92
                }
95
                        else if (OIDplus::getInstallType() === 'svn-snapshot') {
93
                else if (OIDplus::getInstallType() === 'svn-snapshot') {
96
 
94
 
97
                                $rev = $params['rev'];
95
                        $rev = $params['rev'];
98
 
96
 
99
                                $update_version = $params['update_version'] ?? 1;
97
                        $update_version = $params['update_version'] ?? 1;
100
                                if (($update_version != 1) && ($update_version != 2)) {
98
                        if (($update_version != 1) && ($update_version != 2)) {
101
                                        throw new OIDplusException(_L('Unknown update version'));
99
                                throw new OIDplusException(_L('Unknown update version'));
102
                                }
100
                        }
103
 
101
 
104
                                // Download and unzip
102
                        // Download and unzip
105
 
103
 
106
                                $cont = false;
104
                        $cont = false;
107
                                for ($retry=1; $retry<=3; $retry++) {
105
                        for ($retry=1; $retry<=3; $retry++) {
108
                                        if (function_exists('gzdecode')) {
106
                                if (function_exists('gzdecode')) {
109
                                                $url = sprintf(OIDplus::getEditionInfo()['update_package_gz'], $rev-1, $rev);
107
                                        $url = sprintf(OIDplus::getEditionInfo()['update_package_gz'], $rev-1, $rev);
110
                                                $cont = url_get_contents($url);
108
                                        $cont = url_get_contents($url);
111
                                                if ($cont !== false) $cont = @gzdecode($cont);
109
                                        if ($cont !== false) $cont = @gzdecode($cont);
112
                                        } else {
110
                                } else {
113
                                                $url = sprintf(OIDplus::getEditionInfo()['update_package'], $rev-1, $rev);
111
                                        $url = sprintf(OIDplus::getEditionInfo()['update_package'], $rev-1, $rev);
114
                                                $cont = url_get_contents($url);
112
                                        $cont = url_get_contents($url);
115
                                        }
-
 
116
                                        if ($cont !== false) {
-
 
117
                                                break;
-
 
118
                                        } else {
-
 
119
                                                sleep(1);
-
 
120
                                        }
-
 
121
                                }
113
                                }
-
 
114
                                if ($cont !== false) {
-
 
115
                                        break;
-
 
116
                                } else {
-
 
117
                                        sleep(1);
-
 
118
                                }
-
 
119
                        }
122
                                if ($cont === false) throw new OIDplusException(_L("Update %1 could not be downloaded from ViaThinkSoft server. Please try again later.",$rev));
120
                        if ($cont === false) throw new OIDplusException(_L("Update %1 could not be downloaded from ViaThinkSoft server. Please try again later.",$rev));
123
 
-
 
124
                                // Check signature...
-
 
125
 
121
 
126
                                if (function_exists('openssl_verify')) {
122
                        // Check signature...
127
 
123
 
128
                                        $m = array();
-
 
129
                                        if (!preg_match('@<\?php /\* <ViaThinkSoftSignature>(.+)</ViaThinkSoftSignature> \*/ \?>\n@ismU', $cont, $m)) {
-
 
130
                                                throw new OIDplusException(_L("Update package file of revision %1 not digitally signed",$rev));
-
 
131
                                        }
-
 
132
                                        $signature = base64_decode($m[1]);
124
                        if (function_exists('openssl_verify')) {
133
 
125
 
-
 
126
                                $m = array();
134
                                        $naked = preg_replace('@<\?php /\* <ViaThinkSoftSignature>(.+)</ViaThinkSoftSignature> \*/ \?>\n@ismU', '', $cont);
127
                                if (!preg_match('@<\?php /\* <ViaThinkSoftSignature>(.+)</ViaThinkSoftSignature> \*/ \?>\n@ismU', $cont, $m)) {
135
                                        $hash = hash("sha256", $naked."update_".($rev-1)."_to_".($rev).".txt");
128
                                        throw new OIDplusException(_L("Update package file of revision %1 not digitally signed",$rev));
-
 
129
                                }
-
 
130
                                $signature = base64_decode($m[1]);
136
 
131
 
137
                                        $public_key = file_get_contents(__DIR__.'/public.pem');
-
 
138
                                        if (!openssl_verify($hash, $signature, $public_key, OPENSSL_ALGO_SHA256)) {
132
                                $naked = preg_replace('@<\?php /\* <ViaThinkSoftSignature>(.+)</ViaThinkSoftSignature> \*/ \?>\n@ismU', '', $cont);
139
                                                throw new OIDplusException(_L("Update package file of revision %1: Signature invalid",$rev));
133
                                $hash = hash("sha256", $naked."update_".($rev-1)."_to_".($rev).".txt");
140
                                        }
-
 
141
 
134
 
-
 
135
                                $public_key = file_get_contents(__DIR__.'/public.pem');
-
 
136
                                if (!openssl_verify($hash, $signature, $public_key, OPENSSL_ALGO_SHA256)) {
-
 
137
                                        throw new OIDplusException(_L("Update package file of revision %1: Signature invalid",$rev));
142
                                }
138
                                }
143
 
139
 
144
                                // All OK! Now write the file
140
                        }
145
 
141
 
146
                                $tmp_filename = 'update_'.generateRandomString(10).'.tmp.php';
-
 
147
                                $local_file = OIDplus::localpath().$tmp_filename;
142
                        // All OK! Now write the file
148
 
143
 
-
 
144
                        $tmp_filename = 'update_'.generateRandomString(10).'.tmp.php';
149
                                @file_put_contents($local_file, $cont);
145
                        $local_file = OIDplus::localpath().$tmp_filename;
150
 
146
 
151
                                if (!file_exists($local_file) || (@file_get_contents($local_file) !== $cont)) {
147
                        @file_put_contents($local_file, $cont);
152
                                        throw new OIDplusException(_L('Update file could not written. Probably there are no write-permissions to the root folder.'));
-
 
153
                                }
-
 
154
 
148
 
155
                                if ($update_version == 1) {
-
 
156
                                        // Now call the written file
-
 
157
                                        // Note: we may not use eval($cont) because the script uses die(),
-
 
158
                                        // and things in the script might collide with currently (un)loaded source code files, shutdown procedues, etc.
-
 
159
                                        $web_file = OIDplus::webpath(null,OIDplus::PATH_ABSOLUTE).$tmp_filename; // NOT canonical URL! This might fail with reverse proxies which can only be executed from outside
-
 
160
                                        $res = url_get_contents($web_file);
149
                        if (!file_exists($local_file) || (@file_get_contents($local_file) !== $cont)) {
161
                                        if ($res === false) {
-
 
162
                                                throw new OIDplusException(_L('Update-script %1 could not be executed',$web_file));
150
                                throw new OIDplusException(_L('Update file could not written. Probably there are no write-permissions to the root folder.'));
163
                                        }
-
 
164
                                        return array("status" => 0, "content" => $res, "rev" => $rev);
-
 
165
                                } else if ($update_version == 2) {
-
 
166
                                        // In this version, the client will call the web-update file.
-
 
167
                                        // This has the advantage that it will also work if the system is htpasswd protected
-
 
168
                                        return array("status" => 0, "update_file" => $tmp_filename, "rev" => $rev);
-
 
169
                                } else {
-
 
170
                                        throw new OIDplusException(_L("Unexpected update version"));
-
 
171
                                }
-
 
172
                        }
151
                        }
-
 
152
 
-
 
153
                        if ($update_version == 1) {
-
 
154
                                // Now call the written file
-
 
155
                                // Note: we may not use eval($cont) because the script uses die(),
-
 
156
                                // and things in the script might collide with currently (un)loaded source code files, shutdown procedues, etc.
-
 
157
                                $web_file = OIDplus::webpath(null,OIDplus::PATH_ABSOLUTE).$tmp_filename; // NOT canonical URL! This might fail with reverse proxies which can only be executed from outside
-
 
158
                                $res = url_get_contents($web_file);
-
 
159
                                if ($res === false) {
-
 
160
                                        throw new OIDplusException(_L('Update-script %1 could not be executed',$web_file));
-
 
161
                                }
-
 
162
                                return array("status" => 0, "content" => $res, "rev" => $rev);
-
 
163
                        } else if ($update_version == 2) {
-
 
164
                                // In this version, the client will call the web-update file.
-
 
165
                                // This has the advantage that it will also work if the system is htpasswd protected
-
 
166
                                return array("status" => 0, "update_file" => $tmp_filename, "rev" => $rev);
173
                        else {
167
                        } else {
174
                                throw new OIDplusException(_L('Multiple version files/directories (oidplus_version.txt, .version.php, .git, or .svn) are existing! Therefore, the version is ambiguous!'));
168
                                throw new OIDplusException(_L("Unexpected update version"));
175
                        }
169
                        }
-
 
170
                }
-
 
171
                else {
-
 
172
                        throw new OIDplusException(_L('Multiple version files/directories (oidplus_version.txt, .version.php, .git, or .svn) are existing! Therefore, the version is ambiguous!'));
-
 
173
                }
-
 
174
        }
-
 
175
 
-
 
176
        /**
-
 
177
         * @param string $actionID
-
 
178
         * @param array $params
-
 
179
         * @return array
-
 
180
         * @throws OIDplusException
-
 
181
         */
-
 
182
        public function action(string $actionID, array $params): array {
-
 
183
                if ($actionID == 'update_now') {
-
 
184
                        return $this->action_Update($params);
176
                } else {
185
                } else {
177
                        return parent::action($actionID, $params);
186
                        return parent::action($actionID, $params);
178
                }
187
                }
179
        }
188
        }
180
 
189