Skip to content

Commit 0db4f67

Browse files
tmshortopenshift-merge-bot[bot]
authored andcommitted
UPSTREAM: <drop>: Add logging to certpoolwatcher and client
Logging now indicates what certificate (by file and X.509 name) is being watched When an unverified certificate error is returned to the client, log the cert Signed-off-by: Todd Short <[email protected]>
1 parent 241fecf commit 0db4f67

File tree

4 files changed

+106
-5
lines changed

4 files changed

+106
-5
lines changed

internal/catalogmetadata/client/client.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,18 @@ package client
22

33
import (
44
"context"
5+
"crypto/tls"
56
"errors"
67
"fmt"
78
"io"
89
"io/fs"
910
"net/http"
1011
"net/url"
1112

13+
"github.com/go-logr/logr"
1214
"k8s.io/apimachinery/pkg/api/meta"
1315
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
16+
ctrl "sigs.k8s.io/controller-runtime"
1417

1518
"github.com/operator-framework/operator-registry/alpha/declcfg"
1619

@@ -111,6 +114,17 @@ func (c *Client) PopulateCache(ctx context.Context, catalog *catalogd.ClusterCat
111114
return c.cache.Put(catalog.Name, catalog.Status.ResolvedSource.Image.Ref, resp.Body, nil)
112115
}
113116

117+
func logX509Error(err error, l logr.Logger) {
118+
var cvErr *tls.CertificateVerificationError
119+
if errors.As(err, &cvErr) {
120+
n := 1
121+
for _, cert := range cvErr.UnverifiedCertificates {
122+
l.Error(err, "unverified cert", "n", n, "subject", cert.Subject, "issuer", cert.Issuer, "DNSNames", cert.DNSNames, "serial", cert.SerialNumber)
123+
n = n + 1
124+
}
125+
}
126+
}
127+
114128
func (c *Client) doRequest(ctx context.Context, catalog *catalogd.ClusterCatalog) (*http.Response, error) {
115129
if catalog.Status.URLs == nil {
116130
return nil, fmt.Errorf("error: catalog %q has a nil status.urls value", catalog.Name)
@@ -133,6 +147,7 @@ func (c *Client) doRequest(ctx context.Context, catalog *catalogd.ClusterCatalog
133147

134148
resp, err := client.Do(req)
135149
if err != nil {
150+
logX509Error(err, ctrl.Log.WithName("catalog-client"))
136151
return nil, fmt.Errorf("error performing request: %v", err)
137152
}
138153

internal/httputil/certlog.go

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
package httputil
2+
3+
import (
4+
"crypto/x509"
5+
"encoding/pem"
6+
"fmt"
7+
"os"
8+
"path/filepath"
9+
10+
"github.com/go-logr/logr"
11+
)
12+
13+
func logPath(path, action string, log logr.Logger) {
14+
fi, err := os.Stat(path)
15+
if err != nil {
16+
log.Error(err, "error in os.Stat()", "path", path)
17+
return
18+
}
19+
if !fi.IsDir() {
20+
logFile(path, "", fmt.Sprintf("%s file", action), log)
21+
return
22+
}
23+
action = fmt.Sprintf("%s directory", action)
24+
dirEntries, err := os.ReadDir(path)
25+
if err != nil {
26+
log.Error(err, "error in os.ReadDir()", "path", path)
27+
return
28+
}
29+
for _, e := range dirEntries {
30+
file := filepath.Join(path, e.Name())
31+
fi, err := os.Stat(file)
32+
if err != nil {
33+
log.Error(err, "error in os.Stat()", "file", file)
34+
continue
35+
}
36+
if fi.IsDir() {
37+
log.Info("ignoring subdirectory", "directory", file)
38+
continue
39+
}
40+
logFile(e.Name(), path, action, log)
41+
}
42+
}
43+
44+
func logFile(filename, path, action string, log logr.Logger) {
45+
filepath := filepath.Join(path, filename)
46+
data, err := os.ReadFile(filepath)
47+
if err != nil {
48+
log.Error(err, "error in os.ReadFile()", "file", filename)
49+
return
50+
}
51+
logPem(data, filename, path, action, log)
52+
}
53+
54+
func logPem(data []byte, filename, path, action string, log logr.Logger) {
55+
for len(data) > 0 {
56+
var block *pem.Block
57+
block, data = pem.Decode(data)
58+
if block == nil {
59+
log.Info("error: no block returned from pem.Decode()", "file", filename)
60+
return
61+
}
62+
crt, err := x509.ParseCertificate(block.Bytes)
63+
if err != nil {
64+
log.Error(err, "error in x509.ParseCertificate()", "file", filename)
65+
return
66+
}
67+
68+
args := []any{}
69+
if path != "" {
70+
args = append(args, "directory", path)
71+
}
72+
// Find an appopriate certificate identifier
73+
args = append(args, "file", filename)
74+
if s := crt.Subject.String(); s != "" {
75+
args = append(args, "subject", s)
76+
} else if crt.DNSNames != nil {
77+
args = append(args, "DNSNames", crt.DNSNames)
78+
} else if s := crt.SerialNumber.String(); s != "" {
79+
args = append(args, "serial", s)
80+
}
81+
log.Info(action, args...)
82+
}
83+
}

internal/httputil/certpoolwatcher.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,12 @@ func NewCertPoolWatcher(caDir string, log logr.Logger) (*CertPoolWatcher, error)
5050
// If the SSL_CERT_DIR or SSL_CERT_FILE environment variables are
5151
// specified, this means that we have some control over the system root
5252
// location, thus they may change, thus we should watch those locations.
53-
watchPaths := strings.Split(os.Getenv("SSL_CERT_DIR"), ":")
54-
watchPaths = append(watchPaths, caDir, os.Getenv("SSL_CERT_FILE"))
53+
sslCertDir := os.Getenv("SSL_CERT_DIR")
54+
sslCertFile := os.Getenv("SSL_CERT_FILE")
55+
log.Info("SSL environment", "SSL_CERT_DIR", sslCertDir, "SSL_CERT_FILE", sslCertFile)
56+
57+
watchPaths := strings.Split(sslCertDir, ":")
58+
watchPaths = append(watchPaths, caDir, sslCertFile)
5559
watchPaths = slices.DeleteFunc(watchPaths, func(p string) bool {
5660
if p == "" {
5761
return true
@@ -66,6 +70,7 @@ func NewCertPoolWatcher(caDir string, log logr.Logger) (*CertPoolWatcher, error)
6670
if err := watcher.Add(p); err != nil {
6771
return nil, err
6872
}
73+
logPath(p, "watching certificate", log)
6974
}
7075

7176
cpw := &CertPoolWatcher{

internal/httputil/certutil.go

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import (
55
"fmt"
66
"os"
77
"path/filepath"
8-
"time"
98

109
"github.com/go-logr/logr"
1110
)
@@ -24,7 +23,6 @@ func NewCertPool(caDir string, log logr.Logger) (*x509.CertPool, error) {
2423
return nil, err
2524
}
2625
count := 0
27-
firstExpiration := time.Time{}
2826

2927
for _, e := range dirEntries {
3028
file := filepath.Join(caDir, e.Name())
@@ -46,13 +44,13 @@ func NewCertPool(caDir string, log logr.Logger) (*x509.CertPool, error) {
4644
if caCertPool.AppendCertsFromPEM(data) {
4745
count++
4846
}
47+
logPem(data, e.Name(), caDir, "loading certificate file", log)
4948
}
5049

5150
// Found no certs!
5251
if count == 0 {
5352
return nil, fmt.Errorf("no certificates found in %q", caDir)
5453
}
5554

56-
log.Info("first expiration", "time", firstExpiration.Format(time.RFC3339))
5755
return caCertPool, nil
5856
}

0 commit comments

Comments
 (0)