Last active
February 21, 2022 03:22
-
-
Save phuze/a0ec4cb4a79c15ec260bb532bb6c5536 to your computer and use it in GitHub Desktop.
Revisions
-
phuze revised this gist
Feb 21, 2022 . No changes.There are no files selected for viewing
-
phuze created this gist
Feb 21, 2022 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,173 @@ <?php namespace MyApi\Models; use phpseclib3\Net\SSH2; use phpseclib3\Crypt\PublicKeyLoader; /** * FTP model */ class FtpModel { public function __construct() { # load private key $this->key = PublicKeyLoader::load(file_get_contents('/path/to/private/key')); # arrays to hold errors and/or success $this->errors = []; $this->success = []; } /** * Connect to remote FTP server. * Port is 22 and Timeout is 30 seconds. */ private function connectSSH() { $this->ssh = new SSH2('my.domain.com', 22, 30); if (!$this->ssh->login('api', $this->key)) { throw new Exception('Unable to establish SSH connection.'); } } /** * Verify we have a valid username. * Valid usernames may only include (a-z) and dashes (-) * * @param string $username * @return bool */ private function isValidUsername(string $username) { if(preg_match('/[^a-z-]/i', $username)) { return false; } return true; } /** * Generate a cryptographically strong password. * Resulting password length will be twice the length of * the supplied length, and only include [0-9a-z] * * @return string */ private function genPassword(int $length = 8) { return bin2hex(openssl_random_pseudo_bytes($length)); } private function parseResult(string $stdout) { # explode our stdout into individual lines $lines = explode("\n", $stdout); # iterate over the output lines foreach($lines as $line) { # capture any errors if (strpos($line, 'ERROR:') !== false) { $this->errors[] = $line; } if (strpos($line, 'SUCCESS:') !== false) { $this->success[] = $line; } } # if our success array is not empty # (meaning a success line was found) # then our command was successful if(!empty($this->success)) { return true; } return false; } public function addUser(string $username) { # dont allow invalid usernames if(!$this->isValidUsername($username)) { throw new Exception('Invalid username. Only lowercase a-z characters allowed.'); } # generate a new password for the user # note: only admins with local access to the FTP server # may define a password manually $password = $this->genPassword(); # connect to FTP server using SSH $this->connectSSH(); # execute our remote user management script $create = $this->ssh->exec("sudo /etc/vsftpd/users add {$username} {$password}"); # $create will be stdout, so we'll need to parse it to # confirm if the action was successful $result = $this->parseResult($create); # return the result return [ 'success' => $result, 'message' => $result ? $this->success[0] : $this->errors[0], 'password' => $result ? $password : null ]; } public function delUser(string $username) { # dont allow invalid usernames if(!$this->isValidUsername($username)) { throw new Exception('Invalid username. Only lowercase a-z characters allowed.'); } # connect to FTP server using SSH $this->connectSSH(); # execute our remote user management script $delete = $this->ssh->exec("sudo /etc/vsftpd/users del {$username}"); # $delete will be stdout, so we'll need to parse it to # confirm if the action was successful $result = $this->parseResult($delete); # return the result return [ 'success' => $result, 'message' => $result ? $this->success[0] : $this->errors[0] ]; } public function editUser(string $username) { # dont allow invalid usernames if(!$this->isValidUsername($username)) { throw new Exception('Invalid username. Only lowercase a-z characters allowed.'); } # generate a new password for the user # note: only admins with local access to the FTP server # may define a password manually $password = $this->genPassword(); # connect to FTP server using SSH $this->connectSSH(); # execute our remote user management script $edit = $this->ssh->exec("sudo /etc/vsftpd/users edit {$username} {$password}"); # $edit will be stdout, so we'll need to parse it to # confirm if the action was successful $result = $this->parseResult($edit); # return the result return [ 'success' => $result, 'message' => $result ? $this->success[0] : $this->errors[0], 'password' => $result ? $password : null ]; } }