diff options
Diffstat (limited to 'vendor/github.com/lib')
| -rw-r--r-- | vendor/github.com/lib/pq/conn.go | 12 | ||||
| -rw-r--r-- | vendor/github.com/lib/pq/connector.go | 5 | ||||
| -rw-r--r-- | vendor/github.com/lib/pq/copy.go | 38 | ||||
| -rw-r--r-- | vendor/github.com/lib/pq/encode.go | 8 | ||||
| -rw-r--r-- | vendor/github.com/lib/pq/error.go | 7 | ||||
| -rw-r--r-- | vendor/github.com/lib/pq/ssl.go | 11 | ||||
| -rw-r--r-- | vendor/github.com/lib/pq/ssl_permissions.go | 80 | 
7 files changed, 150 insertions, 11 deletions
| diff --git a/vendor/github.com/lib/pq/conn.go b/vendor/github.com/lib/pq/conn.go index e050d53..e70b386 100644 --- a/vendor/github.com/lib/pq/conn.go +++ b/vendor/github.com/lib/pq/conn.go @@ -31,8 +31,10 @@ var (  	ErrNotSupported              = errors.New("pq: Unsupported command")  	ErrInFailedTransaction       = errors.New("pq: Could not complete operation in a failed transaction")  	ErrSSLNotSupported           = errors.New("pq: SSL is not enabled on the server") -	ErrSSLKeyHasWorldPermissions = errors.New("pq: Private key file has group or world access. Permissions should be u=rw (0600) or less") -	ErrCouldNotDetectUsername    = errors.New("pq: Could not detect default username. Please provide one explicitly") +	ErrSSLKeyUnknownOwnership    = errors.New("pq: Could not get owner information for private key, may not be properly protected") +	ErrSSLKeyHasWorldPermissions = errors.New("pq: Private key has world access. Permissions should be u=rw,g=r (0640) if owned by root, or u=rw (0600), or less") + +	ErrCouldNotDetectUsername = errors.New("pq: Could not detect default username. Please provide one explicitly")  	errUnexpectedReady = errors.New("unexpected ReadyForQuery")  	errNoRowsAffected  = errors.New("no RowsAffected available after the empty statement") @@ -322,7 +324,7 @@ func DialOpen(d Dialer, dsn string) (_ driver.Conn, err error) {  	if err != nil {  		return nil, err  	} -	c.dialer = d +	c.Dialer(d)  	return c.open(context.Background())  } @@ -1125,7 +1127,7 @@ func isDriverSetting(key string) bool {  		return true  	case "password":  		return true -	case "sslmode", "sslcert", "sslkey", "sslrootcert", "sslinline": +	case "sslmode", "sslcert", "sslkey", "sslrootcert", "sslinline", "sslsni":  		return true  	case "fallback_application_name":  		return true @@ -2018,6 +2020,8 @@ func parseEnviron(env []string) (out map[string]string) {  			accrue("sslkey")  		case "PGSSLROOTCERT":  			accrue("sslrootcert") +		case "PGSSLSNI": +			accrue("sslsni")  		case "PGREQUIRESSL", "PGSSLCRL":  			unsupported()  		case "PGREQUIREPEER": diff --git a/vendor/github.com/lib/pq/connector.go b/vendor/github.com/lib/pq/connector.go index d7d4726..1145e12 100644 --- a/vendor/github.com/lib/pq/connector.go +++ b/vendor/github.com/lib/pq/connector.go @@ -27,6 +27,11 @@ func (c *Connector) Connect(ctx context.Context) (driver.Conn, error) {  	return c.open(ctx)  } +// Dialer allows change the dialer used to open connections. +func (c *Connector) Dialer(dialer Dialer) { +	c.dialer = dialer +} +  // Driver returns the underlying driver of this Connector.  func (c *Connector) Driver() driver.Driver {  	return &Driver{} diff --git a/vendor/github.com/lib/pq/copy.go b/vendor/github.com/lib/pq/copy.go index c072bc3..2f5c1ec 100644 --- a/vendor/github.com/lib/pq/copy.go +++ b/vendor/github.com/lib/pq/copy.go @@ -1,6 +1,7 @@  package pq  import ( +	"context"  	"database/sql/driver"  	"encoding/binary"  	"errors" @@ -273,6 +274,43 @@ func (ci *copyin) Exec(v []driver.Value) (r driver.Result, err error) {  	return driver.RowsAffected(0), nil  } +// CopyData inserts a raw string into the COPY stream. The insert is +// asynchronous and CopyData can return errors from previous CopyData calls to +// the same COPY stmt. +// +// You need to call Exec(nil) to sync the COPY stream and to get any +// errors from pending data, since Stmt.Close() doesn't return errors +// to the user. +func (ci *copyin) CopyData(ctx context.Context, line string) (r driver.Result, err error) { +	if ci.closed { +		return nil, errCopyInClosed +	} + +	if finish := ci.cn.watchCancel(ctx); finish != nil { +		defer finish() +	} + +	if err := ci.getBad(); err != nil { +		return nil, err +	} +	defer ci.cn.errRecover(&err) + +	if err := ci.err(); err != nil { +		return nil, err +	} + +	ci.buffer = append(ci.buffer, []byte(line)...) +	ci.buffer = append(ci.buffer, '\n') + +	if len(ci.buffer) > ciBufferFlushSize { +		ci.flush(ci.buffer) +		// reset buffer, keep bytes for message identifier and length +		ci.buffer = ci.buffer[:5] +	} + +	return driver.RowsAffected(0), nil +} +  func (ci *copyin) Close() (err error) {  	if ci.closed { // Don't do anything, we're already closed  		return nil diff --git a/vendor/github.com/lib/pq/encode.go b/vendor/github.com/lib/pq/encode.go index 210b1ec..bffe609 100644 --- a/vendor/github.com/lib/pq/encode.go +++ b/vendor/github.com/lib/pq/encode.go @@ -422,7 +422,7 @@ func ParseTimestamp(currentLocation *time.Location, str string) (time.Time, erro  	if remainderIdx < len(str) && str[remainderIdx] == '.' {  		fracStart := remainderIdx + 1 -		fracOff := strings.IndexAny(str[fracStart:], "-+ ") +		fracOff := strings.IndexAny(str[fracStart:], "-+Z ")  		if fracOff < 0 {  			fracOff = len(str) - fracStart  		} @@ -432,7 +432,7 @@ func ParseTimestamp(currentLocation *time.Location, str string) (time.Time, erro  		remainderIdx += fracOff + 1  	}  	if tzStart := remainderIdx; tzStart < len(str) && (str[tzStart] == '-' || str[tzStart] == '+') { -		// time zone separator is always '-' or '+' (UTC is +00) +		// time zone separator is always '-' or '+' or 'Z' (UTC is +00)  		var tzSign int  		switch c := str[tzStart]; c {  		case '-': @@ -454,7 +454,11 @@ func ParseTimestamp(currentLocation *time.Location, str string) (time.Time, erro  			remainderIdx += 3  		}  		tzOff = tzSign * ((tzHours * 60 * 60) + (tzMin * 60) + tzSec) +	} else if tzStart < len(str) && str[tzStart] == 'Z' { +		// time zone Z separator indicates UTC is +00 +		remainderIdx += 1  	} +  	var isoYear int  	if isBC { diff --git a/vendor/github.com/lib/pq/error.go b/vendor/github.com/lib/pq/error.go index 5cfe9c6..f67c5a5 100644 --- a/vendor/github.com/lib/pq/error.go +++ b/vendor/github.com/lib/pq/error.go @@ -402,6 +402,11 @@ func (err *Error) Fatal() bool {  	return err.Severity == Efatal  } +// SQLState returns the SQLState of the error. +func (err *Error) SQLState() string { +	return string(err.Code) +} +  // Get implements the legacy PGError interface. New code should use the fields  // of the Error struct directly.  func (err *Error) Get(k byte) (v string) { @@ -444,7 +449,7 @@ func (err *Error) Get(k byte) (v string) {  	return ""  } -func (err Error) Error() string { +func (err *Error) Error() string {  	return "pq: " + err.Message  } diff --git a/vendor/github.com/lib/pq/ssl.go b/vendor/github.com/lib/pq/ssl.go index e5eb928..36b61ba 100644 --- a/vendor/github.com/lib/pq/ssl.go +++ b/vendor/github.com/lib/pq/ssl.go @@ -8,6 +8,7 @@ import (  	"os"  	"os/user"  	"path/filepath" +	"strings"  )  // ssl generates a function to upgrade a net.Conn based on the "sslmode" and @@ -50,6 +51,16 @@ func ssl(o values) (func(net.Conn) (net.Conn, error), error) {  		return nil, fmterrorf(`unsupported sslmode %q; only "require" (default), "verify-full", "verify-ca", and "disable" supported`, mode)  	} +	// Set Server Name Indication (SNI), if enabled by connection parameters. +	// By default SNI is on, any value which is not starting with "1" disables +	// SNI -- that is the same check vanilla libpq uses. +	if sslsni := o["sslsni"]; sslsni == "" || strings.HasPrefix(sslsni, "1") { +		// RFC 6066 asks to not set SNI if the host is a literal IP address (IPv4 +		// or IPv6). This check is coded already crypto.tls.hostnameInSNI, so +		// just always set ServerName here and let crypto/tls do the filtering. +		tlsConf.ServerName = o["host"] +	} +  	err := sslClientCertificates(&tlsConf, o)  	if err != nil {  		return nil, err diff --git a/vendor/github.com/lib/pq/ssl_permissions.go b/vendor/github.com/lib/pq/ssl_permissions.go index 014af6a..d587f10 100644 --- a/vendor/github.com/lib/pq/ssl_permissions.go +++ b/vendor/github.com/lib/pq/ssl_permissions.go @@ -3,7 +3,28 @@  package pq -import "os" +import ( +	"errors" +	"os" +	"syscall" +) + +const ( +	rootUserID = uint32(0) + +	// The maximum permissions that a private key file owned by a regular user +	// is allowed to have. This translates to u=rw. +	maxUserOwnedKeyPermissions os.FileMode = 0600 + +	// The maximum permissions that a private key file owned by root is allowed +	// to have. This translates to u=rw,g=r. +	maxRootOwnedKeyPermissions os.FileMode = 0640 +) + +var ( +	errSSLKeyHasUnacceptableUserPermissions = errors.New("permissions for files not owned by root should be u=rw (0600) or less") +	errSSLKeyHasUnacceptableRootPermissions = errors.New("permissions for root owned files should be u=rw,g=r (0640) or less") +)  // sslKeyPermissions checks the permissions on user-supplied ssl key files.  // The key file should have very little access. @@ -14,8 +35,59 @@ func sslKeyPermissions(sslkey string) error {  	if err != nil {  		return err  	} -	if info.Mode().Perm()&0077 != 0 { -		return ErrSSLKeyHasWorldPermissions + +	err = hasCorrectPermissions(info) + +	// return ErrSSLKeyHasWorldPermissions for backwards compatability with +	// existing code. +	if err == errSSLKeyHasUnacceptableUserPermissions || err == errSSLKeyHasUnacceptableRootPermissions { +		err = ErrSSLKeyHasWorldPermissions  	} -	return nil +	return err +} + +// hasCorrectPermissions checks the file info (and the unix-specific stat_t +// output) to verify that the permissions on the file are correct. +// +// If the file is owned by the same user the process is running as, +// the file should only have 0600 (u=rw). If the file is owned by root, +// and the group matches the group that the process is running in, the +// permissions cannot be more than 0640 (u=rw,g=r). The file should +// never have world permissions. +// +// Returns an error when the permission check fails. +func hasCorrectPermissions(info os.FileInfo) error { +	// if file's permission matches 0600, allow access. +	userPermissionMask := (os.FileMode(0777) ^ maxUserOwnedKeyPermissions) + +	// regardless of if we're running as root or not, 0600 is acceptable, +	// so we return if we match the regular user permission mask. +	if info.Mode().Perm()&userPermissionMask == 0 { +		return nil +	} + +	// We need to pull the Unix file information to get the file's owner. +	// If we can't access it, there's some sort of operating system level error +	// and we should fail rather than attempting to use faulty information. +	sysInfo := info.Sys() +	if sysInfo == nil { +		return ErrSSLKeyUnknownOwnership +	} + +	unixStat, ok := sysInfo.(*syscall.Stat_t) +	if !ok { +		return ErrSSLKeyUnknownOwnership +	} + +	// if the file is owned by root, we allow 0640 (u=rw,g=r) to match what +	// Postgres does. +	if unixStat.Uid == rootUserID { +		rootPermissionMask := (os.FileMode(0777) ^ maxRootOwnedKeyPermissions) +		if info.Mode().Perm()&rootPermissionMask != 0 { +			return errSSLKeyHasUnacceptableRootPermissions +		} +		return nil +	} + +	return errSSLKeyHasUnacceptableUserPermissions  } | 
