Skip to content

Commit 40fdfb2

Browse files
authored
Certificate based authentication (#4)
Add certificate based authentication
2 parents 761f396 + aa438be commit 40fdfb2

File tree

2 files changed

+49
-8
lines changed

2 files changed

+49
-8
lines changed

check.go

+43-8
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,11 @@ type SSLCheck struct {
4141
DaysCritical int
4242
}
4343

44+
type ClientCert struct {
45+
ClientCertFile string
46+
PrivateKeyFile string
47+
}
48+
4449
// Request
4550
type Request struct {
4651
Scheme string
@@ -57,6 +62,7 @@ type Request struct {
5762
WarningTimeout int
5863
CriticalTimeout int
5964
NoSNI bool
65+
ClientCert ClientCert
6066
}
6167

6268
// Check params
@@ -122,7 +128,7 @@ func checkCerts(certs [][]*x509.Certificate, e *Expected) (string, int) {
122128
}
123129

124130
// TLS config factory
125-
func getTLSConfig(r *Request) *tls.Config {
131+
func getTLSConfig(r *Request) (*tls.Config, error) {
126132
TLSConfig := &tls.Config{}
127133

128134
// InsecureSkipVerify
@@ -135,12 +141,27 @@ func getTLSConfig(r *Request) *tls.Config {
135141
TLSConfig.ServerName = r.Host
136142
}
137143

138-
return TLSConfig
144+
// Client cert
145+
if r.ClientCert.ClientCertFile != "" && r.ClientCert.PrivateKeyFile != "" {
146+
cert, err := tls.LoadX509KeyPair(r.ClientCert.ClientCertFile, r.ClientCert.PrivateKeyFile)
147+
if err != nil {
148+
return nil, err
149+
}
150+
TLSConfig.Certificates = []tls.Certificate{cert}
151+
}
152+
153+
return TLSConfig, nil
139154
}
140155

141156
// HTTP client factory
142-
func initHTTPClient(r *Request) *http.Client {
143-
http.DefaultTransport.(*http.Transport).TLSClientConfig = getTLSConfig(r)
157+
func initHTTPClient(r *Request) (*http.Client, error) {
158+
// Get TLS config
159+
TLSConfig, err := getTLSConfig(r)
160+
if err != nil {
161+
return nil, err
162+
}
163+
164+
http.DefaultTransport.(*http.Transport).TLSClientConfig = TLSConfig
144165

145166
// Setup timeout
146167
var timeout time.Duration
@@ -162,7 +183,7 @@ func initHTTPClient(r *Request) *http.Client {
162183
},
163184
}
164185

165-
return client
186+
return client, nil
166187
}
167188

168189
// Adds custom User-Agent header
@@ -176,7 +197,11 @@ func Check(r *Request, e *Expected) (string, int, error) {
176197
return "UNKNOWN - No host or IP address given", EXIT_UNKNOWN, nil
177198
}
178199

179-
client := initHTTPClient(r)
200+
client, err := initHTTPClient(r)
201+
if err != nil {
202+
return "CRITICAL", EXIT_CRITICAL, err
203+
}
204+
180205
url := r.GetURL()
181206

182207
if r.Verbose {
@@ -203,9 +228,14 @@ func Check(r *Request, e *Expected) (string, int, error) {
203228

204229
// TODO - test
205230
if r.Authentication.Type == AUTH_NTLM {
231+
// Get TLS config
232+
TLSConfig, err := getTLSConfig(r)
233+
if err != nil {
234+
return "CRITICAL", EXIT_CRITICAL, err
235+
}
206236
transport := ntlmssp.Negotiator{
207237
RoundTripper: &http.Transport{
208-
TLSClientConfig: getTLSConfig(r),
238+
TLSClientConfig: TLSConfig,
209239
},
210240
}
211241
client.Transport = transport
@@ -286,7 +316,12 @@ func Check(r *Request, e *Expected) (string, int, error) {
286316

287317
// Detects auth type
288318
func DetectAuthType(r *Request) int {
289-
client := initHTTPClient(r)
319+
client, err := initHTTPClient(r)
320+
if err != nil {
321+
// `Check` should handle all errors
322+
return AUTH_NONE
323+
}
324+
290325
url := r.GetURL()
291326

292327
request, err := http.NewRequest("GET", url, nil)

main.go

+6
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ type Options struct {
2929
WarningTimeout int `short:"w" description:"Warning timeout" default:"0"`
3030
CriticalTimeout int `short:"c" description:"Critical timeout" default:"0"`
3131
NoSNI bool `long:"no-sni" description:"Do not use SNI"`
32+
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"`
33+
PrivateKeyFile string `short:"K" long:"private-key" description:"Name of file containing the private key (PEM format) matching the client certificate"`
3234
}
3335

3436
var options Options
@@ -105,6 +107,10 @@ func main() {
105107
WarningTimeout: options.WarningTimeout,
106108
CriticalTimeout: options.CriticalTimeout,
107109
NoSNI: options.NoSNI,
110+
ClientCert: ClientCert{
111+
ClientCertFile: options.ClientCertFile,
112+
PrivateKeyFile: options.PrivateKeyFile,
113+
},
108114
}
109115

110116
if options.GuessAuth {

0 commit comments

Comments
 (0)