Skip to content

Commit

Permalink
[#557]Fix error when there are no valid server strings
Browse files Browse the repository at this point in the history
  • Loading branch information
nabla-c0d3 committed Mar 12, 2022
1 parent 8255872 commit 60685d9
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 6 deletions.
19 changes: 14 additions & 5 deletions sslyze/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
SslyzeOutputAsJson,
ServerScanResultAsJson,
)
from sslyze.json.json_output import InvalidServerStringAsJson
from sslyze.mozilla_tls_profile.mozilla_config_checker import (
MozillaTlsConfigurationChecker,
ServerNotCompliantWithMozillaTlsConfiguration,
Expand Down Expand Up @@ -56,13 +57,14 @@ def main() -> None:
scan_commands_extra_arguments=parsed_command_line.scan_commands_extra_arguments,
)
all_server_scan_requests.append(scan_request)
assert all_server_scan_requests

sslyze_scanner.queue_scans(all_server_scan_requests)
# If there are servers that we were able to resolve, scan them
all_server_scan_results = []
for result in sslyze_scanner.get_results():
# Results are actually displayed by the observer; here we just store them
all_server_scan_results.append(result)
if all_server_scan_requests:
sslyze_scanner.queue_scans(all_server_scan_requests)
for result in sslyze_scanner.get_results():
# Results are actually displayed by the observer; here we just store them
all_server_scan_results.append(result)

# Write results to a JSON file if needed
json_file_out: Optional[TextIO] = None
Expand All @@ -74,6 +76,9 @@ def main() -> None:
if json_file_out:
json_output = SslyzeOutputAsJson(
server_scan_results=[ServerScanResultAsJson.from_orm(result) for result in all_server_scan_results],
invalid_server_strings=[
InvalidServerStringAsJson.from_orm(bad_server) for bad_server in parsed_command_line.invalid_servers
],
date_scans_started=date_scans_started,
date_scans_completed=datetime.utcnow(),
)
Expand All @@ -84,6 +89,10 @@ def main() -> None:
if parsed_command_line.should_print_json_to_console:
sys.exit(0)

if not all_server_scan_results:
# There are no results to present: all supplied server strings were invalid?
sys.exit(0)

# Check the results against the Mozilla config if needed
are_all_servers_compliant = True
# TODO(AD): Expose format_title method
Expand Down
23 changes: 22 additions & 1 deletion sslyze/json/json_output.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from datetime import datetime
from pathlib import Path
from typing import List, Optional
from typing import List, Optional, TYPE_CHECKING
from uuid import UUID

import pydantic
Expand Down Expand Up @@ -41,6 +41,9 @@
from sslyze.scanner.models import AllScanCommandsAttempts
from sslyze.server_setting import ConnectionTypeEnum, ServerNetworkLocation

if TYPE_CHECKING:
from sslyze.cli.server_string_parser import InvalidServerStringError


class _BaseModelWithOrmModeAndForbid(pydantic.BaseModel):
class Config:
Expand Down Expand Up @@ -211,12 +214,30 @@ def from_orm(cls, server_scan_result: ServerScanResult) -> "ServerScanResultAsJs
ServerScanResultAsJson.__doc__ = ServerScanResult.__doc__ # type: ignore


class InvalidServerStringAsJson(_BaseModelWithOrmModeAndForbid):
"""A hostname:port string supplied via the command line that SSLyze was unable to parse or resolve.
"""

server_string: str
error_message: str

@classmethod
def from_orm(cls, invalid_server_string_error: "InvalidServerStringError") -> "InvalidServerStringAsJson":
return cls(
server_string=invalid_server_string_error.server_string,
error_message=invalid_server_string_error.error_message,
)


class SslyzeOutputAsJson(pydantic.BaseModel):
"""The "root" dictionary of the JSON output when using the --json command line option.
"""

invalid_server_strings: List[InvalidServerStringAsJson] = [] # TODO(AD): Remove default value starting with v6.x.x
server_scan_results: List[ServerScanResultAsJson]

date_scans_started: datetime
date_scans_completed: datetime

sslyze_version: str = __version__
sslyze_url: str = __url__
30 changes: 30 additions & 0 deletions tests/test_main.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import sys
from unittest import mock

import pytest

from sslyze import SslyzeOutputAsJson
from sslyze.__main__ import main


Expand All @@ -12,3 +15,30 @@ def test(self):
# When running the CLI, it succeeds
with mock.patch.object(sys, "argv", command_line):
main()

def test_no_valid_server_strings(self):
# Given a command line to launch the sslyze CLI, but the supplied server string is invalid
command_line = ["sslyze", "--quiet", "--compression", "invalid.server.testests"]

# When running the CLI, it succeeds
with mock.patch.object(sys, "argv", command_line):
# And the CLI exited early because there is no actual server to scan
with pytest.raises(SystemExit):
main()

def test_json_out_in_console(self, capsys):
# Given a command line to launch the sslyze CLI and return results as JSON in the console
command_line = ["sslyze", "--json_out=-", "--compression", "www.google.com"]

# When running the CLI, it succeeds
with mock.patch.object(sys, "argv", command_line):
with pytest.raises(SystemExit):
main()

# And the JSON output was printed to the console
json_output = capsys.readouterr().out
assert json_output

# And the JSON output has the expected format
parsed_output = SslyzeOutputAsJson.parse_raw(json_output)
assert parsed_output

0 comments on commit 60685d9

Please sign in to comment.