Skip to content

Commit

Permalink
tt: move ssl logic from go-tarantool
Browse files Browse the repository at this point in the history
To disable SSL by default we want to transfer OpenSslDialer
and any other ssl logic to the go-openssl repository.

Moved all ssl code from go-tarantool, some test helpers.
Added dependency to go-tarantool.

Part of tarantool/go-tarantool#301
  • Loading branch information
DerekBum committed Jan 31, 2024
1 parent 336ca93 commit d2978e1
Show file tree
Hide file tree
Showing 20 changed files with 1,653 additions and 0 deletions.
19 changes: 19 additions & 0 deletions .github/workflows/go-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,20 @@ jobs:
strategy:
fail-fast: false
matrix:
sdk-path:
- 'release/linux/x86_64/1.10/'
sdk-version:
- 'sdk-1.10.15-0-r598'
os: [ "ubuntu", "macos" ]
go: [ "1.18.x", "1.19.x" ]
tnt_ssl: [false]
include:
- sdk-path: 'release/linux/x86_64/2.10/'
sdk-version: 'sdk-gc64-2.10.8-0-r598.linux.x86_64'
tnt_ssl: true
- sdk-path: 'release/linux/x86_64/2.11/'
sdk-version: 'sdk-gc64-2.11.1-0-r598.linux.x86_64'
tnt_ssl: true
env:
COVERAGES: ""
runs-on: ${{ format('{0}-latest', matrix.os) }}
Expand All @@ -22,6 +34,12 @@ jobs:
- uses: actions/setup-go@v3
with:
go-version: ${{ matrix.go }}
- name: Setup Tarantool ${{ matrix.sdk-version }}
run: |
ARCHIVE_NAME=tarantool-enterprise-${{ matrix.sdk-version }}.tar.gz
curl -O -L https://${{ secrets.SDK_DOWNLOAD_TOKEN }}@download.tarantool.io/enterprise/${{ matrix.sdk-path }}${ARCHIVE_NAME}
tar -xzf ${ARCHIVE_NAME}
rm -f ${ARCHIVE_NAME}
- name: Go information
run: |
go version
Expand All @@ -36,6 +54,7 @@ jobs:
# If package ./A imports ./B, and ./A's tests also cover ./B,
# this means ./B's coverage will be significantly higher than 0%.
run: go test -v -shuffle=on -coverprofile=module-coverage.txt -coverpkg=./... ./...
env_vars: TEST_TNT_SSL=${{matrix.tnt_ssl}}
- name: Run tests (32 bit)
if: ${{ matrix.os != 'macos' }} # can't run 32 bit tests on OSX.
uses: protocol/multiple-go-modules@v1.2
Expand Down
3 changes: 3 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ module github.com/tarantool/go-openssl
require (
github.com/mattn/go-pointer v0.0.1
github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572
github.com/stretchr/testify v1.7.1
github.com/tarantool/go-iproto v1.0.0
github.com/tarantool/go-tarantool/v2 v2.0.0-20240131003940-1a49b281a97e
golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb // indirect
)

Expand Down
29 changes: 29 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,6 +1,35 @@
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/mattn/go-pointer v0.0.1 h1:n+XhsuGeVO6MEAp7xyEukFINEa+Quek5psIR/ylA6o0=
github.com/mattn/go-pointer v0.0.1/go.mod h1:2zXcozF6qYGgmsG+SeTZz3oAbFLdD3OWqnUbNvJZAlc=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 h1:RC6RW7j+1+HkWaX/Yh71Ee5ZHaHYt7ZP4sQgUrm6cDU=
github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572/go.mod h1:w0SWMsp6j9O/dk4/ZpIhL+3CkG8ofA2vuv7k+ltqUMc=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/tarantool/go-iproto v1.0.0 h1:quC4hdFhCuFYaCqOFgUxH2foRkhAy+TlEy7gQLhdVjw=
github.com/tarantool/go-iproto v1.0.0/go.mod h1:LNCtdyZxojUed8SbOiYHoc3v9NvaZTB7p96hUySMlIo=
github.com/tarantool/go-openssl v0.0.8-0.20231004103608-336ca939d2ca/go.mod h1:M7H4xYSbzqpW/ZRBMyH0eyqQBsnhAMfsYk5mv0yid7A=
github.com/tarantool/go-tarantool/v2 v2.0.0-20240130131506-70383596d128/go.mod h1:fGJBRxbkZmNQap9VxQ7xQHlDhRiHFnqP3gK4ghtlro0=
github.com/tarantool/go-tarantool/v2 v2.0.0-20240131003940-1a49b281a97e h1:M8wYDUTrchX2/7cVf2xtzjxW5QesxCe5OmCvGyZ4ybE=
github.com/tarantool/go-tarantool/v2 v2.0.0-20240131003940-1a49b281a97e/go.mod h1:fGJBRxbkZmNQap9VxQ7xQHlDhRiHFnqP3gK4ghtlro0=
github.com/vmihailenco/msgpack/v5 v5.3.5 h1:5gO0H1iULLWGhs2H5tbAHIZTV8/cYafcFOr9znI5mJU=
github.com/vmihailenco/msgpack/v5 v5.3.5/go.mod h1:7xyJ9e+0+9SaZT0Wt1RGleJXzli6Q/V5KbhBonMG9jc=
github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g=
github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds=
golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb h1:fgwFCsaw9buMuxNd6+DQfAuSFqbNiQZpcgJQAgJsK6k=
golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4 h1:myAQVi0cGEoqQVR5POX+8RR2mrocKqNN1hmeMqhX27k=
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
62 changes: 62 additions & 0 deletions tt/connection.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package tt

import (
"errors"
"io"
"net"

"github.com/tarantool/go-tarantool/v2"
)

type tntConn struct {
net net.Conn
reader io.Reader
writer writeFlusher
}

// writeFlusher is the interface that groups the basic Write and Flush methods.
type writeFlusher interface {
io.Writer
Flush() error
}

// Addr makes tntConn satisfy the Conn interface.
func (c *tntConn) Addr() net.Addr {
return c.net.RemoteAddr()
}

// Read makes tntConn satisfy the Conn interface.
func (c *tntConn) Read(p []byte) (int, error) {
return c.reader.Read(p)
}

// Write makes tntConn satisfy the Conn interface.
func (c *tntConn) Write(p []byte) (int, error) {
if l, err := c.writer.Write(p); err != nil {
return l, err
} else if l != len(p) {
return l, errors.New("wrong length written")
} else {
return l, nil
}
}

// Flush makes tntConn satisfy the Conn interface.
func (c *tntConn) Flush() error {
return c.writer.Flush()
}

// Close makes tntConn satisfy the Conn interface.
func (c *tntConn) Close() error {
return c.net.Close()
}

// Greeting makes tntConn satisfy the Conn interface.
func (c *tntConn) Greeting() tarantool.Greeting {
return tarantool.Greeting{}
}

// ProtocolInfo makes tntConn satisfy the Conn interface.
func (c *tntConn) ProtocolInfo() tarantool.ProtocolInfo {
return tarantool.ProtocolInfo{}
}
27 changes: 27 additions & 0 deletions tt/deadline_io.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package tt

import (
"net"
"time"
)

type deadlineIO struct {
to time.Duration
c net.Conn
}

func (d *deadlineIO) Write(b []byte) (n int, err error) {
if d.to > 0 {
d.c.SetWriteDeadline(time.Now().Add(d.to))
}
n, err = d.c.Write(b)
return
}

func (d *deadlineIO) Read(b []byte) (n int, err error) {
if d.to > 0 {
d.c.SetReadDeadline(time.Now().Add(d.to))
}
n, err = d.c.Read(b)
return
}
149 changes: 149 additions & 0 deletions tt/dialer.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
package tt

import (
"bufio"
"context"
"fmt"

"github.com/tarantool/go-tarantool/v2"
)

const bufSize = 128 * 1024

type openSslDialer struct {
address string
sslKeyFile string
sslCertFile string
sslCaFile string
sslCiphers string
sslPassword string
sslPasswordFile string
}

func (d openSslDialer) Dial(ctx context.Context,
opts tarantool.DialOpts) (tarantool.Conn, error) {
var err error
conn := new(tntConn)

network, address := parseAddress(d.address)
conn.net, err = sslDialContext(ctx, network, address, sslOpts{
KeyFile: d.sslKeyFile,
CertFile: d.sslCertFile,
CaFile: d.sslCaFile,
Ciphers: d.sslCiphers,
Password: d.sslPassword,
PasswordFile: d.sslPasswordFile,
})
if err != nil {
return nil, fmt.Errorf("failed to dial: %w", err)
}

dc := &deadlineIO{to: opts.IoTimeout, c: conn.net}
conn.reader = bufio.NewReaderSize(dc, bufSize)
conn.writer = bufio.NewWriterSize(dc, bufSize)

return conn, nil
}

// OpenSslDialer allows to use SSL transport for connection.
type OpenSslDialer struct {
// Address is an address to connect.
// It could be specified in following ways:
//
// - TCP connections (tcp://192.168.1.1:3013, tcp://my.host:3013,
// tcp:192.168.1.1:3013, tcp:my.host:3013, 192.168.1.1:3013, my.host:3013)
//
// - Unix socket, first '/' or '.' indicates Unix socket
// (unix:///abs/path/tnt.sock, unix:path/tnt.sock, /abs/path/tnt.sock,
// ./rel/path/tnt.sock, unix/:path/tnt.sock)
Address string
// Auth is an authentication method.
Auth tarantool.Auth
// Username for logging in to Tarantool.
User string
// User password for logging in to Tarantool.
Password string
// RequiredProtocol contains minimal protocol version and
// list of protocol features that should be supported by
// Tarantool server. By default, there are no restrictions.
RequiredProtocolInfo tarantool.ProtocolInfo
// SslKeyFile is a path to a private SSL key file.
SslKeyFile string
// SslCertFile is a path to an SSL certificate file.
SslCertFile string
// SslCaFile is a path to a trusted certificate authorities (CA) file.
SslCaFile string
// SslCiphers is a colon-separated (:) list of SSL cipher suites the connection
// can use.
//
// We don't provide a list of supported ciphers. This is what OpenSSL
// does. The only limitation is usage of TLSv1.2 (because other protocol
// versions don't seem to support the GOST cipher). To add additional
// ciphers (GOST cipher), you must configure OpenSSL.
//
// See also
//
// * https://www.openssl.org/docs/man1.1.1/man1/ciphers.html
SslCiphers string
// SslPassword is a password for decrypting the private SSL key file.
// The priority is as follows: try to decrypt with SslPassword, then
// try SslPasswordFile.
SslPassword string
// SslPasswordFile is a path to the list of passwords for decrypting
// the private SSL key file. The connection tries every line from the
// file as a password.
SslPasswordFile string
}

// Dial makes OpenSslDialer satisfy the Dialer interface.
func (d OpenSslDialer) Dial(ctx context.Context,
opts tarantool.DialOpts) (tarantool.Conn, error) {
if d.Auth != tarantool.AutoAuth {
d.RequiredProtocolInfo.Auth = d.Auth
}

dialer := tarantool.AuthDialer{
Dialer: tarantool.ProtocolDialer{
Dialer: openSslDialer{
address: d.Address,
sslKeyFile: d.SslKeyFile,
sslCertFile: d.SslCertFile,
sslCaFile: d.SslCaFile,
sslCiphers: d.SslCiphers,
sslPassword: d.SslPassword,
sslPasswordFile: d.SslPasswordFile,
},
RequiredProtocolInfo: d.RequiredProtocolInfo,
},
Auth: d.Auth,
Username: d.User,
Password: d.Password,
}

return dialer.Dial(ctx, opts)
}

// parseAddress split address into network and address parts.
func parseAddress(address string) (string, string) {
network := "tcp"
addrLen := len(address)

if addrLen > 0 && (address[0] == '.' || address[0] == '/') {
network = "unix"
} else if addrLen >= 7 && address[0:7] == "unix://" {
network = "unix"
address = address[7:]
} else if addrLen >= 5 && address[0:5] == "unix:" {
network = "unix"
address = address[5:]
} else if addrLen >= 6 && address[0:6] == "unix/:" {
network = "unix"
address = address[6:]
} else if addrLen >= 6 && address[0:6] == "tcp://" {
address = address[6:]
} else if addrLen >= 4 && address[0:4] == "tcp:" {
address = address[4:]
}

return network, address
}
14 changes: 14 additions & 0 deletions tt/export_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package tt

type SslTestOpts struct {
KeyFile string
CertFile string
CaFile string
Ciphers string
Password string
PasswordFile string
}

func SslCreateContext(opts SslTestOpts) (ctx interface{}, err error) {
return sslCreateContext(sslOpts(opts))
}
Loading

0 comments on commit d2978e1

Please sign in to comment.