refactor addKnownHost
This commit is contained in:
parent
2071128371
commit
4452cf5d01
5 changed files with 55 additions and 29 deletions
|
@ -7,7 +7,7 @@ package org.domaindrivenarchitecture.provs.desktop.domain
|
|||
*/
|
||||
typealias HostKey = String
|
||||
|
||||
open class KnownHost protected constructor(
|
||||
open class KnownHost(
|
||||
val hostName: String,
|
||||
val hostKeys: List<HostKey>
|
||||
) {
|
||||
|
|
|
@ -6,6 +6,6 @@ import org.domaindrivenarchitecture.provs.framework.ubuntu.keys.base.addKnownHos
|
|||
|
||||
fun Prov.addKnownHosts(knownHosts: List<KnownHost> = KnownHost.values()) = task {
|
||||
for (knownHost in knownHosts) {
|
||||
addKnownHost(knownHost.hostName, knownHost.hostKeys, verifyKeys = true)
|
||||
addKnownHost(knownHost, verifyKeys = true)
|
||||
}
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
package org.domaindrivenarchitecture.provs.framework.ubuntu.keys.base
|
||||
|
||||
import org.domaindrivenarchitecture.provs.desktop.domain.KnownHost
|
||||
import org.domaindrivenarchitecture.provs.framework.core.Prov
|
||||
import org.domaindrivenarchitecture.provs.framework.core.ProvResult
|
||||
import org.domaindrivenarchitecture.provs.framework.ubuntu.filesystem.base.*
|
||||
|
@ -7,8 +8,6 @@ import org.domaindrivenarchitecture.provs.framework.ubuntu.keys.SshKeyPair
|
|||
import java.io.File
|
||||
|
||||
|
||||
const val KNOWN_HOSTS_FILE = "~/.ssh/known_hosts"
|
||||
|
||||
/**
|
||||
* Installs ssh keys for active user; ssh filenames depend on the ssh key type, e.g. for public key file: "id_rsa.pub", "id_id_ed25519.pub", etc
|
||||
*/
|
||||
|
@ -24,34 +23,37 @@ fun Prov.configureSshKeys(sshKeys: SshKeyPair) = task {
|
|||
*
|
||||
* @return whether if was found
|
||||
*/
|
||||
fun Prov.isHostKnown(hostOrIp: String) : Boolean {
|
||||
fun Prov.isHostKnown(hostOrIp: String): Boolean {
|
||||
return cmdNoEval("ssh-keygen -F $hostOrIp").out?.isNotEmpty() ?: false
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Adds ssh keys for specified host (which also can be an ip-address) to ssh-file "known_hosts"
|
||||
* Either add the specified keys or - if null - add keys automatically retrieved.
|
||||
* Note: adding keys automatically is vulnerable to a man-in-the-middle attack, thus considered insecure and not recommended.
|
||||
* Adds ssh keys for specified host (which also can be an ip-address) to the ssh-file "known_hosts".
|
||||
* If parameter verifyKeys is true the keys are checked against the live keys of the host and only added if valid.
|
||||
*/
|
||||
fun Prov.addKnownHost(host: String, keysToBeAdded: List<String>?, verifyKeys: Boolean = false) = task {
|
||||
if (!checkFile(KNOWN_HOSTS_FILE)) {
|
||||
fun Prov.addKnownHost(knownHost: KnownHost, verifyKeys: Boolean = false) = task {
|
||||
val knownHostsFile = "~/.ssh/known_hosts"
|
||||
|
||||
if (!checkFile(knownHostsFile)) {
|
||||
createDir(".ssh")
|
||||
createFile(KNOWN_HOSTS_FILE, null)
|
||||
createFile(knownHostsFile, null)
|
||||
}
|
||||
if (keysToBeAdded == null) {
|
||||
// auto add keys
|
||||
cmd("ssh-keyscan $host >> $KNOWN_HOSTS_FILE")
|
||||
} else {
|
||||
for (key in keysToBeAdded) {
|
||||
with(knownHost) {
|
||||
for (key in hostKeys) {
|
||||
if (!verifyKeys) {
|
||||
addTextToFile("\n$host $key\n", File(KNOWN_HOSTS_FILE))
|
||||
addTextToFile("\n$hostName $key\n", File(knownHostsFile))
|
||||
} else {
|
||||
val validKeys = getSshKeys(host)
|
||||
val validKeys = getSshKeys(hostName)
|
||||
if (validKeys?.contains(key) == true) {
|
||||
addTextToFile("\n$host $key\n", File(KNOWN_HOSTS_FILE))
|
||||
addTextToFile("\n$hostName $key\n", File(knownHostsFile))
|
||||
} else {
|
||||
addResultToEval(ProvResult(false, err = "The following key of host [$host] could not be verified successfully: " + key))
|
||||
addResultToEval(
|
||||
ProvResult(
|
||||
false,
|
||||
err = "The following key of host [$hostName] could not be verified successfully: " + key
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,6 @@ package org.domaindrivenarchitecture.provs.desktop.domain
|
|||
|
||||
import org.domaindrivenarchitecture.provs.framework.ubuntu.filesystem.base.deleteFile
|
||||
import org.domaindrivenarchitecture.provs.framework.ubuntu.install.base.aptInstall
|
||||
import org.domaindrivenarchitecture.provs.framework.ubuntu.keys.base.KNOWN_HOSTS_FILE
|
||||
import org.domaindrivenarchitecture.provs.test.defaultTestContainer
|
||||
import org.domaindrivenarchitecture.provs.test.tags.ContainerTest
|
||||
import org.junit.jupiter.api.Assertions.assertEquals
|
||||
|
@ -18,7 +17,7 @@ class KnownHostTest {
|
|||
val prov = defaultTestContainer()
|
||||
prov.task {
|
||||
aptInstall("ssh")
|
||||
deleteFile(KNOWN_HOSTS_FILE)
|
||||
deleteFile("~/.ssh/known_hosts")
|
||||
}
|
||||
|
||||
// when
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package org.domaindrivenarchitecture.provs.framework.ubuntu.keys.base
|
||||
|
||||
import org.domaindrivenarchitecture.provs.desktop.domain.KnownHost
|
||||
import org.domaindrivenarchitecture.provs.framework.core.Secret
|
||||
import org.domaindrivenarchitecture.provs.framework.ubuntu.filesystem.base.deleteFile
|
||||
import org.domaindrivenarchitecture.provs.framework.ubuntu.filesystem.base.fileContainsText
|
||||
|
@ -10,6 +11,8 @@ import org.domaindrivenarchitecture.provs.test.defaultTestContainer
|
|||
import org.domaindrivenarchitecture.provs.test.tags.ContainerTest
|
||||
import org.junit.jupiter.api.Assertions.*
|
||||
|
||||
const val KNOWN_HOSTS_FILE = "~/.ssh/known_hosts"
|
||||
|
||||
internal class SshKtTest {
|
||||
@ContainerTest
|
||||
fun configureSshKeys_for_ssh_type_rsa() {
|
||||
|
@ -48,7 +51,7 @@ internal class SshKtTest {
|
|||
}
|
||||
|
||||
@ContainerTest
|
||||
fun addKnownHost() {
|
||||
fun addKnownHost_without_verification() {
|
||||
// given
|
||||
val prov = defaultTestContainer()
|
||||
prov.task {
|
||||
|
@ -57,10 +60,8 @@ internal class SshKtTest {
|
|||
}
|
||||
|
||||
// when
|
||||
val res = prov.addKnownHost("github.com", listOf("dummyProtocol dummyKey", "dummyProtocol2 dummyKey2", ))
|
||||
val res2 = prov.addKnownHost("github.com", listOf("dummyProtocol dummyKey", "dummyProtocol2 dummyKey2", ))
|
||||
val res3 = prov.addKnownHost("github.com", listOf("ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOMqqnkVzrm0SdG6UOoqKLsabgH5C9okWi0dh2l9GKJl", ), verifyKeys = true)
|
||||
val res4 = prov.addKnownHost("github.com", listOf("ssh-ed25519 AAAAC3Nzalwrongkey!!!", ), verifyKeys = true)
|
||||
val res = prov.addKnownHost(KnownHost("github.com", listOf("dummyProtocol dummyKey", "dummyProtocol2 dummyKey2", )))
|
||||
val res2 = prov.addKnownHost(KnownHost("github.com", listOf("dummyProtocol dummyKey", "dummyProtocol2 dummyKey2", )))
|
||||
|
||||
// then
|
||||
assertTrue(res.success)
|
||||
|
@ -70,8 +71,32 @@ internal class SshKtTest {
|
|||
assertTrue(res2.success)
|
||||
val keyCount = prov.cmd("grep -o -i dummyKey2 $KNOWN_HOSTS_FILE | wc -l").out?.trim()
|
||||
assertEquals("1", keyCount)
|
||||
}
|
||||
|
||||
assertTrue(res3.success)
|
||||
assertFalse(res4.success)
|
||||
@ContainerTest
|
||||
fun addKnownHost_with_verifications() {
|
||||
// given
|
||||
val prov = defaultTestContainer()
|
||||
prov.task {
|
||||
aptInstall("ssh")
|
||||
deleteFile(KNOWN_HOSTS_FILE)
|
||||
}
|
||||
|
||||
// when
|
||||
val res1 = prov.addKnownHost(KnownHost.GITHUB, verifyKeys = true)
|
||||
val res2 = prov.addKnownHost(KnownHost.GITHUB, verifyKeys = true)
|
||||
|
||||
val invalidKey = "ssh-ed25519 AAAAC3Nzalwrongkey!!!"
|
||||
val res3 = prov.addKnownHost(KnownHost("github.com", listOf(invalidKey )), verifyKeys = true)
|
||||
|
||||
// then
|
||||
assertTrue(res1.success)
|
||||
assertTrue(prov.fileContainsText(KNOWN_HOSTS_FILE, KnownHost.GITHUB.hostKeys[0]))
|
||||
|
||||
assertTrue(res2.success)
|
||||
assertTrue(prov.fileContainsText(KNOWN_HOSTS_FILE, KnownHost.GITHUB.hostKeys[0]))
|
||||
|
||||
assertFalse(res3.success)
|
||||
assertFalse(prov.fileContainsText(KNOWN_HOSTS_FILE, invalidKey))
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue