Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Validate hostnames when using TLS in Cassandra #11365

Merged
merged 8 commits into from
Apr 16, 2021

Conversation

pcman312
Copy link
Contributor

Updates Cassandra database engine and physical backend to validate hostnames when configured to use TLS.

This also updates the gocql library to the latest version.

@vercel vercel bot temporarily deployed to Preview – vault April 15, 2021 18:03 Inactive
@vercel vercel bot temporarily deployed to Preview – vault-storybook April 15, 2021 18:16 Inactive
}

tlsConfig, err := parsedCertBundle.GetTLSConfig(certutil.TLSClient)
if err != nil || tlsConfig == nil {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking at GetTLSConfig(), it doesn't seem that we can get a nil tlsConfig if the error is nil so a check on err != nil should be sufficient.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch, fixed.

@@ -269,6 +230,50 @@ func (c *cassandraConnectionProducer) createSession(ctx context.Context) (*gocql
return session, nil
}

func getSslOpts(certBundle *certutil.CertBundle, minTLSVersion string, insecureSkipVerify bool) (*gocql.SslOptions, error) {
var tlsConfig *tls.Config
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we start off with tlsConfig := &tls.Config{} if this is never expected to be nil?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Funnily enough we just fixed this in another DB: https://github.com/hashicorp/vault/pull/10899/files

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. Fixed.

defer cleanup()

// This is fine if it panics - the connection URL should include the port and if it doesn't, this should fail
port := strings.Split(connURL, ":")[1]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we handle this failure a bit more gracefully by doing a length check first instead of letting it panic?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think an additional check is valuable here because it's in a test and it needs to fail, so having it be a test failure rather than a panic doesn't really give us much. It's an irrecoverable error due to the test construct failing which seems like a panic is well suited for.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Further investigation revealed that panicking in a test does not behave the same as running t.Fatal. It will stop all tests that are running in the package. I didn't realize this was the behavior. I've updated this so the PrepareTestContainer function instead returns a new Host type that contains the hostname, the port, and has a function to build the connection URL. It also performs the equivalent check in PrepareTestContainer rather than forcing the callers to make any additional checks.

"testing"
"time"

"github.com/gocql/gocql"
"github.com/hashicorp/vault/helper/testhelpers/docker"
)

func PrepareTestContainer(t *testing.T, version string) (func(), string) {
type containerConfig struct {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is nice!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! I figured since I needed to add another optional field that it would be better to switch to the functional arguments pattern for ease of use downstream.

return nil, fmt.Errorf("failed to parse certificate bundle: %w", err)
}

tlsConfig, err := parsedCertBundle.GetTLSConfig(certutil.TLSClient)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be using = instead of := when assigning to tlsConfig? I think using := here would result in a nil pointer dereference down on L256.

Copy link
Contributor

@calvn calvn Apr 16, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice catch! It won't be a pointer dereference because of tlsConfig = &tls.Config{} on the else, but it won't set the fields from GetTLSConfig since tlsConfig is scoped to this conditional.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ya, was thinking it'd be nil pointer dereference if we don't enter that else branch (since certBundle != nil). In any case, I agree that the correct tlsConfig won't be set due to the scoping.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you're right. Since both variables exist before this line they are shadowed by this call when using :=. Or at least that's what my IDE is telling me.

@vercel vercel bot temporarily deployed to Preview – vault April 16, 2021 17:03 Inactive
@vercel vercel bot temporarily deployed to Preview – vault-storybook April 16, 2021 17:03 Inactive
@pcman312 pcman312 requested a review from calvn April 16, 2021 17:05
@vercel vercel bot temporarily deployed to Preview – vault-storybook April 16, 2021 17:08 Inactive
@vercel vercel bot temporarily deployed to Preview – vault April 16, 2021 17:08 Inactive
@vercel vercel bot temporarily deployed to Preview – vault-storybook April 16, 2021 18:48 Inactive
@vercel vercel bot temporarily deployed to Preview – vault April 16, 2021 18:48 Inactive
@vercel vercel bot temporarily deployed to Preview – vault-storybook April 16, 2021 20:26 Inactive
@vercel vercel bot temporarily deployed to Preview – vault April 16, 2021 20:26 Inactive
Copy link
Contributor

@austingebauer austingebauer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@pcman312 pcman312 merged commit 448d0b4 into master Apr 16, 2021
@pcman312 pcman312 deleted the cassandra-host-verification branch April 16, 2021 21:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants