Passed
Push — master ( f4e5d3...46459a )
by John
14:39 queued 11s
created
lib/private/Security/CertificateManager.php 2 patches
Indentation   +238 added lines, -238 removed lines patch added patch discarded remove patch
@@ -44,242 +44,242 @@
 block discarded – undo
44 44
  * Manage trusted certificates for users
45 45
  */
46 46
 class CertificateManager implements ICertificateManager {
47
-	protected View $view;
48
-	protected IConfig $config;
49
-	protected LoggerInterface $logger;
50
-	protected ISecureRandom $random;
51
-
52
-	private ?string $bundlePath = null;
53
-
54
-	public function __construct(View $view,
55
-								IConfig $config,
56
-								LoggerInterface $logger,
57
-								ISecureRandom $random) {
58
-		$this->view = $view;
59
-		$this->config = $config;
60
-		$this->logger = $logger;
61
-		$this->random = $random;
62
-	}
63
-
64
-	/**
65
-	 * Returns all certificates trusted by the user
66
-	 *
67
-	 * @return \OCP\ICertificate[]
68
-	 */
69
-	public function listCertificates(): array {
70
-		if (!$this->config->getSystemValueBool('installed', false)) {
71
-			return [];
72
-		}
73
-
74
-		$path = $this->getPathToCertificates() . 'uploads/';
75
-		if (!$this->view->is_dir($path)) {
76
-			return [];
77
-		}
78
-		$result = [];
79
-		$handle = $this->view->opendir($path);
80
-		if (!is_resource($handle)) {
81
-			return [];
82
-		}
83
-		while (false !== ($file = readdir($handle))) {
84
-			if ($file != '.' && $file != '..') {
85
-				try {
86
-					$result[] = new Certificate($this->view->file_get_contents($path . $file), $file);
87
-				} catch (\Exception $e) {
88
-				}
89
-			}
90
-		}
91
-		closedir($handle);
92
-		return $result;
93
-	}
94
-
95
-	private function hasCertificates(): bool {
96
-		if (!$this->config->getSystemValueBool('installed', false)) {
97
-			return false;
98
-		}
99
-
100
-		$path = $this->getPathToCertificates() . 'uploads/';
101
-		if (!$this->view->is_dir($path)) {
102
-			return false;
103
-		}
104
-		$result = [];
105
-		$handle = $this->view->opendir($path);
106
-		if (!is_resource($handle)) {
107
-			return false;
108
-		}
109
-		while (false !== ($file = readdir($handle))) {
110
-			if ($file !== '.' && $file !== '..') {
111
-				return true;
112
-			}
113
-		}
114
-		closedir($handle);
115
-		return false;
116
-	}
117
-
118
-	/**
119
-	 * create the certificate bundle of all trusted certificated
120
-	 */
121
-	public function createCertificateBundle(): void {
122
-		$path = $this->getPathToCertificates();
123
-		$certs = $this->listCertificates();
124
-
125
-		if (!$this->view->file_exists($path)) {
126
-			$this->view->mkdir($path);
127
-		}
128
-
129
-		$defaultCertificates = file_get_contents(\OC::$SERVERROOT . '/resources/config/ca-bundle.crt');
130
-		if (strlen($defaultCertificates) < 1024) { // sanity check to verify that we have some content for our bundle
131
-			// log as exception so we have a stacktrace
132
-			$e = new \Exception('Shipped ca-bundle is empty, refusing to create certificate bundle');
133
-			$this->logger->error($e->getMessage(), ['exception' => $e]);
134
-			return;
135
-		}
136
-
137
-		$certPath = $path . 'rootcerts.crt';
138
-		$tmpPath = $certPath . '.tmp' . $this->random->generate(10, ISecureRandom::CHAR_DIGITS);
139
-		$fhCerts = $this->view->fopen($tmpPath, 'w');
140
-
141
-		if (!is_resource($fhCerts)) {
142
-			throw new \RuntimeException('Unable to open file handler to create certificate bundle "' . $tmpPath . '".');
143
-		}
144
-
145
-		// Write user certificates
146
-		foreach ($certs as $cert) {
147
-			$file = $path . '/uploads/' . $cert->getName();
148
-			$data = $this->view->file_get_contents($file);
149
-			if (strpos($data, 'BEGIN CERTIFICATE')) {
150
-				fwrite($fhCerts, $data);
151
-				fwrite($fhCerts, "\r\n");
152
-			}
153
-		}
154
-
155
-		// Append the default certificates
156
-		fwrite($fhCerts, $defaultCertificates);
157
-
158
-		// Append the system certificate bundle
159
-		$systemBundle = $this->getCertificateBundle();
160
-		if ($systemBundle !== $certPath && $this->view->file_exists($systemBundle)) {
161
-			$systemCertificates = $this->view->file_get_contents($systemBundle);
162
-			fwrite($fhCerts, $systemCertificates);
163
-		}
164
-
165
-		fclose($fhCerts);
166
-
167
-		$this->view->rename($tmpPath, $certPath);
168
-	}
169
-
170
-	/**
171
-	 * Save the certificate and re-generate the certificate bundle
172
-	 *
173
-	 * @param string $certificate the certificate data
174
-	 * @param string $name the filename for the certificate
175
-	 * @return \OCP\ICertificate
176
-	 * @throws \Exception If the certificate could not get added
177
-	 */
178
-	public function addCertificate(string $certificate, string $name): ICertificate {
179
-		if (!Filesystem::isValidPath($name) or Filesystem::isFileBlacklisted($name)) {
180
-			throw new \Exception('Filename is not valid');
181
-		}
182
-		$this->bundlePath = null;
183
-
184
-		$dir = $this->getPathToCertificates() . 'uploads/';
185
-		if (!$this->view->file_exists($dir)) {
186
-			$this->view->mkdir($dir);
187
-		}
188
-
189
-		try {
190
-			$file = $dir . $name;
191
-			$certificateObject = new Certificate($certificate, $name);
192
-			$this->view->file_put_contents($file, $certificate);
193
-			$this->createCertificateBundle();
194
-			return $certificateObject;
195
-		} catch (\Exception $e) {
196
-			throw $e;
197
-		}
198
-	}
199
-
200
-	/**
201
-	 * Remove the certificate and re-generate the certificate bundle
202
-	 *
203
-	 * @param string $name
204
-	 * @return bool
205
-	 */
206
-	public function removeCertificate(string $name): bool {
207
-		if (!Filesystem::isValidPath($name)) {
208
-			return false;
209
-		}
210
-		$this->bundlePath = null;
211
-
212
-		$path = $this->getPathToCertificates() . 'uploads/';
213
-		if ($this->view->file_exists($path . $name)) {
214
-			$this->view->unlink($path . $name);
215
-			$this->createCertificateBundle();
216
-		}
217
-		return true;
218
-	}
219
-
220
-	/**
221
-	 * Get the path to the certificate bundle
222
-	 *
223
-	 * @return string
224
-	 */
225
-	public function getCertificateBundle(): string {
226
-		return $this->getPathToCertificates() . 'rootcerts.crt';
227
-	}
228
-
229
-	/**
230
-	 * Get the full local path to the certificate bundle
231
-	 * @throws \Exception when getting bundle path fails
232
-	 */
233
-	public function getAbsoluteBundlePath(): string {
234
-		try {
235
-			if ($this->bundlePath === null) {
236
-				if (!$this->hasCertificates()) {
237
-					$this->bundlePath = \OC::$SERVERROOT . '/resources/config/ca-bundle.crt';
238
-				}
239
-
240
-				if ($this->needsRebundling()) {
241
-					$this->createCertificateBundle();
242
-				}
243
-
244
-				$certificateBundle = $this->getCertificateBundle();
245
-				$this->bundlePath = $this->view->getLocalFile($certificateBundle) ?: null;
246
-
247
-				if ($this->bundlePath === null) {
248
-					throw new \RuntimeException('Unable to get certificate bundle "' . $certificateBundle . '".');
249
-				}
250
-			}
251
-			return $this->bundlePath;
252
-		} catch (\Exception $e) {
253
-			$this->logger->error('Failed to get absolute bundle path. Fallback to default ca-bundle.crt', ['exception' => $e]);
254
-			return \OC::$SERVERROOT . '/resources/config/ca-bundle.crt';
255
-		}
256
-	}
257
-
258
-	private function getPathToCertificates(): string {
259
-		return '/files_external/';
260
-	}
261
-
262
-	/**
263
-	 * Check if we need to re-bundle the certificates because one of the sources has updated
264
-	 *
265
-	 * @return bool
266
-	 */
267
-	private function needsRebundling(): bool {
268
-		$targetBundle = $this->getCertificateBundle();
269
-		if (!$this->view->file_exists($targetBundle)) {
270
-			return true;
271
-		}
272
-
273
-		$sourceMTime = $this->getFilemtimeOfCaBundle();
274
-		return $sourceMTime > $this->view->filemtime($targetBundle);
275
-	}
276
-
277
-	/**
278
-	 * get mtime of ca-bundle shipped by Nextcloud
279
-	 *
280
-	 * @return int
281
-	 */
282
-	protected function getFilemtimeOfCaBundle(): int {
283
-		return filemtime(\OC::$SERVERROOT . '/resources/config/ca-bundle.crt');
284
-	}
47
+    protected View $view;
48
+    protected IConfig $config;
49
+    protected LoggerInterface $logger;
50
+    protected ISecureRandom $random;
51
+
52
+    private ?string $bundlePath = null;
53
+
54
+    public function __construct(View $view,
55
+                                IConfig $config,
56
+                                LoggerInterface $logger,
57
+                                ISecureRandom $random) {
58
+        $this->view = $view;
59
+        $this->config = $config;
60
+        $this->logger = $logger;
61
+        $this->random = $random;
62
+    }
63
+
64
+    /**
65
+     * Returns all certificates trusted by the user
66
+     *
67
+     * @return \OCP\ICertificate[]
68
+     */
69
+    public function listCertificates(): array {
70
+        if (!$this->config->getSystemValueBool('installed', false)) {
71
+            return [];
72
+        }
73
+
74
+        $path = $this->getPathToCertificates() . 'uploads/';
75
+        if (!$this->view->is_dir($path)) {
76
+            return [];
77
+        }
78
+        $result = [];
79
+        $handle = $this->view->opendir($path);
80
+        if (!is_resource($handle)) {
81
+            return [];
82
+        }
83
+        while (false !== ($file = readdir($handle))) {
84
+            if ($file != '.' && $file != '..') {
85
+                try {
86
+                    $result[] = new Certificate($this->view->file_get_contents($path . $file), $file);
87
+                } catch (\Exception $e) {
88
+                }
89
+            }
90
+        }
91
+        closedir($handle);
92
+        return $result;
93
+    }
94
+
95
+    private function hasCertificates(): bool {
96
+        if (!$this->config->getSystemValueBool('installed', false)) {
97
+            return false;
98
+        }
99
+
100
+        $path = $this->getPathToCertificates() . 'uploads/';
101
+        if (!$this->view->is_dir($path)) {
102
+            return false;
103
+        }
104
+        $result = [];
105
+        $handle = $this->view->opendir($path);
106
+        if (!is_resource($handle)) {
107
+            return false;
108
+        }
109
+        while (false !== ($file = readdir($handle))) {
110
+            if ($file !== '.' && $file !== '..') {
111
+                return true;
112
+            }
113
+        }
114
+        closedir($handle);
115
+        return false;
116
+    }
117
+
118
+    /**
119
+     * create the certificate bundle of all trusted certificated
120
+     */
121
+    public function createCertificateBundle(): void {
122
+        $path = $this->getPathToCertificates();
123
+        $certs = $this->listCertificates();
124
+
125
+        if (!$this->view->file_exists($path)) {
126
+            $this->view->mkdir($path);
127
+        }
128
+
129
+        $defaultCertificates = file_get_contents(\OC::$SERVERROOT . '/resources/config/ca-bundle.crt');
130
+        if (strlen($defaultCertificates) < 1024) { // sanity check to verify that we have some content for our bundle
131
+            // log as exception so we have a stacktrace
132
+            $e = new \Exception('Shipped ca-bundle is empty, refusing to create certificate bundle');
133
+            $this->logger->error($e->getMessage(), ['exception' => $e]);
134
+            return;
135
+        }
136
+
137
+        $certPath = $path . 'rootcerts.crt';
138
+        $tmpPath = $certPath . '.tmp' . $this->random->generate(10, ISecureRandom::CHAR_DIGITS);
139
+        $fhCerts = $this->view->fopen($tmpPath, 'w');
140
+
141
+        if (!is_resource($fhCerts)) {
142
+            throw new \RuntimeException('Unable to open file handler to create certificate bundle "' . $tmpPath . '".');
143
+        }
144
+
145
+        // Write user certificates
146
+        foreach ($certs as $cert) {
147
+            $file = $path . '/uploads/' . $cert->getName();
148
+            $data = $this->view->file_get_contents($file);
149
+            if (strpos($data, 'BEGIN CERTIFICATE')) {
150
+                fwrite($fhCerts, $data);
151
+                fwrite($fhCerts, "\r\n");
152
+            }
153
+        }
154
+
155
+        // Append the default certificates
156
+        fwrite($fhCerts, $defaultCertificates);
157
+
158
+        // Append the system certificate bundle
159
+        $systemBundle = $this->getCertificateBundle();
160
+        if ($systemBundle !== $certPath && $this->view->file_exists($systemBundle)) {
161
+            $systemCertificates = $this->view->file_get_contents($systemBundle);
162
+            fwrite($fhCerts, $systemCertificates);
163
+        }
164
+
165
+        fclose($fhCerts);
166
+
167
+        $this->view->rename($tmpPath, $certPath);
168
+    }
169
+
170
+    /**
171
+     * Save the certificate and re-generate the certificate bundle
172
+     *
173
+     * @param string $certificate the certificate data
174
+     * @param string $name the filename for the certificate
175
+     * @return \OCP\ICertificate
176
+     * @throws \Exception If the certificate could not get added
177
+     */
178
+    public function addCertificate(string $certificate, string $name): ICertificate {
179
+        if (!Filesystem::isValidPath($name) or Filesystem::isFileBlacklisted($name)) {
180
+            throw new \Exception('Filename is not valid');
181
+        }
182
+        $this->bundlePath = null;
183
+
184
+        $dir = $this->getPathToCertificates() . 'uploads/';
185
+        if (!$this->view->file_exists($dir)) {
186
+            $this->view->mkdir($dir);
187
+        }
188
+
189
+        try {
190
+            $file = $dir . $name;
191
+            $certificateObject = new Certificate($certificate, $name);
192
+            $this->view->file_put_contents($file, $certificate);
193
+            $this->createCertificateBundle();
194
+            return $certificateObject;
195
+        } catch (\Exception $e) {
196
+            throw $e;
197
+        }
198
+    }
199
+
200
+    /**
201
+     * Remove the certificate and re-generate the certificate bundle
202
+     *
203
+     * @param string $name
204
+     * @return bool
205
+     */
206
+    public function removeCertificate(string $name): bool {
207
+        if (!Filesystem::isValidPath($name)) {
208
+            return false;
209
+        }
210
+        $this->bundlePath = null;
211
+
212
+        $path = $this->getPathToCertificates() . 'uploads/';
213
+        if ($this->view->file_exists($path . $name)) {
214
+            $this->view->unlink($path . $name);
215
+            $this->createCertificateBundle();
216
+        }
217
+        return true;
218
+    }
219
+
220
+    /**
221
+     * Get the path to the certificate bundle
222
+     *
223
+     * @return string
224
+     */
225
+    public function getCertificateBundle(): string {
226
+        return $this->getPathToCertificates() . 'rootcerts.crt';
227
+    }
228
+
229
+    /**
230
+     * Get the full local path to the certificate bundle
231
+     * @throws \Exception when getting bundle path fails
232
+     */
233
+    public function getAbsoluteBundlePath(): string {
234
+        try {
235
+            if ($this->bundlePath === null) {
236
+                if (!$this->hasCertificates()) {
237
+                    $this->bundlePath = \OC::$SERVERROOT . '/resources/config/ca-bundle.crt';
238
+                }
239
+
240
+                if ($this->needsRebundling()) {
241
+                    $this->createCertificateBundle();
242
+                }
243
+
244
+                $certificateBundle = $this->getCertificateBundle();
245
+                $this->bundlePath = $this->view->getLocalFile($certificateBundle) ?: null;
246
+
247
+                if ($this->bundlePath === null) {
248
+                    throw new \RuntimeException('Unable to get certificate bundle "' . $certificateBundle . '".');
249
+                }
250
+            }
251
+            return $this->bundlePath;
252
+        } catch (\Exception $e) {
253
+            $this->logger->error('Failed to get absolute bundle path. Fallback to default ca-bundle.crt', ['exception' => $e]);
254
+            return \OC::$SERVERROOT . '/resources/config/ca-bundle.crt';
255
+        }
256
+    }
257
+
258
+    private function getPathToCertificates(): string {
259
+        return '/files_external/';
260
+    }
261
+
262
+    /**
263
+     * Check if we need to re-bundle the certificates because one of the sources has updated
264
+     *
265
+     * @return bool
266
+     */
267
+    private function needsRebundling(): bool {
268
+        $targetBundle = $this->getCertificateBundle();
269
+        if (!$this->view->file_exists($targetBundle)) {
270
+            return true;
271
+        }
272
+
273
+        $sourceMTime = $this->getFilemtimeOfCaBundle();
274
+        return $sourceMTime > $this->view->filemtime($targetBundle);
275
+    }
276
+
277
+    /**
278
+     * get mtime of ca-bundle shipped by Nextcloud
279
+     *
280
+     * @return int
281
+     */
282
+    protected function getFilemtimeOfCaBundle(): int {
283
+        return filemtime(\OC::$SERVERROOT . '/resources/config/ca-bundle.crt');
284
+    }
285 285
 }
