Ejemplo n.º 1
0
 def delete_account(self, user):
     """
     Delete the 'user'.
     Clear utmp first, to avoid error.
     Removes the /etc/sudoers.d/waagent file.
     """
     userentry = None
     try:
         userentry = pwd.getpwnam(user)
     except (EnvironmentError, KeyError):
         pass
     if userentry is None:
         logger.error("DeleteAccount: " + user + " not found.")
         return
     uidmin = None
     try:
         if os.path.isfile("/etc/login.defs"):
             uidmin = int(
                 ext_utils.get_line_starting_with("UID_MIN", "/etc/login.defs").split()[1])
     except (ValueError, KeyError, AttributeError, EnvironmentError):
         pass
     if uidmin is None:
         uidmin = 100
     if userentry[2] < uidmin:
         logger.error(
             "DeleteAccount: " + user + " is a system user. Will not delete account.")
         return
     # empty contents of utmp to prevent error if we are the 'user' deleted
     ext_utils.run_command_and_write_stdout_to_file(['echo'], '/var/run/utmp')
     ext_utils.run(['rmuser', '-y', user], chk_err=False)
     try:
         os.remove(self.sudoers_dir_base + "/sudoers.d/waagent")
     except EnvironmentError:
         pass
     return
    def test_code_injection2(self):
        self.setup()
        self.addCleanup(self.cleanup)
        # failure cases
        out_file = self.get_random_filename()
        exit_code = ext_utils.run_command_and_write_stdout_to_file(
            "echo hello; echo world", out_file)
        self.assertNotEqual(0, exit_code, "exit code != 0")

        out_file = self.get_random_filename()
        exit_code = ext_utils.run_command_and_write_stdout_to_file(
            ["echo hello; echo world"], out_file)
        self.assertNotEqual(0, exit_code, "exit code != 0")

        # success case
        out_file = self.get_random_filename()
        exit_code = ext_utils.run_command_and_write_stdout_to_file(
            ["echo", "hello", ";", "echo", "world"], out_file)
        self.assertEqual(0, exit_code, "exit code == 0")
        file_contents = ext_utils.get_file_contents(out_file)
        self.assertEqual("hello ; echo world\n", file_contents,
                         "unexpected output")

        out_file = self.get_random_filename()
        exit_code = ext_utils.run_command_and_write_stdout_to_file(
            ["echo", "hello", "world"], out_file)
        self.assertEqual(0, exit_code, "exit code == 0")
        file_contents = ext_utils.get_file_contents(out_file)
        self.assertEqual("hello world\n", file_contents, "unexpected output")
Ejemplo n.º 3
0
 def create_account(self, user, password, expiration, thumbprint):
     """
     Create a user account, with 'user', 'password', 'expiration', ssh keys
     and sudo permissions.
     Returns None if successful, error string on failure.
     """
     userentry = None
     try:
         userentry = pwd.getpwnam(user)
     except (EnvironmentError, KeyError):
         pass
     uidmin = None
     try:
         uidmin = int(ext_utils.get_line_starting_with("UID_MIN", "/etc/login.defs").split()[1])
     except (ValueError, KeyError, AttributeError, EnvironmentError):
         pass
     if uidmin is None:
         uidmin = 100
     if userentry is not None and userentry[2] < uidmin and userentry[2] != self.CORE_UID:
         logger.error(
             "CreateAccount: " + user + " is a system user. Will not set password.")
         return "Failed to set password for system user: "******" (0x06)."
     if userentry is None:
         command = ['useradd', '--create-home',  '--password', '*',  user]
         if expiration is not None:
             command += ['--expiredate', expiration.split('.')[0]]
         if ext_utils.run(command):
             logger.error("Failed to create user account: " + user)
             return "Failed to create user account: " + user + " (0x07)."
     else:
         logger.log("CreateAccount: " + user + " already exists. Will update password.")
     if password is not None:
         self.change_password(user, password)
     try:
         if password is None:
             ext_utils.set_file_contents("/etc/sudoers.d/waagent", user + " ALL = (ALL) NOPASSWD: ALL\n")
         else:
             ext_utils.set_file_contents("/etc/sudoers.d/waagent", user + " ALL = (ALL) ALL\n")
         os.chmod("/etc/sudoers.d/waagent", 0o440)
     except EnvironmentError:
         logger.error("CreateAccount: Failed to configure sudo access for user.")
         return "Failed to configure sudo privileges (0x08)."
     home = self.get_home()
     if thumbprint is not None:
         ssh_dir = home + "/" + user + "/.ssh"
         ext_utils.create_dir(ssh_dir, user, 0o700)
         pub = ssh_dir + "/id_rsa.pub"
         prv = ssh_dir + "/id_rsa"
         ext_utils.run_command_and_write_stdout_to_file(['ssh-keygen', '-y', '-f', thumbprint + '.prv'], pub)
         ext_utils.set_file_contents(prv, ext_utils.get_file_contents(thumbprint + ".prv"))
         for f in [pub, prv]:
             os.chmod(f, 0o600)
             ext_utils.change_owner(f, user)
         ext_utils.set_file_contents(ssh_dir + "/authorized_keys", ext_utils.get_file_contents(pub))
         ext_utils.change_owner(ssh_dir + "/authorized_keys", user)
     logger.log("Created user account: " + user)
     return None
