def testRemoveAllExistingKeys(self):
    pub_key_file = self._CreateTempFile()
    ssh.AddPublicKey(self.UUID_1, self.KEY_A, key_file=pub_key_file)
    ssh.AddPublicKey(self.UUID_1, self.KEY_B, key_file=pub_key_file)
    self.assertFileContent(pub_key_file,
      "123-456 ssh-dss AAAAB3NzaC1w5256closdj32mZaQU root@key-a\n"
      "123-456 ssh-dss BAasjkakfa234SFSFDA345462AAAB root@key-b\n")

    ssh.RemovePublicKey(self.UUID_1, key_file=pub_key_file)
    self.assertFileContent(pub_key_file, "")
Exemple #2
0
def _SetupSSH(options, cluster_name, node, ssh_port, cl):
  """Configures a destination node's SSH daemon.

  @param options: Command line options
  @type cluster_name
  @param cluster_name: Cluster name
  @type node: string
  @param node: Destination node name
  @type ssh_port: int
  @param ssh_port: Destination node ssh port
  @param cl: luxi client

  """
  # Retrieve the list of master and master candidates
  candidate_filter = ["|", ["=", "role", "M"], ["=", "role", "C"]]
  result = cl.Query(constants.QR_NODE, ["uuid"], candidate_filter)
  if len(result.data) < 1:
    raise errors.OpPrereqError("No master or master candidate node is found.")
  candidates = [uuid for ((_, uuid),) in result.data]
  candidate_keys = ssh.QueryPubKeyFile(candidates)

  if options.force_join:
    ToStderr("The \"--force-join\" option is no longer supported and will be"
             " ignored.")

  host_keys = _ReadSshKeys(constants.SSH_DAEMON_KEYFILES)

  (_, root_keyfiles) = \
    ssh.GetAllUserFiles(constants.SSH_LOGIN_USER, mkdir=False, dircheck=False)

  dsa_root_keyfiles = dict((kind, value) for (kind, value)
                           in root_keyfiles.items()
                           if kind == constants.SSHK_DSA)
  root_keys = _ReadSshKeys(dsa_root_keyfiles)

  (_, cert_pem) = \
    utils.ExtractX509Certificate(utils.ReadFile(pathutils.NODED_CERT_FILE))

  data = {
    constants.SSHS_CLUSTER_NAME: cluster_name,
    constants.SSHS_NODE_DAEMON_CERTIFICATE: cert_pem,
    constants.SSHS_SSH_HOST_KEY: host_keys,
    constants.SSHS_SSH_ROOT_KEY: root_keys,
    constants.SSHS_SSH_AUTHORIZED_KEYS: candidate_keys,
    }

  ssh.RunSshCmdWithStdin(cluster_name, node, pathutils.PREPARE_NODE_JOIN,
                         ssh_port, data,
                         debug=options.debug, verbose=options.verbose,
                         use_cluster_key=False, ask_key=options.ssh_key_check,
                         strict_host_check=options.ssh_key_check)

  (_, dsa_pub_keyfile) = root_keyfiles[constants.SSHK_DSA]
  pub_key = ssh.ReadRemoteSshPubKeys(dsa_pub_keyfile, node, cluster_name,
                                     ssh_port, options.ssh_key_check,
                                     options.ssh_key_check)
  # Unfortunately, we have to add the key with the node name rather than
  # the node's UUID here, because at this point, we do not have a UUID yet.
  # The entry will be corrected in noded later.
  ssh.AddPublicKey(node, pub_key)
  def testReplaceNameByUuid(self):
    pub_key_file = self._CreateTempFile()
    name = "my.precious.node"
    ssh.AddPublicKey(name, self.KEY_A, key_file=pub_key_file)
    ssh.AddPublicKey(self.UUID_2, self.KEY_A, key_file=pub_key_file)
    ssh.AddPublicKey(name, self.KEY_B, key_file=pub_key_file)
    self.assertFileContent(pub_key_file,
      "my.precious.node ssh-dss AAAAB3NzaC1w5256closdj32mZaQU root@key-a\n"
      "789-ABC ssh-dss AAAAB3NzaC1w5256closdj32mZaQU root@key-a\n"
      "my.precious.node ssh-dss BAasjkakfa234SFSFDA345462AAAB root@key-b\n")

    ssh.ReplaceNameByUuid(self.UUID_1, name, key_file=pub_key_file)
    self.assertFileContent(pub_key_file,
      "123-456 ssh-dss AAAAB3NzaC1w5256closdj32mZaQU root@key-a\n"
      "789-ABC ssh-dss AAAAB3NzaC1w5256closdj32mZaQU root@key-a\n"
      "123-456 ssh-dss BAasjkakfa234SFSFDA345462AAAB root@key-b\n")
  def testAddingExistingPubKey(self):
    expected_file_content = \
      "123-456 ssh-dss AAAAB3NzaC1w5256closdj32mZaQU root@key-a\n" + \
      "789-ABC ssh-dss BAasjkakfa234SFSFDA345462AAAB root@key-b\n"
    pub_key_file = self._CreateTempFile()
    ssh.AddPublicKey(self.UUID_1, self.KEY_A, key_file=pub_key_file)
    ssh.AddPublicKey(self.UUID_2, self.KEY_B, key_file=pub_key_file)
    self.assertFileContent(pub_key_file, expected_file_content)

    ssh.AddPublicKey(self.UUID_1, self.KEY_A, key_file=pub_key_file)
    self.assertFileContent(pub_key_file, expected_file_content)

    ssh.AddPublicKey(self.UUID_1, self.KEY_B, key_file=pub_key_file)
    self.assertFileContent(pub_key_file,
      "123-456 ssh-dss AAAAB3NzaC1w5256closdj32mZaQU root@key-a\n"
      "789-ABC ssh-dss BAasjkakfa234SFSFDA345462AAAB root@key-b\n"
      "123-456 ssh-dss BAasjkakfa234SFSFDA345462AAAB root@key-b\n")
    def testParseEmptyLines(self):
        pub_key_file = self._CreateTempFile()
        ssh.AddPublicKey(self.UUID_1, self.KEY_A, key_file=pub_key_file)

        # Add an empty line
        fd = open(pub_key_file, 'a')
        fd.write("\n")
        fd.close()

        ssh.AddPublicKey(self.UUID_2, self.KEY_B, key_file=pub_key_file)

        # Add a whitespace line
        fd = open(pub_key_file, 'a')
        fd.write("    \n")
        fd.close()

        result = ssh.QueryPubKeyFile(self.UUID_1, key_file=pub_key_file)
        self.assertEquals([self.KEY_A], result[self.UUID_1])
    def testRetrieveKeys(self):
        pub_key_file = self._CreateTempFile()
        ssh.AddPublicKey(self.UUID_1, self.KEY_A, key_file=pub_key_file)
        ssh.AddPublicKey(self.UUID_2, self.KEY_B, key_file=pub_key_file)
        result = ssh.QueryPubKeyFile(self.UUID_1, key_file=pub_key_file)
        self.assertEquals([self.KEY_A], result[self.UUID_1])

        target_uuids = [self.UUID_1, self.UUID_2, "non-existing-UUID"]
        result = ssh.QueryPubKeyFile(target_uuids, key_file=pub_key_file)
        self.assertEquals([self.KEY_A], result[self.UUID_1])
        self.assertEquals([self.KEY_B], result[self.UUID_2])
        self.assertEquals(2, len(result))

        # Query all keys
        target_uuids = None
        result = ssh.QueryPubKeyFile(target_uuids, key_file=pub_key_file)
        self.assertEquals([self.KEY_A], result[self.UUID_1])
        self.assertEquals([self.KEY_B], result[self.UUID_2])
  def testRemoveNonexistingKey(self):
    pub_key_file = self._CreateTempFile()
    ssh.AddPublicKey(self.UUID_1, self.KEY_B, key_file=pub_key_file)
    self.assertFileContent(pub_key_file,
      "123-456 ssh-dss BAasjkakfa234SFSFDA345462AAAB root@key-b\n")

    ssh.RemovePublicKey(self.UUID_2, key_file=pub_key_file)
    self.assertFileContent(pub_key_file,
      "123-456 ssh-dss BAasjkakfa234SFSFDA345462AAAB root@key-b\n")
