From 5d66f5106e77c378e387c9c9159a3fdc150b0818 Mon Sep 17 00:00:00 2001
From: Henrik Riomar <henrik.riomar@gmail.com>
Date: Sun, 19 Feb 2017 21:10:27 +0100
Subject: [PATCH] ssh.strict_hostkey_checking configurable

Make ssh StrictHostKeyChecking configurable in safekeep.conf with
'ask' as default if not configured.
---
 doc/safekeep.conf.txt |  9 +++++++++
 safekeep              | 14 +++++++++++---
 2 files changed, 20 insertions(+), 3 deletions(-)

diff --git a/doc/safekeep.conf.txt b/doc/safekeep.conf.txt
index 43fff57..11f6876 100644
--- a/doc/safekeep.conf.txt
+++ b/doc/safekeep.conf.txt
@@ -151,6 +151,15 @@ ssh.keygen.bits::
 	option with no corresponding bit size.
 	This value is optional, it defaults to '4096'.
 
+ssh.strict_hostkey_checking::
+	Specifies if StrictHostKeyChecking should be performed by the ssh
+	client when connecting to the remote host.
+	This value is optional, it defaults to 'ask'.
+	Set to 'yes' if you sign host keys with a CA key or manage host keys
+	by other means (FreeIPA/sssd, Ansible,,,).
+	Setting this to 'no' is a bit unsafe as new hosts are automatically
+	added to known_hosts without any validation.
+
 NOTES
 -----
 Safekeep uses `trickle` to implement bandwidth throttling (see
diff --git a/safekeep b/safekeep
index 4cbf374..43b6cd1 100755
--- a/safekeep
+++ b/safekeep
@@ -79,6 +79,8 @@ ssh_keygen_type = 'rsa'
 ssh_keygen_bits = 4096
 SSH_TYPES = ['dsa', 'rsa', 'ed25519', 'ecdsa']
 SSH_KEY_TYPES = ['ssh-dss', 'ssh-rsa', 'ssh-ed25519', 'ecdsa-sha2-nistp256', 'ecdsa-sha2-nistp384', 'ecdsa-sha2-nistp521']
+ssh_StrictHostKeyChecking = 'ask'
+SSH_STRICT_HOSTKEY_CHECK_OPTS = ['ask', 'yes', 'no' ]
 # Default mount options, overridden elsewhere:
 # Key is a file system type, or 'snapshot' for default for snapshot mount
 # or 'bind' for a bind mount (check mount for details)
@@ -1548,7 +1550,7 @@ def do_server_rdiff(cfg, bdir, nice, ionice, force):
     args.extend(['rdiff-backup'])
 
     if cfg['host']:
-        basessh = 'ssh -oStrictHostKeyChecking=no'
+        basessh = 'ssh -oStrictHostKeyChecking=%s' % (ssh_StrictHostKeyChecking)
         if cfg['port']: basessh += ' -p %s' % cfg['port']
         schema = '%s %s -i %s %%s rdiff-backup --server' % (basessh, verbosity_ssh, cfg['key_data'])
         args.extend(['--remote-schema', schema])
@@ -1694,6 +1696,7 @@ def do_server(cfgs, ids, nice, ionice, force, cleanup):
                 cmd.extend(['ssh'])
                 if verbosity_ssh: cmd.extend([verbosity_ssh])
                 if cfg['port']: cmd.extend(['-p', cfg['port']])
+                cmd.extend(['-oStrictHostKeyChecking=%s' % (ssh_StrictHostKeyChecking)])
                 cmd.extend(['-T', '-i', cfg['key_ctrl'], '-l', cfg['user'], cfg['host']])
             cmd.extend(['safekeep', '--client'])
 
@@ -1977,7 +1980,7 @@ def do_keys(cfgs, ids, nice_rem, identity, status, dump, deploy):
         if dump:
             print output
 
-        basessh = ['ssh', '-oStrictHostKeyChecking=no']
+        basessh = ['ssh', '-oStrictHostKeyChecking=%s' % (ssh_StrictHostKeyChecking) ]
         if cfg['port']: basessh.append('-p %s' % cfg['port'])
         if identity: basessh.append('-i %s' % (commands.mkarg(identity)))
 
@@ -2306,7 +2309,7 @@ def main():
                 default_snapshot += 'FREE'
             client_defaults.append('snapshot.size=%s' % default_snapshot)
 
-        global ssh_keygen_type, ssh_keygen_bits
+        global ssh_keygen_type, ssh_keygen_bits, ssh_StrictHostKeyChecking
         if 'ssh.keygen.type' in props:
             ssh_keygen_type = props['ssh.keygen.type']
             if ssh_keygen_type not in SSH_TYPES:
@@ -2324,6 +2327,11 @@ def main():
             else:
                 # For cases where no bit size is required
                 ssh_keygen_bits = 0
+        if 'ssh.strict_hostkey_checking' in props:
+                ssh_StrictHostKeyChecking = props['ssh.strict_hostkey_checking']
+                if ssh_StrictHostKeyChecking not in SSH_STRICT_HOSTKEY_CHECK_OPTS:
+                    error('CONFIG ERROR: invalid ssh.strict_hostkey_checking value: %s' % props['ssh.strict_hostkey_checking'])
+                    sys.exit(2)
 
         if len(cfglocs) == 0:
             locs = os.path.join(os.path.dirname(cfgfile), 'backup.d')
-- 
2.1.4

