first commit

This commit is contained in:
Piotr Domański 2024-07-25 17:03:53 +02:00
commit b12b412a89
5 changed files with 116 additions and 0 deletions

25
.gitignore vendored Normal file
View file

@ -0,0 +1,25 @@
# If you prefer the allow list template instead of the deny list, see community template:
# https://github.com/github/gitignore/blob/main/community/Golang/Go.AllowList.gitignore
#
# Binaries for programs and plugins
*.exe
*.exe~
*.dll
*.so
*.dylib
# Test binary, built with `go test -c`
*.test
# Output of the go coverage tool, specifically when used with LiteIDE
*.out
# Dependency directories (remove the comment below to include it)
# vendor/
# Go workspace file
go.work
go.work.sum
# env file
.env

0
Readme.md Normal file
View file

36
certchecker.go Normal file
View file

@ -0,0 +1,36 @@
package certchecker
import (
"crypto/tls"
"fmt"
"time"
)
// Check checks if the certificate of the domain expires in less than notifyExpirationDays
// and returns an error if it does
func Check(domain string, notifyExpirationDays int) error {
conn, err := tls.Dial("tcp", domain+":443", nil)
if err != nil {
return err
}
defer conn.Close()
err = conn.Handshake()
if err != nil {
return err
}
err = conn.VerifyHostname(domain)
if err != nil {
return err
}
for _, certificate := range conn.ConnectionState().PeerCertificates {
expiresInDays := int(certificate.NotAfter.Sub(time.Now()).Hours() / 24)
if expiresInDays < notifyExpirationDays {
return fmt.Errorf("certificate expires in %d days", expiresInDays)
}
}
return nil
}

52
cmd/main.go Normal file
View file

@ -0,0 +1,52 @@
package main
import (
"doman/certchecker"
"bufio"
"flag"
"fmt"
"os"
"sync"
)
func main() {
notifyExpirationDays := *flag.Int("notify", 7, "Notify when the certificate expires in less than this number of days")
flag.Parse()
domains := flag.Args()
if len(domains) == 0 {
stat, _ := os.Stdin.Stat()
scanner := bufio.NewScanner(os.Stdin)
if (stat.Mode() & os.ModeCharDevice) == 0 {
for scanner.Scan() {
domains = append(domains, scanner.Text())
}
} else {
fmt.Println("Enter a domain to check:")
scanner.Scan()
domains = append(domains, scanner.Text())
}
err := scanner.Err()
if err != nil {
fmt.Fprintln(os.Stderr, "reading standard input:", err)
}
}
var wg sync.WaitGroup
defer wg.Wait()
for _, domain := range domains {
wg.Add(1)
go func() {
err := certchecker.Check(domain, notifyExpirationDays)
if err != nil {
fmt.Printf("%s: %v\n", domain, err)
} else{
fmt.Printf("%s: OK\n", domain)
}
wg.Done()
} ()
}
}

3
go.mod Normal file
View file

@ -0,0 +1,3 @@
module doman/certchecker
go 1.22.5