mirror of
https://github.com/TwiN/gatus.git
synced 2024-11-07 08:34:15 +01:00
#120: Add support for StartTLS protocol
* add starttls * remove starttls from default config Co-authored-by: Gopher Johns <gopher.johns28@gmail.com>
This commit is contained in:
parent
81aeb7a48e
commit
2131fa4412
@ -2,10 +2,14 @@ package client
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"crypto/x509"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/smtp"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/go-ping/ping"
|
||||
@ -74,6 +78,36 @@ func CanCreateTCPConnection(address string) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func CanPerformStartTls(address string, insecure bool) (connected bool, certificate *x509.Certificate, err error) {
|
||||
tokens := strings.Split(address, ":")
|
||||
if len(tokens) != 2 {
|
||||
err = fmt.Errorf("invalid address for starttls, must HOST:PORT")
|
||||
return
|
||||
}
|
||||
tlsconfig := &tls.Config{
|
||||
InsecureSkipVerify: insecure,
|
||||
ServerName: tokens[0],
|
||||
}
|
||||
|
||||
c, err := smtp.Dial(address)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
err = c.StartTLS(tlsconfig)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if state, ok := c.TLSConnectionState(); ok {
|
||||
certificate = state.PeerCertificates[0]
|
||||
} else {
|
||||
err = fmt.Errorf("could not get TLS connection state")
|
||||
return
|
||||
}
|
||||
connected = true
|
||||
return
|
||||
}
|
||||
|
||||
// Ping checks if an address can be pinged and returns the round-trip time if the address can be pinged
|
||||
//
|
||||
// Note that this function takes at least 100ms, even if the address is 127.0.0.1
|
||||
|
@ -1,6 +1,7 @@
|
||||
package client
|
||||
|
||||
import (
|
||||
"crypto/x509"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
@ -49,3 +50,56 @@ func TestPing(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestCanPerformStartTls(t *testing.T) {
|
||||
type args struct {
|
||||
address string
|
||||
insecure bool
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
wantConnected bool
|
||||
wantCertificate *x509.Certificate
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
name: "invalid address",
|
||||
args: args{
|
||||
address: "test",
|
||||
},
|
||||
wantConnected: false,
|
||||
wantCertificate: nil,
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "error dial",
|
||||
args: args{
|
||||
address: "test:1234",
|
||||
},
|
||||
wantConnected: false,
|
||||
wantCertificate: nil,
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "valid starttls",
|
||||
args: args{
|
||||
address: "smtp.gmail.com:587",
|
||||
},
|
||||
wantConnected: true,
|
||||
wantErr: false,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
gotConnected, _, err := CanPerformStartTls(tt.args.address, tt.args.insecure)
|
||||
if (err != nil) != tt.wantErr {
|
||||
t.Errorf("CanPerformStartTls() error = %v, wantErr %v", err, tt.wantErr)
|
||||
return
|
||||
}
|
||||
if gotConnected != tt.wantConnected {
|
||||
t.Errorf("CanPerformStartTls() gotConnected = %v, want %v", gotConnected, tt.wantConnected)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ package core
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/x509"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"io/ioutil"
|
||||
@ -178,10 +179,12 @@ func (service *Service) call(result *Result) {
|
||||
var request *http.Request
|
||||
var response *http.Response
|
||||
var err error
|
||||
var certificate *x509.Certificate
|
||||
isServiceDNS := service.DNS != nil
|
||||
isServiceTCP := strings.HasPrefix(service.URL, "tcp://")
|
||||
isServiceICMP := strings.HasPrefix(service.URL, "icmp://")
|
||||
isServiceHTTP := !isServiceDNS && !isServiceTCP && !isServiceICMP
|
||||
isServiceStartTLS := strings.HasPrefix(service.URL, "starttls://")
|
||||
isServiceHTTP := !isServiceDNS && !isServiceTCP && !isServiceICMP && !isServiceStartTLS
|
||||
if isServiceHTTP {
|
||||
request = service.buildHTTPRequest()
|
||||
}
|
||||
@ -189,6 +192,14 @@ func (service *Service) call(result *Result) {
|
||||
if isServiceDNS {
|
||||
service.DNS.query(service.URL, result)
|
||||
result.Duration = time.Since(startTime)
|
||||
} else if isServiceStartTLS {
|
||||
result.Connected, certificate, err = client.CanPerformStartTls(strings.TrimPrefix(service.URL, "starttls://"), service.Insecure)
|
||||
if err != nil {
|
||||
result.Errors = append(result.Errors, err.Error())
|
||||
return
|
||||
}
|
||||
result.Duration = time.Since(startTime)
|
||||
result.CertificateExpiration = time.Until(certificate.NotAfter)
|
||||
} else if isServiceTCP {
|
||||
result.Connected = client.CanCreateTCPConnection(strings.TrimPrefix(service.URL, "tcp://"))
|
||||
result.Duration = time.Since(startTime)
|
||||
@ -203,7 +214,7 @@ func (service *Service) call(result *Result) {
|
||||
}
|
||||
defer response.Body.Close()
|
||||
if response.TLS != nil && len(response.TLS.PeerCertificates) > 0 {
|
||||
certificate := response.TLS.PeerCertificates[0]
|
||||
certificate = response.TLS.PeerCertificates[0]
|
||||
result.CertificateExpiration = time.Until(certificate.NotAfter)
|
||||
}
|
||||
result.HTTPStatus = response.StatusCode
|
||||
|
Loading…
Reference in New Issue
Block a user