Please login to merge, or discard this patch.
Spacing   +18 added lines, -18 removed lines patch added patch discarded remove patch
@@ -71,7 +71,7 @@  discard block
 block discarded – undo
71 71
 			return [];
72 72
 		}
73 73
 
74
-		$path = $this->getPathToCertificates() . 'uploads/';
74
+		$path = $this->getPathToCertificates().'uploads/';
75 75
 		if (!$this->view->is_dir($path)) {
76 76
 			return [];
77 77
 		}
@@ -83,7 +83,7 @@  discard block
 block discarded – undo
83 83
 		while (false !== ($file = readdir($handle))) {
84 84
 			if ($file != '.' && $file != '..') {
85 85
 				try {
86
-					$result[] = new Certificate($this->view->file_get_contents($path . $file), $file);
86
+					$result[] = new Certificate($this->view->file_get_contents($path.$file), $file);
87 87
 				} catch (\Exception $e) {
88 88
 				}
89 89
 			}
@@ -97,7 +97,7 @@  discard block
 block discarded – undo
97 97
 			return false;
98 98
 		}
99 99
 
100
-		$path = $this->getPathToCertificates() . 'uploads/';
100
+		$path = $this->getPathToCertificates().'uploads/';
101 101
 		if (!$this->view->is_dir($path)) {
102 102
 			return false;
103 103
 		}
