@Test(groups="Integration") public void testReadsPrivateKeyFileWithPassphrase() throws Exception { ConfigBag config = ConfigBag.newInstance(); config.put(LocationConfigKeys.PRIVATE_KEY_FILE, SSH_PRIVATE_KEY_FILE_WITH_PASSPHRASE); LocationConfigUtils.OsCredential cred = LocationConfigUtils.getOsCredential(config).doKeyValidation(false); String data = cred.getPreferredCredential(); assertTrue(data != null && data.length() > 0); Assert.assertFalse(data.isEmpty()); cred.doKeyValidation(true); try { cred.checkNoErrors(); Assert.fail("check should fail as passphrase needed"); } catch (IllegalStateException exception) { } config.put(LocationConfigKeys.PRIVATE_KEY_PASSPHRASE, "passphrase"); cred.checkNoErrors(); config.put(LocationConfigKeys.PRIVATE_KEY_PASSPHRASE, "wrong_passphrase"); try { cred.checkNoErrors(); Assert.fail("check should fail as passphrase needed"); } catch (IllegalStateException exception) { } }
public void testPreferPrivateKeyDataOverFile() throws Exception { ConfigBag config = ConfigBag.newInstance(); config.put(LocationConfigKeys.PRIVATE_KEY_DATA, "mydata"); config.put(LocationConfigKeys.PRIVATE_KEY_FILE, SSH_PRIVATE_KEY_FILE); LocationConfigUtils.OsCredential creds = LocationConfigUtils.getOsCredential(config).doKeyValidation(false); Assert.assertTrue(creds.hasKey()); // warnings, as it is malformed Assert.assertFalse(creds.getWarningMessages().isEmpty()); String data = creds.getPrivateKeyData(); assertEquals(data, "mydata"); }
public void testPreferPublicKeyDataOverFileAndNoPrivateKeyRequired() throws Exception { ConfigBag config = ConfigBag.newInstance(); config.put(LocationConfigKeys.PUBLIC_KEY_DATA, "mydata"); config.put(LocationConfigKeys.PUBLIC_KEY_FILE, SSH_PUBLIC_KEY_FILE); config.put(LocationConfigKeys.PRIVATE_KEY_FILE, ""); LocationConfigUtils.OsCredential creds = LocationConfigUtils.getOsCredential(config); String data = creds.getPublicKeyData(); assertEquals(data, "mydata"); Assert.assertNull(creds.getPreferredCredential()); Assert.assertFalse(creds.hasPassword()); Assert.assertFalse(creds.hasKey()); // and not even any warnings here Assert.assertTrue(creds.getWarningMessages().isEmpty()); }
privateKey = getValidatedPrivateKey(file); addWarning("Unable to find or extract public key for "+file, "skipping"); } else { log.debug("Loaded private key data from "+file+" (public key data not found but not required)"); Exceptions.propagateIfFatal(e); String message = "Missing/invalid private key file "+file; if (privateKeyFilesExplicitlySet) addWarning(message, (!fi.hasNext() ? "no more files to try" : "trying next file")+": "+e); error("No valid private keys found", ""+warningMessages); privateKey = getValidatedPrivateKey("(data)"); error("If explicit "+LocationConfigKeys.PRIVATE_KEY_DATA.getName()+" is supplied, then " + "the corresponding "+LocationConfigKeys.PUBLIC_KEY_DATA.getName()+" must also be supplied.", null); } else { } catch (Exception e) { Exceptions.propagateIfFatal(e); addWarning("Invalid public key: "+decoded); error("Public key inferred from does not match public key extracted from private key", null);
private KeyPair getValidatedPrivateKey(String label) { KeyPair privateKey = null; String passphrase = config.get(CloudLocationConfig.PRIVATE_KEY_PASSPHRASE); try { privateKey = SecureKeys.readPem(privateKeyData.getBytes(), passphrase); if (passphrase!=null) { // get the unencrypted key data for our internal use (jclouds requires this) privateKeyData = SecureKeys.toPem(privateKey); } } catch (PassphraseProblem e) { if (doKeyValidation) { log.debug("Encountered error handling key "+label+": "+e, e); if (Strings.isBlank(passphrase)) addWarning("Passphrase required for key '"+label+"'"); else addWarning("Invalid passphrase for key '"+label+"'"); privateKeyData = null; } } catch (Exception e) { Exceptions.propagateIfFatal(e); if (doKeyValidation) { addWarning("Unable to parse private key from '"+label+"': unknown format"); privateKeyData = null; } } return privateKey; }
/** if both key and password supplied, prefer the key; the default */ public OsCredential preferKey() { preferPassword = false; return dirty(); } /** if both key and password supplied, prefer the password; see {@link #preferKey()} */
/** if both key and password supplied, prefer the password; see {@link #preferKey()} */ public OsCredential preferPassword() { preferPassword = true; return dirty(); }
public static OsCredential newInstance(ConfigBag config) { return new OsCredential(config); }
/** whether to check the private/public keys and passphrase are coherent; default true */ public OsCredential doKeyValidation(boolean doKeyValidation) { this.doKeyValidation = doKeyValidation; return dirty(); } /** if true (the default) this will look at default locations set on keys */
/** if false, do not mind if there is no public key corresponding to any private key; * defaults to true; only applies if a private key is set */ public OsCredential requirePublicKey(boolean requirePublicKey) { this.requirePublicKey = requirePublicKey; return dirty(); } /** whether to check the private/public keys and passphrase are coherent; default true */
/** throws if there were errors resolving (e.g. explicit keys, none of which were found/valid, or public key required and not found) * @return */ public OsCredential checkNoErrors() { throwOnErrors(true); dirty(); infer(); return this; }
private void addWarning(String msg) { addWarning(msg, null); } private void addWarning(String msg, String debugExtension) {
public void testReadsPrivateKeyFileWithMultipleColonSeparatedFilesWithGoodLast() throws Exception { ConfigBag config = ConfigBag.newInstance(); config.put(LocationConfigKeys.PRIVATE_KEY_FILE, "/path/does/not/exist"+File.pathSeparator+SSH_PRIVATE_KEY_FILE); String data = LocationConfigUtils.getOsCredential(config).getPreferredCredential(); assertTrue(data != null && data.length() > 0); }
@Test(groups="Integration") // requires ~/.ssh/id_rsa public void testReadsPublicKeyFileWithTildePath() throws Exception { ConfigBag config = ConfigBag.newInstance(); config.put(LocationConfigKeys.PUBLIC_KEY_FILE, SSH_PUBLIC_KEY_FILE_WITH_TILDE); // don't mind if it has a passphrase String data = LocationConfigUtils.getOsCredential(config).doKeyValidation(false).getPublicKeyData(); assertTrue(data != null && data.length() > 0); }
/** if a password is available, and either this is preferred over a key or there is no key */ public boolean isUsingPassword() { return hasPassword() && (!hasKey() || preferPassword); }
@Test(groups="Integration") // requires ~/.ssh/id_rsa public void testReadsPrivateKeyFileWithTildePath() throws Exception { ConfigBag config = ConfigBag.newInstance(); config.put(LocationConfigKeys.PRIVATE_KEY_FILE, SSH_PRIVATE_KEY_FILE_WITH_TILDE); // don't mind if it has a passphrase String data = LocationConfigUtils.getOsCredential(config).doKeyValidation(false).getPreferredCredential(); assertTrue(data != null && data.length() > 0); }
private void error(String msg, String logExtension) { addWarning(msg); if (warnOnErrors) log.warn(msg+(logExtension==null ? "" : ": "+logExtension)); if (throwOnErrors) throw new IllegalStateException(msg+(logExtension==null ? "" : "; "+logExtension)); }
/** whether to log warnings on problems */ public OsCredential warnOnErrors(boolean warnOnErrors) { this.warnOnErrors = warnOnErrors; return dirty(); } /** whether to throw on problems */
/** whether to throw on problems */ public OsCredential throwOnErrors(boolean throwOnErrors) { this.throwOnErrors = throwOnErrors; return dirty(); }
/** if true (the default) this will look at default locations set on keys */ public OsCredential useDefaultKeys(boolean tryDefaultKeys) { this.tryDefaultKeys = tryDefaultKeys; return dirty(); } /** whether to log warnings on problems */