Skip to content

Commit 7a2d1a7

Browse files
author
Divjot Arora
authored
GODRIVER-1461 Skip mongocryptd spawning if bypassAutoEncryption is true (#280)
1 parent c898612 commit 7a2d1a7

File tree

3 files changed

+95
-7
lines changed

3 files changed

+95
-7
lines changed

mongo/client.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -599,7 +599,7 @@ func (c *Client) configureKeyVault(opts *options.AutoEncryptionOptions) error {
599599

600600
func (c *Client) configureMongocryptd(opts *options.AutoEncryptionOptions) error {
601601
var err error
602-
c.mongocryptd, err = newMcryptClient(opts.ExtraOptions)
602+
c.mongocryptd, err = newMcryptClient(opts)
603603
return err
604604
}
605605

mongo/integration/client_side_encryption_prose_test.go

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import (
1616
"runtime"
1717
"strings"
1818
"testing"
19+
"time"
1920

2021
"go.mongodb.org/mongo-driver/bson"
2122
"go.mongodb.org/mongo-driver/bson/primitive"
@@ -630,6 +631,83 @@ func TestClientSideEncryptionProse(t *testing.T) {
630631
})
631632
}
632633
})
634+
mt.RunOpts("bypass mongocryptd spawning", noClientOpts, func(mt *mtest.T) {
635+
kmsProviders := map[string]map[string]interface{}{
636+
"local": {
637+
"key": localMasterKey,
638+
},
639+
}
640+
schemaMap := map[string]interface{}{
641+
"db.coll": readJSONFile(mt, "external-schema.json"),
642+
}
643+
644+
// All mongocryptd options use port 27021 instead of the default 27020 to avoid interference with mongocryptd
645+
// instances spawned by previous tests.
646+
mongocryptdBypassSpawnTrue := map[string]interface{}{
647+
"mongocryptdBypassSpawn": true,
648+
"mongocryptdURI": "mongodb://localhost:27021/db?serverSelectionTimeoutMS=1000",
649+
"mongocryptdSpawnArgs": []string{"--pidfilepath=bypass-spawning-mongocryptd.pid", "--port=27021"},
650+
}
651+
mongocryptdBypassSpawnFalse := map[string]interface{}{
652+
"mongocryptdBypassSpawn": false,
653+
"mongocryptdSpawnArgs": []string{"--pidfilepath=bypass-spawning-mongocryptd.pid", "--port=27021"},
654+
}
655+
mongocryptdBypassSpawnNotSet := map[string]interface{}{
656+
"mongocryptdSpawnArgs": []string{"--pidfilepath=bypass-spawning-mongocryptd.pid", "--port=27021"},
657+
}
658+
659+
testCases := []struct {
660+
name string
661+
mongocryptdOpts map[string]interface{}
662+
setBypassAutoEncryption bool
663+
bypassAutoEncryption bool
664+
}{
665+
{"mongocryptdBypassSpawn only", mongocryptdBypassSpawnTrue, false, false},
666+
{"bypassAutoEncryption only", mongocryptdBypassSpawnNotSet, true, true},
667+
{"mongocryptdBypassSpawn false, bypassAutoEncryption true", mongocryptdBypassSpawnFalse, true, true},
668+
{"mongocryptdBypassSpawn true, bypassAutoEncryption false", mongocryptdBypassSpawnTrue, true, false},
669+
}
670+
for _, tc := range testCases {
671+
mt.Run(tc.name, func(mt *mtest.T) {
672+
aeo := options.AutoEncryption().
673+
SetKmsProviders(kmsProviders).
674+
SetKeyVaultNamespace(kvNamespace).
675+
SetSchemaMap(schemaMap).
676+
SetExtraOptions(tc.mongocryptdOpts)
677+
if tc.setBypassAutoEncryption {
678+
aeo.SetBypassAutoEncryption(tc.bypassAutoEncryption)
679+
}
680+
cpt := setup(mt, aeo, nil, nil)
681+
defer cpt.teardown(mt)
682+
683+
_, err := cpt.cseColl.InsertOne(mtest.Background, bson.D{{"unencrypted", "test"}})
684+
685+
// Check for mongocryptd server selection error if auto encryption was not bypassed.
686+
if !(tc.setBypassAutoEncryption && tc.bypassAutoEncryption) {
687+
assert.NotNil(mt, err, "expected InsertOne error, got nil")
688+
mcryptErr, ok := err.(mongo.MongocryptdError)
689+
assert.True(mt, ok, "expected error type %T, got %v of type %T", mongo.MongocryptdError{}, err, err)
690+
assert.True(mt, strings.Contains(mcryptErr.Error(), "server selection error"),
691+
"expected mongocryptd server selection error, got %v", err)
692+
return
693+
}
694+
695+
// If auto encryption is bypassed, the command should succeed. Create a new client to connect to
696+
// mongocryptd and verify it is not running.
697+
assert.Nil(mt, err, "InsertOne error: %v", err)
698+
699+
mcryptOpts := options.Client().ApplyURI("mongodb://localhost:27021").
700+
SetServerSelectionTimeout(1 * time.Second)
701+
mcryptClient, err := mongo.Connect(mtest.Background, mcryptOpts)
702+
assert.Nil(mt, err, "mongocryptd Connect error: %v", err)
703+
704+
err = mcryptClient.Database("admin").RunCommand(mtest.Background, bson.D{{"ismaster", 1}}).Err()
705+
assert.NotNil(mt, err, "expected mongocryptd ismaster error, got nil")
706+
assert.True(mt, strings.Contains(err.Error(), "server selection error"),
707+
"expected mongocryptd server selection error, got %v", err)
708+
})
709+
}
710+
})
633711
}
634712

635713
type cseProseTest struct {

mongo/mongocryptd.go

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -35,23 +35,33 @@ type mcryptClient struct {
3535
spawnArgs []string
3636
}
3737

38-
func newMcryptClient(opts map[string]interface{}) (*mcryptClient, error) {
38+
func newMcryptClient(opts *options.AutoEncryptionOptions) (*mcryptClient, error) {
3939
// create mcryptClient instance and spawn process if necessary
40-
mc := &mcryptClient{}
41-
if bypass, ok := opts["mongocryptdBypassSpawn"]; ok {
42-
mc.bypassSpawn = bypass.(bool)
40+
var bypassSpawn bool
41+
var bypassAutoEncryption bool
42+
if bypass, ok := opts.ExtraOptions["mongocryptdBypassSpawn"]; ok {
43+
bypassSpawn = bypass.(bool)
44+
}
45+
if opts.BypassAutoEncryption != nil {
46+
bypassAutoEncryption = *opts.BypassAutoEncryption
47+
}
48+
49+
mc := &mcryptClient{
50+
// mongocryptd should not be spawned if mongocryptdBypassSpawn is passed or if bypassAutoEncryption is
51+
// specified because it is not used during decryption
52+
bypassSpawn: bypassSpawn || bypassAutoEncryption,
4353
}
4454

4555
if !mc.bypassSpawn {
46-
mc.path, mc.spawnArgs = createSpawnArgs(opts)
56+
mc.path, mc.spawnArgs = createSpawnArgs(opts.ExtraOptions)
4757
if err := mc.spawnProcess(); err != nil {
4858
return nil, err
4959
}
5060
}
5161

5262
// get connection string
5363
uri := defaultURI
54-
if u, ok := opts["mongocryptdURI"]; ok {
64+
if u, ok := opts.ExtraOptions["mongocryptdURI"]; ok {
5565
uri = u.(string)
5666
}
5767

0 commit comments

Comments
 (0)