Skip to content

Commit a2ff222

Browse files
authored
cert-checker: use config log level and handle nil mariadb response (#6066)
- Fix cert-checker to use the syslog and stdout logging facilities it reads from the config file instead of having them hard-coded to zero. - Fix cert-checker to handle a nil response from mariadb if no records are found. - Fix comment in log.go to correctly describe when the initialize function and therefore default values would be used. Fixes #6067
1 parent 8ec10c4 commit a2ff222

File tree

3 files changed

+52
-9
lines changed

3 files changed

+52
-9
lines changed

cmd/cert-checker/main.go

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@ import (
44
"bytes"
55
"context"
66
"crypto/x509"
7+
"database/sql"
78
"encoding/json"
9+
"errors"
810
"flag"
911
"fmt"
1012
"log/syslog"
@@ -80,7 +82,7 @@ type reportEntry struct {
8082
// out the saDbMap implementation.
8183
type certDB interface {
8284
Select(i interface{}, query string, args ...interface{}) ([]interface{}, error)
83-
SelectInt(query string, args ...interface{}) (int64, error)
85+
SelectNullInt(query string, args ...interface{}) (sql.NullInt64, error)
8486
}
8587

8688
type certChecker struct {
@@ -118,13 +120,19 @@ func (c *certChecker) getCerts(unexpiredOnly bool) error {
118120
args["now"] = c.clock.Now()
119121
}
120122

121-
initialID, err := c.dbMap.SelectInt(
123+
sni, err := c.dbMap.SelectNullInt(
122124
"SELECT MIN(id) FROM certificates WHERE issued >= :issued AND expires >= :now",
123125
args,
124126
)
125127
if err != nil {
126128
return err
127129
}
130+
if !sni.Valid {
131+
// a nil response was returned by the DB, so return error and fail
132+
return errors.New("the SELECT query resulted in a NULL response from the DB")
133+
}
134+
135+
initialID := sni.Int64
128136
if initialID > 0 {
129137
// decrement the initial ID so that we select below as we aren't using >=
130138
initialID -= 1
@@ -368,8 +376,12 @@ func main() {
368376
syslogger, err := syslog.Dial("", "", syslog.LOG_INFO|syslog.LOG_LOCAL0, "")
369377
cmd.FailOnError(err, "Failed to dial syslog")
370378

371-
logger, err := blog.New(syslogger, 0, 0)
372-
cmd.FailOnError(err, "Failed to construct logger")
379+
syslogLevel := int(syslog.LOG_INFO)
380+
if config.Syslog.SyslogLevel != 0 {
381+
syslogLevel = config.Syslog.SyslogLevel
382+
}
383+
logger, err := blog.New(syslogger, config.Syslog.StdoutLevel, syslogLevel)
384+
cmd.FailOnError(err, "Could not connect to Syslog")
373385

374386
err = blog.Set(logger)
375387
cmd.FailOnError(err, "Failed to set audit logger")

cmd/cert-checker/main_test.go

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
"crypto/rsa"
1010
"crypto/x509"
1111
"crypto/x509/pkix"
12+
"database/sql"
1213
"encoding/asn1"
1314
"encoding/pem"
1415
"io/ioutil"
@@ -380,8 +381,12 @@ type mismatchedCountDB struct{}
380381
// `getCerts` calls `SelectInt` first to determine how many rows there are
381382
// matching the `getCertsCountQuery` criteria. For this mock we return
382383
// a non-zero number
383-
func (db mismatchedCountDB) SelectInt(_ string, _ ...interface{}) (int64, error) {
384-
return 99999, nil
384+
func (db mismatchedCountDB) SelectNullInt(_ string, _ ...interface{}) (sql.NullInt64, error) {
385+
return sql.NullInt64{
386+
Int64: 99999,
387+
Valid: true,
388+
},
389+
nil
385390
}
386391

387392
// `getCerts` then calls `Select` to retrieve the Certificate rows. We pull
@@ -422,6 +427,33 @@ func TestGetCertsEmptyResults(t *testing.T) {
422427
test.AssertNotError(t, err, "Failed to retrieve certificates")
423428
}
424429

430+
// emptyDB is a certDB object with methods used for testing that 'null'
431+
// responses received from the database are handled properly.
432+
type emptyDB struct {
433+
certDB
434+
}
435+
436+
// SelectNullInt is a method that returns a false sql.NullInt64 struct to
437+
// mock a null DB response
438+
func (db emptyDB) SelectNullInt(_ string, _ ...interface{}) (sql.NullInt64, error) {
439+
return sql.NullInt64{Valid: false},
440+
nil
441+
}
442+
443+
// TestGetCertsNullResults tests that a null response from the database will
444+
// be handled properly. It uses the emptyDB above to mock the response
445+
// expected if the DB finds no certificates to match the SELECT query and
446+
// should return an error.
447+
func TestGetCertsNullResults(t *testing.T) {
448+
saDbMap, err := sa.NewDbMap(vars.DBConnSA, sa.DbSettings{})
449+
test.AssertNotError(t, err, "Couldn't connect to database")
450+
checker := newChecker(saDbMap, clock.NewFake(), pa, kp, time.Hour, testValidityDurations)
451+
checker.dbMap = emptyDB{}
452+
453+
err = checker.getCerts(false)
454+
test.AssertError(t, err, "Should have gotten error from empty DB")
455+
}
456+
425457
func TestSaveReport(t *testing.T) {
426458
r := report{
427459
begin: time.Time{},

log/log.go

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -65,10 +65,9 @@ func New(log *syslog.Writer, stdoutLogLevel int, syslogLogLevel int) (Logger, er
6565
}, nil
6666
}
6767

68-
// initialize should only be used in unit tests.
68+
// initialize is used in unit tests and called by `Get` before the logger
69+
// is fully set up.
6970
func initialize() {
70-
// defaultPriority is never used because we always use specific priority-based
71-
// logging methods.
7271
const defaultPriority = syslog.LOG_INFO | syslog.LOG_LOCAL0
7372
syslogger, err := syslog.Dial("", "", defaultPriority, "test")
7473
if err != nil {

0 commit comments

Comments
 (0)