@@ -126,7 +126,7 @@  discard block
 block discarded – undo
126 126
 			$this->view->mkdir($path);
127 127
 		}
128 128
 
129
-		$defaultCertificates = file_get_contents(\OC::$SERVERROOT . '/resources/config/ca-bundle.crt');
129
+		$defaultCertificates = file_get_contents(\OC::$SERVERROOT.'/resources/config/ca-bundle.crt');
130 130
 		if (strlen($defaultCertificates) < 1024) { // sanity check to verify that we have some content for our bundle
131 131
 			// log as exception so we have a stacktrace
132 132
 			$e = new \Exception('Shipped ca-bundle is empty, refusing to create certificate bundle');
@@ -134,17 +134,17 @@  discard block
 block discarded – undo
134 134
 			return;
135 135
 		}
136 136
 
137
-		$certPath = $path . 'rootcerts.crt';
138
-		$tmpPath = $certPath . '.tmp' . $this->random->generate(10, ISecureRandom::CHAR_DIGITS);
137
+		$certPath = $path.'rootcerts.crt';
138
+		$tmpPath = $certPath.'.tmp'.$this->random->generate(10, ISecureRandom::CHAR_DIGITS);
139 139
 		$fhCerts = $this->view->fopen($tmpPath, 'w');
140 140
 
