Example #1
0
// renderOptions render options
func renderOptions(options []option, colorTag string) {
	var (
		curGroup string
		opt      option
		maxSize  int
	)

	maxSize = getMaxOptionSize(options)

	for _, opt = range options {
		if curGroup != opt.group {
			printGroupHeader(opt.group)
			curGroup = opt.group
		}

		fmtc.Printf("  "+colorTag+"%s{!}", opt.name)

		if len(opt.args) != 0 {
			fmtc.Printf(" " + renderArgs(opt.args))
		}

		fmtc.Printf(getBreadcrumbs(opt, maxSize))
		fmtc.Printf(opt.desc)

		fmtc.NewLine()
	}
}
Example #2
0
// printDetailedEndpointInfo fetch and print detailed info for one endpoint
func printDetailedEndpointInfo(ap *sslscan.AnalyzeProgress, ip string) {
	info, err := ap.DetailedInfo(ip)

	if err != nil {
		fmtc.Printf("\n{r}Can't fetch detailed info for %s{!}\n\n", ip)
		return
	}

	if strings.ToUpper(info.StatusMessage) != "READY" {
		fmtc.Printf("\n{r}%s{!}\n\n", info.StatusMessage)
		return
	}

	details := info.Details

	fmtc.NewLine()

	printCertificateInfo(details)
	printCertificationPathsInfo(details)
	printProtocolsInfo(details)
	suiteIndex := printCipherSuitesInfo(details)
	printHandshakeSimulationInfo(details, suiteIndex)
	printProtocolDetailsInfo(details)
	printMiscellaneousInfo(info)

	fmtutil.Separator(true)
	fmtc.NewLine()
}
Example #3
0
// Render print version info to console
func (about *About) Render() {
	switch {
	case about.Build != "":
		fmtc.Printf(
			"\n{*c}%s {c}%s{!}{s}%s{!} {s-}(%s){!} - %s\n\n",
			about.App, about.Version,
			about.Release, about.Build, about.Desc,
		)
	default:
		fmtc.Printf(
			"\n{*c}%s {c}%s{!}{s}%s{!} - %s\n\n",
			about.App, about.Version,
			about.Release, about.Desc,
		)
	}

	if about.Owner != "" {
		if about.Year == 0 {
			fmtc.Printf("{s-}Copyright (C) %s{!}\n", about.Owner)
		} else {
			fmtc.Printf(
				"{s-}Copyright (C) %d-%d %s{!}\n",
				about.Year, time.Now().Year(), about.Owner,
			)
		}
	}

	if about.License != "" {
		fmtc.Printf("{s-}%s{!}\n", about.License)
	}

	fmtc.NewLine()
}
Example #4
0
// renderTemplate read template and render to file
func renderTemplate(doc *Document) {
	projectDir := env.Get().GetS("GOPATH")
	templateFile := path.Join(
		projectDir, "src/github.com/essentialkaos/shdoc/templates",
		arg.GetS(ARG_TEMPLATE)+".tpl",
	)

	if !fsutil.CheckPerms("FRS", templateFile) {
		printError("Can't read template %s - file is not exist or empty", templateFile)
		os.Exit(1)
	}

	outputFile := arg.GetS(ARG_OUTPUT)

	if fsutil.IsExist(outputFile) {
		os.Remove(outputFile)
	}

	fd, err := os.OpenFile(outputFile, os.O_CREATE|os.O_WRONLY, 0644)

	if err != nil {
		printError(err.Error())
		os.Exit(1)
	}

	defer fd.Close()

	tpl, err := ioutil.ReadFile(templateFile)

	if err != nil {
		printError(err.Error())
		os.Exit(1)
	}

	t := template.New("Template")
	t, err = t.Parse(string(tpl[:]))

	err = t.Execute(fd, doc)

	if err != nil {
		printError(err.Error())
		os.Exit(1)
	}

	fmtutil.Separator(false, doc.Title)

	fmtc.Printf("  {*}Constants:{!} %d\n", len(doc.Constants))
	fmtc.Printf("  {*}Variables:{!} %d\n", len(doc.Variables))
	fmtc.Printf("  {*}Methods:{!}   %d\n", len(doc.Methods))
	fmtc.NewLine()
	fmtc.Printf(
		"  {*}Output:{!} %s {s-}(%s){!}\n", outputFile,
		fmtutil.PrettySize(fsutil.GetSize(outputFile)),
	)

	fmtutil.Separator(false)
}
Example #5
0
// Init starts initialization rutine
func Init() {
	args, errs := arg.Parse(argMap)

	if len(errs) != 0 {
		fmtc.Println("{r}Arguments parsing errors:{!}")

		for _, err := range errs {
			fmtc.Printf("  {r}%v{!}\n", err)
		}

		os.Exit(1)
	}

	if arg.GetB(ARG_NO_COLOR) {
		fmtc.DisableColors = true
	}

	if arg.GetB(ARG_VER) {
		showAbout()
		return
	}

	if arg.GetB(ARG_HELP) || len(args) == 0 {
		showUsage()
		return
	}

	runtime.GOMAXPROCS(2)

	process(args)
}
Example #6
0
func readUserInput(title string, nonEmpty bool, private bool) (string, error) {
	if title != "" {
		fmtc.Printf("{c}%s{!}\n", title)
	}

	var (
		input string
		err   error
	)

	for {
		input, err = linenoise.Line(Prompt)

		if err != nil {
			return "", err
		}

		if nonEmpty && strings.TrimSpace(input) == "" {
			PrintWarnMessage("\nYou must enter non empty value\n")
			continue
		}

		if private && input != "" {
			if MaskSymbolColorTag == "" {
				fmt.Println(getPrivateHider(input))
			} else {
				fmtc.Println(MaskSymbolColorTag + getPrivateHider(input) + "{!}")
			}
		}

		break
	}

	return input, err
}
Example #7
0
// renderExamples render examples
func renderExamples(info *Info) {
	printGroupHeader("Examples")

	total := len(info.examples)

	for index, example := range info.examples {
		fmtc.Printf("  %s %s\n", info.name, example.cmd)

		if example.desc != "" {
			fmtc.Printf("  {s-}%s{!}\n", example.desc)
		}

		if index < total-1 {
			fmtc.NewLine()
		}
	}
}
Example #8
0
// simpleRender print all document info to console
func simpleRender(doc *Document) {
	if doc.HasAbout() {
		fmtutil.Separator(false, "ABOUT")

		for _, l := range doc.About {
			fmtc.Printf("  %s\n", l)
		}
	}

	if doc.HasConstants() {
		fmtutil.Separator(false, "CONSTANTS")

		totalConstants := len(doc.Constants)

		for i, c := range doc.Constants {
			renderConstant(c)

			if i < totalConstants-1 {
				fmtc.NewLine()
			}
		}
	}

	if doc.HasVariables() {
		fmtutil.Separator(false, "GLOBAL VARIABLES")

		totalVariables := len(doc.Variables)

		for i, v := range doc.Variables {
			renderVariable(v)

			if i < totalVariables-1 {
				fmtc.NewLine()
			}
		}
	}

	if doc.HasMethods() {
		fmtutil.Separator(false, "METHODS")

		totalMethods := len(doc.Methods)

		for i, m := range doc.Methods {
			renderMethod(m, false)

			if i < totalMethods-1 {
				fmtc.NewLine()
				fmtc.NewLine()
			}
		}
	}

	fmtutil.Separator(false)
}
Example #9
0
// printCipherSuitesInfo print info about supported cipher suites
func printCipherSuitesInfo(details *sslscan.EndpointDetails) map[int]int {
	printCategoryHeader("Cipher Suites")

	suiteIndex := make(map[int]int)

	for index, suite := range details.Suites.List {
		suiteIndex[suite.ID] = index

		tag := ""
		insecure := strings.Contains(suite.Name, "_RC4_")

		switch {
		case suite.Q != nil:
			tag = "{y}(WEAK){!}"
		case suite.DHStrength != 0 && suite.DHStrength < 2048:
			tag = "{y}(WEAK){!}"
		}

		if insecure {
			fmtc.Printf(" {r}%-42s{!} {s}|{!} {r}%d (INSECURE){!} ", suite.Name, suite.CipherStrength)
		} else {
			fmtc.Printf(" %-42s {s}|{!} %d ", suite.Name, suite.CipherStrength)
		}

		switch {
		case suite.DHStrength != 0:
			fmtc.Printf("{s-}(DH %d bits){!} "+tag+"\n",
				suite.DHStrength)
		case suite.ECDHBits != 0:
			fmtc.Printf("{s-}(ECDH %d bits ~ %d bits RSA){!} "+tag+"\n",
				suite.ECDHBits, suite.ECDHStrength)
		default:
			fmtc.Println(tag)
		}
	}

	return suiteIndex
}
Example #10
0
// printProtocolsInfo print info about supported protocols
func printProtocolsInfo(details *sslscan.EndpointDetails) {
	printCategoryHeader("Protocols")

	supportedProtocols := getProtocols(details.Protocols)

	for _, protocol := range protocolList {
		fmtc.Printf(" %-24s {s}|{!} ", protocol)

		switch {
		case protocol == "TLS 1.2":
			if supportedProtocols[protocol] {
				fmtc.Println("{g}Yes{!}")
			} else {
				fmtc.Println("{y}No{!}")
			}
		case protocol == "SSL 3.0" && supportedProtocols[protocol]:
			fmtc.Printf("{r}%s{!}\n", getBool(supportedProtocols[protocol]))
		case protocol == "SSL 2.0" && supportedProtocols[protocol]:
			fmtc.Printf("{r}%s{!}\n", getBool(supportedProtocols[protocol]))
		default:
			fmtc.Printf("%s\n", getBool(supportedProtocols[protocol]))
		}
	}
}
Example #11
0
// printDetailedInfo fetch and print detailed info for all endpoints
func printDetailedInfo(ap *sslscan.AnalyzeProgress, info *sslscan.AnalyzeInfo) {
	showHeaders := len(info.Endpoints) > 1

	if showHeaders {
		fmtc.NewLine()
	}

	for index, endpoint := range info.Endpoints {
		if showHeaders {
			fmtc.Printf("\n{c} %s #%d (%s){!}\n\n", info.Host, index+1, endpoint.IPAdress)
		}

		printDetailedEndpointInfo(ap, endpoint.IPAdress)
	}
}
Example #12
0
// printMiscellaneousInfo print miscellaneous info about endpoint
func printMiscellaneousInfo(info *sslscan.EndpointInfo) {
	printCategoryHeader("Miscellaneous")

	details := info.Details
	testDate := time.Unix(info.Details.HostStartTime/1000, 0)

	// ---

	fmtc.Printf(
		" %-24s {s}|{!} %s {s-}(%s ago){!}\n", "Test date",
		timeutil.Format(testDate, "%Y/%m/%d %H:%M:%S"),
		timeutil.PrettyDuration(time.Since(testDate)),
	)

	// ---

	fmtc.Printf(" %-24s {s}|{!} %s\n", "Test duration", timeutil.PrettyDuration(info.Duration/1000))
	fmtc.Printf(" %-24s {s}|{!} %d\n", "HTTP status code", details.HTTPStatusCode)

	// ---

	if details.HTTPForwarding != "" {
		if strings.Contains(details.HTTPForwarding, "http://") {
			fmtc.Printf(" %-24s {s}|{!} {y}%s (PLAINTEXT){!}\n", "HTTP forwarding", details.HTTPForwarding)
		} else {
			fmtc.Printf(" %-24s {s}|{!} %s\n", "HTTP forwarding", details.HTTPForwarding)
		}
	}

	// ---

	if details.ServerSignature != "" {
		fmtc.Printf(" %-24s {s}|{!} %s\n", "HTTP server signature", details.ServerSignature)
	}

	// ---

	if info.ServerName != "" {
		fmtc.Printf(" %-24s {s}|{!} %s\n", "Server hostname", info.ServerName)
	}
}
Example #13
0
func main() {
	args, errs := arg.Parse(argMap)

	if len(errs) != 0 {
		fmtc.Println("Arguments parsing errors:")

		for _, err := range errs {
			fmtc.Printf("  %s\n", err.Error())
		}

		os.Exit(1)
	}

	if arg.GetB(ARG_NO_COLOR) {
		fmtc.DisableColors = true
	}

	if arg.GetB(ARG_VER) {
		showAbout()
		return
	}

	if arg.GetB(ARG_HELP) || len(args) == 0 {
		showUsage()
		return
	}

	switch len(args) {
	case 1:
		process(args[0], "")
	case 2:
		process(args[0], args[1])
	default:
		showUsage()
	}
}
Example #14
0
// renderMethod print method info to console
func renderMethod(m *Method, showExamples bool) {
	fmtc.Printf("{s-}%4d:{!} {b*}%s{!} {s}-{!} %s\n", m.Line, m.Name, m.UnitedDesc())

	if len(m.Arguments) != 0 {
		fmtc.NewLine()

		for _, a := range m.Arguments {
			switch {
			case a.IsOptional:
				fmtc.Printf("  {s-}%2s.{!} %s "+getVarTypeDesc(a.Type)+" {s-}[Optional]{!}\n", a.Index, a.Desc)
			case a.IsWildcard:
				fmtc.Printf("  {s-}%2s.{!} %s\n", a.Index, a.Desc)
			default:
				fmtc.Printf("  {s-}%2s.{!} %s "+getVarTypeDesc(a.Type)+"\n", a.Index, a.Desc)
			}
		}
	}

	if m.ResultCode {
		fmtc.NewLine()
		fmtc.Printf("  {*}Code:{!} 0 - ok, 1 - not ok\n")
	}

	if m.ResultEcho != nil {
		fmtc.NewLine()
		fmtc.Printf("  {*}Echo:{!} %s "+getVarTypeDesc(m.ResultEcho.Type)+"\n", strings.Join(m.ResultEcho.Desc, " "))
	}

	if m.Example != nil && showExamples {
		fmtc.NewLine()
		fmtc.Println("  {*}Example:{!}")
		fmtc.NewLine()

		for _, l := range m.Example {
			fmtc.Printf("    %s\n", l)
		}
	}
}
Example #15
0
// printHandshakeSimulationInfo print info about handshakes simulations
func printHandshakeSimulationInfo(details *sslscan.EndpointDetails, suiteIndex map[int]int) {
	printCategoryHeader("Handshake Simulation")

	for _, sim := range details.SIMS.Results {
		if sim.ErrorCode != 0 {
			fmtc.Printf(" %-24s {s}|{!} {r}Fail{!}\n", sim.Client.Name+" "+sim.Client.Version)
			continue
		}

		tag := "{s-}No FS{!}"
		suite := details.Suites.List[suiteIndex[sim.SuiteID]]

		if strings.Contains(suite.Name, "DHE_") {
			tag = "{g}   FS{!}"
		}

		if sim.Client.IsReference {
			fmtc.Printf(" %-38s {s}|{!} ", sim.Client.Name+" "+sim.Client.Version+" "+fmtc.Sprintf("{g}R"))
		} else {
			fmtc.Printf(" %-24s {s}|{!} ", sim.Client.Name+" "+sim.Client.Version)
		}

		switch protocolIDs[sim.ProtocolID] {
		case "TLS 1.2":
			fmtc.Printf("{g}%-7s{!} %-42s "+tag+" %d\n",
				protocolIDs[sim.ProtocolID],
				suite.Name, suite.CipherStrength,
			)
		case "SSL 2.0", "SSL 3.0":
			fmtc.Printf("{r}%-7s{!} %-42s "+tag+" %d\n",
				protocolIDs[sim.ProtocolID],
				suite.Name, suite.CipherStrength,
			)
		default:
			fmtc.Printf("%-7s %-42s "+tag+" %d\n",
				protocolIDs[sim.ProtocolID],
				suite.Name, suite.CipherStrength,
			)
		}
	}
}
Example #16
0
// check check some host
func check(host string) string {
	var err error
	var info *sslscan.AnalyzeInfo

	showServerMessage()

	params := sslscan.AnalyzeParams{
		Public:         arg.GetB(ARG_PUBLIC),
		StartNew:       arg.GetB(ARG_AVOID_CACHE),
		FromCache:      !arg.GetB(ARG_AVOID_CACHE),
		IgnoreMismatch: arg.GetB(ARG_IGNORE_MISMATCH),
	}

	fmtc.Printf("{*}%s{!} → ", host)

	ap, err := api.Analyze(host, params)

	if err != nil {
		fmtc.Printf("{r}%v{!}\n", err)
		return "T"
	}

	t := &fmtc.T{}

	for {
		info, err = ap.Info()

		if err != nil {
			t.Printf("{r}%v{!}\n", err)
			return "Err"
		}

		if info.Status == sslscan.STATUS_ERROR {
			t.Printf("{r}%s{!}\n", info.StatusMessage)
			return "Err"
		} else if info.Status == sslscan.STATUS_READY {
			break
		}

		if len(info.Endpoints) != 0 {
			message := getStatusInProgress(info.Endpoints)

			if message != "" {
				t.Printf("{s}%s...{!}", message)
			}
		}

		if info.Status == sslscan.STATUS_IN_PROGRESS {
			time.Sleep(6 * time.Second)
		} else {
			time.Sleep(2 * time.Second)
		}
	}

	if len(info.Endpoints) == 1 {
		t.Println(getColoredGrade(info.Endpoints[0].Grade))
	} else {
		t.Println(getColoredGrades(info.Endpoints))
	}

	if arg.GetB(ARG_DETAILED) {
		printDetailedInfo(ap, info)
	}

	lowestGrade, _ := getGrades(info.Endpoints)

	return lowestGrade
}
Example #17
0
// process starting request processing
func process(args []string) {
	var (
		ok    bool
		err   error
		hosts []string
	)

	api, err = sslscan.NewAPI("SSLCli", VER)

	if err != nil {
		if !arg.GetB(ARG_FORMAT) {
			fmtc.Printf("{r}%v{!}\n", err)
		}

		os.Exit(1)
	}

	// By default all fine
	ok = true
	hosts = args

	if fsutil.CheckPerms("FR", hosts[0]) {
		hosts, err = readHostList(hosts[0])

		if err != nil && arg.GetB(ARG_FORMAT) {
			fmtc.Printf("{r}%v{!}\n", err)
			os.Exit(1)
		}
	}

	var (
		grade      string
		checksInfo []*HostCheckInfo
		checkInfo  *HostCheckInfo
	)

	for _, host := range hosts {

		switch {
		case arg.GetB(ARG_QUIET):
			grade, _ = quietCheck(host)
		case arg.GetB(ARG_FORMAT):
			grade, checkInfo = quietCheck(host)
			checksInfo = append(checksInfo, checkInfo)
		default:
			grade = check(host)
		}

		switch {
		case arg.GetB(ARG_PERFECT) && grade != "A+":
			ok = false
		case grade[:1] != "A":
			ok = false
		}
	}

	if arg.GetB(ARG_FORMAT) {
		switch arg.GetS(ARG_FORMAT) {
		case FORMAT_TEXT:
			encodeAsText(checksInfo)
		case FORMAT_JSON:
			encodeAsJSON(checksInfo)
		case FORMAT_XML:
			encodeAsXML(checksInfo)
		case FORMAT_YAML:
			encodeAsYAML(checksInfo)
		default:
			os.Exit(1)
		}
	}

	if arg.GetB(ARG_NOTIFY) {
		fmtc.Bell()
	}

	if !ok {
		os.Exit(1)
	}
}
Example #18
0
// printGroupHeader print category header
func printGroupHeader(name string) {
	fmtc.Printf("\n{*}%s{!}\n\n", name)
}
Example #19
0
// printError prints warning message to console
func printWarn(f string, a ...interface{}) {
	fmtc.Printf("{y}"+f+"{!}\n", a...)
}
Example #20
0
// printError prints error message to console
func printError(f string, a ...interface{}) {
	fmtc.Printf("{r}"+f+"{!}\n", a...)
}
Example #21
0
// renderMethod print variable info to console
func renderVariable(v *Variable) {
	fmtc.Printf("{s-}%4d:{!} {c*}%s{!} {s}={!} %s "+getVarTypeDesc(v.Type)+"\n", v.Line, v.Name, v.Value)
	fmtc.Printf("      %s\n", v.UnitedDesc())
}
Example #22
0
// renderConstant print constant info to console
func renderConstant(c *Variable) {
	fmtc.Printf("{s-}%4d:{!} {m*}%s{!} {s}={!} %s "+getVarTypeDesc(c.Type)+"\n", c.Line, c.Name, c.Value)
	fmtc.Printf("      %s\n", c.UnitedDesc())
}
Example #23
0
// printCertificationPathsInfo print info about certificates in chain
func printCertificationPathsInfo(details *sslscan.EndpointDetails) {
	printCategoryHeader("Certification Paths")

	fmtc.Printf(" %-24s {s}|{!} %d\n", "Certificates provided", len(details.Chain.Certs))

	fmtc.Printf(" %-24s {s}|{!} ", "Chain issues")

	if details.Chain.Issues == 0 {
		fmtc.Println("None")
	} else {
		fmtc.Printf("{y}%s{!}\n", getChainIssuesDesc(details.Chain.Issues))
	}

	if len(details.Chain.Certs) > 1 {
		fmtutil.Separator(true)

		lastCertIndex := len(details.Chain.Certs) - 2

		for index, cert := range details.Chain.Certs[1:] {
			validUntilDate := time.Unix(cert.NotAfter/1000, 0)

			fmtc.Printf(" %-24s {s}|{!} %s\n", "Subject", cert.Label)
			fmtc.Printf(" %-24s {s}|{!} %s\n", "Valid until", timeutil.Format(validUntilDate, "%Y/%m/%d %H:%M:%S"))

			fmtc.Printf(" %-24s {s}|{!} ", "Key")

			if cert.KeyAlg == "RSA" && cert.KeyStrength < 2048 {
				fmtc.Printf("{y}%s %d bits (WEAK){!}\n", cert.KeyAlg, cert.KeySize)
			} else {
				fmtc.Printf("%s %d bits\n", cert.KeyAlg, cert.KeySize)
			}

			fmtc.Printf(" %-24s {s}|{!} %s\n", "Issuer", cert.IssuerLabel)

			fmtc.Printf(" %-24s {s}|{!} ", "Signature algorithm")

			if weakAlgorithms[cert.SigAlg] {
				fmtc.Printf("{y}%s (WEAK){!}\n", cert.SigAlg)
			} else {
				fmtc.Printf("%s\n", cert.SigAlg)
			}

			if index < lastCertIndex {
				fmtutil.Separator(true)
			}
		}
	}
}
Example #24
0
// printCertificateInfo print basic info about server key and certificate
func printCertificateInfo(details *sslscan.EndpointDetails) {
	printCategoryHeader("Server Key and Certificate")

	validFromDate := time.Unix(details.Cert.NotBefore/1000, 0)
	validUntilDate := time.Unix(details.Cert.NotAfter/1000, 0)

	// ---

	fmtc.Printf(" %-24s {s}|{!} %s\n", "Common names", strings.Join(details.Cert.CommonNames, " "))

	if len(details.Cert.AltNames) > 0 {
		if len(details.Cert.AltNames) > 5 {
			fmtc.Printf(
				" %-24s {s}|{!} %s {s-}(+%d more){!}\n",
				"Alternative names",
				strings.Join(details.Cert.AltNames[:4], " "),
				len(details.Cert.AltNames)-4,
			)
		} else {
			fmtc.Printf(" %-24s {s}|{!} %s\n", "Alternative names", strings.Join(details.Cert.AltNames, " "))
		}
	}

	// ---

	fmtc.Printf(" %-24s {s}|{!} %s\n", "Valid from", timeutil.Format(validFromDate, "%Y/%m/%d %H:%M:%S"))

	// ---

	fmtc.Printf(" %-24s {s}|{!} ", "Valid until")

	if time.Now().Unix() >= validUntilDate.Unix() {
		fmtc.Printf("{r}%s (EXPIRED){!}\n", timeutil.Format(validUntilDate, "%Y/%m/%d %H:%M:%S"))
	} else {
		fmtc.Printf("%s\n", timeutil.Format(validUntilDate, "%Y/%m/%d %H:%M:%S"))
	}

	// ---

	fmtc.Printf(" %-24s {s}|{!} %s %d bits\n", "Key", details.Key.Alg, details.Key.Size)
	fmtc.Printf(" %-24s {s}|{!} %s\n", "Weak Key (Debian)", getBool(details.Key.DebianFlaw))

	// ---

	fmtc.Printf(" %-24s {s}|{!} ", "Issuer")

	if details.Cert.Issues&64 == 64 {
		fmtc.Printf("%s {s-}(Self-signed){!}\n", details.Cert.IssuerLabel)
	} else {
		fmtc.Printf("%s\n", details.Cert.IssuerLabel)
	}

	// ---

	fmtc.Printf(" %-24s {s}|{!} ", "Signature algorithm")

	if weakAlgorithms[details.Cert.SigAlg] {
		fmtc.Printf("{y}%s (WEAK){!}\n", details.Cert.SigAlg)
	} else {
		fmtc.Printf("%s\n", details.Cert.SigAlg)
	}

	// ---

	fmtc.Printf(" %-24s {s}|{!} ", "Extended Validation")

	if details.Cert.ValidationType == "E" {
		fmtc.Println("{g}Yes{!}")
	} else {
		fmtc.Println("No")
	}

	// ---

	fmtc.Printf(" %-24s {s}|{!} ", "Certificate Transparency")

	if details.Cert.SCT {
		fmtc.Println("{g}Yes{!}")
	} else {
		fmtc.Println("No")
	}

	// ---

	if details.Cert.RevocationInfo != 0 {
		fmtc.Printf(" %-24s {s}|{!} %s\n", "Revocation information", getRevocationInfo(details.Cert.RevocationInfo))
	}

	// ---

	fmtc.Printf(" %-24s {s}|{!} ", "Revocation status")

	if details.Cert.RevocationStatus&1 == 1 {
		fmtc.Printf("{r}%s{!}\n", getRevocationStatus(details.Cert.RevocationStatus))
	} else {
		fmtc.Printf("%s\n", getRevocationStatus(details.Cert.RevocationStatus))
	}

	// ---

	fmtc.Printf(" %-24s {s}|{!} ", "Trusted")

	if details.Cert.Issues == 0 {
		fmtc.Println("{g}Yes{!}")
	} else {
		fmtc.Printf("{r}No (%s){!}\n", getCertIssuesDesc(details.Cert.Issues))
	}
}
Example #25
0
// printCategoryHeader print category name and separators
func printCategoryHeader(name string) {
	fmtutil.Separator(true)
	fmtc.Printf(" ▾ {*}%s{!}\n", strings.ToUpper(name))
	fmtutil.Separator(true)
}
Example #26
0
// PrintActionMessage print message about action currently in progress
func PrintActionMessage(message string) {
	fmtc.Printf("{*}%s:{!} ", message)
}
Example #27
0
// printProtocolDetailsInfo print endpoint protocol details
func printProtocolDetailsInfo(details *sslscan.EndpointDetails) {
	printCategoryHeader("Protocol Details")

	// ---

	fmtc.Printf(" %-40s {s}|{!} ", "Secure Renegotiation")

	if details.RenegSupport&1 == 1 {
		fmtc.Println("{y}Not supported{!}")
	} else {
		fmtc.Println("{g}Supported{!}")
	}

	// ---

	fmtc.Printf(" %-40s {s}|{!} ", "Secure Client-Initiated Renegotiation")

	if details.RenegSupport&4 == 4 {
		fmtc.Println("{y}Supported (DoS DANGER){!}")
	} else {
		fmtc.Println("No")
	}

	// ---

	fmtc.Printf(" %-40s {s}|{!} ", "Insecure Client-Initiated Renegotiation")

	if details.RenegSupport&1 == 1 {
		fmtc.Println("{r}Supported (INSECURE){!}")
	} else {
		fmtc.Println("No")
	}

	// ---

	fmtc.Printf(" %-40s {s}|{!} ", "POODLE (SSLv3)")

	if details.Poodle {
		fmtc.Println("{r}Vulnerable (INSECURE){!}")
	} else {
		fmtc.Println("No")
	}

	// ---

	fmtc.Printf(" %-40s {s}|{!} ", "POODLE (TLS)")

	if details.PoodleTLS == 2 {
		fmtc.Println("{r}Vulnerable (INSECURE){!}")
	} else {
		fmtc.Println("No")
	}

	// ---

	fmtc.Printf(" %-40s {s}|{!} ", "DROWN")

	if details.DrownVulnerable {
		fmtc.Println("{r}Vulnerable{!}")
	} else {
		fmtc.Println("No")
	}

	// ---

	if details.Logjam {
		fmtc.Printf(" %-40s {s}|{!} {r}Vulnerable{!}\n", "Logjam")
	}

	// ---

	if details.Freak {
		fmtc.Printf(" %-40s {s}|{!} {r}Vulnerable{!}\n", "Freak")
	}

	// ---

	fmtc.Printf(" %-40s {s}|{!} ", "Downgrade attack prevention")

	if !details.FallbackSCSV {
		fmtc.Println("{y}No, TLS_FALLBACK_SCSV not supported{!}")
	} else {
		fmtc.Println("{g}Yes, TLS_FALLBACK_SCSV supported{!}")
	}

	// ---

	fmtc.Printf(" %-40s {s}|{!} ", "SSL/TLS compression")

	if details.CompressionMethods != 0 {
		fmtc.Println("{r}Vulnerable (INSECURE){!}")
	} else {
		fmtc.Println("No")
	}

	// ---

	fmtc.Printf(" %-40s {s}|{!} ", "RC4")

	if details.SupportsRC4 {
		fmtc.Println("{r}Yes (INSECURE){!}")
	} else {
		fmtc.Println("No")
	}

	// ---

	fmtc.Printf(" %-40s {s}|{!} %s\n", "Heartbeat (extension)", getBool(details.Heartbeat))

	// ---

	fmtc.Printf(" %-40s {s}|{!} ", "Heartbleed (vulnerability)")

	if details.Heartbleed {
		fmtc.Println("{r}Vulnerable (INSECURE){!}")
	} else {
		fmtc.Println("No")
	}

	// ---

	fmtc.Printf(" %-40s {s}|{!} ", "OpenSSL CCS vuln.")

	switch details.OpenSslCCS {
	case -1:
		fmtc.Println("{y}Test failed{!}")
	case 0:
		fmtc.Println("{y}Unknown{!}")
	case 1:
		fmtc.Println("No")
	case 2:
		fmtc.Println("{y}Possibly vulnerable, but not exploitable{!}")
	case 3:
		fmtc.Println("{r}Vulnerable and exploitable{!}")
	}

	// ---

	fmtc.Printf(" %-40s {s}|{!} ", "OpenSSL Padding Oracle vuln.")

	switch details.OpenSSLLuckyMinus20 {
	case -1:
		fmtc.Println("{y}Test failed{!}")
	case 0:
		fmtc.Println("{y}Unknown{!}")
	case 1:
		fmtc.Println("No")
	case 2:
		fmtc.Println("{r}Vulnerable and insecure{!}")
	}

	// ---

	fmtc.Printf(" %-40s {s}|{!} ", "Forward Secrecy")

	switch {
	case details.ForwardSecrecy == 0:
		fmtc.Println("{y}No (WEAK){!}")
	case details.ForwardSecrecy&1 == 1:
		fmtc.Println("{y}With some browsers{!}")
	case details.ForwardSecrecy&2 == 2:
		fmtc.Println("With modern browsers")
	case details.ForwardSecrecy&4 == 4:
		fmtc.Println("{g}Yes (with most browsers) (ROBUST){!}")
	}

	// ---

	fmtc.Printf(" %-40s {s}|{!} ", "Application-Layer Protocol Negotiation")

	if strings.Contains(details.NPNProtocols, "h2") {
		fmtc.Println("Yes")
	} else {
		fmtc.Println("No")
	}

	// ---

	fmtc.Printf(" %-40s {s}|{!} ", "Next Protocol Negotiation")

	if details.SupportsNPN {
		fmtc.Printf("Yes {s-}(%s){!}\n", details.NPNProtocols)
	} else {
		fmtc.Println("No")
	}

	// ---

	fmtc.Printf(" %-40s {s}|{!} ", "Session resumption (caching)")

	switch details.SessionResumption {
	case 0:
		fmtc.Println("{y}No (Session resumption is not enabled){!}")
	case 1:
		fmtc.Println("{y}No (IDs assigned but not accepted){!}")
	case 2:
		fmtc.Println("Yes")
	}

	// ---

	fmtc.Printf(" %-40s {s}|{!} %s\n", "Session resumption (tickets)", getBool(details.SessionTickets&1 == 1))

	// ---

	fmtc.Printf(" %-40s {s}|{!} ", "OCSP stapling")

	if details.OCSPStapling {
		fmtc.Println("{g}Yes{!}")
	} else {
		fmtc.Println("No")
	}

	// ---

	fmtc.Printf(" %-40s {s}|{!} ", "Strict Transport Security (HSTS)")

	if details.HSTSPolicy != nil && details.HSTSPolicy.Status == sslscan.HSTS_STATUS_PRESENT {
		fmtc.Printf("{g}Yes{!} {s-}(%s){!}\n", details.HSTSPolicy.Header)

		if len(details.HSTSPreloads) != 0 {
			fmtc.Printf(" %-40s {s}|{!} ", "HSTS Preloading")
			fmtc.Println(getHSTSPreloadingMarkers(details.HSTSPreloads))
		}
	} else {
		fmtc.Println("No")
	}

	// ---

	fmtc.Printf(" %-40s {s}|{!} ", "Public Key Pinning (HPKP)")

	if details.HPKPPolicy != nil {
		switch details.HPKPPolicy.Status {
		case sslscan.HPKP_STATUS_INVALID:
			fmtc.Println("{r}Invalid{!}")
		case sslscan.HPKP_STATUS_DISABLED:
			fmtc.Println("{y}Disabled{!}")
		case sslscan.HPKP_STATUS_INCOMPLETE:
			fmtc.Println("{y}Incomplete{!}")
		case sslscan.HPKP_STATUS_VALID:
			fmtc.Printf("{g}Yes{!} ")

			if details.HPKPPolicy.IncludeSubDomains {
				fmtc.Printf(
					"{s-}(max-age=%d; includeSubdomains){!}\n",
					details.HPKPPolicy.MaxAge,
				)
			} else {
				fmtc.Printf(
					"{s-}(max-age=%d){!}\n",
					details.HPKPPolicy.MaxAge,
				)
			}

			for _, pin := range getPinsFromPolicy(details.HPKPPolicy) {
				fmtc.Printf(" %-40s {s}|{!} {s-}%s{!}\n", "", pin)
			}
		default:
			fmtc.Println("No")
		}
	} else {
		fmtc.Println("No")
	}

	// ---

	fmtc.Printf(" %-40s {s}|{!} ", "Long handshake intolerance")

	if details.MiscIntolerance&2 == 2 {
		fmtc.Println("{y}Yes{!}")
	} else if details.MiscIntolerance&4 == 4 {
		fmtc.Println("{y}Yes{!} {s-}(workaround success){!}")
	} else {
		fmtc.Println("No")
	}

	// ---

	fmtc.Printf(" %-40s {s}|{!} ", "TLS extension intolerance")

	if details.MiscIntolerance&1 == 1 {
		fmtc.Println("{y}Yes{!}")
	} else {
		fmtc.Println("No")
	}

	// ---

	fmtc.Printf(" %-40s {s}|{!} ", "TLS version intolerance")

	if details.ProtocolIntolerance != 0 {
		fmtc.Printf("{y}%s{!}\n", getProtocolIntolerance(details.ProtocolIntolerance))
	} else {
		fmtc.Println("No")
	}

	// ---

	fmtc.Printf(" %-40s {s}|{!} ", "Uses common DH primes")

	if details.DHUsesKnownPrimes != 0 {
		fmtc.Println("{y}Yes (Replace with custom DH parameters if possible){!}")
	} else {
		fmtc.Println("No")
	}

	// ---

	fmtc.Printf(" %-40s {s}|{!} ", "DH public server param (Ys) reuse")

	if details.DHYsReuse {
		fmtc.Println("{y}Yes{!}")
	} else {
		fmtc.Println("No")
	}
}