Exemple #8
0
def UpdatePubKeyFile(data, dry_run, key_file=pathutils.SSH_PUB_KEYS):
    """Updates the file of public SSH keys.

  @type data: dict
  @param data: Input data
  @type dry_run: boolean
  @param dry_run: Whether to perform a dry run

  """
    instructions = data.get(constants.SSHS_SSH_PUBLIC_KEYS)
    if not instructions:
        logging.info("No instructions to modify public keys received."
                     " Not modifying the public key file at all.")
        return
    (action, public_keys) = instructions

    if action == constants.SSHS_OVERRIDE:
        if dry_run:
            logging.info("This is a dry run, not overriding %s", key_file)
        else:
            ssh.OverridePubKeyFile(public_keys, key_file=key_file)
    elif action in [constants.SSHS_ADD, constants.SSHS_REPLACE_OR_ADD]:
        if dry_run:
            logging.info(
                "This is a dry run, not adding or replacing a key to %s",
                key_file)
        else:
            for uuid, keys in public_keys.items():
                if action == constants.SSHS_REPLACE_OR_ADD:
                    ssh.RemovePublicKey(uuid, key_file=key_file)
                for key in keys:
                    ssh.AddPublicKey(uuid, key, key_file=key_file)
    elif action == constants.SSHS_REMOVE:
        if dry_run:
            logging.info("This is a dry run, not removing keys from %s",
                         key_file)
        else:
            for uuid in public_keys.keys():
                ssh.RemovePublicKey(uuid, key_file=key_file)
    elif action == constants.SSHS_CLEAR:
        if dry_run:
            logging.info("This is a dry run, not clearing file %s", key_file)
        else:
            ssh.ClearPubKeyFile(key_file=key_file)
    else:
        raise SshUpdateError("Action '%s' not implemented for public keys." %
                             action)
 def testClearPubKeyFile(self):
     pub_key_file = self._CreateTempFile()
     ssh.AddPublicKey(self.UUID_2, self.KEY_A, key_file=pub_key_file)
     ssh.ClearPubKeyFile(key_file=pub_key_file)
     self.assertFileContent(pub_key_file, "")