move ssh function as trustHost to correct file
This commit is contained in:
parent
2cd5ae5c7c
commit
10e5bf933e
2 changed files with 71 additions and 80 deletions
|
@ -2,13 +2,11 @@ package org.domaindrivenarchitecture.provs.framework.ubuntu.git.base
|
|||
|
||||
import org.domaindrivenarchitecture.provs.framework.core.Prov
|
||||
import org.domaindrivenarchitecture.provs.framework.core.ProvResult
|
||||
import org.domaindrivenarchitecture.provs.framework.ubuntu.keys.base.isHostKnown
|
||||
import org.domaindrivenarchitecture.provs.framework.core.echoCommandForText
|
||||
import org.domaindrivenarchitecture.provs.framework.ubuntu.filesystem.base.*
|
||||
import org.domaindrivenarchitecture.provs.framework.ubuntu.keys.base.KNOWN_HOSTS_FILE
|
||||
import org.domaindrivenarchitecture.provs.framework.ubuntu.keys.base.trustHost
|
||||
import java.io.File
|
||||
|
||||
val knownHostsFile = "~/.ssh/known_hosts"
|
||||
|
||||
|
||||
fun Prov.gitClone(repo: String, path: String, pullIfExisting: Boolean = true): ProvResult = task {
|
||||
val dir = cmdNoEval("basename $repo .git").out?.trim()
|
||||
|
@ -49,68 +47,6 @@ fun Prov.trustGitlab() = task {
|
|||
gitlab.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCsj2bNKTBSpIYDEGk9KxsGh3mySTRgMtXL583qmBpzeQ+jqCMRgBqB98u3z++J1sKlXHWfM9dyhSevkMwSbhoR8XIq/U0tCNyokEi/ueaBMCvbcTHhO7FcwzY92WK4Yt0aGROY5qX2UKSeOvuP4D6TPqKF1onrSzH9bx9XUf2lEdWT/ia1NEKjunUqu1xOB/StKDHMoX4/OKyIzuS0q/T1zOATthvasJFoPrAjkohTyaDUz2LN5JoH839hViyEG82yB+MjcFV5MU3N1l1QL3cVUCh93xSaua1N85qivl+siMkPGbO5xR/En4iEY6K2XPASUEMaieWVNTRCtJ4S8H+9
|
||||
gitlab.com ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBFSMqzJeV9rUzU4kWitGjeR4PWSa29SPqJ1fVkhtj3Hw9xjLVXVYrU9QlYWrOLXBpQ6KWjbjTDTdDkoohFzgbEY=
|
||||
""".trimIndent()
|
||||
addTextToFile("\n" + gitlabFingerprints + "\n", File(knownHostsFile))
|
||||
addTextToFile("\n" + gitlabFingerprints + "\n", File(KNOWN_HOSTS_FILE))
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Adds ssh keys for specified host (which also can be an ip-address) to ssh-file "known_hosts"
|
||||
* Either add the specified rsaFingerprints or - if null - add automatically retrieved keys.
|
||||
* Note: adding keys automatically is vulnerable to a man-in-the-middle attack and not considered secure.
|
||||
*/
|
||||
// todo: consider making function public and moving to ssh package
|
||||
private fun Prov.trustHost(host: String, fingerprintsOfKeysToBeAdded: Set<String>?) = task {
|
||||
if (isHostKnown(host)) {
|
||||
return@task ProvResult(true, out = "Host already known")
|
||||
}
|
||||
if (!checkFile(knownHostsFile)) {
|
||||
createDir(".ssh")
|
||||
createFile(knownHostsFile, null)
|
||||
}
|
||||
if (fingerprintsOfKeysToBeAdded == null) {
|
||||
// auto add keys
|
||||
cmd("ssh-keyscan $host >> $knownHostsFile")
|
||||
} else {
|
||||
// logic based on https://serverfault.com/questions/447028/non-interactive-git-clone-ssh-fingerprint-prompt
|
||||
val actualKeys = findSshKeys(host)
|
||||
if (actualKeys == null || actualKeys.size == 0) {
|
||||
return@task ProvResult(false, out = "No valid keys found for host: $host")
|
||||
}
|
||||
val actualFingerprints = getFingerprintsForKeys(actualKeys)
|
||||
for (fingerprintToBeAdded in fingerprintsOfKeysToBeAdded) {
|
||||
var indexOfKeyFound = -1
|
||||
|
||||
// search for fingerprint in actual fingerprints
|
||||
for ((i, actualFingerprint) in actualFingerprints.withIndex()) {
|
||||
if (actualFingerprint.contains(fingerprintToBeAdded)) {
|
||||
indexOfKeyFound = i
|
||||
break
|
||||
}
|
||||
}
|
||||
if (indexOfKeyFound == -1) {
|
||||
return@task ProvResult(
|
||||
false,
|
||||
err = "Fingerprint ($fingerprintToBeAdded) could not be found in actual fingerprints: $actualFingerprints"
|
||||
)
|
||||
}
|
||||
cmd(echoCommandForText(actualKeys.get(indexOfKeyFound) + "\n") + " >> $knownHostsFile")
|
||||
}
|
||||
ProvResult(true)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a list of valid ssh keys for the given host (host can also be an ip address)
|
||||
*/
|
||||
private fun Prov.findSshKeys(host: String): List<String>? {
|
||||
return cmd("ssh-keyscan $host 2>/dev/null").out?.split("\n")?.filter { x -> "" != x }
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a list of fingerprints of the given sshKeys; the returning list has same size and order as the specified list of sshKeys
|
||||
*/
|
||||
private fun Prov.getFingerprintsForKeys(sshKeys: List<String>): List<String> {
|
||||
return sshKeys.map { x -> cmd("echo \"$x\" | ssh-keygen -lf -").out ?: "" }
|
||||
}
|
||||
|
|
|
@ -1,11 +1,18 @@
|
|||
package org.domaindrivenarchitecture.provs.framework.ubuntu.keys.base
|
||||
|
||||
import org.domaindrivenarchitecture.provs.framework.core.Prov
|
||||
import org.domaindrivenarchitecture.provs.framework.core.ProvResult
|
||||
import org.domaindrivenarchitecture.provs.framework.core.echoCommandForText
|
||||
import org.domaindrivenarchitecture.provs.framework.ubuntu.filesystem.base.checkFile
|
||||
import org.domaindrivenarchitecture.provs.framework.ubuntu.filesystem.base.createDir
|
||||
import org.domaindrivenarchitecture.provs.framework.ubuntu.filesystem.base.createFile
|
||||
import org.domaindrivenarchitecture.provs.framework.ubuntu.filesystem.base.createSecretFile
|
||||
import org.domaindrivenarchitecture.provs.framework.ubuntu.keys.KeyPair
|
||||
|
||||
|
||||
const val KNOWN_HOSTS_FILE = "~/.ssh/known_hosts"
|
||||
|
||||
|
||||
/**
|
||||
* installs ssh keys for active user
|
||||
*/
|
||||
|
@ -16,19 +23,6 @@ fun Prov.configureSshKeys(sshKeys: KeyPair) = task {
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* Specifies a host or Ip to be trusted
|
||||
*
|
||||
* ATTENTION:
|
||||
* This method is NOT secure as a man-in-the-middle could compromise the connection.
|
||||
* Don't use this for critical systems resp. environments
|
||||
*/
|
||||
@Suppress("unused")
|
||||
fun Prov.trustServer(hostOrIp: String) = task {
|
||||
cmd("ssh-keyscan $hostOrIp >> ~/.ssh/known_hosts")
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Checks if the specified hostname or Ip is in a known_hosts file
|
||||
*
|
||||
|
@ -38,3 +32,64 @@ 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 rsaFingerprints or - if null - add automatically retrieved keys.
|
||||
* Note: adding keys automatically is vulnerable to a man-in-the-middle attack, thus considered insecure and not recommended.
|
||||
*/
|
||||
fun Prov.trustHost(host: String, fingerprintsOfKeysToBeAdded: Set<String>?) = task {
|
||||
if (isHostKnown(host)) {
|
||||
return@task ProvResult(true, out = "Host already known")
|
||||
}
|
||||
if (!checkFile(KNOWN_HOSTS_FILE)) {
|
||||
createDir(".ssh")
|
||||
createFile(KNOWN_HOSTS_FILE, null)
|
||||
}
|
||||
if (fingerprintsOfKeysToBeAdded == null) {
|
||||
// auto add keys
|
||||
cmd("ssh-keyscan $host >> $KNOWN_HOSTS_FILE")
|
||||
} else {
|
||||
// logic based on https://serverfault.com/questions/447028/non-interactive-git-clone-ssh-fingerprint-prompt
|
||||
val actualKeys = findSshKeys(host)
|
||||
if (actualKeys == null || actualKeys.size == 0) {
|
||||
return@task ProvResult(false, out = "No valid keys found for host: $host")
|
||||
}
|
||||
val actualFingerprints = getFingerprintsForKeys(actualKeys)
|
||||
for (fingerprintToBeAdded in fingerprintsOfKeysToBeAdded) {
|
||||
var indexOfKeyFound = -1
|
||||
|
||||
// search for fingerprint in actual fingerprints
|
||||
for ((i, actualFingerprint) in actualFingerprints.withIndex()) {
|
||||
if (actualFingerprint.contains(fingerprintToBeAdded)) {
|
||||
indexOfKeyFound = i
|
||||
break
|
||||
}
|
||||
}
|
||||
if (indexOfKeyFound == -1) {
|
||||
return@task ProvResult(
|
||||
false,
|
||||
err = "Fingerprint ($fingerprintToBeAdded) could not be found in actual fingerprints: $actualFingerprints"
|
||||
)
|
||||
}
|
||||
cmd(echoCommandForText(actualKeys.get(indexOfKeyFound) + "\n") + " >> $KNOWN_HOSTS_FILE")
|
||||
}
|
||||
ProvResult(true)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a list of valid ssh keys for the given host (host can also be an ip address)
|
||||
*/
|
||||
private fun Prov.findSshKeys(host: String): List<String>? {
|
||||
return cmd("ssh-keyscan $host 2>/dev/null").out?.split("\n")?.filter { x -> "" != x }
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a list of fingerprints of the given sshKeys; the returning list has same size and order as the specified list of sshKeys
|
||||
*/
|
||||
private fun Prov.getFingerprintsForKeys(sshKeys: List<String>): List<String> {
|
||||
return sshKeys.map { x -> cmd("echo \"$x\" | ssh-keygen -lf -").out ?: "" }
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue