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 +}