141 141
 		if (!is_resource($fhCerts)) {
142
-			throw new \RuntimeException('Unable to open file handler to create certificate bundle "' . $tmpPath . '".');
142
+			throw new \RuntimeException('Unable to open file handler to create certificate bundle "'.$tmpPath.'".');
143 143
 		}
144 144
 
145 145
 		// Write user certificates
146 146
 		foreach ($certs as $cert) {
147
-			$file = $path . '/uploads/' . $cert->getName();
147
+			$file = $path.'/uploads/'.$cert->getName();
148 148
 			$data = $this->view->file_get_contents($file);
149 149
 			if (strpos($data, 'BEGIN CERTIFICATE')) {
150 150
 				fwrite($fhCerts, $data);
@@ -181,13 +181,13 @@  discard block
 block discarded – undo
181 181
 		}
182 182
 		$this->bundlePath = null;
183 183
 
184
-		$dir = $this->getPathToCertificates() . 'uploads/';
184
+		$dir = $this->getPathToCertificates().'uploads/';
185 185
 		if (!$this->view->file_exists($dir)) {
186 186
 			$this->view->mkdir($dir);
187 187
 		}
188 188
 
189 189
 		try {
190
-			$file = $dir . $name;
190
+			$file = $dir.$name;
191 191
 			$certificateObject = new Certificate($certificate, $name);
192 192
 			$this->view->file_put_contents($file, $certificate);
193 193
 			$this->createCertificateBundle();
@@ -209,9 +209,9 @@  discard block
 block discarded – undo
209 209
 		}
210 210
 		$this->bundlePath = null;
211 211
 
212
-		$path = $this->getPathToCertificates() . 'uploads/';
213
-		if ($this->view->file_exists($path . $name)) {
214
-			$this->view->unlink($path . $name);
212
+		$path = $this->getPathToCertificates().'uploads/';
213
+		if ($this->view->file_exists($path.$name)) {
214
+			$this->view->unlink($path.$name);
215 215
 			$this->createCertificateBundle();
216 216
 		}
217 217
 		return true;
@@ -223,7 +223,7 @@  discard block
 block discarded – undo
223 223
 	 * @return string
224 224
 	 */
225 225
 	public function getCertificateBundle(): string {
226
-		return $this->getPathToCertificates() . 'rootcerts.crt';
226
+		return $this->getPathToCertificates().'rootcerts.crt';
227 227
 	}
228 228
 
229 229
 	/**
@@ -234,7 +234,7 @@  discard block
 block discarded – undo
234 234
 		try {
235 235
 			if ($this->bundlePath === null) {
236 236
 				if (!$this->hasCertificates()) {
237
-					$this->bundlePath = \OC::$SERVERROOT . '/resources/config/ca-bundle.crt';
237
+					$this->bundlePath = \OC::$SERVERROOT.'/resources/config/ca-bundle.crt';
238 238
 				}
239 239
 
240 240
 				if ($this->needsRebundling()) {
@@ -245,13 +245,13 @@  discard block
 block discarded – undo
245 245
 				$this->bundlePath = $this->view->getLocalFile($certificateBundle) ?: null;
246 246
 
247 247
 				if ($this->bundlePath === null) {
248
-					throw new \RuntimeException('Unable to get certificate bundle "' . $certificateBundle . '".');
248
+					throw new \RuntimeException('Unable to get certificate bundle "'.$certificateBundle.'".');
249 249
 				}
250 250
 			}
251 251
 			return $this->bundlePath;
252 252
 		} catch (\Exception $e) {
253 253
 			$this->logger->error('Failed to get absolute bundle path. Fallback to default ca-bundle.crt', ['exception' => $e]);
254
-			return \OC::$SERVERROOT . '/resources/config/ca-bundle.crt';
254
+			return \OC::$SERVERROOT.'/resources/config/ca-bundle.crt';
255 255
 		}
256 256
 	}
257 257
 
@@ -280,6 +280,6 @@  discard block
 block discarded – undo
280 280
 	 * @return int
281 281
 	 */
282 282
 	protected function getFilemtimeOfCaBundle(): int {
283
-		return filemtime(\OC::$SERVERROOT . '/resources/config/ca-bundle.crt');
283
+		return filemtime(\OC::$SERVERROOT.'/resources/config/ca-bundle.crt');
284 284
 	}
285 285
 }
Please login to merge, or discard this patch.