This repository has been archived by the owner on Nov 26, 2017. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 298
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1568 from eBaySF/keychain
Keychain package
- Loading branch information
Showing
11 changed files
with
1,097 additions
and
0 deletions.
There are no files selected for viewing
This file contains 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 characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,381 @@ | ||
#!/usr/bin/env php | ||
<?php | ||
/** | ||
* @package Joomla.Platform | ||
* | ||
* @copyright Copyright (C) 2005 - 2012 Open Source Matters, Inc. All rights reserved. | ||
* @license GNU General Public License version 2 or later; see LICENSE | ||
*/ | ||
|
||
define('_JEXEC', 1); | ||
define('JPATH_BASE', dirname(__FILE__)); | ||
|
||
// Load the Joomla! Platform | ||
require_once realpath('../libraries/import.php'); | ||
|
||
/** | ||
* Keychain Manager | ||
* | ||
* @package Joomla.Platform | ||
* @since 12.3 | ||
*/ | ||
class KeychainManager extends JApplicationCli | ||
{ | ||
/** | ||
* @var boolean A flag if the keychain has been updated to trigger saving the keychain | ||
* @since 12.3 | ||
*/ | ||
protected $updated = false; | ||
|
||
/** | ||
* @var JKeychain The keychain object being manipulated. | ||
* @since 12.3 | ||
*/ | ||
protected $keychain = null; | ||
|
||
/** | ||
* Execute the application | ||
* | ||
* @return void | ||
* | ||
* @since 12.3 | ||
*/ | ||
public function execute( ) | ||
{ | ||
if (!count($this->input->args)) | ||
{ | ||
// Check if they passed --help in otherwise display short usage summary | ||
if ($this->input->get('help', false) === false) | ||
{ | ||
$this->out("usage: {$this->input->executable} [options] [command] [<args>]"); | ||
exit(1); | ||
} | ||
else | ||
{ | ||
$this->displayHelp(); | ||
exit(0); | ||
} | ||
} | ||
|
||
// For all tasks but help and init we use the keychain | ||
if (!in_array($this->input->args[0], array('help', 'init'))) | ||
{ | ||
$this->loadKeychain(); | ||
} | ||
|
||
switch ($this->input->args[0]) | ||
{ | ||
case 'init': | ||
$this->initPassphraseFile(); | ||
break; | ||
case 'list': | ||
$this->listEntries(); | ||
break; | ||
case 'create': | ||
$this->create(); | ||
break; | ||
case 'change': | ||
$this->change(); | ||
case 'delete': | ||
$this->delete(); | ||
break; | ||
case 'read': | ||
$this->read(); | ||
break; | ||
case 'help': | ||
$this->displayHelp(); | ||
break; | ||
default: | ||
$this->out('Invalid command.'); | ||
break; | ||
} | ||
|
||
if ($this->updated) | ||
{ | ||
$this->saveKeychain(); | ||
} | ||
exit(0); | ||
} | ||
|
||
/** | ||
* Load the keychain from a file. | ||
* | ||
* @return void | ||
* | ||
* @since 12.3 | ||
*/ | ||
protected function loadKeychain() | ||
{ | ||
$keychain = $this->input->get('keychain', '', 'raw'); | ||
$publicKeyFile = $this->input->get('public-key', '', 'raw'); | ||
$passphraseFile = $this->input->get('passphrase', '', 'raw'); | ||
|
||
$this->keychain = new JKeychain; | ||
|
||
if (file_exists($keychain)) | ||
{ | ||
if (file_exists($publicKeyFile)) | ||
{ | ||
$this->keychain->loadKeychain($keychain, $passphraseFile, $publicKeyFile); | ||
} | ||
else | ||
{ | ||
$this->out('Public key not specified or missing!'); | ||
exit(1); | ||
} | ||
} | ||
} | ||
|
||
/** | ||
* Save this keychain to a file. | ||
* | ||
* @return void | ||
* | ||
* @since 12.3 | ||
*/ | ||
protected function saveKeychain() | ||
{ | ||
$keychain = $this->input->get('keychain', '', 'raw'); | ||
$publicKeyFile = $this->input->get('public-key', '', 'raw'); | ||
$passphraseFile = $this->input->get('passphrase', '', 'raw'); | ||
|
||
if (!file_exists($publicKeyFile)) | ||
{ | ||
$this->out("Public key file specified doesn't exist: $publicKeyFile"); | ||
exit(1); | ||
} | ||
|
||
$this->keychain->saveKeychain($keychain, $passphraseFile, $publicKeyFile); | ||
} | ||
|
||
/** | ||
* Initialise a new passphrase file. | ||
* | ||
* @return void | ||
* | ||
* @since 12.3 | ||
*/ | ||
protected function initPassphraseFile() | ||
{ | ||
$keychain = new JKeychain; | ||
|
||
$passphraseFile = $this->input->get('passphrase', '', 'raw'); | ||
$privateKeyFile = $this->input->get('private-key', '', 'raw'); | ||
|
||
if (!strlen($passphraseFile)) | ||
{ | ||
$this->out('A passphrase file must be specified with --passphrase'); | ||
exit(1); | ||
} | ||
|
||
if (!file_exists($privateKeyFile)) | ||
{ | ||
$this->out("protected key file specified doesn't exist: $privateKeyFile"); | ||
exit(1); | ||
} | ||
|
||
$this->out('Please enter the new passphrase:'); | ||
$passphrase = $this->in(); | ||
|
||
$this->out('Please enter the passphrase for the protected key:'); | ||
$privateKeyPassphrase = $this->in(); | ||
|
||
$keychain->createPassphraseFile($passphrase, $passphraseFile, $privateKeyFile, $privateKeyPassphrase); | ||
} | ||
|
||
/** | ||
* Create a new entry | ||
* | ||
* @return void | ||
* | ||
* @since 12.3 | ||
*/ | ||
protected function create() | ||
{ | ||
if (count($this->input->args) != 3) | ||
{ | ||
$this->out("usage: {$this->input->executable} [options] create entry_name entry_value"); | ||
exit(1); | ||
} | ||
|
||
if ($this->keychain->exists($this->input->args[1])) | ||
{ | ||
$this->out('error: entry already exists. To change this entry, use "change"'); | ||
exit(1); | ||
} | ||
$this->change(); | ||
} | ||
|
||
/** | ||
* Change an existing entry to a new value or create an entry if missing. | ||
* | ||
* @return void | ||
* | ||
* @since 12.3 | ||
*/ | ||
protected function change() | ||
{ | ||
if (count($this->input->args) != 3) | ||
{ | ||
$this->out("usage: {$this->input->executable} [options] change entry_name entry_value"); | ||
exit(1); | ||
} | ||
$this->updated = true; | ||
$this->keychain->setValue($this->input->args[1], $this->input->args[2]); | ||
} | ||
|
||
/** | ||
* Read an entry from the keychain | ||
* | ||
* @return void | ||
* | ||
* @since 12.3 | ||
*/ | ||
protected function read() | ||
{ | ||
if (count($this->input->args) != 2) | ||
{ | ||
$this->out("usage: {$this->input->executable} [options] read entry_name"); | ||
exit(1); | ||
} | ||
|
||
$key = $this->input->args[1]; | ||
$this->out($key . ': ' . $this->dumpVar($this->keychain->get($key))); | ||
} | ||
|
||
/** | ||
* Get the string from var_dump | ||
* | ||
* @param mixed $var The variable you want to have dumped. | ||
* | ||
* @return string The result of var_dump | ||
* | ||
* @since 12.3 | ||
*/ | ||
private function dumpVar($var) | ||
{ | ||
ob_start(); | ||
var_dump($var); | ||
$result = trim(ob_get_contents()); | ||
ob_end_clean(); | ||
return $result; | ||
} | ||
|
||
/** | ||
* Delete an entry from the keychain | ||
* | ||
* @return void | ||
* | ||
* @since 12.3 | ||
*/ | ||
protected function delete() | ||
{ | ||
if (count($this->input->args) != 2) | ||
{ | ||
$this->out("usage: {$this->input->executable} [options] delete entry_name"); | ||
exit(1); | ||
} | ||
|
||
$this->updated = true; | ||
$this->keychain->deleteValue($this->input->args[1], null); | ||
} | ||
|
||
/** | ||
* List entries in the keychain | ||
* | ||
* @return void | ||
* | ||
* @since 12.3 | ||
*/ | ||
protected function listEntries() | ||
{ | ||
foreach ($this->keychain->toArray() as $key => $value) | ||
{ | ||
$line = $key; | ||
if ($this->input->get('print-values')) | ||
{ | ||
$line .= ': ' . $this->dumpVar($value); | ||
} | ||
$this->out($line); | ||
} | ||
} | ||
|
||
/** | ||
* Display the help information | ||
* | ||
* @return void | ||
* | ||
* @since 12.3 | ||
*/ | ||
protected function displayHelp() | ||
{ | ||
/* | ||
COMMANDS | ||
- list | ||
- create entry_name entry_value | ||
- change entry_name entry_value | ||
- delete entry_name | ||
- read entry_name | ||
*/ | ||
|
||
$help = <<<HELP | ||
Keychain Management Utility | ||
usage: {$this->input->executable} [--keychain=/path/to/keychain] | ||
[--passphrase=/path/to/passphrase.dat] [--public-key=/path/to/public.pem] | ||
[command] [<args>] | ||
OPTIONS | ||
--keychain=/path/to/keychain | ||
Path to a keychain file to manipulate. | ||
--passphrase=/path/to/passphrase.dat | ||
Path to a passphrase file containing the encryption/decryption key. | ||
--public-key=/path/to/public.pem | ||
Path to a public key file to decrypt the passphrase file. | ||
COMMANDS | ||
list: | ||
Usage: list [--print-values] | ||
Lists all entries in the keychain. Optionally pass --print-values to print the values as well. | ||
create: | ||
Usage: create entry_name entry_value | ||
Creates a new entry in the keychain called "entry_name" with the plaintext value "entry_value". | ||
NOTE: This is an alias for change. | ||
change: | ||
Usage: change entry_name entry_value | ||
Updates the keychain entry called "entry_name" with the value "entry_value". | ||
delete: | ||
Usage: delete entry_name | ||
Removes an entry called "entry_name" from the keychain. | ||
read: | ||
Usage: read entry_name | ||
Outputs the plaintext value of "entry_name" from the keychain. | ||
init: | ||
Usage: init | ||
Creates a new passphrase file and prompts for a new passphrase. | ||
HELP; | ||
$this->out($help); | ||
} | ||
} | ||
|
||
try | ||
{ | ||
JApplicationCli::getInstance('KeychainManager')->execute(); | ||
} | ||
catch (Exception $e) | ||
{ | ||
echo $e->getMessage() . "\n"; | ||
exit(1); | ||
} |
Oops, something went wrong.