PageRenderTime 27ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/bin/keychain.php

https://github.com/Hackwar/joomla-platform
PHP | 381 lines | 234 code | 42 blank | 105 comment | 20 complexity | f3b4fff1ced0a6034434ca931cf4f749 MD5 | raw file
  1. #!/usr/bin/env php
  2. <?php
  3. /**
  4. * @package Joomla.Platform
  5. *
  6. * @copyright Copyright (C) 2005 - 2012 Open Source Matters, Inc. All rights reserved.
  7. * @license GNU General Public License version 2 or later; see LICENSE
  8. */
  9. define('_JEXEC', 1);
  10. define('JPATH_BASE', dirname(__FILE__));
  11. // Load the Joomla! Platform
  12. require_once realpath('../libraries/import.php');
  13. /**
  14. * Keychain Manager
  15. *
  16. * @package Joomla.Platform
  17. * @since 12.3
  18. */
  19. class KeychainManager extends JApplicationCli
  20. {
  21. /**
  22. * @var boolean A flag if the keychain has been updated to trigger saving the keychain
  23. * @since 12.3
  24. */
  25. protected $updated = false;
  26. /**
  27. * @var JKeychain The keychain object being manipulated.
  28. * @since 12.3
  29. */
  30. protected $keychain = null;
  31. /**
  32. * Execute the application
  33. *
  34. * @return void
  35. *
  36. * @since 12.3
  37. */
  38. public function execute( )
  39. {
  40. if (!count($this->input->args))
  41. {
  42. // Check if they passed --help in otherwise display short usage summary
  43. if ($this->input->get('help', false) === false)
  44. {
  45. $this->out("usage: {$this->input->executable} [options] [command] [<args>]");
  46. exit(1);
  47. }
  48. else
  49. {
  50. $this->displayHelp();
  51. exit(0);
  52. }
  53. }
  54. // For all tasks but help and init we use the keychain
  55. if (!in_array($this->input->args[0], array('help', 'init')))
  56. {
  57. $this->loadKeychain();
  58. }
  59. switch ($this->input->args[0])
  60. {
  61. case 'init':
  62. $this->initPassphraseFile();
  63. break;
  64. case 'list':
  65. $this->listEntries();
  66. break;
  67. case 'create':
  68. $this->create();
  69. break;
  70. case 'change':
  71. $this->change();
  72. case 'delete':
  73. $this->delete();
  74. break;
  75. case 'read':
  76. $this->read();
  77. break;
  78. case 'help':
  79. $this->displayHelp();
  80. break;
  81. default:
  82. $this->out('Invalid command.');
  83. break;
  84. }
  85. if ($this->updated)
  86. {
  87. $this->saveKeychain();
  88. }
  89. exit(0);
  90. }
  91. /**
  92. * Load the keychain from a file.
  93. *
  94. * @return void
  95. *
  96. * @since 12.3
  97. */
  98. protected function loadKeychain()
  99. {
  100. $keychain = $this->input->get('keychain', '', 'raw');
  101. $publicKeyFile = $this->input->get('public-key', '', 'raw');
  102. $passphraseFile = $this->input->get('passphrase', '', 'raw');
  103. $this->keychain = new JKeychain;
  104. if (file_exists($keychain))
  105. {
  106. if (file_exists($publicKeyFile))
  107. {
  108. $this->keychain->loadKeychain($keychain, $passphraseFile, $publicKeyFile);
  109. }
  110. else
  111. {
  112. $this->out('Public key not specified or missing!');
  113. exit(1);
  114. }
  115. }
  116. }
  117. /**
  118. * Save this keychain to a file.
  119. *
  120. * @return void
  121. *
  122. * @since 12.3
  123. */
  124. protected function saveKeychain()
  125. {
  126. $keychain = $this->input->get('keychain', '', 'raw');
  127. $publicKeyFile = $this->input->get('public-key', '', 'raw');
  128. $passphraseFile = $this->input->get('passphrase', '', 'raw');
  129. if (!file_exists($publicKeyFile))
  130. {
  131. $this->out("Public key file specified doesn't exist: $publicKeyFile");
  132. exit(1);
  133. }
  134. $this->keychain->saveKeychain($keychain, $passphraseFile, $publicKeyFile);
  135. }
  136. /**
  137. * Initialise a new passphrase file.
  138. *
  139. * @return void
  140. *
  141. * @since 12.3
  142. */
  143. protected function initPassphraseFile()
  144. {
  145. $keychain = new JKeychain;
  146. $passphraseFile = $this->input->get('passphrase', '', 'raw');
  147. $privateKeyFile = $this->input->get('private-key', '', 'raw');
  148. if (!strlen($passphraseFile))
  149. {
  150. $this->out('A passphrase file must be specified with --passphrase');
  151. exit(1);
  152. }
  153. if (!file_exists($privateKeyFile))
  154. {
  155. $this->out("protected key file specified doesn't exist: $privateKeyFile");
  156. exit(1);
  157. }
  158. $this->out('Please enter the new passphrase:');
  159. $passphrase = $this->in();
  160. $this->out('Please enter the passphrase for the protected key:');
  161. $privateKeyPassphrase = $this->in();
  162. $keychain->createPassphraseFile($passphrase, $passphraseFile, $privateKeyFile, $privateKeyPassphrase);
  163. }
  164. /**
  165. * Create a new entry
  166. *
  167. * @return void
  168. *
  169. * @since 12.3
  170. */
  171. protected function create()
  172. {
  173. if (count($this->input->args) != 3)
  174. {
  175. $this->out("usage: {$this->input->executable} [options] create entry_name entry_value");
  176. exit(1);
  177. }
  178. if ($this->keychain->exists($this->input->args[1]))
  179. {
  180. $this->out('error: entry already exists. To change this entry, use "change"');
  181. exit(1);
  182. }
  183. $this->change();
  184. }
  185. /**
  186. * Change an existing entry to a new value or create an entry if missing.
  187. *
  188. * @return void
  189. *
  190. * @since 12.3
  191. */
  192. protected function change()
  193. {
  194. if (count($this->input->args) != 3)
  195. {
  196. $this->out("usage: {$this->input->executable} [options] change entry_name entry_value");
  197. exit(1);
  198. }
  199. $this->updated = true;
  200. $this->keychain->setValue($this->input->args[1], $this->input->args[2]);
  201. }
  202. /**
  203. * Read an entry from the keychain
  204. *
  205. * @return void
  206. *
  207. * @since 12.3
  208. */
  209. protected function read()
  210. {
  211. if (count($this->input->args) != 2)
  212. {
  213. $this->out("usage: {$this->input->executable} [options] read entry_name");
  214. exit(1);
  215. }
  216. $key = $this->input->args[1];
  217. $this->out($key . ': ' . $this->dumpVar($this->keychain->get($key)));
  218. }
  219. /**
  220. * Get the string from var_dump
  221. *
  222. * @param mixed $var The variable you want to have dumped.
  223. *
  224. * @return string The result of var_dump
  225. *
  226. * @since 12.3
  227. */
  228. private function dumpVar($var)
  229. {
  230. ob_start();
  231. var_dump($var);
  232. $result = trim(ob_get_contents());
  233. ob_end_clean();
  234. return $result;
  235. }
  236. /**
  237. * Delete an entry from the keychain
  238. *
  239. * @return void
  240. *
  241. * @since 12.3
  242. */
  243. protected function delete()
  244. {
  245. if (count($this->input->args) != 2)
  246. {
  247. $this->out("usage: {$this->input->executable} [options] delete entry_name");
  248. exit(1);
  249. }
  250. $this->updated = true;
  251. $this->keychain->deleteValue($this->input->args[1], null);
  252. }
  253. /**
  254. * List entries in the keychain
  255. *
  256. * @return void
  257. *
  258. * @since 12.3
  259. */
  260. protected function listEntries()
  261. {
  262. foreach ($this->keychain->toArray() as $key => $value)
  263. {
  264. $line = $key;
  265. if ($this->input->get('print-values'))
  266. {
  267. $line .= ': ' . $this->dumpVar($value);
  268. }
  269. $this->out($line);
  270. }
  271. }
  272. /**
  273. * Display the help information
  274. *
  275. * @return void
  276. *
  277. * @since 12.3
  278. */
  279. protected function displayHelp()
  280. {
  281. /*
  282. COMMANDS
  283. - list
  284. - create entry_name entry_value
  285. - change entry_name entry_value
  286. - delete entry_name
  287. - read entry_name
  288. */
  289. $help = <<<HELP
  290. Keychain Management Utility
  291. usage: {$this->input->executable} [--keychain=/path/to/keychain]
  292. [--passphrase=/path/to/passphrase.dat] [--public-key=/path/to/public.pem]
  293. [command] [<args>]
  294. OPTIONS
  295. --keychain=/path/to/keychain
  296. Path to a keychain file to manipulate.
  297. --passphrase=/path/to/passphrase.dat
  298. Path to a passphrase file containing the encryption/decryption key.
  299. --public-key=/path/to/public.pem
  300. Path to a public key file to decrypt the passphrase file.
  301. COMMANDS
  302. list:
  303. Usage: list [--print-values]
  304. Lists all entries in the keychain. Optionally pass --print-values to print the values as well.
  305. create:
  306. Usage: create entry_name entry_value
  307. Creates a new entry in the keychain called "entry_name" with the plaintext value "entry_value".
  308. NOTE: This is an alias for change.
  309. change:
  310. Usage: change entry_name entry_value
  311. Updates the keychain entry called "entry_name" with the value "entry_value".
  312. delete:
  313. Usage: delete entry_name
  314. Removes an entry called "entry_name" from the keychain.
  315. read:
  316. Usage: read entry_name
  317. Outputs the plaintext value of "entry_name" from the keychain.
  318. init:
  319. Usage: init
  320. Creates a new passphrase file and prompts for a new passphrase.
  321. HELP;
  322. $this->out($help);
  323. }
  324. }
  325. try
  326. {
  327. JApplicationCli::getInstance('KeychainManager')->execute();
  328. }
  329. catch (Exception $e)
  330. {
  331. echo $e->getMessage() . "\n";
  332. exit(1);
  333. }