Passed
Push — master ( 32577f...c1368b )
by Robin
11:13 queued 10s
created
apps/encryption/lib/Controller/SettingsController.php 2 patches
Indentation   +124 added lines, -124 removed lines patch added patch discarded remove patch
@@ -38,129 +38,129 @@
 block discarded – undo
38 38
 
39 39
 class SettingsController extends Controller {
40 40
 
41
-	/** @var IL10N */
42
-	private $l;
43
-
44
-	/** @var IUserManager */
45
-	private $userManager;
46
-
47
-	/** @var IUserSession */
48
-	private $userSession;
49
-
50
-	/** @var KeyManager */
51
-	private $keyManager;
52
-
53
-	/** @var Crypt */
54
-	private $crypt;
55
-
56
-	/** @var Session */
57
-	private $session;
58
-
59
-	/** @var ISession  */
60
-	private $ocSession;
61
-
62
-	/** @var  Util */
63
-	private $util;
64
-
65
-	/**
66
-	 * @param string $AppName
67
-	 * @param IRequest $request
68
-	 * @param IL10N $l10n
69
-	 * @param IUserManager $userManager
70
-	 * @param IUserSession $userSession
71
-	 * @param KeyManager $keyManager
72
-	 * @param Crypt $crypt
73
-	 * @param Session $session
74
-	 * @param ISession $ocSession
75
-	 * @param Util $util
76
-	 */
77
-	public function __construct($AppName,
78
-								IRequest $request,
79
-								IL10N $l10n,
80
-								IUserManager $userManager,
81
-								IUserSession $userSession,
82
-								KeyManager $keyManager,
83
-								Crypt $crypt,
84
-								Session $session,
85
-								ISession $ocSession,
86
-								Util $util
41
+    /** @var IL10N */
42
+    private $l;
43
+
44
+    /** @var IUserManager */
45
+    private $userManager;
46
+
47
+    /** @var IUserSession */
48
+    private $userSession;
49
+
50
+    /** @var KeyManager */
51
+    private $keyManager;
52
+
53
+    /** @var Crypt */
54
+    private $crypt;
55
+
56
+    /** @var Session */
57
+    private $session;
58
+
59
+    /** @var ISession  */
60
+    private $ocSession;
61
+
62
+    /** @var  Util */
63
+    private $util;
64
+
65
+    /**
66
+     * @param string $AppName
67
+     * @param IRequest $request
68
+     * @param IL10N $l10n
69
+     * @param IUserManager $userManager
70
+     * @param IUserSession $userSession
71
+     * @param KeyManager $keyManager
72
+     * @param Crypt $crypt
73
+     * @param Session $session
74
+     * @param ISession $ocSession
75
+     * @param Util $util
76
+     */
77
+    public function __construct($AppName,
78
+                                IRequest $request,
79
+                                IL10N $l10n,
80
+                                IUserManager $userManager,
81
+                                IUserSession $userSession,
82
+                                KeyManager $keyManager,
83
+                                Crypt $crypt,
84
+                                Session $session,
85
+                                ISession $ocSession,
86
+                                Util $util
87 87
 ) {
88
-		parent::__construct($AppName, $request);
89
-		$this->l = $l10n;
90
-		$this->userSession = $userSession;
91
-		$this->userManager = $userManager;
92
-		$this->keyManager = $keyManager;
93
-		$this->crypt = $crypt;
94
-		$this->session = $session;
95
-		$this->ocSession = $ocSession;
96
-		$this->util = $util;
97
-	}
98
-
99
-
100
-	/**
101
-	 * @NoAdminRequired
102
-	 * @UseSession
103
-	 *
104
-	 * @param string $oldPassword
105
-	 * @param string $newPassword
106
-	 * @return DataResponse
107
-	 */
108
-	public function updatePrivateKeyPassword($oldPassword, $newPassword) {
109
-		$result = false;
110
-		$uid = $this->userSession->getUser()->getUID();
111
-		$errorMessage = $this->l->t('Could not update the private key password.');
112
-
113
-		//check if password is correct
114
-		$passwordCorrect = $this->userManager->checkPassword($uid, $newPassword);
115
-		if ($passwordCorrect === false) {
116
-			// if check with uid fails we need to check the password with the login name
117
-			// e.g. in the ldap case. For local user we need to check the password with
118
-			// the uid because in this case the login name is case insensitive
119
-			$loginName = $this->ocSession->get('loginname');
120
-			$passwordCorrect = $this->userManager->checkPassword($loginName, $newPassword);
121
-		}
122
-
123
-		if ($passwordCorrect !== false) {
124
-			$encryptedKey = $this->keyManager->getPrivateKey($uid);
125
-			$decryptedKey = $this->crypt->decryptPrivateKey($encryptedKey, $oldPassword, $uid);
126
-
127
-			if ($decryptedKey) {
128
-				$encryptedKey = $this->crypt->encryptPrivateKey($decryptedKey, $newPassword, $uid);
129
-				$header = $this->crypt->generateHeader();
130
-				if ($encryptedKey) {
131
-					$this->keyManager->setPrivateKey($uid, $header . $encryptedKey);
132
-					$this->session->setPrivateKey($decryptedKey);
133
-					$result = true;
134
-				}
135
-			} else {
136
-				$errorMessage = $this->l->t('The old password was not correct, please try again.');
137
-			}
138
-		} else {
139
-			$errorMessage = $this->l->t('The current log-in password was not correct, please try again.');
140
-		}
141
-
142
-		if ($result === true) {
143
-			$this->session->setStatus(Session::INIT_SUCCESSFUL);
144
-			return new DataResponse(
145
-				['message' => (string) $this->l->t('Private key password successfully updated.')]
146
-			);
147
-		} else {
148
-			return new DataResponse(
149
-				['message' => (string) $errorMessage],
150
-				Http::STATUS_BAD_REQUEST
151
-			);
152
-		}
153
-
154
-	}
155
-
156
-	/**
157
-	 * @UseSession
158
-	 *
159
-	 * @param bool $encryptHomeStorage
160
-	 * @return DataResponse
161
-	 */
162
-	public function setEncryptHomeStorage($encryptHomeStorage) {
163
-		$this->util->setEncryptHomeStorage($encryptHomeStorage);
164
-		return new DataResponse();
165
-	}
88
+        parent::__construct($AppName, $request);
89
+        $this->l = $l10n;
90
+        $this->userSession = $userSession;
91
+        $this->userManager = $userManager;
92
+        $this->keyManager = $keyManager;
93
+        $this->crypt = $crypt;
94
+        $this->session = $session;
95
+        $this->ocSession = $ocSession;
96
+        $this->util = $util;
97
+    }
98
+
99
+
100
+    /**
101
+     * @NoAdminRequired
102
+     * @UseSession
103
+     *
104
+     * @param string $oldPassword
105
+     * @param string $newPassword
106
+     * @return DataResponse
107
+     */
108
+    public function updatePrivateKeyPassword($oldPassword, $newPassword) {
109
+        $result = false;
110
+        $uid = $this->userSession->getUser()->getUID();
111
+        $errorMessage = $this->l->t('Could not update the private key password.');
112
+
113
+        //check if password is correct
114
+        $passwordCorrect = $this->userManager->checkPassword($uid, $newPassword);
115
+        if ($passwordCorrect === false) {
116
+            // if check with uid fails we need to check the password with the login name
117
+            // e.g. in the ldap case. For local user we need to check the password with
118
+            // the uid because in this case the login name is case insensitive
119
+            $loginName = $this->ocSession->get('loginname');
120
+            $passwordCorrect = $this->userManager->checkPassword($loginName, $newPassword);
121
+        }
122
+
123
+        if ($passwordCorrect !== false) {
124
+            $encryptedKey = $this->keyManager->getPrivateKey($uid);
125
+            $decryptedKey = $this->crypt->decryptPrivateKey($encryptedKey, $oldPassword, $uid);
126
+
127
+            if ($decryptedKey) {
128
+                $encryptedKey = $this->crypt->encryptPrivateKey($decryptedKey, $newPassword, $uid);
129
+                $header = $this->crypt->generateHeader();
130
+                if ($encryptedKey) {
131
+                    $this->keyManager->setPrivateKey($uid, $header . $encryptedKey);
132
+                    $this->session->setPrivateKey($decryptedKey);
133
+                    $result = true;
134
+                }
135
+            } else {
136
+                $errorMessage = $this->l->t('The old password was not correct, please try again.');
137
+            }
138
+        } else {
139
+            $errorMessage = $this->l->t('The current log-in password was not correct, please try again.');
140
+        }
141
+
142
+        if ($result === true) {
143
+            $this->session->setStatus(Session::INIT_SUCCESSFUL);
144
+            return new DataResponse(
145
+                ['message' => (string) $this->l->t('Private key password successfully updated.')]
146
+            );
147
+        } else {
148
+            return new DataResponse(
149
+                ['message' => (string) $errorMessage],
150
+                Http::STATUS_BAD_REQUEST
151
+            );
152
+        }
153
+
154
+    }
155
+
156
+    /**
157
+     * @UseSession
158
+     *
159
+     * @param bool $encryptHomeStorage
160
+     * @return DataResponse
161
+     */
162
+    public function setEncryptHomeStorage($encryptHomeStorage) {
163
+        $this->util->setEncryptHomeStorage($encryptHomeStorage);
164
+        return new DataResponse();
165
+    }
166 166
 }
Please login to merge, or discard this patch.
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -128,7 +128,7 @@
 block discarded – undo
128 128
 				$encryptedKey = $this->crypt->encryptPrivateKey($decryptedKey, $newPassword, $uid);
129 129
 				$header = $this->crypt->generateHeader();
130 130
 				if ($encryptedKey) {
131
-					$this->keyManager->setPrivateKey($uid, $header . $encryptedKey);
131
+					$this->keyManager->setPrivateKey($uid, $header.$encryptedKey);
132 132
 					$this->session->setPrivateKey($decryptedKey);
133 133
 					$result = true;
134 134
 				}
Please login to merge, or discard this patch.
apps/encryption/lib/Controller/RecoveryController.php 2 patches
Spacing   +18 added lines, -18 removed lines patch added patch discarded remove patch
@@ -74,36 +74,36 @@  discard block
 block discarded – undo
74 74
 	public function adminRecovery($recoveryPassword, $confirmPassword, $adminEnableRecovery) {
75 75
 		// Check if both passwords are the same
76 76
 		if (empty($recoveryPassword)) {
77
-			$errorMessage = (string)$this->l->t('Missing recovery key password');
77
+			$errorMessage = (string) $this->l->t('Missing recovery key password');
78 78
 			return new DataResponse(['data' => ['message' => $errorMessage]],
79 79
 				Http::STATUS_BAD_REQUEST);
80 80
 		}
81 81
 
82 82
 		if (empty($confirmPassword)) {
83
-			$errorMessage = (string)$this->l->t('Please repeat the recovery key password');
83
+			$errorMessage = (string) $this->l->t('Please repeat the recovery key password');
84 84
 			return new DataResponse(['data' => ['message' => $errorMessage]],
85 85
 				Http::STATUS_BAD_REQUEST);
86 86
 		}
87 87
 
88 88
 		if ($recoveryPassword !== $confirmPassword) {
89
-			$errorMessage = (string)$this->l->t('Repeated recovery key password does not match the provided recovery key password');
89
+			$errorMessage = (string) $this->l->t('Repeated recovery key password does not match the provided recovery key password');
90 90
 			return new DataResponse(['data' => ['message' => $errorMessage]],
91 91
 				Http::STATUS_BAD_REQUEST);
92 92
 		}
93 93
 
94 94
 		if (isset($adminEnableRecovery) && $adminEnableRecovery === '1') {
95 95
 			if ($this->recovery->enableAdminRecovery($recoveryPassword)) {
96
-				return new DataResponse(['data' => ['message' => (string)$this->l->t('Recovery key successfully enabled')]]);
96
+				return new DataResponse(['data' => ['message' => (string) $this->l->t('Recovery key successfully enabled')]]);
97 97
 			}
98
-			return new DataResponse(['data' => ['message' => (string)$this->l->t('Could not enable recovery key. Please check your recovery key password!')]], Http::STATUS_BAD_REQUEST);
98
+			return new DataResponse(['data' => ['message' => (string) $this->l->t('Could not enable recovery key. Please check your recovery key password!')]], Http::STATUS_BAD_REQUEST);
99 99
 		} elseif (isset($adminEnableRecovery) && $adminEnableRecovery === '0') {
100 100
 			if ($this->recovery->disableAdminRecovery($recoveryPassword)) {
101
-				return new DataResponse(['data' => ['message' => (string)$this->l->t('Recovery key successfully disabled')]]);
101
+				return new DataResponse(['data' => ['message' => (string) $this->l->t('Recovery key successfully disabled')]]);
102 102
 			}
103
-			return new DataResponse(['data' => ['message' => (string)$this->l->t('Could not disable recovery key. Please check your recovery key password!')]], Http::STATUS_BAD_REQUEST);
103
+			return new DataResponse(['data' => ['message' => (string) $this->l->t('Could not disable recovery key. Please check your recovery key password!')]], Http::STATUS_BAD_REQUEST);
104 104
 		}
105 105
 		// this response should never be sent but just in case.
106
-		return new DataResponse(['data' => ['message' => (string)$this->l->t('Missing parameters')]], Http::STATUS_BAD_REQUEST);
106
+		return new DataResponse(['data' => ['message' => (string) $this->l->t('Missing parameters')]], Http::STATUS_BAD_REQUEST);
107 107
 	}
108 108
 
