Commit d2d62a0b authored by Anders Mundt Due's avatar Anders Mundt Due
Browse files

sqlite1 tested, check-certs might work :)

parent a6c4521f
// https://github.com/timewasted/go-check-certs/blob/master/check-certs.go
//
// Copyright 2013 Ryan Rogers. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package main
import (
"crypto/tls"
"crypto/x509"
"flag"
"fmt"
"io/ioutil"
"log"
"strings"
"sync"
"time"
)
const defaultConcurrency = 8
const (
errExpiringShortly = "%s: ** '%s' (S/N %X) expires in %d hours! **"
errExpiringSoon = "%s: '%s' (S/N %X) expires in roughly %d days."
errSunsetAlg = "%s: '%s' (S/N %X) expires after the sunset date for its signature algorithm '%s'."
)
type sigAlgSunset struct {
name string // Human readable name of signature algorithm
sunsetsAt time.Time // Time the algorithm will be sunset
}
// sunsetSigAlgs is an algorithm to string mapping for signature algorithms
// which have been or are being deprecated. See the following links to learn
// more about SHA1's inclusion on this list.
//
// - https://technet.microsoft.com/en-us/library/security/2880823.aspx
// - http://googleonlinesecurity.blogspot.com/2014/09/gradually-sunsetting-sha-1.html
var sunsetSigAlgs = map[x509.SignatureAlgorithm]sigAlgSunset{
x509.MD2WithRSA: sigAlgSunset{
name: "MD2 with RSA",
sunsetsAt: time.Now(),
},
x509.MD5WithRSA: sigAlgSunset{
name: "MD5 with RSA",
sunsetsAt: time.Now(),
},
x509.SHA1WithRSA: sigAlgSunset{
name: "SHA1 with RSA",
sunsetsAt: time.Date(2017, 1, 1, 0, 0, 0, 0, time.UTC),
},
x509.DSAWithSHA1: sigAlgSunset{
name: "DSA with SHA1",
sunsetsAt: time.Date(2017, 1, 1, 0, 0, 0, 0, time.UTC),
},
x509.ECDSAWithSHA1: sigAlgSunset{
name: "ECDSA with SHA1",
sunsetsAt: time.Date(2017, 1, 1, 0, 0, 0, 0, time.UTC),
},
}
var (
hostsFile = flag.String("hosts", "", "The path to the file containing a list of hosts to check.")
warnYears = flag.Int("years", 0, "Warn if the certificate will expire within this many years.")
warnMonths = flag.Int("months", 0, "Warn if the certificate will expire within this many months.")
warnDays = flag.Int("days", 0, "Warn if the certificate will expire within this many days.")
checkSigAlg = flag.Bool("check-sig-alg", true, "Verify that non-root certificates are using a good signature algorithm.")
concurrency = flag.Int("concurrency", defaultConcurrency, "Maximum number of hosts to check at once.")
)
type certErrors struct {
commonName string
errs []error
}
type hostResult struct {
host string
err error
certs []certErrors
}
func main() {
flag.Parse()
if len(*hostsFile) == 0 {
flag.Usage()
return
}
if *warnYears < 0 {
*warnYears = 0
}
if *warnMonths < 0 {
*warnMonths = 0
}
if *warnDays < 0 {
*warnDays = 0
}
if *warnYears == 0 && *warnMonths == 0 && *warnDays == 0 {
*warnDays = 30
}
if *concurrency < 0 {
*concurrency = defaultConcurrency
}
processHosts()
}
func processHosts() {
done := make(chan struct{})
defer close(done)
hosts := queueHosts(done)
results := make(chan hostResult)
var wg sync.WaitGroup
wg.Add(*concurrency)
for i := 0; i < *concurrency; i++ {
go func() {
processQueue(done, hosts, results)
wg.Done()
}()
}
go func() {
wg.Wait()
close(results)
}()
for r := range results {
if r.err != nil {
log.Printf("%s: %v\n", r.host, r.err)
continue
}
for _, cert := range r.certs {
for _, err := range cert.errs {
log.Println(err)
}
}
}
}
func queueHosts(done <-chan struct{}) <-chan string {
hosts := make(chan string)
go func() {
defer close(hosts)
fileContents, err := ioutil.ReadFile(*hostsFile)
if err != nil {
return
}
lines := strings.Split(string(fileContents), "\n")
for _, line := range lines {
host := strings.TrimSpace(line)
if len(host) == 0 || host[0] == '#' {
continue
}
select {
case hosts <- host:
case <-done:
return
}
}
}()
return hosts
}
func processQueue(done <-chan struct{}, hosts <-chan string, results chan<- hostResult) {
for host := range hosts {
select {
case results <- checkHost(host):
case <-done:
return
}
}
}
func checkHost(host string) (result hostResult) {
result = hostResult{
host: host,
certs: []certErrors{},
}
conn, err := tls.Dial("tcp", host, nil)
if err != nil {
result.err = err
return
}
defer conn.Close()
timeNow := time.Now()
checkedCerts := make(map[string]struct{})
for _, chain := range conn.ConnectionState().VerifiedChains {
for certNum, cert := range chain {
if _, checked := checkedCerts[string(cert.Signature)]; checked {
continue
}
checkedCerts[string(cert.Signature)] = struct{}{}
cErrs := []error{}
// Check the expiration.
if timeNow.AddDate(*warnYears, *warnMonths, *warnDays).After(cert.NotAfter) {
expiresIn := int64(cert.NotAfter.Sub(timeNow).Hours())
if expiresIn <= 48 {
cErrs = append(cErrs, fmt.Errorf(errExpiringShortly, host, cert.Subject.CommonName, cert.SerialNumber, expiresIn))
} else {
cErrs = append(cErrs, fmt.Errorf(errExpiringSoon, host, cert.Subject.CommonName, cert.SerialNumber, expiresIn/24))
}
}
// Check the signature algorithm, ignoring the root certificate.
if alg, exists := sunsetSigAlgs[cert.SignatureAlgorithm]; *checkSigAlg && exists && certNum != len(chain)-1 {
if cert.NotAfter.Equal(alg.sunsetsAt) || cert.NotAfter.After(alg.sunsetsAt) {
cErrs = append(cErrs, fmt.Errorf(errSunsetAlg, host, cert.Subject.CommonName, cert.SerialNumber, alg.name))
}
}
result.certs = append(result.certs, certErrors{
commonName: cert.Subject.CommonName,
errs: cErrs,
})
}
}
return
}
......@@ -14,8 +14,10 @@ func main() {
database, _ := sql.Open("sqlite3", "./nraboy.db")
statement, _ := database.Prepare("CREATE TABLE IF NOT EXISTS people (id INTEGER PRIMARY KEY, firstname TEXT, lastname TEXT)")
statement.Exec()
statement, _ := database.Prepare("INSERT INTO people (firstname, lastname) values (?, ?)")
statement, _ = database.Prepare("INSERT INTO people (firstname, lastname) values (?, ?)")
statement.Exec("Nic", "Raboy")
statement.Exec("Bob", "Blacen")
statement.Exec("Jen", "Xenon")
rows, _ := database.Query("SELECT id, firstname, lastname FROM people")
var id int
var firstname string
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment