Beispiel #1
0
    def __init__(
        self,
        api_id: Optional[str] = None,
        api_secret: Optional[str] = None,
        url: Optional[str] = DEFAULT_URL,
        **kwargs,
    ):
        CensysAPIBase.__init__(self, url, **kwargs)

        # Gets config file
        config = get_config()

        # Try to get credentials
        self._api_id = (api_id or os.getenv("CENSYS_API_ID")
                        or config.get(DEFAULT, "api_id"))
        self._api_secret = (api_secret or os.getenv("CENSYS_API_SECRET")
                            or config.get(DEFAULT, "api_secret"))
        if not self._api_id or not self._api_secret:
            raise CensysException("No API ID or API secret configured.")

        self._session.auth = (self._api_id, self._api_secret)

        # Generate concrete paths to be called
        self.search_path = f"search/{self.INDEX_NAME}"
        self.view_path = f"view/{self.INDEX_NAME}"
        self.report_path = f"report/{self.INDEX_NAME}"

        # Confirm setup
        self.account()
Beispiel #2
0
    def __init__(self, api_key: Optional[str] = None, **kwargs):
        url = kwargs.pop("url", self.DEFAULT_URL)
        CensysAPIBase.__init__(self, url=url, **kwargs)

        # Gets config file
        config = get_config()

        # Try to get credentials
        self._api_key = (api_key or os.getenv("CENSYS_ASM_API_KEY")
                         or config.get(DEFAULT, "asm_api_key"))

        if not self._api_key:
            raise CensysMissingApiKeyException("No ASM API key configured.")

        self._session.headers.update({
            "Content-Type": "application/json",
            "Censys-Api-Key": self._api_key
        })
Beispiel #3
0
def cli_config(_):  # pragma: no cover
    """
    config subcommand.

    Args:
        _: Argparse Namespace.
    """

    api_id_prompt = "Censys API ID"
    api_secret_prompt = "Censys API Secret"

    config = get_config()
    api_id = config.get(DEFAULT, "api_id")
    api_secret = config.get(DEFAULT, "api_secret")

    if api_id and api_secret:
        redacted_id = api_id.replace(api_id[:32], 32 * "*")
        redacted_secret = api_secret.replace(api_secret[:28], 28 * "*")
        api_id_prompt = f"{api_id_prompt} [{redacted_id}]"
        api_secret_prompt = f"{api_secret_prompt} [{redacted_secret}]"

    api_id = input(api_id_prompt + ": ").strip() or api_id
    api_secret = input(api_secret_prompt + ": ").strip() or api_secret

    if not (api_id and api_secret):
        print("Please enter valid credentials")
        sys.exit(1)

    try:
        client = CensysSearchAPI(api_id, api_secret)
        account = client.account()
        email = account.get("email")

        # Assumes that login was successfully
        config.set(DEFAULT, "api_id", api_id)
        config.set(DEFAULT, "api_secret", api_secret)

        write_config(config)
        print(f"\nSuccessfully authenticated for {email}")
        sys.exit(0)
    except CensysUnauthorizedException:
        print("Failed to authenticate")
        sys.exit(1)
Beispiel #4
0
    def __init__(self,
                 api_id: Optional[str] = None,
                 api_secret: Optional[str] = None,
                 **kwargs):
        # Gets config file
        config = get_config()

        # Try to get credentials
        self._api_id = (api_id or os.getenv("CENSYS_API_ID")
                        or config.get(DEFAULT, "api_id"))
        self._api_secret = (api_secret or os.getenv("CENSYS_API_SECRET")
                            or config.get(DEFAULT, "api_secret"))
        if not self._api_id or not self._api_secret:
            raise CensysException("No API ID or API secret configured.")

        self.timeout = kwargs.get("timeout") or self.DEFAULT_TIMEOUT
        self._api_url = (kwargs.get("url") or os.getenv("CENSYS_API_URL")
                         or self.DEFAULT_URL)

        # Create a session and sets credentials
        self._session = requests.Session()
        proxies = kwargs.get("proxies")
        if proxies:
            if "http" in proxies.keys():
                warnings.warn("HTTP proxies will not be used.")
                proxies.pop("http", None)
            self._session.proxies = proxies
        self._session.auth = (self._api_id, self._api_secret)
        self._session.headers.update({
            "accept":
            "application/json, */8",
            "User-Agent":
            " ".join([
                requests.utils.default_user_agent(),
                kwargs.get("user_agent") or kwargs.get("user_agent_identifier")
                or self.DEFAULT_USER_AGENT,
            ]),
        })

        # Confirm setup
        self.account()
Beispiel #5
0
    def __init__(
        self,
        api_id: Optional[str] = None,
        api_secret: Optional[str] = None,
        url: Optional[str] = None,
        timeout: Optional[int] = None,
        user_agent_identifier: Optional[str] = None,
    ):
        # Gets config file
        config = get_config()

        # Try to get credentials
        self.api_id = (api_id or os.getenv("CENSYS_API_ID")
                       or config.get(DEFAULT, "api_id"))
        self.api_secret = (api_secret or os.getenv("CENSYS_API_SECRET")
                           or config.get(DEFAULT, "api_secret"))
        if not self.api_id or not self.api_secret:
            raise CensysException("No API ID or API secret configured.")

        self.timeout = timeout or self.DEFAULT_TIMEOUT
        self._api_url = url or os.getenv("CENSYS_API_URL") or self.DEFAULT_URL

        # Create a session and sets credentials
        self._session = requests.Session()
        self._session.auth = (self.api_id, self.api_secret)
        self._session.headers.update({
            "accept":
            "application/json, */8",
            "User-Agent":
            " ".join([
                requests.utils.default_user_agent(),
                user_agent_identifier or self.DEFAULT_USER_AGENT,
            ]),
        })

        # Confirm setup
        self.account()