109 109
 	/**
@@ -115,22 +115,22 @@  discard block
 block discarded – undo
115 115
 	public function changeRecoveryPassword($newPassword, $oldPassword, $confirmPassword) {
116 116
 		//check if both passwords are the same
117 117
 		if (empty($oldPassword)) {
118
-			$errorMessage = (string)$this->l->t('Please provide the old recovery password');
118
+			$errorMessage = (string) $this->l->t('Please provide the old recovery password');
119 119
 			return new DataResponse(['data' => ['message' => $errorMessage]], Http::STATUS_BAD_REQUEST);
120 120
 		}
121 121
 
122 122
 		if (empty($newPassword)) {
123
-			$errorMessage = (string)$this->l->t('Please provide a new recovery password');
124
-			return new DataResponse (['data' => ['message' => $errorMessage]], Http::STATUS_BAD_REQUEST);
123
+			$errorMessage = (string) $this->l->t('Please provide a new recovery password');
124
+			return new DataResponse(['data' => ['message' => $errorMessage]], Http::STATUS_BAD_REQUEST);
125 125
 		}
126 126
 
127 127
 		if (empty($confirmPassword)) {
128
-			$errorMessage = (string)$this->l->t('Please repeat the new recovery password');
128
+			$errorMessage = (string) $this->l->t('Please repeat the new recovery password');
129 129
 			return new DataResponse(['data' => ['message' => $errorMessage]], Http::STATUS_BAD_REQUEST);
130 130
 		}
131 131
 
132 132
 		if ($newPassword !== $confirmPassword) {
133
-			$errorMessage = (string)$this->l->t('Repeated recovery key password does not match the provided recovery key password');
133
+			$errorMessage = (string) $this->l->t('Repeated recovery key password does not match the provided recovery key password');
134 134
 			return new DataResponse(['data' => ['message' => $errorMessage]], Http::STATUS_BAD_REQUEST);
135 135
 		}
136 136
 
@@ -141,14 +141,14 @@  discard block
 block discarded – undo
141 141
 			return new DataResponse(
142 142
 				[
143 143
 					'data' => [
144
-						'message' => (string)$this->l->t('Password successfully changed.')]
144
+						'message' => (string) $this->l->t('Password successfully changed.')]
145 145
 				]
146 146
 			);
147 147
 		}
148 148
 		return new DataResponse(
149 149
 			[
150 150
 				'data' => [
151
-					'message' => (string)$this->l->t('Could not change the password. Maybe the old password was not correct.')
151
+					'message' => (string) $this->l->t('Could not change the password. Maybe the old password was not correct.')
152 152
 				]
153 153
 			], Http::STATUS_BAD_REQUEST);
154 154
 	}
@@ -169,14 +169,14 @@  discard block
 block discarded – undo
169 169
 					return new DataResponse(
170 170
 						[
171 171
 							'data' => [
172
-								'message' => (string)$this->l->t('Recovery Key disabled')]
172
+								'message' => (string) $this->l->t('Recovery Key disabled')]
173 173
 						]
174 174
 					);
175 175
 				}
176 176
 				return new DataResponse(
177 177
 					[
178 178
 						'data' => [
179
-							'message' => (string)$this->l->t('Recovery Key enabled')]
179
+							'message' => (string) $this->l->t('Recovery Key enabled')]
180 180
 					]
181 181
 				);
182 182
 			}
@@ -185,7 +185,7 @@  discard block
 block discarded – undo
185 185
 		return new DataResponse(
186 186
 			[
187 187
 				'data' => [
188
-					'message' => (string)$this->l->t('Could not enable the recovery key, please try again or contact your administrator')
188
+					'message' => (string) $this->l->t('Could not enable the recovery key, please try again or contact your administrator')
189 189
 				]
190 190
 			], Http::STATUS_BAD_REQUEST);
191 191
 	}
Please login to merge, or discard this patch.
Indentation   +155 added lines, -155 removed lines patch added patch discarded remove patch
@@ -34,160 +34,160 @@
 block discarded – undo
34 34
 use OCP\IRequest;
35 35
 
36 36
 class RecoveryController extends Controller {
37
-	/**
38
-	 * @var IConfig
39
-	 */
40
-	private $config;
41
-	/**
42
-	 * @var IL10N
43
-	 */
44
-	private $l;
45
-	/**
46
-	 * @var Recovery
47
-	 */
48
-	private $recovery;
49
-
50
-	/**
51
-	 * @param string $AppName
52
-	 * @param IRequest $request
53
-	 * @param IConfig $config
54
-	 * @param IL10N $l10n
55
-	 * @param Recovery $recovery
56
-	 */
57
-	public function __construct($AppName,
58
-								IRequest $request,
59
-								IConfig $config,
60
-								IL10N $l10n,
61
-								Recovery $recovery) {
62
-		parent::__construct($AppName, $request);
63
-		$this->config = $config;
64
-		$this->l = $l10n;
65
-		$this->recovery = $recovery;
66
-	}
67
-
68
-	/**
69
-	 * @param string $recoveryPassword
70
-	 * @param string $confirmPassword
71
-	 * @param string $adminEnableRecovery
72
-	 * @return DataResponse
73
-	 */
74
-	public function adminRecovery($recoveryPassword, $confirmPassword, $adminEnableRecovery) {
75
-		// Check if both passwords are the same
76
-		if (empty($recoveryPassword)) {
77
-			$errorMessage = (string)$this->l->t('Missing recovery key password');
78
-			return new DataResponse(['data' => ['message' => $errorMessage]],
79
-				Http::STATUS_BAD_REQUEST);
80
-		}
81
-
82
-		if (empty($confirmPassword)) {
83
-			$errorMessage = (string)$this->l->t('Please repeat the recovery key password');
84
-			return new DataResponse(['data' => ['message' => $errorMessage]],
85
-				Http::STATUS_BAD_REQUEST);
86
-		}
87
-
88
-		if ($recoveryPassword !== $confirmPassword) {
89
-			$errorMessage = (string)$this->l->t('Repeated recovery key password does not match the provided recovery key password');
90
-			return new DataResponse(['data' => ['message' => $errorMessage]],
91
-				Http::STATUS_BAD_REQUEST);
92
-		}
93
-
94
-		if (isset($adminEnableRecovery) && $adminEnableRecovery === '1') {
95
-			if ($this->recovery->enableAdminRecovery($recoveryPassword)) {
96
-				return new DataResponse(['data' => ['message' => (string)$this->l->t('Recovery key successfully enabled')]]);
97
-			}
98
-			return new DataResponse(['data' => ['message' => (string)$this->l->t('Could not enable recovery key. Please check your recovery key password!')]], Http::STATUS_BAD_REQUEST);
99
-		} elseif (isset($adminEnableRecovery) && $adminEnableRecovery === '0') {
100
-			if ($this->recovery->disableAdminRecovery($recoveryPassword)) {
101
-				return new DataResponse(['data' => ['message' => (string)$this->l->t('Recovery key successfully disabled')]]);
102
-			}
103
-			return new DataResponse(['data' => ['message' => (string)$this->l->t('Could not disable recovery key. Please check your recovery key password!')]], Http::STATUS_BAD_REQUEST);
104
-		}
105
-		// this response should never be sent but just in case.
106
-		return new DataResponse(['data' => ['message' => (string)$this->l->t('Missing parameters')]], Http::STATUS_BAD_REQUEST);
107
-	}
108
-
109
-	/**
110
-	 * @param string $newPassword
111
-	 * @param string $oldPassword
112
-	 * @param string $confirmPassword
113
-	 * @return DataResponse
114
-	 */
115
-	public function changeRecoveryPassword($newPassword, $oldPassword, $confirmPassword) {
116
-		//check if both passwords are the same
117
-		if (empty($oldPassword)) {
118
-			$errorMessage = (string)$this->l->t('Please provide the old recovery password');
119
-			return new DataResponse(['data' => ['message' => $errorMessage]], Http::STATUS_BAD_REQUEST);
120
-		}
121
-
122
-		if (empty($newPassword)) {
123
-			$errorMessage = (string)$this->l->t('Please provide a new recovery password');
124
-			return new DataResponse (['data' => ['message' => $errorMessage]], Http::STATUS_BAD_REQUEST);
125
-		}
126
-
127
-		if (empty($confirmPassword)) {
128
-			$errorMessage = (string)$this->l->t('Please repeat the new recovery password');
129
-			return new DataResponse(['data' => ['message' => $errorMessage]], Http::STATUS_BAD_REQUEST);
130
-		}
131
-
132
-		if ($newPassword !== $confirmPassword) {
133
-			$errorMessage = (string)$this->l->t('Repeated recovery key password does not match the provided recovery key password');
134
-			return new DataResponse(['data' => ['message' => $errorMessage]], Http::STATUS_BAD_REQUEST);
135
-		}
136
-
137
-		$result = $this->recovery->changeRecoveryKeyPassword($newPassword,
138
-			$oldPassword);
139
-
140
-		if ($result) {
141
-			return new DataResponse(
142
-				[
143
-					'data' => [
144
-						'message' => (string)$this->l->t('Password successfully changed.')]
145
-				]
146
-			);
147
-		}
148
-		return new DataResponse(
149
-			[
150
-				'data' => [
151
-					'message' => (string)$this->l->t('Could not change the password. Maybe the old password was not correct.')
152
-				]
153
-			], Http::STATUS_BAD_REQUEST);
154
-	}
155
-
156
-	/**
157
-	 * @NoAdminRequired
158
-	 *
159
-	 * @param string $userEnableRecovery
160
-	 * @return DataResponse
161
-	 */
162
-	public function userSetRecovery($userEnableRecovery) {
163
-		if ($userEnableRecovery === '0' || $userEnableRecovery === '1') {
164
-
165
-			$result = $this->recovery->setRecoveryForUser($userEnableRecovery);
166
-
167
-			if ($result) {
168
-				if ($userEnableRecovery === '0') {
169
-					return new DataResponse(
170
-						[
171
-							'data' => [
172
-								'message' => (string)$this->l->t('Recovery Key disabled')]
173
-						]
174
-					);
175
-				}
176
-				return new DataResponse(
177
-					[
178
-						'data' => [
179
-							'message' => (string)$this->l->t('Recovery Key enabled')]
180
-					]
181
-				);
182
-			}
183
-
184
-		}
185
-		return new DataResponse(
186
-			[
187
-				'data' => [
188
-					'message' => (string)$this->l->t('Could not enable the recovery key, please try again or contact your administrator')
189
-				]
190
-			], Http::STATUS_BAD_REQUEST);
191
-	}
37
+    /**
38
+     * @var IConfig
39
+     */
40
+    private $config;
41
+    /**
42
+     * @var IL10N
43
+     */
44
+    private $l;
45
+    /**
46
+     * @var Recovery
47
+     */
48
+    private $recovery;
49
+
50
+    /**
51
+     * @param string $AppName
52
+     * @param IRequest $request
53
+     * @param IConfig $config
54
+     * @param IL10N $l10n
55
+     * @param Recovery $recovery
56
+     */
57
+    public function __construct($AppName,
58
+                                IRequest $request,
59
+                                IConfig $config,
60
+                                IL10N $l10n,
61
+                                Recovery $recovery) {
62
+        parent::__construct($AppName, $request);
63
+        $this->config = $config;
64
+        $this->l = $l10n;
65
+        $this->recovery = $recovery;
66
+    }
67
+
68
+    /**
69
+     * @param string $recoveryPassword
70
+     * @param string $confirmPassword
71
+     * @param string $adminEnableRecovery
72
+     * @return DataResponse
73
+     */
74
+    public function adminRecovery($recoveryPassword, $confirmPassword, $adminEnableRecovery) {
75
+        // Check if both passwords are the same
76
+        if (empty($recoveryPassword)) {
77
+            $errorMessage = (string)$this->l->t('Missing recovery key password');
78
+            return new DataResponse(['data' => ['message' => $errorMessage]],
79
+                Http::STATUS_BAD_REQUEST);
80
+        }
81
+
82
+        if (empty($confirmPassword)) {
83
+            $errorMessage = (string)$this->l->t('Please repeat the recovery key password');
84
+            return new DataResponse(['data' => ['message' => $errorMessage]],
85
+                Http::STATUS_BAD_REQUEST);
86
+        }
87
+
88
+        if ($recoveryPassword !== $confirmPassword) {
89
+            $errorMessage = (string)$this->l->t('Repeated recovery key password does not match the provided recovery key password');
90
+            return new DataResponse(['data' => ['message' => $errorMessage]],
91
+                Http::STATUS_BAD_REQUEST);
92
+        }
93
+
94
+        if (isset($adminEnableRecovery) && $adminEnableRecovery === '1') {
95
+            if ($this->recovery->enableAdminRecovery($recoveryPassword)) {
96
+                return new DataResponse(['data' => ['message' => (string)$this->l->t('Recovery key successfully enabled')]]);
97
+            }
98
+            return new DataResponse(['data' => ['message' => (string)$this->l->t('Could not enable recovery key. Please check your recovery key password!')]], Http::STATUS_BAD_REQUEST);
99
+        } elseif (isset($adminEnableRecovery) && $adminEnableRecovery === '0') {
100
+            if ($this->recovery->disableAdminRecovery($recoveryPassword)) {
101
+                return new DataResponse(['data' => ['message' => (string)$this->l->t('Recovery key successfully disabled')]]);
102
+            }
103
+            return new DataResponse(['data' => ['message' => (string)$this->l->t('Could not disable recovery key. Please check your recovery key password!')]], Http::STATUS_BAD_REQUEST);
104
+        }
105
+        // this response should never be sent but just in case.
106
+        return new DataResponse(['data' => ['message' => (string)$this->l->t('Missing parameters')]], Http::STATUS_BAD_REQUEST);
107
+    }
108
+
109
+    /**
110
+     * @param string $newPassword
111
+     * @param string $oldPassword
112
+     * @param string $confirmPassword
113
+     * @return DataResponse
114
+     */
115
+    public function changeRecoveryPassword($newPassword, $oldPassword, $confirmPassword) {
116
+        //check if both passwords are the same
117
+        if (empty($oldPassword)) {
118
+            $errorMessage = (string)$this->l->t('Please provide the old recovery password');
119
+            return new DataResponse(['data' => ['message' => $errorMessage]], Http::STATUS_BAD_REQUEST);
120
+        }
121
+
122
+        if (empty($newPassword)) {
123
+            $errorMessage = (string)$this->l->t('Please provide a new recovery password');
124
+            return new DataResponse (['data' => ['message' => $errorMessage]], Http::STATUS_BAD_REQUEST);
125
+        }
126
+
127
+        if (empty($confirmPassword)) {
128
+            $errorMessage = (string)$this->l->t('Please repeat the new recovery password');
129
+            return new DataResponse(['data' => ['message' => $errorMessage]], Http::STATUS_BAD_REQUEST);
130
+        }
131
+
132
+        if ($newPassword !== $confirmPassword) {
133
+            $errorMessage = (string)$this->l->t('Repeated recovery key password does not match the provided recovery key password');
134
+            return new DataResponse(['data' => ['message' => $errorMessage]], Http::STATUS_BAD_REQUEST);
135
+        }
136
+
137
+        $result = $this->recovery->changeRecoveryKeyPassword($newPassword,
138
+            $oldPassword);
139
+
140
+        if ($result) {
141
+            return new DataResponse(
142
+                [
143
+                    'data' => [
144
+                        'message' => (string)$this->l->t('Password successfully changed.')]
145
+                ]
146
+            );
147
+        }
148
+        return new DataResponse(
149
+            [
150
+                'data' => [
151
+                    'message' => (string)$this->l->t('Could not change the password. Maybe the old password was not correct.')
152
+                ]
153
+            ], Http::STATUS_BAD_REQUEST);
154
+    }
155
+
156
+    /**
157
+     * @NoAdminRequired
158
+     *
159
+     * @param string $userEnableRecovery
160
+     * @return DataResponse
161
+     */
162
+    public function userSetRecovery($userEnableRecovery) {
163
+        if ($userEnableRecovery === '0' || $userEnableRecovery === '1') {
164
+
165
+            $result = $this->recovery->setRecoveryForUser($userEnableRecovery);
166
+
167
+            if ($result) {
168
+                if ($userEnableRecovery === '0') {
169
+                    return new DataResponse(
170
+                        [
171
+                            'data' => [
172
+                                'message' => (string)$this->l->t('Recovery Key disabled')]
173
+                        ]
174
+                    );
175
+                }
176
+                return new DataResponse(
177
+                    [
178
+                        'data' => [
179
+                            'message' => (string)$this->l->t('Recovery Key enabled')]
180
+                    ]
181
+                );
182
+            }
183
+
184
+        }
185
+        return new DataResponse(
186
+            [
187
+                'data' => [
188
+                    'message' => (string)$this->l->t('Could not enable the recovery key, please try again or contact your administrator')
189
+                ]
190
+            ], Http::STATUS_BAD_REQUEST);
191
+    }
192 192
 
