Skip to content

Commit 3dd1c26

Browse files
committed
Make guest-agent buildable on FreeBSD
This commit, when paired with corresponding dependency patches, makes guest-agent buildable on FreeBSD. The plan is to incrementally fix guest-agent's behavior on FreeBSD. Because this commit only introduces files with the `_freebsd` suffix, it does not impact the current behavior on Linux or Windows. The list of required dependency patches: - google/go-sev-guest#189 - google/go-tdx-guest#101 - tarm/serial#134
1 parent c2949ef commit 3dd1c26

7 files changed

Lines changed: 302 additions & 232 deletions

File tree

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package agentcrypto
2+
3+
const (
4+
// defaultCredsDir is the directory location for MTLS MDS credentials.
5+
defaultCredsDir = "/var/run/google-mds-mtls"
6+
)
7+
8+
var (
9+
// certUpdaters is a map of known CA certificate updaters with the local directory paths for certificates.
10+
certUpdaters = map[string][]string{
11+
"certctl": {"/usr/local/share/certs"},
12+
}
13+
)

google_guest_agent/agentcrypto/mtls_mds_linux.go

Lines changed: 0 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -14,26 +14,9 @@
1414

1515
package agentcrypto
1616

17-
import (
18-
"context"
19-
"fmt"
20-
"os"
21-
"os/exec"
22-
"path/filepath"
23-
24-
"github.com/GoogleCloudPlatform/guest-agent/google_guest_agent/run"
25-
"github.com/GoogleCloudPlatform/guest-agent/utils"
26-
"github.com/GoogleCloudPlatform/guest-logging-go/logger"
27-
)
28-
2917
const (
3018
// defaultCredsDir is the directory location for MTLS MDS credentials.
3119
defaultCredsDir = "/run/google-mds-mtls"
32-
// rootCACertFileName is the root CA cert.
33-
rootCACertFileName = "root.crt"
34-
// clientCredsFileName are client credentials, its basically the file
35-
// that has the EC private key and the client certificate concatenated.
36-
clientCredsFileName = "client.key"
3720
)
3821

3922
var (
@@ -48,93 +31,3 @@ var (
4831
"update-ca-trust": {"/etc/pki/ca-trust/source/anchors"},
4932
}
5033
)
51-
52-
// writeRootCACert writes Root CA cert from UEFI variable to output file.
53-
func (j *CredsJob) writeRootCACert(ctx context.Context, content []byte, outputFile string) error {
54-
// The directory should be executable, but the file does not need to be.
55-
if err := os.MkdirAll(filepath.Dir(outputFile), 0655); err != nil {
56-
return err
57-
}
58-
if err := utils.SaferWriteFile(content, outputFile, 0644); err != nil {
59-
return err
60-
}
61-
62-
if !j.useNativeStore.Load() {
63-
logger.Debugf("SkipNativeStore is enabled, will not write root cert to system store")
64-
return nil
65-
}
66-
67-
// Best effort to update system store, don't fail.
68-
if err := updateSystemStore(ctx, outputFile); err != nil {
69-
logger.Errorf("Failed add Root MDS cert to system trust store with error: %v", err)
70-
}
71-
72-
return nil
73-
}
74-
75-
// writeClientCredentials stores client credentials (certificate and private key).
76-
func (j *CredsJob) writeClientCredentials(plaintext []byte, outputFile string) error {
77-
// The directory should be executable, but the file does not need to be.
78-
if err := os.MkdirAll(filepath.Dir(outputFile), 0655); err != nil {
79-
return err
80-
}
81-
return utils.SaferWriteFile(plaintext, outputFile, 0644)
82-
}
83-
84-
// getCAStoreUpdater interates over known system trust store updaters and returns the first found.
85-
func getCAStoreUpdater() (string, error) {
86-
var errs []string
87-
88-
for u := range certUpdaters {
89-
_, err := exec.LookPath(u)
90-
if err == nil {
91-
return u, nil
92-
}
93-
errs = append(errs, fmt.Sprintf("lookup for %q failed with error: %v", u, err))
94-
}
95-
96-
return "", fmt.Errorf("no known trust updaters were found: %v", errs)
97-
}
98-
99-
// certificateDirFromUpdater returns directory of local CA certificates for the given updater tool.
100-
func certificateDirFromUpdater(updater string) (string, error) {
101-
dirs, ok := certUpdaters[updater]
102-
if !ok {
103-
return "", fmt.Errorf("unknown updater %q, no local trusted CA certificate directory found", updater)
104-
}
105-
106-
for _, dir := range dirs {
107-
fi, err := os.Stat(dir)
108-
if err == nil && fi.IsDir() {
109-
return dir, nil
110-
}
111-
}
112-
return "", fmt.Errorf("no of the known directories %v found for updater %q", dirs, updater)
113-
}
114-
115-
// updateSystemStore updates the local system store with the cert.
116-
func updateSystemStore(ctx context.Context, cert string) error {
117-
cmd, err := getCAStoreUpdater()
118-
if err != nil {
119-
return err
120-
}
121-
122-
dir, err := certificateDirFromUpdater(cmd)
123-
if err != nil {
124-
return err
125-
}
126-
127-
dest := filepath.Join(dir, filepath.Base(cert))
128-
129-
if err := utils.CopyFile(cert, dest, 0644); err != nil {
130-
return err
131-
}
132-
133-
res := run.WithOutput(ctx, cmd)
134-
if res.ExitCode != 0 {
135-
return fmt.Errorf("command %q failed with error: %s", cmd, res.Error())
136-
}
137-
138-
logger.Infof("Certificate %q added to system store successfully %s", cert, res.StdOut)
139-
return nil
140-
}
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
//go:build linux || freebsd
2+
3+
// Copyright 2023 Google LLC
4+
5+
// Licensed under the Apache License, Version 2.0 (the "License");
6+
// you may not use this file except in compliance with the License.
7+
// You may obtain a copy of the License at
8+
9+
// https://www.apache.org/licenses/LICENSE-2.0
10+
11+
// Unless required by applicable law or agreed to in writing, software
12+
// distributed under the License is distributed on an "AS IS" BASIS,
13+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
// See the License for the specific language governing permissions and
15+
// limitations under the License.
16+
17+
package agentcrypto
18+
19+
import (
20+
"context"
21+
"fmt"
22+
"os"
23+
"os/exec"
24+
"path/filepath"
25+
26+
"github.com/GoogleCloudPlatform/guest-agent/google_guest_agent/run"
27+
"github.com/GoogleCloudPlatform/guest-agent/utils"
28+
"github.com/GoogleCloudPlatform/guest-logging-go/logger"
29+
)
30+
31+
const (
32+
// rootCACertFileName is the root CA cert.
33+
rootCACertFileName = "root.crt"
34+
// clientCredsFileName are client credentials, its basically the file
35+
// that has the EC private key and the client certificate concatenated.
36+
clientCredsFileName = "client.key"
37+
)
38+
39+
// writeRootCACert writes Root CA cert from UEFI variable to output file.
40+
func (j *CredsJob) writeRootCACert(ctx context.Context, content []byte, outputFile string) error {
41+
// The directory should be executable, but the file does not need to be.
42+
if err := os.MkdirAll(filepath.Dir(outputFile), 0655); err != nil {
43+
return err
44+
}
45+
if err := utils.SaferWriteFile(content, outputFile, 0644); err != nil {
46+
return err
47+
}
48+
49+
if !j.useNativeStore.Load() {
50+
logger.Debugf("SkipNativeStore is enabled, will not write root cert to system store")
51+
return nil
52+
}
53+
54+
// Best effort to update system store, don't fail.
55+
if err := updateSystemStore(ctx, outputFile); err != nil {
56+
logger.Errorf("Failed add Root MDS cert to system trust store with error: %v", err)
57+
}
58+
59+
return nil
60+
}
61+
62+
// writeClientCredentials stores client credentials (certificate and private key).
63+
func (j *CredsJob) writeClientCredentials(plaintext []byte, outputFile string) error {
64+
// The directory should be executable, but the file does not need to be.
65+
if err := os.MkdirAll(filepath.Dir(outputFile), 0655); err != nil {
66+
return err
67+
}
68+
return utils.SaferWriteFile(plaintext, outputFile, 0644)
69+
}
70+
71+
// getCAStoreUpdater interates over known system trust store updaters and returns the first found.
72+
func getCAStoreUpdater() (string, error) {
73+
var errs []string
74+
75+
for u := range certUpdaters {
76+
_, err := exec.LookPath(u)
77+
if err == nil {
78+
return u, nil
79+
}
80+
errs = append(errs, fmt.Sprintf("lookup for %q failed with error: %v", u, err))
81+
}
82+
83+
return "", fmt.Errorf("no known trust updaters were found: %v", errs)
84+
}
85+
86+
// certificateDirFromUpdater returns directory of local CA certificates for the given updater tool.
87+
func certificateDirFromUpdater(updater string) (string, error) {
88+
dirs, ok := certUpdaters[updater]
89+
if !ok {
90+
return "", fmt.Errorf("unknown updater %q, no local trusted CA certificate directory found", updater)
91+
}
92+
93+
for _, dir := range dirs {
94+
fi, err := os.Stat(dir)
95+
if err == nil && fi.IsDir() {
96+
return dir, nil
97+
}
98+
}
99+
return "", fmt.Errorf("no of the known directories %v found for updater %q", dirs, updater)
100+
}
101+
102+
// updateSystemStore updates the local system store with the cert.
103+
func updateSystemStore(ctx context.Context, cert string) error {
104+
cmd, err := getCAStoreUpdater()
105+
if err != nil {
106+
return err
107+
}
108+
109+
dir, err := certificateDirFromUpdater(cmd)
110+
if err != nil {
111+
return err
112+
}
113+
114+
dest := filepath.Join(dir, filepath.Base(cert))
115+
116+
if err := utils.CopyFile(cert, dest, 0644); err != nil {
117+
return err
118+
}
119+
120+
res := run.WithOutput(ctx, cmd)
121+
if res.ExitCode != 0 {
122+
return fmt.Errorf("command %q failed with error: %s", cmd, res.Error())
123+
}
124+
125+
logger.Infof("Certificate %q added to system store successfully %s", cert, res.StdOut)
126+
return nil
127+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// Copyright 2026 Google Inc. All Rights Reserved.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package command
16+
17+
// DefaultPipePath is the default unix socket path for FreeBSD.
18+
const DefaultPipePath = "/var/run/google-guest-agent/commands.sock"

0 commit comments

Comments
 (0)