Beispiel #6
0
def cli_asm_config(_):  # pragma: no cover
    """
    config asm subcommand.

    Args:
        _: Argparse Namespace.
    """

    api_key_prompt = "Censys ASM API Key"

    config = get_config()
    api_key = config.get(DEFAULT, "asm_api_key")

    if api_key:
        key_len = len(api_key) - 4
        redacted_api_key = api_key.replace(api_key[:key_len], key_len * "*")
        api_key_prompt = f"{api_key_prompt} [{redacted_api_key}]"

    api_key = input(api_key_prompt + ": ").strip() or api_key

    if not api_key:
        print("Please enter valid credentials")
        sys.exit(1)

    try:
        AsmClient(api_key)

        # Assumes that login was successfully
        config.set(DEFAULT, "asm_api_key", api_key)

        write_config(config)
        print("\nSuccessfully authenticated")
        sys.exit(0)
    except CensysUnauthorizedException:
        print("Failed to authenticate")
        sys.exit(1)
Beispiel #7
0
def get_parser() -> argparse.ArgumentParser:
    """
    Gets ArgumentParser for CLI.

    Returns:
        argparse.ArgumentParser
    """

    config = get_config()

    auth = argparse.ArgumentParser(add_help=False)
    auth.add_argument(
        "--api-id",
        default=os.getenv("CENSYS_API_ID") or config.get(DEFAULT, "api_id"),
        required=False,
        help="a Censys API ID \
            (alternatively you can use the env variable CENSYS_API_ID)",
    )
    auth.add_argument(
        "--api-secret",
        default=os.getenv("CENSYS_API_SECRET")
        or config.get(DEFAULT, "api_secret"),
        required=False,
        help="a Censys API SECRET \
            (alternatively you can use the env variable CENSYS_API_SECRET)",
    )

    parser = argparse.ArgumentParser()
    parser.set_defaults()
    subparsers = parser.add_subparsers()

    # Search Specific Args
    search_parser = subparsers.add_parser(
        "search",
        description="Query Censys Search for resource data by providing a query \
            string, the resource index, and the fields to be returned",
        help="query Censys search",
        parents=[auth],
    )
    search_parser.add_argument(
        "-q",
        "--query",
        type=str,
        required=True,
        help="a string written in Censys Search syntax",
    )

    index_types = ["ipv4", "certs", "websites"]
    index_metavar = "ipv4|certs|websites"
    index_default = "ipv4"
    search_parser.add_argument(
        "--index-type",
        type=str,
        default=index_default,
        choices=index_types,
        metavar=index_metavar,
        help="which resource index to query",
    )
    # Backwards compatibility
    search_parser.add_argument(
        "--query_type",
        type=str,
        default=index_default,
        choices=index_types,
        metavar=index_metavar,
        help=argparse.SUPPRESS,
    )

    search_parser.add_argument("--fields",
                               nargs="+",
                               help="list of index-specific fields")
    search_parser.add_argument(
        "--overwrite",
        action="store_true",
        default=False,
        help="overwrite instead of append fields returned by default \
            with fields provided in the fields argument",
    )
    search_parser.add_argument(
        "-f",
        "--format",
        type=str,
        default="screen",
        metavar="json|csv|screen",
        help="format of output",
    )
    search_parser.add_argument(
        "-o",
        "--output",
        type=Path,
        help="output file path",
    )
    search_parser.add_argument("--start-page",
                               default=1,
                               type=int,
                               help="page number to start from")
    search_parser.add_argument(
        "--max-pages",
        default=1,
        type=int,
        help="maximum number of pages of results to return",
    )
    search_parser.set_defaults(func=search)

    # HNRI Specific Args
    hnri_parser = subparsers.add_parser(
        "hnri",
        description="Home Network Risk Identifier (H.N.R.I.)",
        help="home network risk identifier",
        parents=[auth],
    )
    hnri_parser.set_defaults(func=hnri)

    # Config Specific Args
    config_parser = subparsers.add_parser(
        "config",
        description="Configure Censys Search API Settings",
        help="configure Censys search API settings",
    )
    config_parser.set_defaults(func=cli_config)

    # ASM Config Args
    asm_config_parser = subparsers.add_parser(
        "config-asm",
        description="Configure Censys ASM API Settings",
        help="configure Censys ASM API settings",
    )
    asm_config_parser.set_defaults(func=cli_asm_config)

    return parser
Beispiel #8
0
import os
import unittest
import pytest

from censys.config import DEFAULT, get_config

config = get_config()
api_key = config.get(DEFAULT, "asm_api_key") or os.getenv("CENSYS_ASM_API_KEY")

required_env_asm = pytest.mark.skipif(
    not api_key,
    reason="API key not found",
)

RESOURCE_PAGING_RESULTS = ["a", "b", "c", "a", "b", "c", "a", "b", "c"]
TEST_TIMEOUT = 30
TEST_SUCCESS_CODE = 200
BASE_URL = "https://app.censys.io/api/v1"


@required_env_asm
class CensysAsmTestCase(unittest.TestCase):
    pass


class MockResponse:
    # Dummy resource list to iterate over for testing paging
    RESOURCES = ["a", "b", "c"]
    # Dummy end of events list to simulate 3 pages of results
    END_OF_EVENTS = [False, False, True]
Beispiel #9
0
 def test_write_default(self, mock_file):
     get_config()
     os.path.isdir.assert_called_with(censys_path)
     os.mkdir.assert_called_with(censys_path)
     os.path.exists.assert_called_with(test_config_path)
     mock_file.assert_called_with(test_config_path, "w")