X Tutup
Skip to content

Commit 4c6c090

Browse files
committed
Support signed urls
1 parent 8095322 commit 4c6c090

File tree

4 files changed

+70
-5
lines changed

4 files changed

+70
-5
lines changed

apps/dav/lib/Connector/Sabre/Auth.php

Lines changed: 47 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@
2929
*/
3030
namespace OCA\DAV\Connector\Sabre;
3131

32-
use Exception;
3332
use OC\AppFramework\Http\Request;
3433
use OC\Authentication\Exceptions\PasswordLoginForbiddenException;
3534
use OC\Authentication\TwoFactorAuth\Manager;
@@ -55,8 +54,6 @@ class Auth extends AbstractBasic {
5554
private $userSession;
5655
/** @var IRequest */
5756
private $request;
58-
/** @var string */
59-
private $currentUser;
6057
/** @var Manager */
6158
private $twoFactorManager;
6259
/** @var AccountModuleManager */
@@ -158,7 +155,7 @@ public function check(RequestInterface $request, ResponseInterface $response) {
158155
throw new NotAuthenticated($e->getMessage(), $e->getCode(), $e);
159156
} catch (NotAuthenticated $e) {
160157
throw $e;
161-
} catch (Exception $e) {
158+
} catch (\Exception $e) {
162159
$class = \get_class($e);
163160
$msg = $e->getMessage();
164161
throw new ServiceUnavailable("$class: $msg");
@@ -230,7 +227,7 @@ private function auth(RequestInterface $request, ResponseInterface $response) {
230227
$this->checkAccountModule($user);
231228
$uid = $user->getUID();
232229
\OC_Util::setupFS($uid);
233-
$this->currentUser = $uid;
230+
$currentUser = $uid;
234231
$this->session->close();
235232
return [true, $this->principalPrefix . $uid];
236233
}
@@ -246,6 +243,19 @@ private function auth(RequestInterface $request, ResponseInterface $response) {
246243
$startPos = \strrpos($data[1], '/') + 1;
247244
$data[1] = \substr_replace($data[1], $user->getUID(), $startPos);
248245
}
246+
247+
// signed url handling
248+
$params = $request->getQueryParameters();
249+
$urlSignature = $params['OC-Signature'];
250+
$urlCredential = $params['OC-Credential'];
251+
if ($urlSignature && $urlCredential && $this->signedRequestIsValid($request)) {
252+
// TODO: setup session
253+
$user = \OC::$server->getUserManager()->get($urlCredential);
254+
$this->userSession->setUser($user);
255+
\OC_Util::setupFS($urlCredential);
256+
$this->session->close();
257+
return [true, $this->principalPrefix . $urlCredential];
258+
}
249259
return $data;
250260
}
251261

@@ -274,4 +284,36 @@ public function challenge(RequestInterface $request, ResponseInterface $response
274284
$response->addHeader('WWW-Authenticate', "$schema realm=\"{$this->realm}\", charset=\"UTF-8\"");
275285
$response->setStatus(401);
276286
}
287+
288+
private function signedRequestIsValid(RequestInterface $request) {
289+
$params = $request->getQueryParameters();
290+
$urlSignature = $params['OC-Signature'];
291+
$urlCredential = $params['OC-Credential'];
292+
$urlDate = $params['OC-Date'];
293+
$urlExpires = $params['OC-Expires'];
294+
$urlVerb = $params['OC-Verb'];
295+
296+
unset($params['OC-Signature']);
297+
298+
$qp = \http_build_query($params);
299+
$url = \Sabre\Uri\parse($request->getAbsoluteUrl());
300+
$url['query'] = $qp;
301+
$url = \Sabre\Uri\build($url);
302+
303+
$signingKey = \OC::$server->getConfig()->getUserValue($urlCredential, 'core', 'signing-key');
304+
305+
$hash = \hash_pbkdf2("sha512", $url, $signingKey, 10000, 64, false);
306+
if ($hash !== $urlSignature) {
307+
return false;
308+
}
309+
if (\strtoupper($request->getMethod()) !== \strtoupper($urlVerb)) {
310+
return false;
311+
}
312+
$date = new \DateTime($urlDate);
313+
$date->add(new \DateInterval("PT${urlExpires}S"));
314+
if ($date < new \DateTime()) {
315+
return false;
316+
}
317+
return true;
318+
}
277319
}

core/Controller/CloudController.php

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,4 +71,25 @@ public function getCurrentUser() {
7171
];
7272
return ['data' => $data];
7373
}
74+
75+
/**
76+
* @NoAdminRequired
77+
* @NoCSRFRequired
78+
* @CORS
79+
*
80+
* @return array
81+
* @throws \OCP\PreConditionNotMetException
82+
*/
83+
public function getSigningKey(): array {
84+
$userId = \OC_User::getUser();
85+
$signingKey = \OC::$server->getConfig()->getUserValue($userId, 'core', 'signing-key', null);
86+
if ($signingKey === null) {
87+
$signingKey = \OC::$server->getSecureRandom()->generate(64);
88+
\OC::$server->getConfig()->setUserValue($userId, 'core', 'signing-key', $signingKey, null);
89+
}
90+
return ['data' => [
91+
'user' => $userId,
92+
'signing-key' => $signingKey
93+
]];
94+
}
7495
}

core/routes.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@
5959
'ocs' => [
6060
['root' => '/cloud', 'name' => 'Cloud#getCapabilities', 'url' => '/capabilities', 'verb' => 'GET'],
6161
['root' => '/cloud', 'name' => 'Cloud#getCurrentUser', 'url' => '/user', 'verb' => 'GET'],
62+
['root' => '/cloud', 'name' => 'Cloud#getSigningKey', 'url' => '/user/signing-key', 'verb' => 'GET'],
6263
['root' => '/cloud', 'name' => 'Roles#getRoles', 'url' => '/roles', 'verb' => 'GET'],
6364
['root' => '/cloud', 'name' => 'UserSync#syncUser', 'url' => '/user-sync/{userId}', 'verb' => 'POST'],
6465
]

lib/private/OCS/CoreCapabilities.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ public function getCapabilities() {
5454
'pollinterval' => $this->config->getSystemValue('pollinterval', 60),
5555
'webdav-root' => $this->config->getSystemValue('webdav-root', 'remote.php/webdav'),
5656
'status' => Util::getStatusInfo(true),
57+
'support-url-signing' => true,
5758
]
5859
];
5960
}

0 commit comments

Comments
 (0)
X Tutup