368d6fafea
Code backup
172 lines
5.5 KiB
Go
172 lines
5.5 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"strconv"
|
|
"strings"
|
|
|
|
"github.com/jessevdk/go-flags"
|
|
)
|
|
|
|
type Options struct {
|
|
Host string `short:"H" description:"Host ex. google.com" default:""`
|
|
IPAddress string `short:"I" description:"IPv4 address ex. 8.8.4.4" default:""`
|
|
URI string `short:"u" long:"uri" description:"URI to check" default:"/"`
|
|
Port int `short:"p" description:"Port ex. 80 for HTTP 443 for HTTPS" default:"80"`
|
|
SSL bool `short:"S" long:"tls" description:"Use HTTPS"`
|
|
Timeout int `short:"t" long:"timeout" description:"Timeout" default:"30"`
|
|
AuthBasic bool `long:"auth-basic" description:"Use bacis auth"`
|
|
AuthNtlm bool `long:"auth-ntlm" description:"Use NTLM auth"`
|
|
Auth string `short:"a" long:"auth" description:"ex. user:password" default:""`
|
|
ExpectedCode string `short:"e" long:"expect" description:"Expected HTTP code" default:"200"`
|
|
BodyText string `short:"s" long:"string" description:"Search for given string in response body" default:""`
|
|
SSLExpiration string `short:"C" description:"Check SSL cert expiration" default:""`
|
|
SSLNoVerify bool `short:"k" long:"insecure" description:"Controls whether a client verifies the server's certificate chain and host name"`
|
|
Verbose bool `short:"v" long:"verbose" description:"Verbose mode"`
|
|
GuessAuth bool `long:"guess-auth" description:"Guess auth type"`
|
|
FollowRedirects bool `long:"follow-redirects" description:"Follow redirects"`
|
|
WarningTimeout int `short:"w" description:"Warning timeout" default:"0"`
|
|
CriticalTimeout int `short:"c" description:"Critical timeout" default:"0"`
|
|
NoSNI bool `long:"no-sni" description:"Do not use SNI"`
|
|
ClientCertFile string `short:"J" long:"client-cert" description:"Name of file containing the client certificate (PEM format) to be used in establishing the SSL session"`
|
|
PrivateKeyFile string `short:"K" long:"private-key" description:"Name of file containing the private key (PEM format) matching the client certificate"`
|
|
DisableTLSRenegotiation bool `long:"disable-tls-renegotiation" description:"Disable TLS Renegotiation"`
|
|
}
|
|
|
|
var options Options
|
|
var parser = flags.NewParser(&options, flags.Default)
|
|
var appVersion string
|
|
var goVersion string
|
|
|
|
func main() {
|
|
if _, err := parser.Parse(); err != nil {
|
|
if flagsErr, ok := err.(*flags.Error); ok && flagsErr.Type == flags.ErrHelp {
|
|
os.Exit(0)
|
|
} else {
|
|
os.Exit(1)
|
|
}
|
|
}
|
|
|
|
var scheme string
|
|
if options.Port == 443 || options.SSL {
|
|
scheme = "https"
|
|
} else {
|
|
scheme = "http"
|
|
}
|
|
|
|
port := options.Port
|
|
if scheme == "https" && port == 80 {
|
|
port = 443
|
|
}
|
|
|
|
authType := AUTH_NONE
|
|
if options.AuthBasic {
|
|
authType = AUTH_BASIC
|
|
}
|
|
if options.AuthNtlm {
|
|
authType = AUTH_NTLM
|
|
}
|
|
|
|
var authUser string
|
|
var authPassword string
|
|
|
|
if strings.Contains(options.Auth, ":") {
|
|
authParts := strings.Split(options.Auth, ":")
|
|
if len(authParts) != 2 {
|
|
fmt.Println("UNKNOWN - Username and password not given: provide -a|--auth username:password")
|
|
os.Exit(EXIT_UNKNOWN)
|
|
}
|
|
authUser = authParts[0]
|
|
authPassword = authParts[1]
|
|
}
|
|
|
|
if authType == AUTH_NONE && len(authUser) > 0 && len(authPassword) > 0 {
|
|
authType = AUTH_BASIC
|
|
}
|
|
|
|
if len(options.Auth) > 0 && len(authUser) == 0 && len(authPassword) == 0 {
|
|
fmt.Println("UNKNOWN - Username and password not given: provide -a|--auth username:password")
|
|
os.Exit(EXIT_UNKNOWN)
|
|
}
|
|
|
|
r := &Request{
|
|
Host: options.Host,
|
|
IPAddress: options.IPAddress,
|
|
URI: options.URI,
|
|
Port: port,
|
|
Scheme: scheme,
|
|
Timeout: options.Timeout,
|
|
Authentication: Authentication{
|
|
Type: authType,
|
|
User: authUser,
|
|
Password: authPassword,
|
|
},
|
|
SSLNoVerify: options.SSLNoVerify,
|
|
Verbose: options.Verbose,
|
|
FollowRedirects: options.FollowRedirects,
|
|
WarningTimeout: options.WarningTimeout,
|
|
CriticalTimeout: options.CriticalTimeout,
|
|
NoSNI: options.NoSNI,
|
|
ClientCert: ClientCert{
|
|
ClientCertFile: options.ClientCertFile,
|
|
PrivateKeyFile: options.PrivateKeyFile,
|
|
},
|
|
TLSRenegotiation: !options.DisableTLSRenegotiation,
|
|
}
|
|
|
|
if options.GuessAuth {
|
|
authType = DetectAuthType(r)
|
|
if r.Verbose {
|
|
fmt.Println(fmt.Sprintf(">> Detected auth: %s", authLookup[authType]))
|
|
}
|
|
r.Authentication.Type = authType
|
|
}
|
|
|
|
var statusCodes []int
|
|
if strings.Contains(options.ExpectedCode, ",") {
|
|
for _, code := range strings.Split(options.ExpectedCode, ",") {
|
|
codeInt, _ := strconv.Atoi(code)
|
|
statusCodes = append(statusCodes, codeInt)
|
|
}
|
|
} else {
|
|
codeInt, _ := strconv.Atoi(options.ExpectedCode)
|
|
statusCodes = append(statusCodes, codeInt)
|
|
}
|
|
|
|
var SSLWarning int
|
|
var SSLCritical int
|
|
if strings.Contains(options.SSLExpiration, ",") {
|
|
SSLParts := strings.Split(options.SSLExpiration, ",")
|
|
if len(SSLParts) != 2 {
|
|
fmt.Println("UNKNOWN - SSL check has invalid parameters: provide e.g. -C 14,7")
|
|
os.Exit(EXIT_UNKNOWN)
|
|
}
|
|
SSLWarning, _ = strconv.Atoi(SSLParts[0])
|
|
SSLCritical, _ = strconv.Atoi(SSLParts[1])
|
|
} else {
|
|
SSLWarning, _ = strconv.Atoi(options.SSLExpiration)
|
|
SSLCritical = 0
|
|
}
|
|
|
|
e := &Expected{
|
|
StatusCodes: statusCodes,
|
|
BodyText: options.BodyText,
|
|
SSLCheck: SSLCheck{
|
|
Run: options.SSL,
|
|
DaysWarning: SSLWarning,
|
|
DaysCritical: SSLCritical,
|
|
},
|
|
}
|
|
|
|
msg, code, err := Check(r, e)
|
|
|
|
if err != nil {
|
|
fmt.Println(fmt.Sprintf("UNKNOWN, %s", err.Error()))
|
|
os.Exit(EXIT_UNKNOWN)
|
|
}
|
|
|
|
fmt.Println(msg)
|
|
os.Exit(code)
|
|
}
|