From 56a1ea901242ecd36dd6758322ce147cfd8ee09b Mon Sep 17 00:00:00 2001 From: Igor Dubinskiy Date: Fri, 23 Dec 2016 00:39:26 -0800 Subject: [PATCH 1/2] provider/postgresql: Quote connection string parameters --- builtin/providers/postgresql/GNUmakefile | 4 +++- builtin/providers/postgresql/config.go | 2 +- builtin/providers/postgresql/provider.go | 3 +-- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/builtin/providers/postgresql/GNUmakefile b/builtin/providers/postgresql/GNUmakefile index 926b843f90..cdaa01f548 100644 --- a/builtin/providers/postgresql/GNUmakefile +++ b/builtin/providers/postgresql/GNUmakefile @@ -4,7 +4,8 @@ PSQL?=/opt/local/lib/postgresql96/bin/psql PGDATA?=$(GOPATH)/src/github.com/hashicorp/terraform/builtin/providers/postgresql/data initdb:: - /opt/local/lib/postgresql96/bin/initdb --no-locale -U postgres -D $(PGDATA) + echo "" > pwfile + /opt/local/lib/postgresql96/bin/initdb --no-locale -U postgres -A md5 --pwfile=pwfile -D $(PGDATA) startdb:: 2>&1 \ @@ -18,6 +19,7 @@ startdb:: cleandb:: rm -rf $(PGDATA) + rm -f pwfile freshdb:: cleandb initdb startdb diff --git a/builtin/providers/postgresql/config.go b/builtin/providers/postgresql/config.go index f7e82ad824..005cd6511b 100644 --- a/builtin/providers/postgresql/config.go +++ b/builtin/providers/postgresql/config.go @@ -31,7 +31,7 @@ type Client struct { func (c *Config) NewClient() (*Client, error) { // NOTE: dbname must come before user otherwise dbname will be set to // user. - const dsnFmt = "host=%s port=%d dbname=%s user=%s password=%s sslmode=%s fallback_application_name=%s connect_timeout=%d" + const dsnFmt = "host='%s' port='%d' dbname='%s' user='%s' password='%s' sslmode='%s' fallback_application_name='%s' connect_timeout='%d'" logDSN := fmt.Sprintf(dsnFmt, c.Host, c.Port, c.Database, c.Username, "", c.SSLMode, c.ApplicationName, c.ConnectTimeoutSec) log.Printf("[INFO] PostgreSQL DSN: `%s`", logDSN) diff --git a/builtin/providers/postgresql/provider.go b/builtin/providers/postgresql/provider.go index 2f7064447b..ab26af8b98 100644 --- a/builtin/providers/postgresql/provider.go +++ b/builtin/providers/postgresql/provider.go @@ -112,11 +112,10 @@ func tfAppName() string { const VersionPrerelease = terraform.VersionPrerelease var versionString bytes.Buffer - fmt.Fprintf(&versionString, "'Terraform v%s", terraform.Version) + fmt.Fprintf(&versionString, "Terraform v%s", terraform.Version) if terraform.VersionPrerelease != "" { fmt.Fprintf(&versionString, "-%s", terraform.VersionPrerelease) } - fmt.Fprintf(&versionString, "'") return versionString.String() } From d673a0b5320faa9f97a91422e32dbb179b20fea1 Mon Sep 17 00:00:00 2001 From: Sean Chittenden Date: Sun, 25 Dec 2016 05:53:12 -0800 Subject: [PATCH 2/2] Properly escape DSN parameters. --- builtin/providers/postgresql/config.go | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/builtin/providers/postgresql/config.go b/builtin/providers/postgresql/config.go index 005cd6511b..125c2d79cd 100644 --- a/builtin/providers/postgresql/config.go +++ b/builtin/providers/postgresql/config.go @@ -1,6 +1,7 @@ package postgresql import ( + "bytes" "database/sql" "fmt" "log" @@ -31,12 +32,31 @@ type Client struct { func (c *Config) NewClient() (*Client, error) { // NOTE: dbname must come before user otherwise dbname will be set to // user. - const dsnFmt = "host='%s' port='%d' dbname='%s' user='%s' password='%s' sslmode='%s' fallback_application_name='%s' connect_timeout='%d'" + const dsnFmt = "host=%s port=%d dbname=%s user=%s password=%s sslmode=%s fallback_application_name=%s connect_timeout=%d" - logDSN := fmt.Sprintf(dsnFmt, c.Host, c.Port, c.Database, c.Username, "", c.SSLMode, c.ApplicationName, c.ConnectTimeoutSec) + // Quote empty strings or strings that contain whitespace + q := func(s string) string { + b := bytes.NewBufferString(`'`) + b.Grow(len(s) + 2) + for _, r := range s { + switch r { + case '\'': + b.WriteString(`\'`) + case '\\': + b.WriteString(`\\`) + default: + b.WriteRune(r) + } + } + + b.WriteString(`'`) + return b.String() + } + + logDSN := fmt.Sprintf(dsnFmt, q(c.Host), c.Port, q(c.Database), q(c.Username), q(""), q(c.SSLMode), q(c.ApplicationName), c.ConnectTimeoutSec) log.Printf("[INFO] PostgreSQL DSN: `%s`", logDSN) - connStr := fmt.Sprintf(dsnFmt, c.Host, c.Port, c.Database, c.Username, c.Password, c.SSLMode, c.ApplicationName, c.ConnectTimeoutSec) + connStr := fmt.Sprintf(dsnFmt, q(c.Host), c.Port, q(c.Database), q(c.Username), q(c.Password), q(c.SSLMode), q(c.ApplicationName), c.ConnectTimeoutSec) client := Client{ connStr: connStr, username: c.Username,