diff --git a/Makefile.am b/Makefile.am
index 732c0d2b4799287feb5179f253672ed56d46d674..04fb36164a1622c913822694d5208d603be0ce73 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -681,8 +681,7 @@ python_scripts = \
 	tools/lvmstrap \
 	tools/move-instance \
 	tools/ovfconverter \
-	tools/sanitize-config \
-	tools/setup-ssh
+	tools/sanitize-config
 
 dist_tools_SCRIPTS = \
 	$(python_scripts) \
diff --git a/lib/pathutils.py b/lib/pathutils.py
index fba77d83f4ec132a4dd7a6c7d04b1b66f3c45be3..bab240911b4ce4c875314fab91fa5ad2ab1846e7 100644
--- a/lib/pathutils.py
+++ b/lib/pathutils.py
@@ -43,7 +43,6 @@ DAEMON_UTIL = _autoconf.PKGLIBDIR + "/daemon-util"
 IMPORT_EXPORT_DAEMON = _autoconf.PKGLIBDIR + "/import-export"
 KVM_CONSOLE_WRAPPER = _autoconf.PKGLIBDIR + "/tools/kvm-console-wrapper"
 KVM_IFUP = _autoconf.PKGLIBDIR + "/kvm-ifup"
-SETUP_SSH = _autoconf.TOOLSDIR + "/setup-ssh"
 PREPARE_NODE_JOIN = _autoconf.PKGLIBDIR + "/prepare-node-join"
 XM_CONSOLE_WRAPPER = _autoconf.PKGLIBDIR + "/tools/xm-console-wrapper"
 ETC_HOSTS = vcluster.ETC_HOSTS
@@ -139,4 +138,3 @@ def GetLogFilename(daemon_name):
 LOG_WATCHER = GetLogFilename("watcher")
 LOG_COMMANDS = GetLogFilename("commands")
 LOG_BURNIN = GetLogFilename("burnin")