Ejemplo n.º 4
0
 def ssh_deploy_public_key(self, fprint, path):
     """
     Generic sshDeployPublicKey - over-ridden in some concrete Distro classes due to minor differences
     in openssl packages deployed
     """
     keygen_retcode = ext_utils.run_command_and_write_stdout_to_file(
         ['ssh-keygen', '-i', '-m', 'PKCS8', '-f', fprint], path)
     if keygen_retcode:
         return 1
     else:
         return 0
Ejemplo n.º 5
0
def _set_user_account_pub_key(protect_settings, hutil):
    ovf_xml = None
    ovf_env = None
    try:
        ovf_xml = ext_utils.get_file_contents('/var/lib/waagent/ovf-env.xml')
        ovf_env = ovf_utils.OvfEnv.parse(ovf_xml, Configuration)
    except (EnvironmentError, ValueError, KeyError, AttributeError):
        pass
    if ovf_xml is None or ovf_env is None:
        # default ovf_env with empty data
        ovf_env = ovf_utils.OvfEnv()
        logger.log("could not load ovf-env.xml")

    # user name must be provided if set ssh key or password
    if not protect_settings or 'username' not in protect_settings:
        return

    user_name = protect_settings['username']
    user_pass = protect_settings.get('password')
    cert_txt = protect_settings.get('ssh_key')
    expiration = protect_settings.get('expiration')
    no_convert = False
    if not user_pass and not cert_txt and not ovf_env.SshPublicKeys:
        raise Exception("No password or ssh_key is specified.")

    if user_pass is not None and len(user_pass) == 0:
        user_pass = None
        hutil.log("empty passwords are not allowed, ignoring password reset")

    # Reset user account and password, password could be empty
    sudoers = _get_other_sudoers(user_name)
    error_string = MyDistro.create_account(user_name, user_pass, expiration,
                                           None)
    _save_other_sudoers(sudoers)

    if error_string is not None:
        err_msg = "Failed to create the account or set the password"
        ext_utils.add_extension_event(name=hutil.get_name(),
                                      op=constants.WALAEventOperation.Enable,
                                      is_success=False,
                                      message="(02101)" + err_msg)
        raise Exception(err_msg + " with " + error_string)
    hutil.log("Succeeded in creating the account or setting the password.")

    # Allow password authentication if user_pass is provided
    if user_pass is not None:
        ext_utils.add_extension_event(name=hutil.get_name(),
                                      op="scenario",
                                      is_success=True,
                                      message="create-user-with-password")
        _allow_password_auth()

    # Reset ssh key with the new public key passed in or reuse old public key.
    if cert_txt:
        if cert_txt and cert_txt.strip().lower().startswith("ssh-rsa"):
            no_convert = True
        try:
            pub_path = os.path.join('/home/', user_name, '.ssh',
                                    'authorized_keys')
            ovf_env.UserName = user_name
            if no_convert:
                if cert_txt:
                    pub_path = ovf_env.prepare_dir(pub_path, MyDistro)
                    final_cert_txt = cert_txt
                    if not cert_txt.endswith("\n"):
                        final_cert_txt = final_cert_txt + "\n"
                    ext_utils.append_file_contents(pub_path, final_cert_txt)
                    MyDistro.set_se_linux_context(
                        pub_path, 'unconfined_u:object_r:ssh_home_t:s0')
                    ext_utils.change_owner(pub_path, user_name)
                    ext_utils.add_extension_event(name=hutil.get_name(),
                                                  op="scenario",
                                                  is_success=True,
                                                  message="create-user")
                    hutil.log("Succeeded in resetting ssh_key.")
                else:
                    err_msg = "Failed to reset ssh key because the cert content is empty."
                    ext_utils.add_extension_event(
                        name=hutil.get_name(),
                        op=constants.WALAEventOperation.Enable,
                        is_success=False,
                        message="(02100)" + err_msg)
            else:
                # do the certificate conversion
                # we support PKCS8 certificates besides ssh-rsa public keys
                _save_cert_str_as_file(cert_txt, 'temp.crt')
                pub_path = ovf_env.prepare_dir(pub_path, MyDistro)
                retcode = ext_utils.run_command_and_write_stdout_to_file([
                    constants.Openssl, 'x509', '-in', 'temp.crt', '-noout',
                    '-pubkey'
                ], "temp.pub")
                if retcode > 0:
                    raise Exception("Failed to generate public key file.")

                MyDistro.ssh_deploy_public_key('temp.pub', pub_path)
                os.remove('temp.pub')
                os.remove('temp.crt')
                ext_utils.add_extension_event(name=hutil.get_name(),
                                              op="scenario",
                                              is_success=True,
                                              message="create-user")
                hutil.log("Succeeded in resetting ssh_key.")
        except Exception as e:
            hutil.log(str(e))
            ext_utils.add_extension_event(
                name=hutil.get_name(),
                op=constants.WALAEventOperation.Enable,
                is_success=False,
                message="(02100)Failed to reset ssh key.")
            raise e