193 193
 }
Please login to merge, or discard this patch.
apps/encryption/lib/Exceptions/PublicKeyMissingException.php 2 patches
Indentation   +9 added lines, -9 removed lines patch added patch discarded remove patch
@@ -25,14 +25,14 @@
 block discarded – undo
25 25
 
26 26
 class PublicKeyMissingException extends GenericEncryptionException {
27 27
 
28
-	/**
29
-	 * @param string $userId
30
-	 */
31
-	public function __construct($userId) {
32
-		if(empty($userId)) {
33
-			$userId = "<no-user-id-given>";
34
-		}
35
-		parent::__construct("Public Key missing for user: $userId");
36
-	}
28
+    /**
29
+     * @param string $userId
30
+     */
31
+    public function __construct($userId) {
32
+        if(empty($userId)) {
33
+            $userId = "<no-user-id-given>";
34
+        }
35
+        parent::__construct("Public Key missing for user: $userId");
36
+    }
37 37
 
38 38
 }
Please login to merge, or discard this patch.
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -29,7 +29,7 @@
 block discarded – undo
29 29
 	 * @param string $userId
30 30
 	 */
31 31
 	public function __construct($userId) {
32
-		if(empty($userId)) {
32
+		if (empty($userId)) {
33 33
 			$userId = "<no-user-id-given>";
34 34
 		}
35 35
 		parent::__construct("Public Key missing for user: $userId");
Please login to merge, or discard this patch.
apps/encryption/lib/Exceptions/PrivateKeyMissingException.php 2 patches
Indentation   +9 added lines, -9 removed lines patch added patch discarded remove patch
@@ -28,14 +28,14 @@
 block discarded – undo
28 28
 
29 29
 class PrivateKeyMissingException extends GenericEncryptionException {
30 30
 
31
-	/**
32
-	 * @param string $userId
33
-	 */
34
-	public function __construct($userId) {
35
-		if(empty($userId)) {
36
-			$userId = "<no-user-id-given>";
37
-		}
38
-		parent::__construct("Private Key missing for user: $userId");
39
-	}
31
+    /**
32
+     * @param string $userId
33
+     */
34
+    public function __construct($userId) {
35
+        if(empty($userId)) {
36
+            $userId = "<no-user-id-given>";
37
+        }
38
+        parent::__construct("Private Key missing for user: $userId");
39
+    }
40 40
 
41 41
 }
Please login to merge, or discard this patch.
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -32,7 +32,7 @@
 block discarded – undo
32 32
 	 * @param string $userId
33 33
 	 */
34 34
 	public function __construct($userId) {
35
-		if(empty($userId)) {
35
+		if (empty($userId)) {
36 36
 			$userId = "<no-user-id-given>";
37 37
 		}
38 38
 		parent::__construct("Private Key missing for user: $userId");
Please login to merge, or discard this patch.
apps/encryption/lib/Recovery.php 2 patches
Spacing   +10 added lines, -10 removed lines patch added patch discarded remove patch
@@ -109,7 +109,7 @@  discard block
 block discarded – undo
109 109
 
110 110
 		if (!$keyManager->recoveryKeyExists()) {
111 111
 			$keyPair = $this->crypt->createKeyPair();
112
-			if(!is_array($keyPair)) {
112
+			if (!is_array($keyPair)) {
113 113
 				return false;
114 114
 			}
115 115
 
@@ -134,13 +134,13 @@  discard block
 block discarded – undo
134 134
 	public function changeRecoveryKeyPassword($newPassword, $oldPassword) {
135 135
 		$recoveryKey = $this->keyManager->getSystemPrivateKey($this->keyManager->getRecoveryKeyId());
136 136
 		$decryptedRecoveryKey = $this->crypt->decryptPrivateKey($recoveryKey, $oldPassword);
137
-		if($decryptedRecoveryKey === false) {
137
+		if ($decryptedRecoveryKey === false) {
138 138
 			return false;
139 139
 		}
140 140
 		$encryptedRecoveryKey = $this->crypt->encryptPrivateKey($decryptedRecoveryKey, $newPassword);
141 141
 		$header = $this->crypt->generateHeader();
142 142
 		if ($encryptedRecoveryKey) {
143
-			$this->keyManager->setSystemPrivateKey($this->keyManager->getRecoveryKeyId(), $header . $encryptedRecoveryKey);
143
+			$this->keyManager->setSystemPrivateKey($this->keyManager->getRecoveryKeyId(), $header.$encryptedRecoveryKey);
144 144
 			return true;
145 145
 		}
146 146
 		return false;
@@ -202,9 +202,9 @@  discard block
 block discarded – undo
202 202
 				$value);
203 203
 
204 204
 			if ($value === '1') {
205
-				$this->addRecoveryKeys('/' . $this->user->getUID() . '/files/');
205
+				$this->addRecoveryKeys('/'.$this->user->getUID().'/files/');
206 206
 			} else {
207
-				$this->removeRecoveryKeys('/' . $this->user->getUID() . '/files/');
207
+				$this->removeRecoveryKeys('/'.$this->user->getUID().'/files/');
208 208
 			}
209 209
 
210 210
 			return true;
@@ -222,7 +222,7 @@  discard block
 block discarded – undo
222 222
 		foreach ($dirContent as $item) {
223 223
 			$filePath = $item->getPath();
224 224
 			if ($item['type'] === 'dir') {
225
-				$this->addRecoveryKeys($filePath . '/');
225
+				$this->addRecoveryKeys($filePath.'/');
226 226
 			} else {
227 227
 				$fileKey = $this->keyManager->getFileKey($filePath, $this->user->getUID());
228 228
 				if (!empty($fileKey)) {
@@ -250,7 +250,7 @@  discard block
 block discarded – undo
250 250
 		foreach ($dirContent as $item) {
251 251
 			$filePath = $item->getPath();
252 252
 			if ($item['type'] === 'dir') {
253
-				$this->removeRecoveryKeys($filePath . '/');
253
+				$this->removeRecoveryKeys($filePath.'/');
254 254
 			} else {
255 255
 				$this->keyManager->deleteShareKey($filePath, $this->keyManager->getRecoveryKeyId());
256 256
 			}
@@ -267,8 +267,8 @@  discard block
 block discarded – undo
267 267
 		$encryptedKey = $this->keyManager->getSystemPrivateKey($this->keyManager->getRecoveryKeyId());
268 268
 
269 269
 		$privateKey = $this->crypt->decryptPrivateKey($encryptedKey, $recoveryPassword);
270
-		if($privateKey !== false) {
271
-			$this->recoverAllFiles('/' . $user . '/files/', $privateKey, $user);
270
+		if ($privateKey !== false) {
271
+			$this->recoverAllFiles('/'.$user.'/files/', $privateKey, $user);
272 272
 		}
273 273
 	}
274 274
 
@@ -286,7 +286,7 @@  discard block
 block discarded – undo
286 286
 			// Get relative path from encryption/keyfiles
287 287
 			$filePath = $item->getPath();
288 288
 			if ($this->view->is_dir($filePath)) {
289
-				$this->recoverAllFiles($filePath . '/', $privateKey, $uid);
289
+				$this->recoverAllFiles($filePath.'/', $privateKey, $uid);
290 290
 			} else {
291 291
 				$this->recoverFile($filePath, $privateKey, $uid);
292 292
 			}
Please login to merge, or discard this patch.
Indentation   +273 added lines, -273 removed lines patch added patch discarded remove patch
@@ -38,279 +38,279 @@
 block discarded – undo
38 38
 class Recovery {
39 39
 
40 40
 
41
-	/**
42
-	 * @var null|IUser
43
-	 */
44
-	protected $user;
45
-	/**
46
-	 * @var Crypt
47
-	 */
48
-	protected $crypt;
49
-	/**
50
-	 * @var KeyManager
51
-	 */
52
-	private $keyManager;
53
-	/**
54
-	 * @var IConfig
55
-	 */
56
-	private $config;
57
-	/**
58
-	 * @var View
59
-	 */
60
-	private $view;
61
-	/**
62
-	 * @var IFile
63
-	 */
64
-	private $file;
65
-
66
-	/**
67
-	 * @param IUserSession $userSession
68
-	 * @param Crypt $crypt
69
-	 * @param KeyManager $keyManager
70
-	 * @param IConfig $config
71
-	 * @param IFile $file
72
-	 * @param View $view
73
-	 */
74
-	public function __construct(IUserSession $userSession,
75
-								Crypt $crypt,
76
-								KeyManager $keyManager,
77
-								IConfig $config,
78
-								IFile $file,
79
-								View $view) {
80
-		$this->user = ($userSession && $userSession->isLoggedIn()) ? $userSession->getUser() : false;
81
-		$this->crypt = $crypt;
82
-		$this->keyManager = $keyManager;
83
-		$this->config = $config;
84
-		$this->view = $view;
85
-		$this->file = $file;
86
-	}
87
-
88
-	/**
89
-	 * @param string $password
90
-	 * @return bool
91
-	 */
92
-	public function enableAdminRecovery($password) {
93
-		$appConfig = $this->config;
94
-		$keyManager = $this->keyManager;
95
-
96
-		if (!$keyManager->recoveryKeyExists()) {
97
-			$keyPair = $this->crypt->createKeyPair();
98
-			if(!is_array($keyPair)) {
99
-				return false;
100
-			}
101
-
102
-			$this->keyManager->setRecoveryKey($password, $keyPair);
103
-		}
104
-
105
-		if ($keyManager->checkRecoveryPassword($password)) {
106
-			$appConfig->setAppValue('encryption', 'recoveryAdminEnabled', 1);
107
-			return true;
108
-		}
109
-
110
-		return false;
111
-	}
112
-
113
-	/**
114
-	 * change recovery key id
115
-	 *
116
-	 * @param string $newPassword
117
-	 * @param string $oldPassword
118
-	 * @return bool
119
-	 */
120
-	public function changeRecoveryKeyPassword($newPassword, $oldPassword) {
121
-		$recoveryKey = $this->keyManager->getSystemPrivateKey($this->keyManager->getRecoveryKeyId());
122
-		$decryptedRecoveryKey = $this->crypt->decryptPrivateKey($recoveryKey, $oldPassword);
123
-		if($decryptedRecoveryKey === false) {
124
-			return false;
125
-		}
126
-		$encryptedRecoveryKey = $this->crypt->encryptPrivateKey($decryptedRecoveryKey, $newPassword);
127
-		$header = $this->crypt->generateHeader();
128
-		if ($encryptedRecoveryKey) {
129
-			$this->keyManager->setSystemPrivateKey($this->keyManager->getRecoveryKeyId(), $header . $encryptedRecoveryKey);
130
-			return true;
131
-		}
132
-		return false;
133
-	}
134
-
135
-	/**
136
-	 * @param string $recoveryPassword
137
-	 * @return bool
138
-	 */
139
-	public function disableAdminRecovery($recoveryPassword) {
140
-		$keyManager = $this->keyManager;
141
-
142
-		if ($keyManager->checkRecoveryPassword($recoveryPassword)) {
143
-			// Set recoveryAdmin as disabled
144
-			$this->config->setAppValue('encryption', 'recoveryAdminEnabled', 0);
145
-			return true;
146
-		}
147
-		return false;
148
-	}
149
-
150
-	/**
151
-	 * check if recovery is enabled for user
152
-	 *
153
-	 * @param string $user if no user is given we check the current logged-in user
154
-	 *
155
-	 * @return bool
156
-	 */
157
-	public function isRecoveryEnabledForUser($user = '') {
158
-		$uid = $user === '' ? $this->user->getUID() : $user;
159
-		$recoveryMode = $this->config->getUserValue($uid,
160
-			'encryption',
161
-			'recoveryEnabled',
162
-			0);
163
-
164
-		return ($recoveryMode === '1');
165
-	}
166
-
167
-	/**
168
-	 * check if recovery is key is enabled by the administrator
169
-	 *
170
-	 * @return bool
171
-	 */
172
-	public function isRecoveryKeyEnabled() {
173
-		$enabled = $this->config->getAppValue('encryption', 'recoveryAdminEnabled', 0);
174
-
175
-		return ($enabled === '1');
176
-	}
177
-
178
-	/**
179
-	 * @param string $value
180
-	 * @return bool
181
-	 */
182
-	public function setRecoveryForUser($value) {
183
-
184
-		try {
185
-			$this->config->setUserValue($this->user->getUID(),
186
-				'encryption',
187
-				'recoveryEnabled',
188
-				$value);
189
-
190
-			if ($value === '1') {
191
-				$this->addRecoveryKeys('/' . $this->user->getUID() . '/files/');
192
-			} else {
193
-				$this->removeRecoveryKeys('/' . $this->user->getUID() . '/files/');
194
-			}
195
-
196
-			return true;
197
-		} catch (PreConditionNotMetException $e) {
198
-			return false;
199
-		}
200
-	}
201
-
202
-	/**
203
-	 * add recovery key to all encrypted files
204
-	 * @param string $path
205
-	 */
206
-	private function addRecoveryKeys($path) {
207
-		$dirContent = $this->view->getDirectoryContent($path);
208
-		foreach ($dirContent as $item) {
209
-			$filePath = $item->getPath();
210
-			if ($item['type'] === 'dir') {
211
-				$this->addRecoveryKeys($filePath . '/');
212
-			} else {
213
-				$fileKey = $this->keyManager->getFileKey($filePath, $this->user->getUID());
214
-				if (!empty($fileKey)) {
215
-					$accessList = $this->file->getAccessList($filePath);
216
-					$publicKeys = [];
217
-					foreach ($accessList['users'] as $uid) {
218
-						$publicKeys[$uid] = $this->keyManager->getPublicKey($uid);
219
-					}
220
-
221
-					$publicKeys = $this->keyManager->addSystemKeys($accessList, $publicKeys, $this->user->getUID());
222
-
223
-					$encryptedKeyfiles = $this->crypt->multiKeyEncrypt($fileKey, $publicKeys);
224
-					$this->keyManager->setAllFileKeys($filePath, $encryptedKeyfiles);
225
-				}
226
-			}
227
-		}
228
-	}
229
-
230
-	/**
231
-	 * remove recovery key to all encrypted files
232
-	 * @param string $path
233
-	 */
234
-	private function removeRecoveryKeys($path) {
235
-		$dirContent = $this->view->getDirectoryContent($path);
236
-		foreach ($dirContent as $item) {
237
-			$filePath = $item->getPath();
238
-			if ($item['type'] === 'dir') {
239
-				$this->removeRecoveryKeys($filePath . '/');
240
-			} else {
241
-				$this->keyManager->deleteShareKey($filePath, $this->keyManager->getRecoveryKeyId());
242
-			}
243
-		}
244
-	}
245
-
246
-	/**
247
-	 * recover users files with the recovery key
248
-	 *
249
-	 * @param string $recoveryPassword
250
-	 * @param string $user
251
-	 */
252
-	public function recoverUsersFiles($recoveryPassword, $user) {
253
-		$encryptedKey = $this->keyManager->getSystemPrivateKey($this->keyManager->getRecoveryKeyId());
254
-
255
-		$privateKey = $this->crypt->decryptPrivateKey($encryptedKey, $recoveryPassword);
256
-		if($privateKey !== false) {
257
-			$this->recoverAllFiles('/' . $user . '/files/', $privateKey, $user);
258
-		}
259
-	}
260
-
261
-	/**
262
-	 * recover users files
263
-	 *
264
-	 * @param string $path
265
-	 * @param string $privateKey
266
-	 * @param string $uid
267
-	 */
268
-	private function recoverAllFiles($path, $privateKey, $uid) {
269
-		$dirContent = $this->view->getDirectoryContent($path);
270
-
271
-		foreach ($dirContent as $item) {
272
-			// Get relative path from encryption/keyfiles
273
-			$filePath = $item->getPath();
274
-			if ($this->view->is_dir($filePath)) {
275
-				$this->recoverAllFiles($filePath . '/', $privateKey, $uid);
276
-			} else {
277
-				$this->recoverFile($filePath, $privateKey, $uid);
278
-			}
279
-		}
280
-
281
-	}
282
-
283
-	/**
284
-	 * recover file
285
-	 *
286
-	 * @param string $path
287
-	 * @param string $privateKey
288
-	 * @param string $uid
289
-	 */
290
-	private function recoverFile($path, $privateKey, $uid) {
291
-		$encryptedFileKey = $this->keyManager->getEncryptedFileKey($path);
292
-		$shareKey = $this->keyManager->getShareKey($path, $this->keyManager->getRecoveryKeyId());
293
-
294
-		if ($encryptedFileKey && $shareKey && $privateKey) {
295
-			$fileKey = $this->crypt->multiKeyDecrypt($encryptedFileKey,
296
-				$shareKey,
297
-				$privateKey);
298
-		}
299
-
300
-		if (!empty($fileKey)) {
301
-			$accessList = $this->file->getAccessList($path);
302
-			$publicKeys = [];
303
-			foreach ($accessList['users'] as $user) {
304
-				$publicKeys[$user] = $this->keyManager->getPublicKey($user);
305
-			}
306
-
307
-			$publicKeys = $this->keyManager->addSystemKeys($accessList, $publicKeys, $uid);
308
-
309
-			$encryptedKeyfiles = $this->crypt->multiKeyEncrypt($fileKey, $publicKeys);
310
-			$this->keyManager->setAllFileKeys($path, $encryptedKeyfiles);
311
-		}
312
-
313
-	}
41
+    /**
42
+     * @var null|IUser
43
+     */
44
+    protected $user;
45
+    /**
46
+     * @var Crypt
47
+     */
48
+    protected $crypt;
49
+    /**
50
+     * @var KeyManager
51
+     */
52
+    private $keyManager;
53
+    /**
54
+     * @var IConfig
55
+     */
56
+    private $config;
57
+    /**
58
+     * @var View
59
+     */
60
+    private $view;
61
+    /**
62
+     * @var IFile
63
+     */
64
+    private $file;
65
+
66
+    /**
67
+     * @param IUserSession $userSession
68
+     * @param Crypt $crypt
69
+     * @param KeyManager $keyManager
70
+     * @param IConfig $config
71
+     * @param IFile $file
72
+     * @param View $view
73
+     */
74
+    public function __construct(IUserSession $userSession,
75
+                                Crypt $crypt,
76
+                                KeyManager $keyManager,
77
+                                IConfig $config,
78
+                                IFile $file,
79
+                                View $view) {
80
+        $this->user = ($userSession && $userSession->isLoggedIn()) ? $userSession->getUser() : false;
81
+        $this->crypt = $crypt;
82
+        $this->keyManager = $keyManager;
83
+        $this->config = $config;
84
+        $this->view = $view;
85
+        $this->file = $file;
86
+    }
87
+
88
+    /**
89
+     * @param string $password
90
+     * @return bool
91
+     */
92
+    public function enableAdminRecovery($password) {
93
+        $appConfig = $this->config;
94
+        $keyManager = $this->keyManager;
95
+
96
+        if (!$keyManager->recoveryKeyExists()) {
97
+            $keyPair = $this->crypt->createKeyPair();
98
+            if(!is_array($keyPair)) {
99
+                return false;
100
+            }
101
+
102
+            $this->keyManager->setRecoveryKey($password, $keyPair);
103
+        }
104
+
105
+        if ($keyManager->checkRecoveryPassword($password)) {
106
+            $appConfig->setAppValue('encryption', 'recoveryAdminEnabled', 1);
107
+            return true;
108
+        }
109
+
110
+        return false;
111
+    }
112
+
113
+    /**
114
+     * change recovery key id
115
+     *
116
+     * @param string $newPassword
117
+     * @param string $oldPassword
118
+     * @return bool
119
+     */
120
+    public function changeRecoveryKeyPassword($newPassword, $oldPassword) {
121
+        $recoveryKey = $this->keyManager->getSystemPrivateKey($this->keyManager->getRecoveryKeyId());
122
+        $decryptedRecoveryKey = $this->crypt->decryptPrivateKey($recoveryKey, $oldPassword);
123
+        if($decryptedRecoveryKey === false) {
124
+            return false;
125
+        }
126
+        $encryptedRecoveryKey = $this->crypt->encryptPrivateKey($decryptedRecoveryKey, $newPassword);
127
+        $header = $this->crypt->generateHeader();
128
+        if ($encryptedRecoveryKey) {
129
+            $this->keyManager->setSystemPrivateKey($this->keyManager->getRecoveryKeyId(), $header . $encryptedRecoveryKey);
130
+            return true;
131
+        }
132
+        return false;
133
+    }
134
+
135
+    /**
136
+     * @param string $recoveryPassword
137
+     * @return bool
138
+     */
139
+    public function disableAdminRecovery($recoveryPassword) {
140
+        $keyManager = $this->keyManager;
141
+
142
+        if ($keyManager->checkRecoveryPassword($recoveryPassword)) {
143
+            // Set recoveryAdmin as disabled
144
+            $this->config->setAppValue('encryption', 'recoveryAdminEnabled', 0);
145
+            return true;
146
+        }
147
+        return false;
148
+    }
149
+
150
+    /**
151
+     * check if recovery is enabled for user
152
+     *
153
+     * @param string $user if no user is given we check the current logged-in user
154
+     *
155
+     * @return bool
156
+     */
157
+    public function isRecoveryEnabledForUser($user = '') {
158
+        $uid = $user === '' ? $this->user->getUID() : $user;
159
+        $recoveryMode = $this->config->getUserValue($uid,
160
+            'encryption',
161
+            'recoveryEnabled',
162
+            0);
163
+
164
+        return ($recoveryMode === '1');
165
+    }
166
+
167
+    /**
168
+     * check if recovery is key is enabled by the administrator
169
+     *
170
+     * @return bool
171
+     */
172
+    public function isRecoveryKeyEnabled() {
173
+        $enabled = $this->config->getAppValue('encryption', 'recoveryAdminEnabled', 0);
174
+
175
+        return ($enabled === '1');
176
+    }
177
+
178
+    /**
179
+     * @param string $value
180
+     * @return bool
181
+     */
182
+    public function setRecoveryForUser($value) {
183
+
184
+        try {
185
+            $this->config->setUserValue($this->user->getUID(),
186
+                'encryption',
187
+                'recoveryEnabled',
188
+                $value);
189
+
190
+            if ($value === '1') {
191
+                $this->addRecoveryKeys('/' . $this->user->getUID() . '/files/');
192
+            } else {
193
+                $this->removeRecoveryKeys('/' . $this->user->getUID() . '/files/');
194
+            }
195
+
196
+            return true;
197
+        } catch (PreConditionNotMetException $e) {
198
+            return false;
199
+        }
200
+    }
201
+
202
+    /**
203
+     * add recovery key to all encrypted files
204
+     * @param string $path
205
+     */
206
+    private function addRecoveryKeys($path) {
207
+        $dirContent = $this->view->getDirectoryContent($path);
208
+        foreach ($dirContent as $item) {
209
+            $filePath = $item->getPath();
210
+            if ($item['type'] === 'dir') {
211
+                $this->addRecoveryKeys($filePath . '/');
212
+            } else {
213
+                $fileKey = $this->keyManager->getFileKey($filePath, $this->user->getUID());
214
+                if (!empty($fileKey)) {
215
+                    $accessList = $this->file->getAccessList($filePath);
216
+                    $publicKeys = [];
217
+                    foreach ($accessList['users'] as $uid) {
218
+                        $publicKeys[$uid] = $this->keyManager->getPublicKey($uid);
219
+                    }
220
+
221
+                    $publicKeys = $this->keyManager->addSystemKeys($accessList, $publicKeys, $this->user->getUID());
222
+
223
+                    $encryptedKeyfiles = $this->crypt->multiKeyEncrypt($fileKey, $publicKeys);
224
+                    $this->keyManager->setAllFileKeys($filePath, $encryptedKeyfiles);
225
+                }
226
+            }
227
+        }
228
+    }
229
+
230
+    /**
231
+     * remove recovery key to all encrypted files
232
+     * @param string $path
233
+     */
234
+    private function removeRecoveryKeys($path) {
235
+        $dirContent = $this->view->getDirectoryContent($path);
236
+        foreach ($dirContent as $item) {
237
+            $filePath = $item->getPath();
238
+            if ($item['type'] === 'dir') {
239
+                $this->removeRecoveryKeys($filePath . '/');
240
+            } else {
241
+                $this->keyManager->deleteShareKey($filePath, $this->keyManager->getRecoveryKeyId());
242
+            }
243
+        }
244
+    }
245
+
246
+    /**
247
+     * recover users files with the recovery key
248
+     *
249
+     * @param string $recoveryPassword
250
+     * @param string $user
251
+     */
252
+    public function recoverUsersFiles($recoveryPassword, $user) {
253
+        $encryptedKey = $this->keyManager->getSystemPrivateKey($this->keyManager->getRecoveryKeyId());
254
+
255
+        $privateKey = $this->crypt->decryptPrivateKey($encryptedKey, $recoveryPassword);
256
+        if($privateKey !== false) {
257
+            $this->recoverAllFiles('/' . $user . '/files/', $privateKey, $user);
258
+        }
259
+    }
260
+
261
+    /**
262
+     * recover users files
263
+     *
264
+     * @param string $path
265
+     * @param string $privateKey
266
+     * @param string $uid
267
+     */
268
+    private function recoverAllFiles($path, $privateKey, $uid) {
269
+        $dirContent = $this->view->getDirectoryContent($path);
270
+
271
+        foreach ($dirContent as $item) {
272
+            // Get relative path from encryption/keyfiles
273
+            $filePath = $item->getPath();
274
+            if ($this->view->is_dir($filePath)) {
275
+                $this->recoverAllFiles($filePath . '/', $privateKey, $uid);
276
+            } else {
277
+                $this->recoverFile($filePath, $privateKey, $uid);
278
+            }
279
+        }
280
+
281
+    }
282
+
283
+    /**
284
+     * recover file
285
+     *
286
+     * @param string $path
287
+     * @param string $privateKey
288
+     * @param string $uid
289
+     */
290
+    private function recoverFile($path, $privateKey, $uid) {
291
+        $encryptedFileKey = $this->keyManager->getEncryptedFileKey($path);
292
+        $shareKey = $this->keyManager->getShareKey($path, $this->keyManager->getRecoveryKeyId());
293
+
294
+        if ($encryptedFileKey && $shareKey && $privateKey) {
295
+            $fileKey = $this->crypt->multiKeyDecrypt($encryptedFileKey,
296
+                $shareKey,
297
+                $privateKey);
298
+        }
299
+
300
+        if (!empty($fileKey)) {
301
+            $accessList = $this->file->getAccessList($path);
302
+            $publicKeys = [];
303
+            foreach ($accessList['users'] as $user) {
304
+                $publicKeys[$user] = $this->keyManager->getPublicKey($user);
305
+            }
306
+
307
+            $publicKeys = $this->keyManager->addSystemKeys($accessList, $publicKeys, $uid);
308
+
309
+            $encryptedKeyfiles = $this->crypt->multiKeyEncrypt($fileKey, $publicKeys);
310
+            $this->keyManager->setAllFileKeys($path, $encryptedKeyfiles);
311
+        }
312
+
313
+    }
314 314
 
315 315
 
316 316
 }
Please login to merge, or discard this patch.
apps/encryption/lib/Command/EnableMasterKey.php 2 patches
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -68,7 +68,7 @@
 block discarded – undo
68 68
 
69 69
 		$isAlreadyEnabled = $this->util->isMasterKeyEnabled();
70 70
 
71
-		if($isAlreadyEnabled) {
71
+		if ($isAlreadyEnabled) {
72 72
 			$output->writeln('Master key already enabled');
73 73
 		} else {
74 74
 			$question = new ConfirmationQuestion(
Please login to merge, or discard this patch.
Indentation   +40 added lines, -40 removed lines patch added patch discarded remove patch
@@ -33,54 +33,54 @@
 block discarded – undo
33 33
 
34 34
 class EnableMasterKey extends Command {
35 35
 
36
-	/** @var Util */
37
-	protected $util;
36
+    /** @var Util */
37
+    protected $util;
38 38
 
39
-	/** @var IConfig */
40
-	protected $config;
39
+    /** @var IConfig */
40
+    protected $config;
41 41
 
42
-	/** @var  QuestionHelper */
43
-	protected $questionHelper;
42
+    /** @var  QuestionHelper */
43
+    protected $questionHelper;
44 44
 
45
-	/**
46
-	 * @param Util $util
47
-	 * @param IConfig $config
48
-	 * @param QuestionHelper $questionHelper
49
-	 */
50
-	public function __construct(Util $util,
51
-								IConfig $config,
52
-								QuestionHelper $questionHelper) {
45
+    /**
46
+     * @param Util $util
47
+     * @param IConfig $config
48
+     * @param QuestionHelper $questionHelper
49
+     */
50
+    public function __construct(Util $util,
51
+                                IConfig $config,
52
+                                QuestionHelper $questionHelper) {
53 53
 
54
-		$this->util = $util;
55
-		$this->config = $config;
56
-		$this->questionHelper = $questionHelper;
57
-		parent::__construct();
58
-	}
54
+        $this->util = $util;
55
+        $this->config = $config;
56
+        $this->questionHelper = $questionHelper;
57
+        parent::__construct();
58
+    }
59 59
 
60
-	protected function configure() {
61
-		$this
62
-			->setName('encryption:enable-master-key')
63
-			->setDescription('Enable the master key. Only available for fresh installations with no existing encrypted data! There is also no way to disable it again.');
64
-	}
60
+    protected function configure() {
61
+        $this
62
+            ->setName('encryption:enable-master-key')
63
+            ->setDescription('Enable the master key. Only available for fresh installations with no existing encrypted data! There is also no way to disable it again.');
64
+    }
65 65
 
66
-	protected function execute(InputInterface $input, OutputInterface $output) {
66
+    protected function execute(InputInterface $input, OutputInterface $output) {
67 67
 
68
-		$isAlreadyEnabled = $this->util->isMasterKeyEnabled();
68
+        $isAlreadyEnabled = $this->util->isMasterKeyEnabled();
69 69
 
70
-		if($isAlreadyEnabled) {
71
-			$output->writeln('Master key already enabled');
72
-		} else {
73
-			$question = new ConfirmationQuestion(
74
-				'Warning: Only available for fresh installations with no existing encrypted data! '
75
-			. 'There is also no way to disable it again. Do you want to continue? (y/n) ', false);
76
-			if ($this->questionHelper->ask($input, $output, $question)) {
77
-				$this->config->setAppValue('encryption', 'useMasterKey', '1');
78
-				$output->writeln('Master key successfully enabled.');
79
-			} else {
80
-				$output->writeln('aborted.');
81
-			}
82
-		}
70
+        if($isAlreadyEnabled) {
71
+            $output->writeln('Master key already enabled');
72
+        } else {
73
+            $question = new ConfirmationQuestion(
74
+                'Warning: Only available for fresh installations with no existing encrypted data! '
75
+            . 'There is also no way to disable it again. Do you want to continue? (y/n) ', false);
76
+            if ($this->questionHelper->ask($input, $output, $question)) {
77
+                $this->config->setAppValue('encryption', 'useMasterKey', '1');
78
+                $output->writeln('Master key successfully enabled.');
79
+            } else {
80
+                $output->writeln('aborted.');
81
+            }
82
+        }
83 83
 
84
-	}
84
+    }
85 85
 
86 86
 }
Please login to merge, or discard this patch.
apps/encryption/lib/Hooks/Contracts/IHook.php 1 patch
Indentation   +6 added lines, -6 removed lines patch added patch discarded remove patch
@@ -24,10 +24,10 @@
 block discarded – undo
24 24
 
25 25
 
26 26
 interface IHook {
27
-	/**
28
-	 * Connects Hooks
29
-	 *
30
-	 * @return null
31
-	 */
32
-	public function addHooks();
27
+    /**
28
+     * Connects Hooks
29
+     *
30
+     * @return null
31
+     */
32
+    public function addHooks();
33 33
 }
Please login to merge, or discard this patch.
apps/encryption/lib/Crypto/Encryption.php 2 patches
Spacing   +8 added lines, -8 removed lines patch added patch discarded remove patch
@@ -177,7 +177,7 @@  discard block
 block discarded – undo
177 177
 		$this->isWriteOperation = false;
178 178
 		$this->writeCache = '';
179 179
 
180
-		if($this->session->isReady() === false) {
180
+		if ($this->session->isReady() === false) {
181 181
 			// if the master key is enabled we can initialize encryption
182 182
 			// with a empty password and user name
183 183
 			if ($this->util->isMasterKeyEnabled()) {
@@ -198,7 +198,7 @@  discard block
 block discarded – undo
198 198
 		// always use the version from the original file, also part files
199 199
 		// need to have a correct version number if they get moved over to the
200 200
 		// final location
201
-		$this->version = (int)$this->keyManager->getVersion($this->stripPartFileExtension($path), new View());
201
+		$this->version = (int) $this->keyManager->getVersion($this->stripPartFileExtension($path), new View());
202 202
 
203 203
 		if (
204 204
 			$mode === 'w'
@@ -214,7 +214,7 @@  discard block
 block discarded – undo
214 214
 			// if we read a part file we need to increase the version by 1
215 215
 			// because the version number was also increased by writing
216 216
 			// the part file
217
-			if(Scanner::isPartialFile($path)) {
217
+			if (Scanner::isPartialFile($path)) {
218 218
 				$this->version = $this->version + 1;
219 219
 			}
220 220
 		}
@@ -300,7 +300,7 @@  discard block
 block discarded – undo
300 300
 		if ($this->writeCache) {
301 301
 
302 302
 			// Concat writeCache to start of $data
303
-			$data = $this->writeCache . $data;
303
+			$data = $this->writeCache.$data;
304 304
 
305 305
 			// Clear the write cache, ready for reuse - it has been
306 306
 			// flushed and its old contents processed
@@ -402,7 +402,7 @@  discard block
 block discarded – undo
402 402
 					try {
403 403
 						$publicKeys[$user] = $this->keyManager->getPublicKey($user);
404 404
 					} catch (PublicKeyMissingException $e) {
405
-						$this->logger->warning('Could not encrypt file for ' . $user . ': ' . $e->getMessage());
405
+						$this->logger->warning('Could not encrypt file for '.$user.': '.$e->getMessage());
406 406
 					}
407 407
 				}
408 408
 			}
@@ -489,8 +489,8 @@  discard block
 block discarded – undo
489 489
 				// error message because in this case it means that the file was
490 490
 				// shared with the user at a point where the user didn't had a
491 491
 				// valid private/public key
492
-				$msg = 'Encryption module "' . $this->getDisplayName() .
493
-					'" is not able to read ' . $path;
492
+				$msg = 'Encryption module "'.$this->getDisplayName().
493
+					'" is not able to read '.$path;
494 494
 				$hint = $this->l->t('Can not read this file, probably this is a shared file. Please ask the file owner to reshare the file with you.');
495 495
 				$this->logger->warning($msg);
496 496
 				throw new DecryptionFailedException($msg, $hint);
@@ -532,7 +532,7 @@  discard block
 block discarded – undo
532 532
 		$realPath = $path;
533 533
 		$parts = explode('/', $path);
534 534
 		if ($parts[2] === 'files_versions') {
535
-			$realPath = '/' . $parts[1] . '/files/' . implode('/', array_slice($parts, 3));
535
+			$realPath = '/'.$parts[1].'/files/'.implode('/', array_slice($parts, 3));
536 536
 			$length = strrpos($realPath, '.');
537 537
 			$realPath = substr($realPath, 0, $length);
538 538
 		}
Please login to merge, or discard this patch.
Indentation   +553 added lines, -553 removed lines patch added patch discarded remove patch
@@ -46,557 +46,557 @@
 block discarded – undo
46 46
 
47 47
 class Encryption implements IEncryptionModule {
48 48
 
49
-	const ID = 'OC_DEFAULT_MODULE';
50
-	const DISPLAY_NAME = 'Default encryption module';
51
-
52
-	/**
53
-	 * @var Crypt
54
-	 */
55
-	private $crypt;
56
-
57
-	/** @var string */
58
-	private $cipher;
59
-
60
-	/** @var string */
61
-	private $path;
62
-
63
-	/** @var string */
64
-	private $user;
65
-
66
-	/** @var  array */
67
-	private $owner;
68
-
69
-	/** @var string */
70
-	private $fileKey;
71
-
72
-	/** @var string */
73
-	private $writeCache;
74
-
75
-	/** @var KeyManager */
76
-	private $keyManager;
77
-
78
-	/** @var array */
79
-	private $accessList;
80
-
81
-	/** @var boolean */
82
-	private $isWriteOperation;
83
-
84
-	/** @var Util */
85
-	private $util;
86
-
87
-	/** @var  Session */
88
-	private $session;
89
-
90
-	/** @var  ILogger */
91
-	private $logger;
92
-
93
-	/** @var IL10N */
94
-	private $l;
95
-
96
-	/** @var EncryptAll */
97
-	private $encryptAll;
98
-
99
-	/** @var  bool */
100
-	private $useMasterPassword;
101
-
102
-	/** @var DecryptAll  */
103
-	private $decryptAll;
104
-
105
-	/** @var int unencrypted block size if block contains signature */
106
-	private $unencryptedBlockSizeSigned = 6072;
107
-
108
-	/** @var int unencrypted block size */
109
-	private $unencryptedBlockSize = 6126;
110
-
111
-	/** @var int Current version of the file */
112
-	private $version = 0;
113
-
114
-	/** @var array remember encryption signature version */
115
-	private static $rememberVersion = [];
116
-
117
-
118
-	/**
119
-	 *
120
-	 * @param Crypt $crypt
121
-	 * @param KeyManager $keyManager
122
-	 * @param Util $util
123
-	 * @param Session $session
124
-	 * @param EncryptAll $encryptAll
125
-	 * @param DecryptAll $decryptAll
126
-	 * @param ILogger $logger
127
-	 * @param IL10N $il10n
128
-	 */
129
-	public function __construct(Crypt $crypt,
130
-								KeyManager $keyManager,
131
-								Util $util,
132
-								Session $session,
133
-								EncryptAll $encryptAll,
134
-								DecryptAll $decryptAll,
135
-								ILogger $logger,
136
-								IL10N $il10n) {
137
-		$this->crypt = $crypt;
138
-		$this->keyManager = $keyManager;
139
-		$this->util = $util;
140
-		$this->session = $session;
141
-		$this->encryptAll = $encryptAll;
142
-		$this->decryptAll = $decryptAll;
143
-		$this->logger = $logger;
144
-		$this->l = $il10n;
145
-		$this->owner = [];
146
-		$this->useMasterPassword = $util->isMasterKeyEnabled();
147
-	}
148
-
149
-	/**
150
-	 * @return string defining the technical unique id
151
-	 */
152
-	public function getId() {
153
-		return self::ID;
154
-	}
155
-
156
-	/**
157
-	 * In comparison to getKey() this function returns a human readable (maybe translated) name
158
-	 *
159
-	 * @return string
160
-	 */
161
-	public function getDisplayName() {
162
-		return self::DISPLAY_NAME;
163
-	}
164
-
165
-	/**
166
-	 * start receiving chunks from a file. This is the place where you can
167
-	 * perform some initial step before starting encrypting/decrypting the
168
-	 * chunks
169
-	 *
170
-	 * @param string $path to the file
171
-	 * @param string $user who read/write the file
172
-	 * @param string $mode php stream open mode
173
-	 * @param array $header contains the header data read from the file
174
-	 * @param array $accessList who has access to the file contains the key 'users' and 'public'
175
-	 *
176
-	 * @return array $header contain data as key-value pairs which should be
177
-	 *                       written to the header, in case of a write operation
178
-	 *                       or if no additional data is needed return a empty array
179
-	 */
180
-	public function begin($path, $user, $mode, array $header, array $accessList) {
181
-		$this->path = $this->getPathToRealFile($path);
182
-		$this->accessList = $accessList;
183
-		$this->user = $user;
184
-		$this->isWriteOperation = false;
185
-		$this->writeCache = '';
186
-
187
-		if($this->session->isReady() === false) {
188
-			// if the master key is enabled we can initialize encryption
189
-			// with a empty password and user name
190
-			if ($this->util->isMasterKeyEnabled()) {
191
-				$this->keyManager->init('', '');
192
-			}
193
-		}
194
-
195
-		if ($this->session->decryptAllModeActivated()) {
196
-			$encryptedFileKey = $this->keyManager->getEncryptedFileKey($this->path);
197
-			$shareKey = $this->keyManager->getShareKey($this->path, $this->session->getDecryptAllUid());
198
-			$this->fileKey = $this->crypt->multiKeyDecrypt($encryptedFileKey,
199
-				$shareKey,
200
-				$this->session->getDecryptAllKey());
201
-		} else {
202
-			$this->fileKey = $this->keyManager->getFileKey($this->path, $this->user);
203
-		}
204
-
205
-		// always use the version from the original file, also part files
206
-		// need to have a correct version number if they get moved over to the
207
-		// final location
208
-		$this->version = (int)$this->keyManager->getVersion($this->stripPartFileExtension($path), new View());
209
-
210
-		if (
211
-			$mode === 'w'
212
-			|| $mode === 'w+'
213
-			|| $mode === 'wb'
214
-			|| $mode === 'wb+'
215
-		) {
216
-			$this->isWriteOperation = true;
217
-			if (empty($this->fileKey)) {
218
-				$this->fileKey = $this->crypt->generateFileKey();
219
-			}
220
-		} else {
221
-			// if we read a part file we need to increase the version by 1
222
-			// because the version number was also increased by writing
223
-			// the part file
224
-			if(Scanner::isPartialFile($path)) {
225
-				$this->version = $this->version + 1;
226
-			}
227
-		}
228
-
229
-		if ($this->isWriteOperation) {
230
-			$this->cipher = $this->crypt->getCipher();
231
-		} elseif (isset($header['cipher'])) {
232
-			$this->cipher = $header['cipher'];
233
-		} else {
234
-			// if we read a file without a header we fall-back to the legacy cipher
235
-			// which was used in <=oC6
236
-			$this->cipher = $this->crypt->getLegacyCipher();
237
-		}
238
-
239
-		return ['cipher' => $this->cipher, 'signed' => 'true'];
240
-	}
241
-
242
-	/**
243
-	 * last chunk received. This is the place where you can perform some final
244
-	 * operation and return some remaining data if something is left in your
245
-	 * buffer.
246
-	 *
247
-	 * @param string $path to the file
248
-	 * @param int $position
249
-	 * @return string remained data which should be written to the file in case
250
-	 *                of a write operation
251
-	 * @throws PublicKeyMissingException
252
-	 * @throws \Exception
253
-	 * @throws \OCA\Encryption\Exceptions\MultiKeyEncryptException
254
-	 */
255
-	public function end($path, $position = 0) {
256
-		$result = '';
257
-		if ($this->isWriteOperation) {
258
-			// in case of a part file we remember the new signature versions
259
-			// the version will be set later on update.
260
-			// This way we make sure that other apps listening to the pre-hooks
261
-			// still get the old version which should be the correct value for them
262
-			if (Scanner::isPartialFile($path)) {
263
-				self::$rememberVersion[$this->stripPartFileExtension($path)] = $this->version + 1;
264
-			}
265
-			if (!empty($this->writeCache)) {
266
-				$result = $this->crypt->symmetricEncryptFileContent($this->writeCache, $this->fileKey, $this->version + 1, $position);
267
-				$this->writeCache = '';
268
-			}
269
-			$publicKeys = [];
270
-			if ($this->useMasterPassword === true) {
271
-				$publicKeys[$this->keyManager->getMasterKeyId()] = $this->keyManager->getPublicMasterKey();
272
-			} else {
273
-				foreach ($this->accessList['users'] as $uid) {
274
-					try {
275
-						$publicKeys[$uid] = $this->keyManager->getPublicKey($uid);
276
-					} catch (PublicKeyMissingException $e) {
277
-						$this->logger->warning(
278
-							'no public key found for user "{uid}", user will not be able to read the file',
279
-							['app' => 'encryption', 'uid' => $uid]
280
-						);
281
-						// if the public key of the owner is missing we should fail
282
-						if ($uid === $this->user) {
283
-							throw $e;
284
-						}
285
-					}
286
-				}
287
-			}
288
-
289
-			$publicKeys = $this->keyManager->addSystemKeys($this->accessList, $publicKeys, $this->getOwner($path));
290
-			$encryptedKeyfiles = $this->crypt->multiKeyEncrypt($this->fileKey, $publicKeys);
291
-			$this->keyManager->setAllFileKeys($this->path, $encryptedKeyfiles);
292
-		}
293
-		return $result;
294
-	}
295
-
296
-
297
-
298
-	/**
299
-	 * encrypt data
300
-	 *
301
-	 * @param string $data you want to encrypt
302
-	 * @param int $position
303
-	 * @return string encrypted data
304
-	 */
305
-	public function encrypt($data, $position = 0) {
306
-		// If extra data is left over from the last round, make sure it
307
-		// is integrated into the next block
308
-		if ($this->writeCache) {
309
-
310
-			// Concat writeCache to start of $data
311
-			$data = $this->writeCache . $data;
312
-
313
-			// Clear the write cache, ready for reuse - it has been
314
-			// flushed and its old contents processed
315
-			$this->writeCache = '';
316
-
317
-		}
318
-
319
-		$encrypted = '';
320
-		// While there still remains some data to be processed & written
321
-		while (strlen($data) > 0) {
322
-
323
-			// Remaining length for this iteration, not of the
324
-			// entire file (may be greater than 8192 bytes)
325
-			$remainingLength = strlen($data);
326
-
327
-			// If data remaining to be written is less than the
328
-			// size of 1 6126 byte block
329
-			if ($remainingLength < $this->unencryptedBlockSizeSigned) {
330
-
331
-				// Set writeCache to contents of $data
332
-				// The writeCache will be carried over to the
333
-				// next write round, and added to the start of
334
-				// $data to ensure that written blocks are
335
-				// always the correct length. If there is still
336
-				// data in writeCache after the writing round
337
-				// has finished, then the data will be written
338
-				// to disk by $this->flush().
339
-				$this->writeCache = $data;
340
-
341
-				// Clear $data ready for next round
342
-				$data = '';
343
-
344
-			} else {
345
-
346
-				// Read the chunk from the start of $data
347
-				$chunk = substr($data, 0, $this->unencryptedBlockSizeSigned);
348
-
349
-				$encrypted .= $this->crypt->symmetricEncryptFileContent($chunk, $this->fileKey, $this->version + 1, $position);
350
-
351
-				// Remove the chunk we just processed from
352
-				// $data, leaving only unprocessed data in $data
353
-				// var, for handling on the next round
354
-				$data = substr($data, $this->unencryptedBlockSizeSigned);
355
-
356
-			}
357
-
358
-		}
359
-
360
-		return $encrypted;
361
-	}
362
-
363
-	/**
364
-	 * decrypt data
365
-	 *
366
-	 * @param string $data you want to decrypt
367
-	 * @param int $position
368
-	 * @return string decrypted data
369
-	 * @throws DecryptionFailedException
370
-	 */
371
-	public function decrypt($data, $position = 0) {
372
-		if (empty($this->fileKey)) {
373
-			$msg = 'Can not decrypt this file, probably this is a shared file. Please ask the file owner to reshare the file with you.';
374
-			$hint = $this->l->t('Can not decrypt this file, probably this is a shared file. Please ask the file owner to reshare the file with you.');
375
-			$this->logger->error($msg);
376
-
377
-			throw new DecryptionFailedException($msg, $hint);
378
-		}
379
-
380
-		return $this->crypt->symmetricDecryptFileContent($data, $this->fileKey, $this->cipher, $this->version, $position);
381
-	}
382
-
383
-	/**
384
-	 * update encrypted file, e.g. give additional users access to the file
385
-	 *
386
-	 * @param string $path path to the file which should be updated
387
-	 * @param string $uid of the user who performs the operation
388
-	 * @param array $accessList who has access to the file contains the key 'users' and 'public'
389
-	 * @return boolean
390
-	 */
391
-	public function update($path, $uid, array $accessList) {
392
-
393
-		if (empty($accessList)) {
394
-			if (isset(self::$rememberVersion[$path])) {
395
-				$this->keyManager->setVersion($path, self::$rememberVersion[$path], new View());
396
-				unset(self::$rememberVersion[$path]);
397
-			}
398
-			return;
399
-		}
400
-
401
-		$fileKey = $this->keyManager->getFileKey($path, $uid);
402
-
403
-		if (!empty($fileKey)) {
404
-
405
-			$publicKeys = [];
406
-			if ($this->useMasterPassword === true) {
407
-				$publicKeys[$this->keyManager->getMasterKeyId()] = $this->keyManager->getPublicMasterKey();
408
-			} else {
409
-				foreach ($accessList['users'] as $user) {
410
-					try {
411
-						$publicKeys[$user] = $this->keyManager->getPublicKey($user);
412
-					} catch (PublicKeyMissingException $e) {
413
-						$this->logger->warning('Could not encrypt file for ' . $user . ': ' . $e->getMessage());
414
-					}
415
-				}
416
-			}
417
-
418
-			$publicKeys = $this->keyManager->addSystemKeys($accessList, $publicKeys, $this->getOwner($path));
419
-
420
-			$encryptedFileKey = $this->crypt->multiKeyEncrypt($fileKey, $publicKeys);
421
-
422
-			$this->keyManager->deleteAllFileKeys($path);
423
-
424
-			$this->keyManager->setAllFileKeys($path, $encryptedFileKey);
425
-
426
-		} else {
427
-			$this->logger->debug('no file key found, we assume that the file "{file}" is not encrypted',
428
-				['file' => $path, 'app' => 'encryption']);
429
-
430
-			return false;
431
-		}
432
-
433
-		return true;
434
-	}
435
-
436
-	/**
437
-	 * should the file be encrypted or not
438
-	 *
439
-	 * @param string $path
440
-	 * @return boolean
441
-	 */
442
-	public function shouldEncrypt($path) {
443
-		if ($this->util->shouldEncryptHomeStorage() === false) {
444
-			$storage = $this->util->getStorage($path);
445
-			if ($storage->instanceOfStorage('\OCP\Files\IHomeStorage')) {
446
-				return false;
447
-			}
448
-		}
449
-		$parts = explode('/', $path);
450
-		if (count($parts) < 4) {
451
-			return false;
452
-		}
453
-
454
-		if ($parts[2] === 'files') {
455
-			return true;
456
-		}
457
-		if ($parts[2] === 'files_versions') {
458
-			return true;
459
-		}
460
-		if ($parts[2] === 'files_trashbin') {
461
-			return true;
462
-		}
463
-
464
-		return false;
465
-	}
466
-
467
-	/**
468
-	 * get size of the unencrypted payload per block.
469
-	 * Nextcloud read/write files with a block size of 8192 byte
470
-	 *
471
-	 * @param bool $signed
472
-	 * @return int
473
-	 */
474
-	public function getUnencryptedBlockSize($signed = false) {
475
-		if ($signed === false) {
476
-			return $this->unencryptedBlockSize;
477
-		}
478
-
479
-		return $this->unencryptedBlockSizeSigned;
480
-	}
481
-
482
-	/**
483
-	 * check if the encryption module is able to read the file,
484
-	 * e.g. if all encryption keys exists
485
-	 *
486
-	 * @param string $path
487
-	 * @param string $uid user for whom we want to check if he can read the file
488
-	 * @return bool
489
-	 * @throws DecryptionFailedException
490
-	 */
491
-	public function isReadable($path, $uid) {
492
-		$fileKey = $this->keyManager->getFileKey($path, $uid);
493
-		if (empty($fileKey)) {
494
-			$owner = $this->util->getOwner($path);
495
-			if ($owner !== $uid) {
496
-				// if it is a shared file we throw a exception with a useful
497
-				// error message because in this case it means that the file was
498
-				// shared with the user at a point where the user didn't had a
499
-				// valid private/public key
500
-				$msg = 'Encryption module "' . $this->getDisplayName() .
501
-					'" is not able to read ' . $path;
502
-				$hint = $this->l->t('Can not read this file, probably this is a shared file. Please ask the file owner to reshare the file with you.');
503
-				$this->logger->warning($msg);
504
-				throw new DecryptionFailedException($msg, $hint);
505
-			}
506
-			return false;
507
-		}
508
-
509
-		return true;
510
-	}
511
-
512
-	/**
513
-	 * Initial encryption of all files
514
-	 *
515
-	 * @param InputInterface $input
516
-	 * @param OutputInterface $output write some status information to the terminal during encryption
517
-	 */
518
-	public function encryptAll(InputInterface $input, OutputInterface $output) {
519
-		$this->encryptAll->encryptAll($input, $output);
520
-	}
521
-
522
-	/**
523
-	 * prepare module to perform decrypt all operation
524
-	 *
525
-	 * @param InputInterface $input
526
-	 * @param OutputInterface $output
527
-	 * @param string $user
528
-	 * @return bool
529
-	 */
530
-	public function prepareDecryptAll(InputInterface $input, OutputInterface $output, $user = '') {
531
-		return $this->decryptAll->prepare($input, $output, $user);
532
-	}
533
-
534
-
535
-	/**
536
-	 * @param string $path
537
-	 * @return string
538
-	 */
539
-	protected function getPathToRealFile($path) {
540
-		$realPath = $path;
541
-		$parts = explode('/', $path);
542
-		if ($parts[2] === 'files_versions') {
543
-			$realPath = '/' . $parts[1] . '/files/' . implode('/', array_slice($parts, 3));
544
-			$length = strrpos($realPath, '.');
545
-			$realPath = substr($realPath, 0, $length);
546
-		}
547
-
548
-		return $realPath;
549
-	}
550
-
551
-	/**
552
-	 * remove .part file extension and the ocTransferId from the file to get the
553
-	 * original file name
554
-	 *
555
-	 * @param string $path
556
-	 * @return string
557
-	 */
558
-	protected function stripPartFileExtension($path) {
559
-		if (pathinfo($path, PATHINFO_EXTENSION) === 'part') {
560
-			$pos = strrpos($path, '.', -6);
561
-			$path = substr($path, 0, $pos);
562
-		}
563
-
564
-		return $path;
565
-	}
566
-
567
-	/**
568
-	 * get owner of a file
569
-	 *
570
-	 * @param string $path
571
-	 * @return string
572
-	 */
573
-	protected function getOwner($path) {
574
-		if (!isset($this->owner[$path])) {
575
-			$this->owner[$path] = $this->util->getOwner($path);
576
-		}
577
-		return $this->owner[$path];
578
-	}
579
-
580
-	/**
581
-	 * Check if the module is ready to be used by that specific user.
582
-	 * In case a module is not ready - because e.g. key pairs have not been generated
583
-	 * upon login this method can return false before any operation starts and might
584
-	 * cause issues during operations.
585
-	 *
586
-	 * @param string $user
587
-	 * @return boolean
588
-	 * @since 9.1.0
589
-	 */
590
-	public function isReadyForUser($user) {
591
-		return $this->keyManager->userHasKeys($user);
592
-	}
593
-
594
-	/**
595
-	 * We only need a detailed access list if the master key is not enabled
596
-	 *
597
-	 * @return bool
598
-	 */
599
-	public function needDetailedAccessList() {
600
-		return !$this->util->isMasterKeyEnabled();
601
-	}
49
+    const ID = 'OC_DEFAULT_MODULE';
50
+    const DISPLAY_NAME = 'Default encryption module';
51
+
52
+    /**
53
+     * @var Crypt
54
+     */
55
+    private $crypt;
56
+
57
+    /** @var string */
58
+    private $cipher;
59
+
60
+    /** @var string */
61
+    private $path;
62
+
63
+    /** @var string */
64
+    private $user;
65
+
66
+    /** @var  array */
67
+    private $owner;
68
+
69
+    /** @var string */
70
+    private $fileKey;
71
+
72
+    /** @var string */
73
+    private $writeCache;
74
+
75
+    /** @var KeyManager */
76
+    private $keyManager;
77
+
78
+    /** @var array */
79
+    private $accessList;
80
+
81
+    /** @var boolean */
82
+    private $isWriteOperation;
83
+
84
+    /** @var Util */
85
+    private $util;
86
+
87
+    /** @var  Session */
88
+    private $session;
89
+
90
+    /** @var  ILogger */
91
+    private $logger;
92
+
93
+    /** @var IL10N */
94
+    private $l;
95
+
96
+    /** @var EncryptAll */
97
+    private $encryptAll;
98
+
99
+    /** @var  bool */
100
+    private $useMasterPassword;
101
+
102
+    /** @var DecryptAll  */
103
+    private $decryptAll;
104
+
105
+    /** @var int unencrypted block size if block contains signature */
106
+    private $unencryptedBlockSizeSigned = 6072;
107
+
108
+    /** @var int unencrypted block size */
109
+    private $unencryptedBlockSize = 6126;
110
+
111
+    /** @var int Current version of the file */
112
+    private $version = 0;
113
+
114
+    /** @var array remember encryption signature version */
115
+    private static $rememberVersion = [];
116
+
117
+
118
+    /**
119
+     *
120
+     * @param Crypt $crypt
121
+     * @param KeyManager $keyManager
122
+     * @param Util $util
123
+     * @param Session $session
124
+     * @param EncryptAll $encryptAll
125
+     * @param DecryptAll $decryptAll
126
+     * @param ILogger $logger
127
+     * @param IL10N $il10n
128
+     */
129
+    public function __construct(Crypt $crypt,
130
+                                KeyManager $keyManager,
131
+                                Util $util,
132
+                                Session $session,
133
+                                EncryptAll $encryptAll,
134
+                                DecryptAll $decryptAll,
135
+                                ILogger $logger,
136
+                                IL10N $il10n) {
137
+        $this->crypt = $crypt;
138
+        $this->keyManager = $keyManager;
139
+        $this->util = $util;
140
+        $this->session = $session;
141
+        $this->encryptAll = $encryptAll;
142
+        $this->decryptAll = $decryptAll;
143
+        $this->logger = $logger;
144
+        $this->l = $il10n;
145
+        $this->owner = [];
146
+        $this->useMasterPassword = $util->isMasterKeyEnabled();
147
+    }
148
+
149
+    /**
150
+     * @return string defining the technical unique id
151
+     */
152
+    public function getId() {
153
+        return self::ID;
154
+    }
155
+
156
+    /**
157
+     * In comparison to getKey() this function returns a human readable (maybe translated) name
158
+     *
159
+     * @return string
160
+     */
161
+    public function getDisplayName() {
162
+        return self::DISPLAY_NAME;
163
+    }
164
+
165
+    /**
166
+     * start receiving chunks from a file. This is the place where you can
167
+     * perform some initial step before starting encrypting/decrypting the
168
+     * chunks
169
+     *
170
+     * @param string $path to the file
171
+     * @param string $user who read/write the file
172
+     * @param string $mode php stream open mode
173
+     * @param array $header contains the header data read from the file
174
+     * @param array $accessList who has access to the file contains the key 'users' and 'public'
175
+     *
176
+     * @return array $header contain data as key-value pairs which should be
177
+     *                       written to the header, in case of a write operation
178
+     *                       or if no additional data is needed return a empty array
179
+     */
180
+    public function begin($path, $user, $mode, array $header, array $accessList) {
181
+        $this->path = $this->getPathToRealFile($path);
182
+        $this->accessList = $accessList;
183
+        $this->user = $user;
184
+        $this->isWriteOperation = false;
185
+        $this->writeCache = '';
186
+
187
+        if($this->session->isReady() === false) {
188
+            // if the master key is enabled we can initialize encryption
189
+            // with a empty password and user name
190
+            if ($this->util->isMasterKeyEnabled()) {
191
+                $this->keyManager->init('', '');
192
+            }
193
+        }
194
+
195
+        if ($this->session->decryptAllModeActivated()) {
196
+            $encryptedFileKey = $this->keyManager->getEncryptedFileKey($this->path);
197
+            $shareKey = $this->keyManager->getShareKey($this->path, $this->session->getDecryptAllUid());
198
+            $this->fileKey = $this->crypt->multiKeyDecrypt($encryptedFileKey,
199
+                $shareKey,
200
+                $this->session->getDecryptAllKey());
201
+        } else {
202
+            $this->fileKey = $this->keyManager->getFileKey($this->path, $this->user);
203
+        }
204
+
205
+        // always use the version from the original file, also part files
206
+        // need to have a correct version number if they get moved over to the
207
+        // final location
208
+        $this->version = (int)$this->keyManager->getVersion($this->stripPartFileExtension($path), new View());
209
+
210
+        if (
211
+            $mode === 'w'
212
+            || $mode === 'w+'
213
+            || $mode === 'wb'
214
+            || $mode === 'wb+'
215
+        ) {
216
+            $this->isWriteOperation = true;
217
+            if (empty($this->fileKey)) {
218
+                $this->fileKey = $this->crypt->generateFileKey();
219
+            }
220
+        } else {
221
+            // if we read a part file we need to increase the version by 1
222
+            // because the version number was also increased by writing
223
+            // the part file
224
+            if(Scanner::isPartialFile($path)) {
225
+                $this->version = $this->version + 1;
226
+            }
227
+        }
228
+
229
+        if ($this->isWriteOperation) {
230
+            $this->cipher = $this->crypt->getCipher();
231
+        } elseif (isset($header['cipher'])) {
232
+            $this->cipher = $header['cipher'];
233
+        } else {
234
+            // if we read a file without a header we fall-back to the legacy cipher
235
+            // which was used in <=oC6
236
+            $this->cipher = $this->crypt->getLegacyCipher();
237
+        }
238
+
239
+        return ['cipher' => $this->cipher, 'signed' => 'true'];
240
+    }
241
+
242
+    /**
243
+     * last chunk received. This is the place where you can perform some final
244
+     * operation and return some remaining data if something is left in your
245
+     * buffer.
246
+     *
247
+     * @param string $path to the file
248
+     * @param int $position
249
+     * @return string remained data which should be written to the file in case
250
+     *                of a write operation
251
+     * @throws PublicKeyMissingException
252
+     * @throws \Exception
253
+     * @throws \OCA\Encryption\Exceptions\MultiKeyEncryptException
254
+     */
255
+    public function end($path, $position = 0) {
256
+        $result = '';
257
+        if ($this->isWriteOperation) {
258
+            // in case of a part file we remember the new signature versions
259
+            // the version will be set later on update.
260
+            // This way we make sure that other apps listening to the pre-hooks
261
+            // still get the old version which should be the correct value for them
262
+            if (Scanner::isPartialFile($path)) {
263
+                self::$rememberVersion[$this->stripPartFileExtension($path)] = $this->version + 1;
264
+            }
265
+            if (!empty($this->writeCache)) {
266
+                $result = $this->crypt->symmetricEncryptFileContent($this->writeCache, $this->fileKey, $this->version + 1, $position);
267
+                $this->writeCache = '';
268
+            }
269
+            $publicKeys = [];
270
+            if ($this->useMasterPassword === true) {
271
+                $publicKeys[$this->keyManager->getMasterKeyId()] = $this->keyManager->getPublicMasterKey();
272
+            } else {
273
+                foreach ($this->accessList['users'] as $uid) {
274
+                    try {
275
+                        $publicKeys[$uid] = $this->keyManager->getPublicKey($uid);
276
+                    } catch (PublicKeyMissingException $e) {
277
+                        $this->logger->warning(
278
+                            'no public key found for user "{uid}", user will not be able to read the file',
279
+                            ['app' => 'encryption', 'uid' => $uid]
280
+                        );
281
+                        // if the public key of the owner is missing we should fail
282
+                        if ($uid === $this->user) {
283
+                            throw $e;
284
+                        }
285
+                    }
286
+                }
287
+            }
288
+
289
+            $publicKeys = $this->keyManager->addSystemKeys($this->accessList, $publicKeys, $this->getOwner($path));
290
+            $encryptedKeyfiles = $this->crypt->multiKeyEncrypt($this->fileKey, $publicKeys);
291
+            $this->keyManager->setAllFileKeys($this->path, $encryptedKeyfiles);
292
+        }
293
+        return $result;
294
+    }
295
+
296
+
297
+
298
+    /**
299
+     * encrypt data
300
+     *
301
+     * @param string $data you want to encrypt
302
+     * @param int $position
303
+     * @return string encrypted data
304
+     */
305
+    public function encrypt($data, $position = 0) {
306
+        // If extra data is left over from the last round, make sure it
307
+        // is integrated into the next block
308
+        if ($this->writeCache) {
309
+
310
+            // Concat writeCache to start of $data
311
+            $data = $this->writeCache . $data;
312
+
313
+            // Clear the write cache, ready for reuse - it has been
314
+            // flushed and its old contents processed
315
+            $this->writeCache = '';
316
+
317
+        }
318
+
319
+        $encrypted = '';
320
+        // While there still remains some data to be processed & written
321
+        while (strlen($data) > 0) {
322
+
323
+            // Remaining length for this iteration, not of the
324
+            // entire file (may be greater than 8192 bytes)
325
+            $remainingLength = strlen($data);
326
+
327
+            // If data remaining to be written is less than the
328
+            // size of 1 6126 byte block
329
+            if ($remainingLength < $this->unencryptedBlockSizeSigned) {
330
+
331
+                // Set writeCache to contents of $data
332
+                // The writeCache will be carried over to the
333
+                // next write round, and added to the start of
334
+                // $data to ensure that written blocks are
335
+                // always the correct length. If there is still
336
+                // data in writeCache after the writing round
337
+                // has finished, then the data will be written
338
+                // to disk by $this->flush().
339
+                $this->writeCache = $data;
340
+
341
+                // Clear $data ready for next round
342
+                $data = '';
343
+
344
+            } else {
345
+
346
+                // Read the chunk from the start of $data
347
+                $chunk = substr($data, 0, $this->unencryptedBlockSizeSigned);
348
+
349
+                $encrypted .= $this->crypt->symmetricEncryptFileContent($chunk, $this->fileKey, $this->version + 1, $position);
350
+
351
+                // Remove the chunk we just processed from
352
+                // $data, leaving only unprocessed data in $data
353
+                // var, for handling on the next round
354
+                $data = substr($data, $this->unencryptedBlockSizeSigned);
355
+
356
+            }
357
+
358
+        }
359
+
360
+        return $encrypted;
361
+    }
362
+
363
+    /**
364
+     * decrypt data
365
+     *
366
+     * @param string $data you want to decrypt
367
+     * @param int $position
368
+     * @return string decrypted data
369
+     * @throws DecryptionFailedException
370
+     */
371
+    public function decrypt($data, $position = 0) {
372
+        if (empty($this->fileKey)) {
373
+            $msg = 'Can not decrypt this file, probably this is a shared file. Please ask the file owner to reshare the file with you.';
374
+            $hint = $this->l->t('Can not decrypt this file, probably this is a shared file. Please ask the file owner to reshare the file with you.');
375
+            $this->logger->error($msg);
376
+
377
+            throw new DecryptionFailedException($msg, $hint);
378
+        }
379
+
380
+        return $this->crypt->symmetricDecryptFileContent($data, $this->fileKey, $this->cipher, $this->version, $position);
381
+    }
382
+
383
+    /**
384
+     * update encrypted file, e.g. give additional users access to the file
385
+     *
386
+     * @param string $path path to the file which should be updated
387
+     * @param string $uid of the user who performs the operation
388
+     * @param array $accessList who has access to the file contains the key 'users' and 'public'
389
+     * @return boolean
390
+     */
391
+    public function update($path, $uid, array $accessList) {
392
+
393
+        if (empty($accessList)) {
394
+            if (isset(self::$rememberVersion[$path])) {
395
+                $this->keyManager->setVersion($path, self::$rememberVersion[$path], new View());
396
+                unset(self::$rememberVersion[$path]);
397
+            }
398
+            return;
399
+        }
400
+
401
+        $fileKey = $this->keyManager->getFileKey($path, $uid);
402
+
403
+        if (!empty($fileKey)) {
404
+
405
+            $publicKeys = [];
406
+            if ($this->useMasterPassword === true) {
407
+                $publicKeys[$this->keyManager->getMasterKeyId()] = $this->keyManager->getPublicMasterKey();
408
+            } else {
409
+                foreach ($accessList['users'] as $user) {
410
+                    try {
411
+                        $publicKeys[$user] = $this->keyManager->getPublicKey($user);
412
+                    } catch (PublicKeyMissingException $e) {
413
+                        $this->logger->warning('Could not encrypt file for ' . $user . ': ' . $e->getMessage());
414
+                    }
415
+                }
416
+            }
417
+
418
+            $publicKeys = $this->keyManager->addSystemKeys($accessList, $publicKeys, $this->getOwner($path));
419
+
420
+            $encryptedFileKey = $this->crypt->multiKeyEncrypt($fileKey, $publicKeys);
421
+
422
+            $this->keyManager->deleteAllFileKeys($path);
423
+
424
+            $this->keyManager->setAllFileKeys($path, $encryptedFileKey);
425
+
426
+        } else {
427
+            $this->logger->debug('no file key found, we assume that the file "{file}" is not encrypted',
428
+                ['file' => $path, 'app' => 'encryption']);
429
+
430
+            return false;
431
+        }
432
+
433
+        return true;
434
+    }
435
+
436
+    /**
437
+     * should the file be encrypted or not
438
+     *
439
+     * @param string $path
440
+     * @return boolean
441
+     */
442
+    public function shouldEncrypt($path) {
443
+        if ($this->util->shouldEncryptHomeStorage() === false) {
444
+            $storage = $this->util->getStorage($path);
445
+            if ($storage->instanceOfStorage('\OCP\Files\IHomeStorage')) {
446
+                return false;
447
+            }
448
+        }
449
+        $parts = explode('/', $path);
450
+        if (count($parts) < 4) {
451
+            return false;
452
+        }
453
+
454
+        if ($parts[2] === 'files') {
455
+            return true;
456
+        }
457
+        if ($parts[2] === 'files_versions') {
458
+            return true;
459
+        }
460
+        if ($parts[2] === 'files_trashbin') {
461
+            return true;
462
+        }
463
+
464
+        return false;
465
+    }
466
+
467
+    /**
468
+     * get size of the unencrypted payload per block.
469
+     * Nextcloud read/write files with a block size of 8192 byte
470
+     *
471
+     * @param bool $signed
472
+     * @return int
473
+     */
474
+    public function getUnencryptedBlockSize($signed = false) {
475
+        if ($signed === false) {
476
+            return $this->unencryptedBlockSize;
477
+        }
478
+
479
+        return $this->unencryptedBlockSizeSigned;
480
+    }
481
+
482
+    /**
483
+     * check if the encryption module is able to read the file,
484
+     * e.g. if all encryption keys exists
485
+     *
486
+     * @param string $path
487
+     * @param string $uid user for whom we want to check if he can read the file
488
+     * @return bool
489
+     * @throws DecryptionFailedException
490
+     */
491
+    public function isReadable($path, $uid) {
492
+        $fileKey = $this->keyManager->getFileKey($path, $uid);
493
+        if (empty($fileKey)) {
494
+            $owner = $this->util->getOwner($path);
495
+            if ($owner !== $uid) {
496
+                // if it is a shared file we throw a exception with a useful
497
+                // error message because in this case it means that the file was
498
+                // shared with the user at a point where the user didn't had a
499
+                // valid private/public key
500
+                $msg = 'Encryption module "' . $this->getDisplayName() .
501
+                    '" is not able to read ' . $path;
502
+                $hint = $this->l->t('Can not read this file, probably this is a shared file. Please ask the file owner to reshare the file with you.');
503
+                $this->logger->warning($msg);
504
+                throw new DecryptionFailedException($msg, $hint);
505
+            }
506
+            return false;
507
+        }
508
+
509
+        return true;
510
+    }
511
+
512
+    /**
513
+     * Initial encryption of all files
514
+     *
515
+     * @param InputInterface $input
516
+     * @param OutputInterface $output write some status information to the terminal during encryption
517
+     */
518
+    public function encryptAll(InputInterface $input, OutputInterface $output) {
519
+        $this->encryptAll->encryptAll($input, $output);
520
+    }
521
+
522
+    /**
523
+     * prepare module to perform decrypt all operation
524
+     *
525
+     * @param InputInterface $input
526
+     * @param OutputInterface $output
527
+     * @param string $user
528
+     * @return bool
529
+     */
530
+    public function prepareDecryptAll(InputInterface $input, OutputInterface $output, $user = '') {
531
+        return $this->decryptAll->prepare($input, $output, $user);
532
+    }
533
+
534
+
535
+    /**
536
+     * @param string $path
537
+     * @return string
538
+     */
539
+    protected function getPathToRealFile($path) {
540
+        $realPath = $path;
541
+        $parts = explode('/', $path);
542
+        if ($parts[2] === 'files_versions') {
543
+            $realPath = '/' . $parts[1] . '/files/' . implode('/', array_slice($parts, 3));
544
+            $length = strrpos($realPath, '.');
545
+            $realPath = substr($realPath, 0, $length);
546
+        }
547
+
548
+        return $realPath;
549
+    }
550
+
551
+    /**
552
+     * remove .part file extension and the ocTransferId from the file to get the
553
+     * original file name
554
+     *
555
+     * @param string $path
556
+     * @return string
557
+     */
558
+    protected function stripPartFileExtension($path) {
559
+        if (pathinfo($path, PATHINFO_EXTENSION) === 'part') {
560
+            $pos = strrpos($path, '.', -6);
561
+            $path = substr($path, 0, $pos);
562
+        }
563
+
564
+        return $path;
565
+    }
566
+
567
+    /**
568
+     * get owner of a file
569
+     *
570
+     * @param string $path
571
+     * @return string
572
+     */
573
+    protected function getOwner($path) {
574
+        if (!isset($this->owner[$path])) {
575
+            $this->owner[$path] = $this->util->getOwner($path);
576
+        }
577
+        return $this->owner[$path];
578
+    }
579
+
580
+    /**
581
+     * Check if the module is ready to be used by that specific user.
582
+     * In case a module is not ready - because e.g. key pairs have not been generated
583
+     * upon login this method can return false before any operation starts and might
584
+     * cause issues during operations.
585
+     *
586
+     * @param string $user
587
+     * @return boolean
588
+     * @since 9.1.0
589
+     */
590
+    public function isReadyForUser($user) {
591
+        return $this->keyManager->userHasKeys($user);
592
+    }
593
+
594
+    /**
595
+     * We only need a detailed access list if the master key is not enabled
596
+     *
597
+     * @return bool
598
+     */
599
+    public function needDetailedAccessList() {
600
+        return !$this->util->isMasterKeyEnabled();
601
+    }
602 602
 }
Please login to merge, or discard this patch.
apps/encryption/lib/Crypto/DecryptAll.php 2 patches
Indentation   +123 added lines, -123 removed lines patch added patch discarded remove patch
@@ -35,127 +35,127 @@
 block discarded – undo
35 35
 
36 36
 class DecryptAll {
37 37
 
38
-	/** @var Util  */
39
-	protected $util;
40
-
41
-	/** @var QuestionHelper  */
42
-	protected $questionHelper;
43
-
44
-	/** @var  Crypt */
45
-	protected $crypt;
46
-
47
-	/** @var  KeyManager */
48
-	protected $keyManager;
49
-
50
-	/** @var Session  */
51
-	protected $session;
52
-
53
-	/**
54
-	 * @param Util $util
55
-	 * @param KeyManager $keyManager
56
-	 * @param Crypt $crypt
57
-	 * @param Session $session
58
-	 * @param QuestionHelper $questionHelper
59
-	 */
60
-	public function __construct(
61
-		Util $util,
62
-		KeyManager $keyManager,
63
-		Crypt $crypt,
64
-		Session $session,
65
-		QuestionHelper $questionHelper
66
-	) {
67
-		$this->util = $util;
68
-		$this->keyManager = $keyManager;
69
-		$this->crypt = $crypt;
70
-		$this->session = $session;
71
-		$this->questionHelper = $questionHelper;
72
-	}
73
-
74
-	/**
75
-	 * prepare encryption module to decrypt all files
76
-	 *
77
-	 * @param InputInterface $input
78
-	 * @param OutputInterface $output
79
-	 * @param $user
80
-	 * @return bool
81
-	 */
82
-	public function prepare(InputInterface $input, OutputInterface $output, $user) {
83
-
84
-		$question = new Question('Please enter the recovery key password: ');
85
-
86
-		if($this->util->isMasterKeyEnabled()) {
87
-			$output->writeln('Use master key to decrypt all files');
88
-			$user = $this->keyManager->getMasterKeyId();
89
-			$password =$this->keyManager->getMasterKeyPassword();
90
-		} else {
91
-			$recoveryKeyId = $this->keyManager->getRecoveryKeyId();
92
-			if (!empty($user)) {
93
-				$output->writeln('You can only decrypt the users files if you know');
94
-				$output->writeln('the users password or if he activated the recovery key.');
95
-				$output->writeln('');
96
-				$questionUseLoginPassword = new ConfirmationQuestion(
97
-					'Do you want to use the users login password to decrypt all files? (y/n) ',
98
-					false
99
-				);
100
-				$useLoginPassword = $this->questionHelper->ask($input, $output, $questionUseLoginPassword);
101
-				if ($useLoginPassword) {
102
-					$question = new Question('Please enter the user\'s login password: ');
103
-				} else if ($this->util->isRecoveryEnabledForUser($user) === false) {
104
-					$output->writeln('No recovery key available for user ' . $user);
105
-					return false;
106
-				} else {
107
-					$user = $recoveryKeyId;
108
-				}
109
-			} else {
110
-				$output->writeln('You can only decrypt the files of all users if the');
111
-				$output->writeln('recovery key is enabled by the admin and activated by the users.');
112
-				$output->writeln('');
113
-				$user = $recoveryKeyId;
114
-			}
115
-
116
-			$question->setHidden(true);
117
-			$question->setHiddenFallback(false);
118
-			$password = $this->questionHelper->ask($input, $output, $question);
119
-		}
120
-
121
-		$privateKey = $this->getPrivateKey($user, $password);
122
-		if ($privateKey !== false) {
123
-			$this->updateSession($user, $privateKey);
124
-			return true;
125
-		} else {
126
-			$output->writeln('Could not decrypt private key, maybe you entered the wrong password?');
127
-		}
128
-
129
-
130
-		return false;
131
-	}
132
-
133
-	/**
134
-	 * get the private key which will be used to decrypt all files
135
-	 *
136
-	 * @param string $user
137
-	 * @param string $password
138
-	 * @return bool|string
139
-	 * @throws \OCA\Encryption\Exceptions\PrivateKeyMissingException
140
-	 */
141
-	protected function getPrivateKey($user, $password) {
142
-		$recoveryKeyId = $this->keyManager->getRecoveryKeyId();
143
-		$masterKeyId = $this->keyManager->getMasterKeyId();
144
-		if ($user === $recoveryKeyId) {
145
-			$recoveryKey = $this->keyManager->getSystemPrivateKey($recoveryKeyId);
146
-			$privateKey = $this->crypt->decryptPrivateKey($recoveryKey, $password);
147
-		} elseif ($user === $masterKeyId) {
148
-			$masterKey = $this->keyManager->getSystemPrivateKey($masterKeyId);
149
-			$privateKey = $this->crypt->decryptPrivateKey($masterKey, $password, $masterKeyId);
150
-		} else {
151
-			$userKey = $this->keyManager->getPrivateKey($user);
152
-			$privateKey = $this->crypt->decryptPrivateKey($userKey, $password, $user);
153
-		}
154
-
155
-		return $privateKey;
156
-	}
157
-
158
-	protected function updateSession($user, $privateKey) {
159
-		$this->session->prepareDecryptAll($user, $privateKey);
160
-	}
38
+    /** @var Util  */
39
+    protected $util;
40
+
41
+    /** @var QuestionHelper  */
42
+    protected $questionHelper;
43
+
44
+    /** @var  Crypt */
45
+    protected $crypt;
46
+
47
+    /** @var  KeyManager */
48
+    protected $keyManager;
49
+
50
+    /** @var Session  */
51
+    protected $session;
52
+
53
+    /**
54
+     * @param Util $util
55
+     * @param KeyManager $keyManager
56
+     * @param Crypt $crypt
57
+     * @param Session $session
58
+     * @param QuestionHelper $questionHelper
59
+     */
60
+    public function __construct(
61
+        Util $util,
62
+        KeyManager $keyManager,
63
+        Crypt $crypt,
64
+        Session $session,
65
+        QuestionHelper $questionHelper
66
+    ) {
67
+        $this->util = $util;
68
+        $this->keyManager = $keyManager;
69
+        $this->crypt = $crypt;
70
+        $this->session = $session;
71
+        $this->questionHelper = $questionHelper;
72
+    }
73
+
74
+    /**
75
+     * prepare encryption module to decrypt all files
76
+     *
77
+     * @param InputInterface $input
78
+     * @param OutputInterface $output
79
+     * @param $user
80
+     * @return bool
81
+     */
82
+    public function prepare(InputInterface $input, OutputInterface $output, $user) {
83
+
84
+        $question = new Question('Please enter the recovery key password: ');
85
+
86
+        if($this->util->isMasterKeyEnabled()) {
87
+            $output->writeln('Use master key to decrypt all files');
88
+            $user = $this->keyManager->getMasterKeyId();
89
+            $password =$this->keyManager->getMasterKeyPassword();
90
+        } else {
91
+            $recoveryKeyId = $this->keyManager->getRecoveryKeyId();
92
+            if (!empty($user)) {
93
+                $output->writeln('You can only decrypt the users files if you know');
94
+                $output->writeln('the users password or if he activated the recovery key.');
95
+                $output->writeln('');
96
+                $questionUseLoginPassword = new ConfirmationQuestion(
97
+                    'Do you want to use the users login password to decrypt all files? (y/n) ',
98
+                    false
99
+                );
100
+                $useLoginPassword = $this->questionHelper->ask($input, $output, $questionUseLoginPassword);
101
+                if ($useLoginPassword) {
102
+                    $question = new Question('Please enter the user\'s login password: ');
103
+                } else if ($this->util->isRecoveryEnabledForUser($user) === false) {
104
+                    $output->writeln('No recovery key available for user ' . $user);
105
+                    return false;
106
+                } else {
107
+                    $user = $recoveryKeyId;
108
+                }
109
+            } else {
110
+                $output->writeln('You can only decrypt the files of all users if the');
111
+                $output->writeln('recovery key is enabled by the admin and activated by the users.');
112
+                $output->writeln('');
113
+                $user = $recoveryKeyId;
114
+            }
115
+
116
+            $question->setHidden(true);
117
+            $question->setHiddenFallback(false);
118
+            $password = $this->questionHelper->ask($input, $output, $question);
119
+        }
120
+
121
+        $privateKey = $this->getPrivateKey($user, $password);
122
+        if ($privateKey !== false) {
123
+            $this->updateSession($user, $privateKey);
124
+            return true;
125
+        } else {
126
+            $output->writeln('Could not decrypt private key, maybe you entered the wrong password?');
127
+        }
128
+
129
+
130
+        return false;
131
+    }
132
+
133
+    /**
134
+     * get the private key which will be used to decrypt all files
135
+     *
136
+     * @param string $user
137
+     * @param string $password
138
+     * @return bool|string
139
+     * @throws \OCA\Encryption\Exceptions\PrivateKeyMissingException
140
+     */
141
+    protected function getPrivateKey($user, $password) {
142
+        $recoveryKeyId = $this->keyManager->getRecoveryKeyId();
143
+        $masterKeyId = $this->keyManager->getMasterKeyId();
144
+        if ($user === $recoveryKeyId) {
145
+            $recoveryKey = $this->keyManager->getSystemPrivateKey($recoveryKeyId);
146
+            $privateKey = $this->crypt->decryptPrivateKey($recoveryKey, $password);
147
+        } elseif ($user === $masterKeyId) {
148
+            $masterKey = $this->keyManager->getSystemPrivateKey($masterKeyId);
149
+            $privateKey = $this->crypt->decryptPrivateKey($masterKey, $password, $masterKeyId);
150
+        } else {
151
+            $userKey = $this->keyManager->getPrivateKey($user);
152
+            $privateKey = $this->crypt->decryptPrivateKey($userKey, $password, $user);
153
+        }
154
+
155
+        return $privateKey;
156
+    }
157
+
158
+    protected function updateSession($user, $privateKey) {
159
+        $this->session->prepareDecryptAll($user, $privateKey);
160
+    }
161 161
 }
Please login to merge, or discard this patch.
Spacing   +3 added lines, -3 removed lines patch added patch discarded remove patch
@@ -83,10 +83,10 @@  discard block
 block discarded – undo
83 83
 
84 84
 		$question = new Question('Please enter the recovery key password: ');
85 85
 
86
-		if($this->util->isMasterKeyEnabled()) {
86
+		if ($this->util->isMasterKeyEnabled()) {
87 87
 			$output->writeln('Use master key to decrypt all files');
88 88
 			$user = $this->keyManager->getMasterKeyId();
89
-			$password =$this->keyManager->getMasterKeyPassword();
89
+			$password = $this->keyManager->getMasterKeyPassword();
90 90
 		} else {
91 91
 			$recoveryKeyId = $this->keyManager->getRecoveryKeyId();
92 92
 			if (!empty($user)) {
@@ -101,7 +101,7 @@  discard block
 block discarded – undo
101 101
 				if ($useLoginPassword) {
102 102
 					$question = new Question('Please enter the user\'s login password: ');
103 103
 				} else if ($this->util->isRecoveryEnabledForUser($user) === false) {
104
-					$output->writeln('No recovery key available for user ' . $user);
104
+					$output->writeln('No recovery key available for user '.$user);
105 105
 					return false;
106 106
 				} else {
107 107
 					$user = $recoveryKeyId;
Please login to merge, or discard this patch.