From 9cfca3281a14144e76075a77d5e54e3fa37781ca Mon Sep 17 00:00:00 2001 From: Netkas Date: Thu, 28 Sep 2023 21:56:15 -0400 Subject: [PATCH] Touch-up & Implemented authentication system --- src/ncc/CLI/Management/CredentialMenu.php | 7 ++-- src/ncc/CLI/Management/PackageManagerMenu.php | 42 +++++++++++++++++-- src/ncc/Managers/PackageManager.php | 3 +- src/ncc/Objects/Vault.php | 11 ++--- src/ncc/Objects/Vault/Entry.php | 11 +++-- 5 files changed, 55 insertions(+), 19 deletions(-) diff --git a/src/ncc/CLI/Management/CredentialMenu.php b/src/ncc/CLI/Management/CredentialMenu.php index 712294d..1253c0d 100644 --- a/src/ncc/CLI/Management/CredentialMenu.php +++ b/src/ncc/CLI/Management/CredentialMenu.php @@ -128,8 +128,7 @@ while(true) { - $password = Console::passwordInput('Password/Secret: '); - if (!$entry->unlock($password)) + if (!$entry->unlock(Console::passwordInput('Password/Secret: '))) { $tries++; if ($tries >= 3) @@ -138,7 +137,7 @@ return 1; } - Console::outError('Invalid password.', true, 1); + Console::outError(sprintf('Invalid password, %d attempts remaining.', 3 - $tries)); } else { @@ -173,7 +172,7 @@ Console::out('Entries:'); foreach($entries as $entry) { - Console::out(sprintf(' - %s (%s)', $entry->getName(), $entry->isEncrypted() ? ' (encrypted)' : '')); + Console::out(sprintf(' - %s %s', $entry->getName(), $entry->isEncrypted() ? ' (encrypted)' : '')); } Console::out('Total: ' . count($entries)); diff --git a/src/ncc/CLI/Management/PackageManagerMenu.php b/src/ncc/CLI/Management/PackageManagerMenu.php index f075ea1..6c45308 100644 --- a/src/ncc/CLI/Management/PackageManagerMenu.php +++ b/src/ncc/CLI/Management/PackageManagerMenu.php @@ -30,6 +30,7 @@ use ncc\Exceptions\IOException; use ncc\Exceptions\OperationException; use ncc\Exceptions\PathNotFoundException; + use ncc\Managers\CredentialManager; use ncc\Managers\PackageManager; use ncc\Managers\RepositoryManager; use ncc\Objects\CliHelpSection; @@ -116,20 +117,55 @@ } /** + * Installs a package from a local file or from a remote repository + * * @param array $args * @return int * @throws ConfigurationException * @throws IOException * @throws OperationException * @throws PathNotFoundException + * @throws Exception */ private static function installPackage(array $args): int { $package = $args['package'] ?? $args['p'] ?? null; + $authentication = $args['authentication'] ?? $args['a'] ?? null; + $authentication_entry = null; $auto_yes = isset($args['y']); $repository_manager = new RepositoryManager(); $package_manager = new PackageManager(); + if($authentication !== null) + { + $entry = (new CredentialManager())->getVault()?->getEntry($authentication); + + if($entry->isEncrypted()) + { + $tries = 0; + while(true) + { + if (!$entry->unlock(Console::passwordInput('Password/Secret: '))) + { + $tries++; + if ($tries >= 3) + { + Console::outError('Too many failed attempts.', true, 1); + return 1; + } + + Console::outError(sprintf('Incorrect password/secret, %d attempts remaining', 3 - $tries)); + } + else + { + Console::out('Authentication successful.'); + return 1; + } + } + } + + $authentication_entry = $entry->getPassword(); + } if(preg_match(RegexPatterns::REMOTE_PACKAGE, $package) === 1) { @@ -147,7 +183,7 @@ return 0; } - $results = $package_manager->install($package_input); + $results = $package_manager->install($package_input, $authentication_entry); Console::out(sprintf('Installed %d packages', count($results))); return 0; } @@ -252,7 +288,7 @@ return 0; } - $package_manager->install($package_reader); + Console::out(sprintf('Installed %d packages', count($package_manager->install($package_reader, $authentication_entry)))); return 0; } @@ -415,7 +451,7 @@ } Console::out(sprintf('Fixing missing dependency %s', $package)); - $package_manager->install($source); + Console::out(sprintf('Installed %d packages', count($package_manager->install($source)))); } return 0; diff --git a/src/ncc/Managers/PackageManager.php b/src/ncc/Managers/PackageManager.php index cf2e8db..0047b87 100644 --- a/src/ncc/Managers/PackageManager.php +++ b/src/ncc/Managers/PackageManager.php @@ -170,7 +170,7 @@ * * @param string $package_name * @param string|null $version - * @return void + * @return array * @throws IOException * @throws OperationException */ @@ -481,6 +481,7 @@ * @return void * @throws ConfigurationException * @throws IOException + * @throws OperationException */ private function extractPackageContents(PackageReader $package_reader, string $package_path): void { diff --git a/src/ncc/Objects/Vault.php b/src/ncc/Objects/Vault.php index 32e3aca..8d8e74d 100644 --- a/src/ncc/Objects/Vault.php +++ b/src/ncc/Objects/Vault.php @@ -24,6 +24,7 @@ namespace ncc\Objects; + use InvalidArgumentException; use ncc\Enums\Types\AuthenticationType; use ncc\Enums\Versions; use ncc\Interfaces\AuthenticationInterface; @@ -142,9 +143,9 @@ * Returns an existing entry from the vault * * @param string $name - * @return Entry|null + * @return Entry */ - public function getEntry(string $name): ?Entry + public function getEntry(string $name): Entry { foreach($this->entries as $entry) { @@ -154,7 +155,7 @@ } } - return null; + throw new InvalidArgumentException(sprintf('Entry "%s" does not exist in the vault', $name)); } /** @@ -167,10 +168,6 @@ public function authenticate(string $name, string $password): bool { $entry = $this->getEntry($name); - if($entry === null) - { - return false; - } if(($entry->getPassword() === null) && $entry->isEncrypted() && !$entry->isCurrentlyDecrypted()) { diff --git a/src/ncc/Objects/Vault/Entry.php b/src/ncc/Objects/Vault/Entry.php index eff6bfc..29e7cb9 100644 --- a/src/ncc/Objects/Vault/Entry.php +++ b/src/ncc/Objects/Vault/Entry.php @@ -24,10 +24,12 @@ namespace ncc\Objects\Vault; + use Exception; use ncc\Defuse\Crypto\Crypto; use ncc\Defuse\Crypto\Exception\EnvironmentIsBrokenException; use ncc\Defuse\Crypto\Exception\WrongKeyOrModifiedCiphertextException; use ncc\Enums\Types\AuthenticationType; + use ncc\Exceptions\ConfigurationException; use ncc\Extensions\ZiProto\ZiProto; use ncc\Interfaces\AuthenticationInterface; use ncc\Interfaces\BytecodeObjectInterface; @@ -202,7 +204,7 @@ * * @param string $password * @return bool - * @noinspection PhpUnhandledExceptionInspection + * @throws Exception */ public function unlock(string $password): bool { @@ -327,13 +329,13 @@ } /** - * @return AuthenticationInterface|null + * @return AuthenticationInterface */ - public function getPassword(): ?AuthenticationInterface + public function getPassword(): AuthenticationInterface { if(!$this->currently_decrypted) { - return null; + throw new RuntimeException(sprintf('Cannot get password for entry "%s" because it is currently encrypted', $this->name)); } return $this->password; @@ -379,6 +381,7 @@ * * @param array $data * @return Entry + * @throws ConfigurationException */ public static function fromArray(array $data): self {