From 35679297a9d262caf8fbd9bdd263b3c06b306ff6 Mon Sep 17 00:00:00 2001 From: Matthew McPherrin Date: Fri, 17 Feb 2017 12:35:58 -0800 Subject: [PATCH] Move StartTLS functionality into a subpackage, enabling use elsewhere This moves two functions out of main.go. The only change to the functions was to make them take arguments, instead of using global variables in main. The mysql and psql imports are moved here too. --- main.go | 45 +--------- {mysql => starttls/mysql}/AUTHORS | 0 {mysql => starttls/mysql}/LICENSE | 0 {mysql => starttls/mysql}/README.md | 0 {mysql => starttls/mysql}/buffer.go | 0 {mysql => starttls/mysql}/collations.go | 0 {mysql => starttls/mysql}/connection.go | 0 {mysql => starttls/mysql}/const.go | 0 {mysql => starttls/mysql}/driver.go | 0 {mysql => starttls/mysql}/dsn.go | 0 {mysql => starttls/mysql}/errors.go | 0 {mysql => starttls/mysql}/infile.go | 0 {mysql => starttls/mysql}/packets.go | 0 {mysql => starttls/mysql}/result.go | 0 {mysql => starttls/mysql}/rows.go | 0 {mysql => starttls/mysql}/statement.go | 0 {mysql => starttls/mysql}/transaction.go | 0 {mysql => starttls/mysql}/utils.go | 0 {psql => starttls/psql}/LICENSE.md | 0 {psql => starttls/psql}/README.md | 0 {psql => starttls/psql}/array.go | 0 {psql => starttls/psql}/buf.go | 2 +- {psql => starttls/psql}/conn.go | 2 +- {psql => starttls/psql}/conn_go18.go | 0 {psql => starttls/psql}/copy.go | 0 {psql => starttls/psql}/doc.go | 0 {psql => starttls/psql}/encode.go | 2 +- {psql => starttls/psql}/error.go | 0 {psql => starttls/psql}/notify.go | 0 {psql => starttls/psql}/oid/doc.go | 0 {psql => starttls/psql}/oid/gen.go | 0 {psql => starttls/psql}/oid/types.go | 0 {psql => starttls/psql}/ssl.go | 0 {psql => starttls/psql}/ssl_go1.7.go | 0 {psql => starttls/psql}/ssl_permissions.go | 0 {psql => starttls/psql}/ssl_renegotiation.go | 0 {psql => starttls/psql}/ssl_windows.go | 0 {psql => starttls/psql}/url.go | 0 {psql => starttls/psql}/user_posix.go | 0 {psql => starttls/psql}/user_windows.go | 0 {psql => starttls/psql}/uuid.go | 0 starttls/starttls.go | 91 ++++++++++++++++++++ 42 files changed, 96 insertions(+), 46 deletions(-) rename {mysql => starttls/mysql}/AUTHORS (100%) rename {mysql => starttls/mysql}/LICENSE (100%) rename {mysql => starttls/mysql}/README.md (100%) rename {mysql => starttls/mysql}/buffer.go (100%) rename {mysql => starttls/mysql}/collations.go (100%) rename {mysql => starttls/mysql}/connection.go (100%) rename {mysql => starttls/mysql}/const.go (100%) rename {mysql => starttls/mysql}/driver.go (100%) rename {mysql => starttls/mysql}/dsn.go (100%) rename {mysql => starttls/mysql}/errors.go (100%) rename {mysql => starttls/mysql}/infile.go (100%) rename {mysql => starttls/mysql}/packets.go (100%) rename {mysql => starttls/mysql}/result.go (100%) rename {mysql => starttls/mysql}/rows.go (100%) rename {mysql => starttls/mysql}/statement.go (100%) rename {mysql => starttls/mysql}/transaction.go (100%) rename {mysql => starttls/mysql}/utils.go (100%) rename {psql => starttls/psql}/LICENSE.md (100%) rename {psql => starttls/psql}/README.md (100%) rename {psql => starttls/psql}/array.go (100%) rename {psql => starttls/psql}/buf.go (97%) rename {psql => starttls/psql}/conn.go (99%) rename {psql => starttls/psql}/conn_go18.go (100%) rename {psql => starttls/psql}/copy.go (100%) rename {psql => starttls/psql}/doc.go (100%) rename {psql => starttls/psql}/encode.go (99%) rename {psql => starttls/psql}/error.go (100%) rename {psql => starttls/psql}/notify.go (100%) rename {psql => starttls/psql}/oid/doc.go (100%) rename {psql => starttls/psql}/oid/gen.go (100%) rename {psql => starttls/psql}/oid/types.go (100%) rename {psql => starttls/psql}/ssl.go (100%) rename {psql => starttls/psql}/ssl_go1.7.go (100%) rename {psql => starttls/psql}/ssl_permissions.go (100%) rename {psql => starttls/psql}/ssl_renegotiation.go (100%) rename {psql => starttls/psql}/ssl_windows.go (100%) rename {psql => starttls/psql}/url.go (100%) rename {psql => starttls/psql}/user_posix.go (100%) rename {psql => starttls/psql}/user_windows.go (100%) rename {psql => starttls/psql}/uuid.go (100%) create mode 100644 starttls/starttls.go diff --git a/main.go b/main.go index 8ac255d..958fc94 100644 --- a/main.go +++ b/main.go @@ -28,8 +28,7 @@ import ( "gopkg.in/alecthomas/kingpin.v2" "github.com/square/certigo/lib" - "github.com/square/certigo/mysql" - "github.com/square/certigo/psql" + "github.com/square/certigo/starttls" "golang.org/x/crypto/ssh/terminal" ) @@ -96,7 +95,7 @@ func main() { } case connect.FullCommand(): // Get certs by connecting to a server - connState := getConnectionState() + connState := starttls.GetConnectionState(*connectStartTLS, *connectName, *connectTo, *connectCert, *connectKey) for _, cert := range connState.PeerCertificates { if *connectPem { pem.Encode(os.Stdout, lib.EncodeX509ToPEM(cert, nil)) @@ -148,46 +147,6 @@ func main() { } } -func getConnectionState() *tls.ConnectionState { - var state *tls.ConnectionState - var err error - - switch *connectStartTLS { - case "": - conn, err := tls.Dial("tcp", *connectTo, tlsConfigForConnect()) - if err != nil { - fmt.Fprintf(os.Stderr, "error connecting: %v\n", err) - os.Exit(1) - } - defer conn.Close() - s := conn.ConnectionState() - state = &s - case "mysql": - mysql.RegisterTLSConfig("certigo", tlsConfigForConnect()) - state, err = mysql.DumpTLS(fmt.Sprintf("certigo@tcp(%s)/?tls=certigo", *connectTo)) - case "postgres", "psql": - // Setting sslmode to "require" skips verification. - url := fmt.Sprintf("postgres://certigo@%s/?sslmode=require", *connectTo) - if *connectCert != "" { - url += fmt.Sprintf("&sslcert=%s", *connectCert) - } - if *connectKey != "" { - url += fmt.Sprintf("&sslkey=%s", *connectCert) - } - state, err = pq.DumpTLS(url) - default: - fmt.Fprintf(os.Stderr, "error connecting: unknown StartTLS protocol '%s'\n", *connectStartTLS) - os.Exit(1) - } - - if err != nil { - fmt.Fprintf(os.Stderr, "error connecting: %v\n", err) - os.Exit(1) - } - - return state -} - func inputFile(fileName string) *os.File { if fileName == "" { return os.Stdin diff --git a/mysql/AUTHORS b/starttls/mysql/AUTHORS similarity index 100% rename from mysql/AUTHORS rename to starttls/mysql/AUTHORS diff --git a/mysql/LICENSE b/starttls/mysql/LICENSE similarity index 100% rename from mysql/LICENSE rename to starttls/mysql/LICENSE diff --git a/mysql/README.md b/starttls/mysql/README.md similarity index 100% rename from mysql/README.md rename to starttls/mysql/README.md diff --git a/mysql/buffer.go b/starttls/mysql/buffer.go similarity index 100% rename from mysql/buffer.go rename to starttls/mysql/buffer.go diff --git a/mysql/collations.go b/starttls/mysql/collations.go similarity index 100% rename from mysql/collations.go rename to starttls/mysql/collations.go diff --git a/mysql/connection.go b/starttls/mysql/connection.go similarity index 100% rename from mysql/connection.go rename to starttls/mysql/connection.go diff --git a/mysql/const.go b/starttls/mysql/const.go similarity index 100% rename from mysql/const.go rename to starttls/mysql/const.go diff --git a/mysql/driver.go b/starttls/mysql/driver.go similarity index 100% rename from mysql/driver.go rename to starttls/mysql/driver.go diff --git a/mysql/dsn.go b/starttls/mysql/dsn.go similarity index 100% rename from mysql/dsn.go rename to starttls/mysql/dsn.go diff --git a/mysql/errors.go b/starttls/mysql/errors.go similarity index 100% rename from mysql/errors.go rename to starttls/mysql/errors.go diff --git a/mysql/infile.go b/starttls/mysql/infile.go similarity index 100% rename from mysql/infile.go rename to starttls/mysql/infile.go diff --git a/mysql/packets.go b/starttls/mysql/packets.go similarity index 100% rename from mysql/packets.go rename to starttls/mysql/packets.go diff --git a/mysql/result.go b/starttls/mysql/result.go similarity index 100% rename from mysql/result.go rename to starttls/mysql/result.go diff --git a/mysql/rows.go b/starttls/mysql/rows.go similarity index 100% rename from mysql/rows.go rename to starttls/mysql/rows.go diff --git a/mysql/statement.go b/starttls/mysql/statement.go similarity index 100% rename from mysql/statement.go rename to starttls/mysql/statement.go diff --git a/mysql/transaction.go b/starttls/mysql/transaction.go similarity index 100% rename from mysql/transaction.go rename to starttls/mysql/transaction.go diff --git a/mysql/utils.go b/starttls/mysql/utils.go similarity index 100% rename from mysql/utils.go rename to starttls/mysql/utils.go diff --git a/psql/LICENSE.md b/starttls/psql/LICENSE.md similarity index 100% rename from psql/LICENSE.md rename to starttls/psql/LICENSE.md diff --git a/psql/README.md b/starttls/psql/README.md similarity index 100% rename from psql/README.md rename to starttls/psql/README.md diff --git a/psql/array.go b/starttls/psql/array.go similarity index 100% rename from psql/array.go rename to starttls/psql/array.go diff --git a/psql/buf.go b/starttls/psql/buf.go similarity index 97% rename from psql/buf.go rename to starttls/psql/buf.go index db4c88a..4f8a558 100644 --- a/psql/buf.go +++ b/starttls/psql/buf.go @@ -4,7 +4,7 @@ import ( "bytes" "encoding/binary" - "github.com/square/certigo/psql/oid" + "github.com/square/certigo/starttls/psql/oid" ) type readBuf []byte diff --git a/psql/conn.go b/starttls/psql/conn.go similarity index 99% rename from psql/conn.go rename to starttls/psql/conn.go index 13eceb6..b2c38c7 100644 --- a/psql/conn.go +++ b/starttls/psql/conn.go @@ -20,7 +20,7 @@ import ( "time" "unicode" - "github.com/square/certigo/psql/oid" + "github.com/square/certigo/starttls/psql/oid" ) // Common error types diff --git a/psql/conn_go18.go b/starttls/psql/conn_go18.go similarity index 100% rename from psql/conn_go18.go rename to starttls/psql/conn_go18.go diff --git a/psql/copy.go b/starttls/psql/copy.go similarity index 100% rename from psql/copy.go rename to starttls/psql/copy.go diff --git a/psql/doc.go b/starttls/psql/doc.go similarity index 100% rename from psql/doc.go rename to starttls/psql/doc.go diff --git a/psql/encode.go b/starttls/psql/encode.go similarity index 99% rename from psql/encode.go rename to starttls/psql/encode.go index 50fcc55..ce32c52 100644 --- a/psql/encode.go +++ b/starttls/psql/encode.go @@ -13,7 +13,7 @@ import ( "sync" "time" - "github.com/square/certigo/psql/oid" + "github.com/square/certigo/starttls/psql/oid" ) func binaryEncode(parameterStatus *parameterStatus, x interface{}) []byte { diff --git a/psql/error.go b/starttls/psql/error.go similarity index 100% rename from psql/error.go rename to starttls/psql/error.go diff --git a/psql/notify.go b/starttls/psql/notify.go similarity index 100% rename from psql/notify.go rename to starttls/psql/notify.go diff --git a/psql/oid/doc.go b/starttls/psql/oid/doc.go similarity index 100% rename from psql/oid/doc.go rename to starttls/psql/oid/doc.go diff --git a/psql/oid/gen.go b/starttls/psql/oid/gen.go similarity index 100% rename from psql/oid/gen.go rename to starttls/psql/oid/gen.go diff --git a/psql/oid/types.go b/starttls/psql/oid/types.go similarity index 100% rename from psql/oid/types.go rename to starttls/psql/oid/types.go diff --git a/psql/ssl.go b/starttls/psql/ssl.go similarity index 100% rename from psql/ssl.go rename to starttls/psql/ssl.go diff --git a/psql/ssl_go1.7.go b/starttls/psql/ssl_go1.7.go similarity index 100% rename from psql/ssl_go1.7.go rename to starttls/psql/ssl_go1.7.go diff --git a/psql/ssl_permissions.go b/starttls/psql/ssl_permissions.go similarity index 100% rename from psql/ssl_permissions.go rename to starttls/psql/ssl_permissions.go diff --git a/psql/ssl_renegotiation.go b/starttls/psql/ssl_renegotiation.go similarity index 100% rename from psql/ssl_renegotiation.go rename to starttls/psql/ssl_renegotiation.go diff --git a/psql/ssl_windows.go b/starttls/psql/ssl_windows.go similarity index 100% rename from psql/ssl_windows.go rename to starttls/psql/ssl_windows.go diff --git a/psql/url.go b/starttls/psql/url.go similarity index 100% rename from psql/url.go rename to starttls/psql/url.go diff --git a/psql/user_posix.go b/starttls/psql/user_posix.go similarity index 100% rename from psql/user_posix.go rename to starttls/psql/user_posix.go diff --git a/psql/user_windows.go b/starttls/psql/user_windows.go similarity index 100% rename from psql/user_windows.go rename to starttls/psql/user_windows.go diff --git a/psql/uuid.go b/starttls/psql/uuid.go similarity index 100% rename from psql/uuid.go rename to starttls/psql/uuid.go diff --git a/starttls/starttls.go b/starttls/starttls.go new file mode 100644 index 0000000..936d3d0 --- /dev/null +++ b/starttls/starttls.go @@ -0,0 +1,91 @@ +/*- + * Copyright 2017 Square Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package starttls + +import ( + "crypto/tls" + "fmt" + "os" + + "github.com/square/certigo/starttls/mysql" + "github.com/square/certigo/starttls/psql" +) + +func tlsConfigForConnect(connectName, connectCert, connectKey string) *tls.Config { + conf := &tls.Config{ + // We verify later manually so we can print results + InsecureSkipVerify: true, + ServerName: connectName, + } + + if connectCert != "" { + keyFile := connectCert + if connectKey != "" { + keyFile = connectKey + } + + cert, err := tls.LoadX509KeyPair(connectCert, keyFile) + if err != nil { + fmt.Fprintf(os.Stderr, "unable to read client certificate/key: %s\n", err) + os.Exit(1) + } + + conf.Certificates = []tls.Certificate{cert} + } + + return conf +} + +func GetConnectionState(connectStartTLS, connectName, connectTo, connectCert, connectKey string) *tls.ConnectionState { + var state *tls.ConnectionState + var err error + + switch connectStartTLS { + case "": + conn, err := tls.Dial("tcp", connectTo, tlsConfigForConnect(connectName, connectCert, connectKey)) + if err != nil { + fmt.Fprintf(os.Stderr, "error connecting: %v\n", err) + os.Exit(1) + } + defer conn.Close() + s := conn.ConnectionState() + state = &s + case "mysql": + mysql.RegisterTLSConfig("certigo", tlsConfigForConnect(connectName, connectCert, connectKey)) + state, err = mysql.DumpTLS(fmt.Sprintf("certigo@tcp(%s)/?tls=certigo", connectTo)) + case "postgres", "psql": + // Setting sslmode to "require" skips verification. + url := fmt.Sprintf("postgres://certigo@%s/?sslmode=require", connectTo) + if connectCert != "" { + url += fmt.Sprintf("&sslcert=%s", connectCert) + } + if connectKey != "" { + url += fmt.Sprintf("&sslkey=%s", connectCert) + } + state, err = pq.DumpTLS(url) + default: + fmt.Fprintf(os.Stderr, "error connecting: unknown StartTLS protocol '%s'\n", connectStartTLS) + os.Exit(1) + } + + if err != nil { + fmt.Fprintf(os.Stderr, "error connecting: %v\n", err) + os.Exit(1) + } + + return state +}