-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathmain.go
171 lines (151 loc) · 5.55 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
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)
}