-LOG_SETUP_SSH = GetLogFilename("setup-ssh")
diff --git a/tools/setup-ssh b/tools/setup-ssh
deleted file mode 100755
index dc2a7459f5ab8e5dd78f6cf7dfbecabe8942d043..0000000000000000000000000000000000000000
--- a/tools/setup-ssh
+++ /dev/null
@@ -1,507 +0,0 @@
-#!/usr/bin/python
-#
-
-# Copyright (C) 2010, 2012 Google Inc.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-# General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-# 02110-1301, USA.
-
-"""Tool to setup the SSH configuration on a remote node.
-
-This is needed before we can join the node into the cluster.
-
-"""
-
-# pylint: disable=C0103
-# C0103: Invalid name setup-ssh
-
-import getpass
-import logging
-import os.path
-import optparse
-import sys
-
-# workaround paramiko warnings
-# FIXME: use 'with warnings.catch_warnings' once we drop Python 2.4
-import warnings
-warnings.simplefilter("ignore")
-import paramiko
-warnings.resetwarnings()
-
-from ganeti import cli
-from ganeti import constants
-from ganeti import errors
-from ganeti import netutils
-from ganeti import ssconf
-from ganeti import ssh
-from ganeti import utils
-from ganeti import pathutils
-
-
-class RemoteCommandError(errors.GenericError):
-  """Exception if remote command was not successful.
-
-  """
-
-
-class JoinCheckError(errors.GenericError):
-  """Exception raised if join check fails.
-
-  """
-
-
-class HostKeyVerificationError(errors.GenericError):
-  """Exception if host key do not match.
-
-  """
-
-
-class AuthError(errors.GenericError):
-  """Exception for authentication errors to hosts.
-
-  """
-
-
-def _CheckJoin(transport):
-  """Checks if a join is safe or dangerous.
-
-  Note: This function relies on the fact, that all
-  hosts have the same configuration at compile time of
-  Ganeti. So that the constants do not mismatch.
-
-  @param transport: The paramiko transport instance
-  @return: True if the join is safe; False otherwise
-
-  """
-  sftp = transport.open_sftp_client()
-  ss = ssconf.SimpleStore()
-  ss_cluster_name_path = ss.KeyToFilename(constants.SS_CLUSTER_NAME)
-
-  cluster_files = [
-    (pathutils.NODED_CERT_FILE, utils.ReadFile(pathutils.NODED_CERT_FILE)),
-    (ss_cluster_name_path, utils.ReadFile(ss_cluster_name_path)),
-    ]
-
-  for (filename, local_content) in cluster_files:
-    try:
-      remote_content = _ReadSftpFile(sftp, filename)
-    except IOError, err:
-      # Assume file does not exist. Paramiko's error reporting is lacking.
-      logging.debug("Failed to read %s: %s", filename, err)
-      continue
-
-    if remote_content != local_content:
-      logging.error("File %s doesn't match local version", filename)
-      return False
-
-  return True
-
-
-def _RunRemoteCommand(transport, command):
-  """Invokes and wait for the command over SSH.
-
-  @param transport: The paramiko transport instance
-  @param command: The command to be executed
-
-  """
-  chan = transport.open_session()
-  chan.set_combine_stderr(True)
-  output_handler = chan.makefile("r")
-  chan.exec_command(command)
-
-  result = chan.recv_exit_status()
-  msg = output_handler.read()
-
-  out_msg = "'%s' exited with status code %s, output %r" % (command, result,
-                                                            msg)
-
-  # If result is -1 (no exit status provided) we assume it was not successful
-  if result:
-    raise RemoteCommandError(out_msg)
-
-  if msg:
-    logging.info(out_msg)
-
-
-def _InvokeDaemonUtil(transport, command):
-  """Invokes daemon-util on the remote side.
-
-  @param transport: The paramiko transport instance
-  @param command: The daemon-util command to be run
-
-  """
-  _RunRemoteCommand(transport, "%s %s" % (pathutils.DAEMON_UTIL, command))
-
-
-def _ReadSftpFile(sftp, filename):
-  """Reads a file over sftp.
-
-  @param sftp: An open paramiko SFTP client
-  @param filename: The filename of the file to read
-  @return: The content of the file
-
-  """
-  remote_file = sftp.open(filename, "r")
-  try:
-    return remote_file.read()
-  finally:
-    remote_file.close()
-
-
-def _WriteSftpFile(sftp, name, perm, data):
-  """SFTPs data to a remote file.
-
-  @param sftp: A open paramiko SFTP client
-  @param name: The remote file name
-  @param perm: The remote file permission
-  @param data: The data to write
-
-  """
-  remote_file = sftp.open(name, "w")
-  try:
-    sftp.chmod(name, perm)
-    remote_file.write(data)
-  finally:
-    remote_file.close()
-
-
-def SetupSSH(transport):
-  """Sets the SSH up on the other side.
-
-  @param transport: The paramiko transport instance
-
-  """
-  priv_key, pub_key, auth_keys = ssh.GetUserFiles(constants.SSH_LOGIN_USER)
-  keyfiles = [
-    (pathutils.SSH_HOST_DSA_PRIV, 0600),
-    (pathutils.SSH_HOST_DSA_PUB, 0644),
-    (pathutils.SSH_HOST_RSA_PRIV, 0600),
-    (pathutils.SSH_HOST_RSA_PUB, 0644),
-    (priv_key, 0600),
-    (pub_key, 0644),
-    ]
-
-  sftp = transport.open_sftp_client()
-
-  filemap = dict((name, (utils.ReadFile(name), perm))
-                 for (name, perm) in keyfiles)
-
-  auth_path = os.path.dirname(auth_keys)
-
-  try:
-    sftp.mkdir(auth_path, 0700)
-  except IOError, err:
-    # Sadly paramiko doesn't provide errno or similiar
-    # so we can just assume that the path already exists
-    logging.info("Assuming directory %s on remote node exists: %s",
-                 auth_path, err)
-
-  for name, (data, perm) in filemap.iteritems():
-    _WriteSftpFile(sftp, name, perm, data)
-
-  authorized_keys = sftp.open(auth_keys, "a+")
-  try:
-    # Due to the way SFTPFile and BufferedFile are implemented,
-    # opening in a+ mode and then issuing a read(), readline() or
-    # iterating over the file (which uses read() internally) will see
-    # an empty file, since the paramiko internal file position and the
-    # OS-level file-position are desynchronized; therefore, we issue
-    # an explicit seek to resynchronize these; writes should (note
-    # should) still go to the right place
-    authorized_keys.seek(0, 0)
-    # We don't have to close, as the close happened already in AddAuthorizedKey
-    utils.AddAuthorizedKey(authorized_keys, filemap[pub_key][0])
-  finally:
-    authorized_keys.close()
-
-  _InvokeDaemonUtil(transport, "reload-ssh-keys")
-
-
-def ParseOptions():
-  """Parses options passed to program.
-
-  """
-  program = os.path.basename(sys.argv[0])
-  (default_key, _, _) = ssh.GetUserFiles(constants.SSH_LOGIN_USER)
-
-  parser = optparse.OptionParser(usage=("%prog [--debug|--verbose] [--force]"
-                                        " <node> <node...>"), prog=program)
-  parser.add_option(cli.DEBUG_OPT)
-  parser.add_option(cli.VERBOSE_OPT)
-  parser.add_option(cli.NOSSH_KEYCHECK_OPT)
-  parser.add_option(optparse.Option("-f", dest="private_key",
-                                    default=default_key,
-                                    help="The private key to (try to) use for"
-                                    "authentication "))
-  parser.add_option(optparse.Option("--key-type", dest="key_type",
-                                    choices=("rsa", "dsa"), default="dsa",
-                                    help="The private key type (rsa or dsa)"))
-  parser.add_option(optparse.Option("-j", "--force-join", dest="force_join",
-                                    action="store_true", default=False,
-                                    help="Force the join of the host"))
-
-  (options, args) = parser.parse_args()
-
-  if not args:
-    parser.print_help()
-    sys.exit(constants.EXIT_FAILURE)
-
-  return (options, args)
-
-
-def SetupLogging(options):
-  """Sets up the logging.
-
-  @param options: Parsed options
-
-  """
-  fmt = "%(asctime)s: %(threadName)s "
-  if options.debug or options.verbose:
-    fmt += "%(levelname)s "
-  fmt += "%(message)s"
-
-  formatter = logging.Formatter(fmt)
-
-  file_handler = logging.FileHandler(pathutils.LOG_SETUP_SSH)
-  stderr_handler = logging.StreamHandler()
-  stderr_handler.setFormatter(formatter)
-  file_handler.setFormatter(formatter)
-  file_handler.setLevel(logging.INFO)
-
-  if options.debug:
-    stderr_handler.setLevel(logging.DEBUG)
-  elif options.verbose:
-    stderr_handler.setLevel(logging.INFO)
-  else:
-    stderr_handler.setLevel(logging.WARNING)
-
-  root_logger = logging.getLogger("")
-  root_logger.setLevel(logging.NOTSET)
-  root_logger.addHandler(stderr_handler)
-  root_logger.addHandler(file_handler)
-
-  # This is the paramiko logger instance
-  paramiko_logger = logging.getLogger("paramiko")
-  paramiko_logger.addHandler(file_handler)
-  # We don't want to debug Paramiko, so filter anything below warning
-  paramiko_logger.setLevel(logging.WARNING)
-
-
-def LoadPrivateKeys(options):
-  """Load the list of available private keys.
-
-  It loads the standard ssh key from disk and then tries to connect to
-  the ssh agent too.
-
-  @rtype: list
-  @return: a list of C{paramiko.PKey}
-
-  """
-  if options.key_type == "rsa":
-    pkclass = paramiko.RSAKey
-  elif options.key_type == "dsa":
-    pkclass = paramiko.DSSKey
-  else:
-    logging.critical("Unknown key type %s selected (choose either rsa or dsa)",
-                     options.key_type)
-    sys.exit(1)
-
-  try:
-    private_key = pkclass.from_private_key_file(options.private_key)
-  except (paramiko.SSHException, EnvironmentError), err:
-    logging.critical("Can't load private key %s: %s", options.private_key, err)
-    sys.exit(1)
-
-  try:
-    agent = paramiko.Agent()
-    agent_keys = agent.get_keys()
-  except paramiko.SSHException, err:
-    # this will only be seen when the agent is broken/uses invalid
-    # protocol; for non-existing agent, get_keys() will just return an
-    # empty tuple
-    logging.warning("Can't connect to the ssh agent: %s; skipping its use",
-                    err)
-    agent_keys = []
-
-  return [private_key] + list(agent_keys)
-
-
-def _FormatFingerprint(fpr):
-  """Formats a paramiko.PKey.get_fingerprint() human readable.
-
-  @param fpr: The fingerprint to be formatted
-  @return: A human readable fingerprint
-
-  """
-  return ssh.FormatParamikoFingerprint(paramiko.util.hexify(fpr))
-
-
-def LoginViaKeys(transport, username, keys):
-  """Try to login on the given transport via a list of keys.
-
-  @param transport: the transport to use
-  @param username: the username to login as
-  @type keys: list
-  @param keys: list of C{paramiko.PKey} to use for authentication
-  @rtype: boolean
-  @return: True or False depending on whether the login was
-      successfull or not
-
-  """
-  for private_key in keys:
-    try:
-      transport.auth_publickey(username, private_key)
-      fpr = _FormatFingerprint(private_key.get_fingerprint())
-      if isinstance(private_key, paramiko.AgentKey):
-        logging.debug("Authentication via the ssh-agent key %s", fpr)
-      else:
-        logging.debug("Authenticated via public key %s", fpr)
-      return True
-    except paramiko.SSHException:
-      continue
-  else:
-    # all keys exhausted
-    return False
-
-
-def LoadKnownHosts():
-  """Load the known hosts.
-
-  @return: paramiko.util.load_host_keys dict
-
-  """
-  homedir = utils.GetHomeDir(constants.SSH_LOGIN_USER)
-  known_hosts = os.path.join(homedir, ".ssh", "known_hosts")
-
-  try:
-    return paramiko.util.load_host_keys(known_hosts)
-  except EnvironmentError:
-    # We didn't find the path, silently ignore and return an empty dict
-    return {}
-
-
-def _VerifyServerKey(transport, host, host_keys):
-  """Verify the server keys.
-
-  @param transport: A paramiko.transport instance
-  @param host: Name of the host we verify
-  @param host_keys: Loaded host keys
-  @raises HostkeyVerificationError: When the host identify couldn't be verified
-
-  """
-
-  server_key = transport.get_remote_server_key()
-  keytype = server_key.get_name()
-
-  our_server_key = host_keys.get(host, {}).get(keytype, None)
-  if not our_server_key:
-    hexified_key = _FormatFingerprint(server_key.get_fingerprint())
-    msg = ("Unable to verify hostkey of host %s: %s. Do you want to accept"
-           " it?" % (host, hexified_key))
-
-    if cli.AskUser(msg):
-      our_server_key = server_key
-
-  if our_server_key != server_key:
-    raise HostKeyVerificationError("Unable to verify host identity")
-
-
-def main():
-  """Main routine.
-
-  """
-  (options, args) = ParseOptions()
-
-  SetupLogging(options)
-
-  all_keys = LoadPrivateKeys(options)
-
-  passwd = None
-  username = constants.SSH_LOGIN_USER
-  ssh_port = netutils.GetDaemonPort("ssh")
-  host_keys = LoadKnownHosts()
-
-  # Below, we need to join() the transport objects, as otherwise the
-  # following happens:
-  # - the main thread finishes
-  # - the atexit functions run (in the main thread), and cause the
-  #   logging file to be closed
-  # - a tiny bit later, the transport thread is finally ending, and
-  #   wants to log one more message, which fails as the file is closed
-  #   now
-
-  success = True
-
-  for host in args:
-    logging.info("Configuring %s", host)
-
-    transport = paramiko.Transport((host, ssh_port))
-    try:
-      try:
-        transport.start_client()
-
-        if options.ssh_key_check:
-          _VerifyServerKey(transport, host, host_keys)
-
-        try:
-          if LoginViaKeys(transport, username, all_keys):
-            logging.info("Authenticated to %s via public key", host)
-          else:
-            if all_keys:
-              logging.warning("Authentication to %s via public key failed,"
-                              " trying password", host)
-            if passwd is None:
-              passwd = getpass.getpass(prompt="%s password:" % username)
-            transport.auth_password(username=username, password=passwd)
-            logging.info("Authenticated to %s via password", host)
-        except paramiko.SSHException, err:
-          raise AuthError("Auth error TODO" % err)
-
-        if not _CheckJoin(transport):
-          if not options.force_join:
-            raise JoinCheckError(("Host %s failed join check; Please verify"
-                                  " that the host was not previously joined"
-                                  " to another cluster and use --force-join"
-                                  " to continue") % host)
-
-          logging.warning("Host %s failed join check, forced to continue",
-                          host)
-
-        SetupSSH(transport)
-        logging.info("%s successfully configured", host)
-      finally:
-        transport.close()
-        # this is needed for compatibility with older Paramiko or Python
-        # versions
-        transport.join()
-    except AuthError, err:
-      logging.error("Authentication error: %s", err)
-      success = False
-      break
-    except HostKeyVerificationError, err:
-      logging.error("Host key verification error: %s", err)
-      success = False
-    except Exception, err:
-      logging.exception("During setup of %s: %s", host, err)
-      success = False
-
-  if success:
-    sys.exit(constants.EXIT_SUCCESS)
-
-  sys.exit(constants.EXIT_FAILURE)
-
-
-if __name__ == "__main__":
-  main()