Skip to content

Commit 2cf1c7f

Browse files
committed
Fix handling of SFTP authorization; closes pterodactyl#1972
1 parent 72ecac5 commit 2cf1c7f

File tree

3 files changed

+71
-366
lines changed

3 files changed

+71
-366
lines changed

app/Http/Controllers/Api/Remote/SftpAuthenticationController.php

Lines changed: 71 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,15 @@
33
namespace Pterodactyl\Http\Controllers\Api\Remote;
44

55
use Illuminate\Http\Request;
6-
use Illuminate\Http\Response;
76
use Illuminate\Http\JsonResponse;
7+
use Pterodactyl\Models\Permission;
88
use Pterodactyl\Http\Controllers\Controller;
99
use Illuminate\Foundation\Auth\ThrottlesLogins;
10-
use Pterodactyl\Exceptions\Repository\RecordNotFoundException;
11-
use Pterodactyl\Services\Sftp\AuthenticateUsingPasswordService;
10+
use Pterodactyl\Repositories\Eloquent\UserRepository;
11+
use Pterodactyl\Exceptions\Http\HttpForbiddenException;
12+
use Pterodactyl\Repositories\Eloquent\ServerRepository;
13+
use Pterodactyl\Services\Servers\GetUserPermissionsService;
14+
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
1215
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
1316
use Pterodactyl\Http\Requests\Api\Remote\SftpAuthenticationFormRequest;
1417

@@ -17,18 +20,35 @@ class SftpAuthenticationController extends Controller
1720
use ThrottlesLogins;
1821

1922
/**
20-
* @var \Pterodactyl\Services\Sftp\AuthenticateUsingPasswordService
23+
* @var \Pterodactyl\Repositories\Eloquent\UserRepository
2124
*/
22-
private $authenticationService;
25+
private $userRepository;
26+
27+
/**
28+
* @var \Pterodactyl\Repositories\Eloquent\ServerRepository
29+
*/
30+
private $serverRepository;
31+
32+
/**
33+
* @var \Pterodactyl\Services\Servers\GetUserPermissionsService
34+
*/
35+
private $permissionsService;
2336

2437
/**
2538
* SftpController constructor.
2639
*
27-
* @param \Pterodactyl\Services\Sftp\AuthenticateUsingPasswordService $authenticationService
40+
* @param \Pterodactyl\Services\Servers\GetUserPermissionsService $permissionsService
41+
* @param \Pterodactyl\Repositories\Eloquent\UserRepository $userRepository
42+
* @param \Pterodactyl\Repositories\Eloquent\ServerRepository $serverRepository
2843
*/
29-
public function __construct(AuthenticateUsingPasswordService $authenticationService)
30-
{
31-
$this->authenticationService = $authenticationService;
44+
public function __construct(
45+
GetUserPermissionsService $permissionsService,
46+
UserRepository $userRepository,
47+
ServerRepository $serverRepository
48+
) {
49+
$this->userRepository = $userRepository;
50+
$this->serverRepository = $serverRepository;
51+
$this->permissionsService = $permissionsService;
3252
}
3353

3454
/**
@@ -38,7 +58,7 @@ public function __construct(AuthenticateUsingPasswordService $authenticationServ
3858
* @param \Pterodactyl\Http\Requests\Api\Remote\SftpAuthenticationFormRequest $request
3959
* @return \Illuminate\Http\JsonResponse
4060
*
41-
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
61+
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
4262
*/
4363
public function __invoke(SftpAuthenticationFormRequest $request): JsonResponse
4464
{
@@ -52,33 +72,54 @@ public function __invoke(SftpAuthenticationFormRequest $request): JsonResponse
5272
];
5373

5474
$this->incrementLoginAttempts($request);
55-
5675
if ($this->hasTooManyLoginAttempts($request)) {
57-
return response()->json([
58-
'error' => 'Logins throttled.',
59-
], Response::HTTP_TOO_MANY_REQUESTS);
76+
return JsonResponse::create([
77+
'error' => 'Too many logins attempted too quickly.',
78+
], JsonResponse::HTTP_TOO_MANY_REQUESTS);
6079
}
6180

62-
try {
63-
$data = $this->authenticationService->handle(
64-
$connection['username'],
65-
$request->input('password'),
66-
object_get($request->attributes->get('node'), 'id', 0),
67-
empty($connection['server']) ? null : $connection['server']
81+
/** @var \Pterodactyl\Models\Node $node */
82+
$node = $request->attributes->get('node');
83+
if (empty($connection['server'])) {
84+
throw new NotFoundHttpException;
85+
}
86+
87+
/** @var \Pterodactyl\Models\User $user */
88+
$user = $this->userRepository->findFirstWhere([
89+
['username', '=', $connection['username']],
90+
]);
91+
92+
$server = $this->serverRepository->getByUuid($connection['server'] ?? '');
93+
if (! password_verify($request->input('password'), $user->password) || $server->node_id !== $node->id) {
94+
throw new HttpForbiddenException(
95+
'Authorization credentials were not correct, please try again.'
6896
);
97+
}
6998

70-
$this->clearLoginAttempts($request);
71-
} catch (BadRequestHttpException $exception) {
72-
return response()->json([
73-
'error' => 'The server you are trying to access is not installed or is suspended.',
74-
], Response::HTTP_BAD_REQUEST);
75-
} catch (RecordNotFoundException $exception) {
76-
return response()->json([
77-
'error' => 'Unable to locate a resource using the username and password provided.',
78-
], Response::HTTP_NOT_FOUND);
99+
if (! $user->root_admin && $server->owner_id !== $user->id) {
100+
$permissions = $this->permissionsService->handle($server, $user);
101+
102+
if (! in_array(Permission::ACTION_FILE_SFTP, $permissions)) {
103+
throw new HttpForbiddenException(
104+
'You do not have permission to access SFTP for this server.'
105+
);
106+
}
107+
}
108+
109+
// Remeber, for security purposes, only reveal the existence of the server to people that
110+
// have provided valid credentials, and have permissions to know about it.
111+
if ($server->installed !== 1 || $server->suspended) {
112+
throw new BadRequestHttpException(
113+
'Server is not installed or is currently suspended.'
114+
);
79115
}
80116

81-
return response()->json($data);
117+
return JsonResponse::create([
118+
'server' => $server->uuid,
119+
// Deprecated, but still needed at the moment for Wings.
120+
'token' => '',
121+
'permissions' => $permissions ?? ['*'],
122+
]);
82123
}
83124

84125
/**

app/Services/Sftp/AuthenticateUsingPasswordService.php

Lines changed: 0 additions & 108 deletions
This file was deleted.

0 commit comments

Comments
 (0)