Skip to content

Instantly share code, notes, and snippets.

@rossdylan
Last active December 27, 2015 15:19
Show Gist options
  • Select an option

  • Save rossdylan/7347336 to your computer and use it in GitHub Desktop.

Select an option

Save rossdylan/7347336 to your computer and use it in GitHub Desktop.
check some servers ssl certs
package main
import (
"bytes"
"crypto/tls"
"crypto/x509"
"fmt"
"io"
"net"
"net/smtp"
"os"
"sort"
"strconv"
"strings"
"text/tabwriter"
"time"
)
func MailReport(report, to_addr string) {
smtpAuth := smtp.PlainAuth("", "", "", "localhost")
err := smtp.SendMail("localhost:25", smtpAuth, "[email protected]", []string{to_addr}, []byte(report))
if err != nil {
panic(err)
}
}
type Certificates []*x509.Certificate
func (c Certificates) Len() int {
return len(c)
}
func (c Certificates) Swap(i, j int) {
c[i], c[j] = c[j], c[i]
}
func (c Certificates) Less(i, j int) bool {
return c[i].Subject.CommonName < c[j].Subject.CommonName
}
func GenerateReport(certs Certificates) string {
sort.Sort(certs)
pReader, pWriter := io.Pipe()
var buff bytes.Buffer
reportWriter := new(tabwriter.Writer)
reportWriter.Init(pWriter, 0, 8, 0, '\t', 0)
fmt.Fprintln(reportWriter, "Site\tStatus\t \tDays Left\tExpire Date")
for _, cert := range certs {
if cert != nil {
eDate := cert.NotAfter
var expired string
if IsExpired(eDate) {
expired = "Expired"
} else {
expired = "Valid"
}
daysToExpire := GetExpireDays(eDate)
cn := cert.Subject.CommonName
fmt.Fprintf(reportWriter, "%s\t%s\t \t%d\t%s\n", cn, expired, daysToExpire, eDate.Local())
}
}
go buff.ReadFrom(pReader)
reportWriter.Flush()
pWriter.Close()
pReader.Close()
return buff.String()
}
func IsExpired(then time.Time) bool {
return time.Now().After(then)
}
func GetExpireDays(then time.Time) int {
now := time.Now()
delta := then.Sub(now)
return int(delta.Hours() / 24)
}
func GetCerts(host string, port int) *x509.Certificate {
uri := host + fmt.Sprintf(":%d", port)
connection, err := net.Dial("tcp", uri)
if err != nil {
panic(err)
}
defer connection.Close()
config := tls.Config{ServerName: host, InsecureSkipVerify: true}
secConn := tls.Client(connection, &config)
defer secConn.Close()
handshakeError := secConn.Handshake()
if handshakeError != nil {
return nil
}
certs := secConn.ConnectionState().PeerCertificates
if certs == nil || len(certs) < 1 {
return nil
}
return certs[0]
}
func CertGrabber(uri string, queue chan *x509.Certificate, exitQueue chan bool) {
hostSplit := strings.Split(uri, ":")
host := hostSplit[0]
port, err := strconv.Atoi(hostSplit[1])
if err != nil {
panic(err)
}
queue <- GetCerts(host, port)
exitQueue <- true
}
func main() {
queue := make(chan *x509.Certificate, 10)
exitQueue := make(chan bool)
var numThreads int
numThreads = 0
for _, arg := range os.Args[1:] {
go CertGrabber(arg, queue, exitQueue)
numThreads += 1
}
var count int
count = 0
for val := range exitQueue {
if val {
count += 1
}
if count == numThreads {
break
}
}
queue <- nil
var certs []*x509.Certificate
certs = make([]*x509.Certificate, 0)
for cert := range queue {
if cert != nil {
certs = append(certs, cert)
} else {
break
}
}
report := GenerateReport(certs)
fmt.Println(report)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment