diff --git a/src/ssh_audit/ssh_audit.py b/src/ssh_audit/ssh_audit.py index 67b90db9..8c04048e 100755 --- a/src/ssh_audit/ssh_audit.py +++ b/src/ssh_audit/ssh_audit.py @@ -583,7 +583,7 @@ def output(out: OutputBuffer, aconf: AuditConf, banner: Optional[Banner], header if aconf.json: out.reset() # Build & write the JSON struct. - out.info(json.dumps(build_struct(aconf.host + ":" + str(aconf.port), banner, kex=kex, client_host=client_host, software=software, algorithms=algs, algorithm_recommendation_suppress_list=algorithm_recommendation_suppress_list, additional_notes=additional_notes), indent=4 if aconf.json_print_indent else None, sort_keys=True)) + out.info(json.dumps(build_struct(aconf.host + ":" + str(aconf.port), banner, kex=kex, client_host=client_host, software=software, algorithms=algs, algorithm_recommendation_suppress_list=algorithm_recommendation_suppress_list, additional_notes=additional_notes), indent=4 if aconf.json_print_indent else None, sort_keys=True), always_print=True) elif len(unknown_algorithms) > 0: # If we encountered any unknown algorithms, ask the user to report them. out.warn("\n\n!!! WARNING: unknown algorithm(s) found!: %s. If this is the latest version of ssh-audit (see ), please create a new Github issue at with the full output above.\n" % ','.join(unknown_algorithms)) @@ -603,7 +603,7 @@ def evaluate_policy(out: OutputBuffer, aconf: AuditConf, banner: Optional['Banne json_struct = {'host': aconf.host, 'port': aconf.port, 'policy': aconf.policy.get_name_and_version(), 'passed': passed, 'errors': error_struct, 'warnings': warnings} - out.info(json.dumps(json_struct, indent=4 if aconf.json_print_indent else None, sort_keys=True)) + out.info(json.dumps(json_struct, indent=4 if aconf.json_print_indent else None, sort_keys=True), always_print=True) else: spacing = '' if aconf.client_audit: @@ -1430,7 +1430,7 @@ def run_gex_granular_modulus_size_test(out: OutputBuffer, s: 'SSH_Socket', kex: if mod_dict: if aconf.json: json_struct = {'dh-gex-modulus-size': mod_dict} - out.info(json.dumps(json_struct, indent=4 if aconf.json_print_indent else None, sort_keys=True)) + out.info(json.dumps(json_struct, indent=4 if aconf.json_print_indent else None, sort_keys=True), always_print=True) else: out.head('# diffie-hellman group exchange modulus size') max_key_len = len(max(mod_dict, key=len)) diff --git a/test/test_outputbuffer.py b/test/test_outputbuffer.py index d92d7bdd..8633b23d 100644 --- a/test/test_outputbuffer.py +++ b/test/test_outputbuffer.py @@ -181,3 +181,13 @@ def test_outputbuffer_batch(self, output_spy): out.fail('fail color') out.write() assert len(output_spy.flush()) == 4 + + def test_outputbuffer_always_print_bypasses_level(self): + """JSON payloads are written via out.info(..., always_print=True) so --level=warn still emits them (#373).""" + out = self.OutputBuffer() + out.level = 'warn' + out.info('{"json": "payload"}') + assert out.get_buffer() == '' + out.info('{"json": "payload"}', always_print=True) + assert '{"json": "payload"}' in out.get_buffer() +