MCPcopy
hub / github.com/jtesta/ssh-audit / output

Function output

src/ssh_audit/ssh_audit.py:566–663  ·  view source on GitHub ↗
(out: OutputBuffer, aconf: AuditConf, banner: Optional[Banner], header: List[str], client_host: Optional[str] = None, kex: Optional[SSH2_Kex] = None, pkm: Optional[SSH1_PublicKeyMessage] = None, print_target: bool = False, dh_rate_test_notes: str = "")

Source from the content-addressed store, hash-verified

564
565# Returns a exitcodes.* flag to denote if any failures or warnings were encountered.
566def output(out: OutputBuffer, aconf: AuditConf, banner: Optional[Banner], header: List[str], client_host: Optional[str] = None, kex: Optional[SSH2_Kex] = None, pkm: Optional[SSH1_PublicKeyMessage] = None, print_target: bool = False, dh_rate_test_notes: str = "") -> int:
567
568 program_retval = exitcodes.GOOD
569 client_audit = client_host is not None # If set, this is a client audit.
570 sshv = 1 if pkm is not None else 2
571 algs = Algorithms(pkm, kex)
572
573 # Perform post-processing on the findings to make final adjustments before outputting the results.
574 algorithm_recommendation_suppress_list, additional_notes = post_process_findings(banner, algs, client_audit, dh_rate_test_notes)
575
576 with out:
577 if print_target:
578 host = aconf.host
579
580 # Print the port if it's not the default of 22.
581 if aconf.port != 22:
582
583 # Check if this is an IPv6 address, as that is printed in a different format.
584 if Utils.is_ipv6_address(aconf.host):
585 host = '[%s]:%d' % (aconf.host, aconf.port)
586 else:
587 host = '%s:%d' % (aconf.host, aconf.port)
588
589 out.good('(gen) target: {}'. format(host))
590 if client_audit:
591 out.good('(gen) client IP: {}'.format(client_host))
592 if len(header) > 0:
593 out.info('(gen) header: ' + '\n'.join(header))
594 if banner is not None:
595 banner_line = '(gen) banner: {}'.format(banner)
596 if sshv == 1 or banner.protocol[0] == 1:
597 out.fail(banner_line)
598 out.fail('(gen) protocol SSH1 enabled')
599 else:
600 out.good(banner_line)
601
602 if not banner.valid_ascii:
603 # NOTE: RFC 4253, Section 4.2
604 out.warn('(gen) banner contains non-printable ASCII')
605
606 software = Software.parse(banner)
607 if software is not None:
608 out.good('(gen) software: {}'.format(software))
609 else:
610 software = None
611 output_compatibility(out, algs, client_audit)
612 if kex is not None:
613 compressions = [x for x in kex.server.compression if x != 'none']
614 if len(compressions) > 0:
615 cmptxt = 'enabled ({})'.format(', '.join(compressions))
616 else:
617 cmptxt = 'disabled'
618 out.good('(gen) compression: {}'.format(cmptxt))
619 if not out.is_section_empty() and not aconf.json: # Print output when it exists and JSON output isn't requested.
620 out.head('# general')
621 out.flush_section()
622 out.sep()
623 maxlen = algs.maxlen + 1

Callers 1

auditFunction · 0.85

Calls 15

AlgorithmsClass · 0.90
post_process_findingsFunction · 0.85
output_compatibilityFunction · 0.85
output_securityFunction · 0.85
output_algorithmsFunction · 0.85
output_fingerprintsFunction · 0.85
output_recommendationsFunction · 0.85
output_infoFunction · 0.85
build_structFunction · 0.85
is_ipv6_addressMethod · 0.80
goodMethod · 0.80
infoMethod · 0.80

Tested by

no test coverage detected