Exemplo n.º 1
0
    def _determine_current_priv(self, current_prompt: str) -> List[str]:
        """
        Determine current privilege level from prompt string

        Args:
            current_prompt: string of current prompt

        Returns:
            matching_priv_levels: list of string names of matching privilege levels

        Raises:
            UnknownPrivLevel: if privilege level cannot be determined

        """
        matching_priv_levels = []
        for priv_level in self.privilege_levels.values():
            search_result = re.search(pattern=priv_level.pattern,
                                      string=current_prompt,
                                      flags=re.M | re.I)
            if not search_result:
                continue
            matching_priv_levels.append(priv_level.name)
            self.logger.debug(
                f"Current privilege level could be `{priv_level.name}`")
        if not matching_priv_levels:
            raise UnknownPrivLevel(
                f"Could not determine privilege level from provided prompt: `{current_prompt}`"
            )
        self.logger.debug(
            f"Determined current privilege level is one of `{matching_priv_levels}`"
        )
        return matching_priv_levels
Exemplo n.º 2
0
    def _escalate(self) -> None:
        """
        Escalate to the next privilege level up

        Args:
            N/A

        Returns:
            N/A  # noqa: DAR202

        Raises:
            UnknownPrivLevel: if priv level cant be attained
            TypeError: if invalid next prompt value

        """
        current_priv = self._determine_current_priv(self.channel.get_prompt())
        if not current_priv.escalate:
            return

        next_priv = self.privs.get(current_priv.escalate_priv, None)
        if next_priv is None:
            raise UnknownPrivLevel(
                f"Could not get next priv level, current priv is {current_priv.name}"
            )
        next_prompt = next_priv.pattern
        if current_priv.escalate_auth:
            if not self.auth_secondary:
                err = (
                    "Privilege escalation generally requires an `auth_secondary` password, "
                    "but none is set!")
                msg = f"***** {err} {'*' * (80 - len(err))}"
                fix = (
                    "scrapli will try to escalate privilege without entering a password but may "
                    "fail.\nSet an `auth_secondary` password if your device requires a password to "
                    "increase privilege, otherwise ignore this message.")
                warning = "\n" + msg + "\n" + fix + "\n" + msg
                warnings.warn(warning)
            else:
                escalate_cmd: str = current_priv.escalate
                escalate_prompt: str = current_priv.escalate_prompt
                escalate_auth = self.auth_secondary
                if not isinstance(next_prompt, str):
                    raise TypeError(
                        f"got {type(next_prompt)} for {current_priv.name} escalate priv, "
                        "expected str")
                self.channel.send_inputs_interact(
                    [
                        escalate_cmd, escalate_prompt, escalate_auth,
                        next_prompt
                    ],
                    hidden_response=True,
                )
                self.channel.comms_prompt_pattern = next_priv.pattern
                return
        self.channel.comms_prompt_pattern = next_priv.pattern
        self.channel.send_input(current_priv.escalate)
Exemplo n.º 3
0
    def _get_privilege_level_name(self, requested_priv: str) -> str:
        """
        Get privilege level name if provided privilege is valid

        Args:
            requested_priv: string name of desired privilege level

        Returns:
            str: name of the privilege level requested

        Raises:
            UnknownPrivLevel: if attempting to acquire an unknown priv

        """
        desired_privilege_level = self.privilege_levels.get(
            requested_priv, None)
        if desired_privilege_level is None:
            raise UnknownPrivLevel(
                f"Requested privilege level `{requested_priv}` not a valid privilege level of "
                f"`{self.__class__.__name__}`")
        resolved_privilege_level = desired_privilege_level.name
        return resolved_privilege_level
Exemplo n.º 4
0
    def _deescalate(self) -> None:
        """
        Deescalate to the next privilege level down

        Args:
            N/A

        Returns:
            N/A  # noqa: DAR202

        Raises:
            UnknownPrivLevel: if no default priv level set to deescalate to

        """
        current_priv = self._determine_current_priv(self.channel.get_prompt())
        if current_priv.deescalate:
            next_priv = self.privs.get(current_priv.deescalate_priv, None)
            if not next_priv:
                raise UnknownPrivLevel(
                    "NetworkDriver has no default priv levels, set them or use a network driver"
                )
            self.channel.comms_prompt_pattern = next_priv.pattern
            self.channel.send_input(current_priv.deescalate)