CasperSecurity

Current Path : /lib/python3/dist-packages/uaclient/clouds/
Upload File :
Current File : //lib/python3/dist-packages/uaclient/clouds/aws.py

import json
import logging
from typing import Any, Dict

from uaclient import exceptions, http, secret_manager, system, util
from uaclient.clouds import PublicCloudAutoAttachInstance

IMDS_IPV4_ADDRESS = "169.254.169.254"
IMDS_IPV6_ADDRESS = "[fd00:ec2::254]"

IMDS_IP_ADDRESS = (IMDS_IPV4_ADDRESS, IMDS_IPV6_ADDRESS)
IMDS_V2_TOKEN_URL = "http://{}/latest/api/token"
IMDS_URL = "http://{}/latest/dynamic/instance-identity/pkcs7"
_IMDS_IID_URL = "http://{}/latest/dynamic/instance-identity/document"

SYS_HYPERVISOR_PRODUCT_UUID = "/sys/hypervisor/uuid"
DMI_PRODUCT_SERIAL = "/sys/class/dmi/id/product_serial"
DMI_PRODUCT_UUID = "/sys/class/dmi/id/product_uuid"

AWS_TOKEN_TTL_SECONDS = "21600"
AWS_TOKEN_PUT_HEADER = "X-aws-ec2-metadata-token"
AWS_TOKEN_REQ_HEADER = AWS_TOKEN_PUT_HEADER + "-ttl-seconds"

LOG = logging.getLogger(util.replace_top_level_logger_name(__name__))


class AWSAutoAttachInstance(PublicCloudAutoAttachInstance):
    _api_token = None
    _ip_address = None

    def _get_imds_url_response(self, url: str, headers):
        response = http.readurl(url, headers=headers, timeout=1)
        if response.code == 200:
            return response.body
        else:
            raise exceptions.CloudMetadataError(
                code=response.code, body=response.body
            )

    # mypy does not handle @property around inner decorators
    # https://github.com/python/mypy/issues/1362
    @property  # type: ignore
    @util.retry(exceptions.CloudMetadataError, retry_sleeps=[0.5, 1, 1])
    def identity_doc(self) -> Dict[str, Any]:
        headers = self._request_imds_v2_token_headers()
        url = IMDS_URL.format(self._ip_address)
        imds_url_response = self._get_imds_url_response(url, headers=headers)
        secret_manager.secrets.add_secret(imds_url_response)
        return {"pkcs7": imds_url_response}

    @util.retry(exceptions.CloudMetadataError, retry_sleeps=[0.5, 1, 1])
    def _get_ii_doc(self) -> Dict:
        """
        Get the instance identity doc associated with the current instance.

        See
        https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/retrieve-iid.html
        for more context.

        @return: Dict containing the instance identity document.
        """
        headers = self._request_imds_v2_token_headers()
        url = _IMDS_IID_URL.format(self._ip_address)
        try:
            ii_doc = json.loads(
                self._get_imds_url_response(url, headers=headers)
            )
        except json.JSONDecodeError as e:
            LOG.debug("Error decoding instance identity document: %s", e)
            return {}
        return ii_doc

    @property  # type: ignore
    def is_likely_pro(self) -> bool:
        """
        Determines if the instance is likely Ubuntu Pro.

        Criteria: if any billing-product or marketplace-product-code is
        present, then is likely a Pro instance.

        @return: Boolean indicating if the instance is likely pro or not.
        """
        ii_doc = self._get_ii_doc()
        billing_products = ii_doc.get("billingProducts", None)
        marketplace_product_codes = ii_doc.get("marketplaceProductCodes", None)
        return bool(billing_products) or bool(marketplace_product_codes)

    def _request_imds_v2_token_headers(self):
        for address in IMDS_IP_ADDRESS:
            try:
                headers = self._get_imds_v2_token_headers(ip_address=address)
            except Exception as e:
                LOG.warning(
                    "Could not reach AWS IMDS at http://%s: %s\n",
                    address,
                    getattr(e, "reason", ""),
                )
            else:
                self._ip_address = address
                break
        if self._ip_address is None:
            raise exceptions.AWSNoValidIMDS(
                addresses=", ".join(IMDS_IP_ADDRESS)
            )
        return headers

    @util.retry(exceptions.CloudMetadataError, retry_sleeps=[1, 2, 5])
    def _get_imds_v2_token_headers(self, ip_address):
        if self._api_token == "IMDSv1":
            return None
        elif self._api_token:
            return {AWS_TOKEN_PUT_HEADER: self._api_token}

        response = http.readurl(
            IMDS_V2_TOKEN_URL.format(ip_address),
            method="PUT",
            headers={AWS_TOKEN_REQ_HEADER: AWS_TOKEN_TTL_SECONDS},
            timeout=1,
        )
        if response.code == 200:
            self._api_token = response.body
            secret_manager.secrets.add_secret(self._api_token)
            return {AWS_TOKEN_PUT_HEADER: self._api_token}
        if response.code == 404:
            self._api_token = "IMDSv1"
            return None

        raise exceptions.CloudMetadataError(
            code=response.code, body=response.body
        )

    @property
    def cloud_type(self) -> str:
        return "aws"

    @property
    def is_viable(self) -> bool:
        """This machine is a viable AWSInstance"""
        try:
            hypervisor_uuid = system.load_file(SYS_HYPERVISOR_PRODUCT_UUID)
            if "ec2" == hypervisor_uuid[0:3]:
                return True
        except FileNotFoundError:
            # SYS_HYPERVISOR_PRODUCT_UUID isn't present on all EC2 instance
            # types, fall through
            pass
        # Both DMI product_uuid and product_serial start with 'ec2'
        dmi_uuid = system.load_file(DMI_PRODUCT_UUID).lower()
        dmi_serial = system.load_file(DMI_PRODUCT_SERIAL).lower()
        if "ec2" == dmi_uuid[0:3] == dmi_serial[0:3]:
            return True
        return False

    def should_poll_for_pro_license(self) -> bool:
        """Unsupported"""
        return False

    def is_pro_license_present(self, *, wait_for_change: bool) -> bool:
        raise exceptions.InPlaceUpgradeNotSupportedError()
Hacker Blog, Shell İndir, Sql İnjection, XSS Attacks, LFI Attacks, Social Hacking, Exploit Bot, Proxy Tools, Web Shell, PHP Shell, Alfa Shell İndir, Hacking Training Set, DDoS Script, Denial Of Service, Botnet, RFI Attacks, Encryption
Telegram @BIBIL_0DAY