Skip to content

Commit

Permalink
api: remove ssl
Browse files Browse the repository at this point in the history
`OpenSslDialer` and all of its helper functions and tests
were rellocated to the `go-tlsdialer` [1] package (and renamed
to `OpenSSLDialer`). So now we can safely remove all the
copy-pasted code from `go-tarantool`.

This way, in order to use SSL, user should import the
`go-tlsdialer` package and call functions from there.

1. https://github.com/tarantool/go-tlsdialer/

Part of #301
  • Loading branch information
DerekBum authored and oleg-jukovec committed Feb 8, 2024
1 parent c83fcdc commit df9254c
Show file tree
Hide file tree
Showing 23 changed files with 119 additions and 1,329 deletions.
23 changes: 0 additions & 23 deletions .github/workflows/testing.yml
Original file line number Diff line number Diff line change
Expand Up @@ -103,11 +103,6 @@ jobs:
make test
make testrace
- name: Run regression tests with disabled SSL
run: |
make test TAGS="go_tarantool_ssl_disable"
make testrace TAGS="go_tarantool_ssl_disable"
- name: Run fuzzing tests
if: ${{ matrix.fuzzing }}
run: make fuzzing TAGS="go_tarantool_decimal_fuzzing"
Expand Down Expand Up @@ -149,16 +144,13 @@ jobs:
- 'sdk-1.10.15-0-r598'
coveralls: [false]
fuzzing: [false]
ssl: [false]
include:
- sdk-path: 'release/linux/x86_64/2.10/'
sdk-version: 'sdk-gc64-2.10.8-0-r598.linux.x86_64'
coveralls: false
ssl: true
- sdk-path: 'release/linux/x86_64/2.11/'
sdk-version: 'sdk-gc64-2.11.1-0-r598.linux.x86_64'
coveralls: true
ssl: true

steps:
- name: Clone the connector
Expand Down Expand Up @@ -195,14 +187,6 @@ jobs:
source tarantool-enterprise/env.sh
make test
make testrace
env:
TEST_TNT_SSL: ${{matrix.ssl}}

- name: Run regression tests with disabled SSL
run: |
source tarantool-enterprise/env.sh
make test TAGS="go_tarantool_ssl_disable"
make testrace TAGS="go_tarantool_ssl_disable"
- name: Run fuzzing tests
if: ${{ matrix.fuzzing }}
Expand All @@ -212,7 +196,6 @@ jobs:
if: ${{ matrix.coveralls }}
env:
COVERALLS_TOKEN: ${{ secrets.GITHUB_TOKEN }}
TEST_TNT_SSL: ${{matrix.ssl}}
run: |
source tarantool-enterprise/env.sh
make coveralls
Expand Down Expand Up @@ -376,12 +359,6 @@ jobs:
make test
make testrace
- name: Run regression tests with disabled SSL
run: |
cd "${SRCDIR}"
make test TAGS="go_tarantool_ssl_disable"
make testrace TAGS="go_tarantool_ssl_disable"
- name: Run fuzzing tests
if: ${{ matrix.fuzzing }}
run: |
Expand Down
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ Versioning](http://semver.org/spec/v2.0.0.html) except to the first release.
- IsNullable flag for Field (#302)
- More linters on CI (#310)
- Meaningful description for read/write socket errors (#129)
- Support password and password file to decrypt private SSL key file (#319)
- Support `operation_data` in `crud.Error` (#330)
- Support `fetch_latest_metadata` option for crud requests with metadata (#335)
- Support `noreturn` option for data change crud requests (#335)
Expand Down Expand Up @@ -127,6 +126,7 @@ Versioning](http://semver.org/spec/v2.0.0.html) except to the first release.
- Code() method from the Request interface (#158)
- `Schema` field from the `Connection` struct (#7)
- `OkCode` and `PushCode` constants (#237)
- SSL support (#301)

### Fixed

Expand Down
14 changes: 0 additions & 14 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,20 +34,6 @@ make testrace
The tests set up all required `tarantool` processes before run and clean up
afterwards.

If you want to run the tests with specific build tags:
```bash
make test TAGS=go_tarantool_ssl_disable
make testrace TAGS=go_tarantool_ssl_disable
```

If you have Tarantool Enterprise Edition 2.10 or newer, you can run additional
SSL tests. To do this, you need to set an environment variable 'TEST_TNT_SSL':

```bash
TEST_TNT_SSL=true make test
TEST_TNT_SSL=true make testrace
```

If you want to run the tests for a specific package:
```bash
make test-<SUBDIR>
Expand Down
66 changes: 59 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,11 +68,7 @@ We define multiple [build tags](https://pkg.go.dev/go/build#hdr-Build_Constraint

This allows us to introduce new features without losing backward compatibility.

1. To disable SSL support and linking with OpenSSL, you can use the tag:
```
go_tarantool_ssl_disable
```
2. To run fuzz tests with decimals, you can use the build tag:
1. To run fuzz tests with decimals, you can use the build tag:
```
go_tarantool_decimal_fuzzing
```
Expand Down Expand Up @@ -169,6 +165,60 @@ otherwise it will have a description which can be retrieved with `err.Error()`.
by the method `Do` of object `conn` which is the object that was returned
by `Connect()`.

### Example with encrypting traffic

For SSL-enabled connections, use `OpenSSLDialer` from the [`go-tlsdialer`](https://github.com/tarantool/go-tlsdialer)
package.

Here is small example with importing `go-tlsdialer` and using the
`OpenSSLDialer`:

```go
package tarantool

import (
"context"
"fmt"
"time"

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

func main() {
sslDialer := tlsdialer.OpenSSLDialer{
Address: "127.0.0.1:3013",
User: "test",
Password: "test",
SslKeyFile: "testdata/localhost.key",
SslCertFile: "testdata/localhost.crt",
SslCaFile: "testdata/ca.crt",
}
opts := tarantool.Opts{
Timeout: time.Second,
}

ctx, cancel := context.WithTimeout(context.Background(), 500*time.Millisecond)
defer cancel()
conn, err := tarantool.Connect(ctx, sslDialer, opts)
if err != nil {
fmt.Printf("Connection refused: %s", err)
}

data, err := conn.Do(tarantool.NewInsertRequest(999).
Tuple([]interface{}{99999, "BB"}),
).Get()
if err != nil {
fmt.Printf("Error: %s", err)
} else {
fmt.Printf("Data: %v", data)
}
}
```

Note that [traffic encryption](https://www.tarantool.io/en/doc/latest/enterprise/security/#encrypting-traffic)
is only available in Tarantool Enterprise Edition 2.10 or newer.

### Migration to v2

The article describes migration from go-tarantool to go-tarantool/v2.
Expand Down Expand Up @@ -315,8 +365,10 @@ and user may cancel it in process.

Now you need to pass `Dialer` as the second argument instead of URI.
If you were using a non-SSL connection, you need to create `NetDialer`.
For SSL-enabled connections, use `OpenSslDialer`. Please note that the options
for creating a connection are now stored in corresponding `Dialer`, not in `Opts`.
For SSL-enabled connections, use `OpenSSLDialer` from the `go-tlsdialer`
package.
Please note that the options for creating a connection are now stored in
corresponding `Dialer`, not in `Opts`.

#### Connection schema

Expand Down
109 changes: 0 additions & 109 deletions dial.go
Original file line number Diff line number Diff line change
Expand Up @@ -205,115 +205,6 @@ func (d NetDialer) Dial(ctx context.Context, opts DialOpts) (Conn, error) {
return dialer.Dial(ctx, opts)
}

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 DialOpts) (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 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 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 DialOpts) (Conn, error) {
dialer := AuthDialer{
Dialer: ProtocolDialer{
Dialer: GreetingDialer{
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)
}

type fdAddr struct {
Fd uintptr
}
Expand Down
48 changes: 38 additions & 10 deletions dial_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -442,7 +442,6 @@ type testDialOpts struct {
isErrGreeting bool
isErrId bool
isIdUnsupported bool
isPapSha256Auth bool
isErrAuth bool
isEmptyAuth bool
}
Expand Down Expand Up @@ -485,9 +484,7 @@ func testDialAccept(opts testDialOpts, l net.Listener) chan dialServerActual {

// Read Auth request.
authRequestExpected := authRequestExpectedChapSha1
if opts.isPapSha256Auth {
authRequestExpected = authRequestExpectedPapSha256
} else if opts.isEmptyAuth {
if opts.isEmptyAuth {
authRequestExpected = []byte{}
}
authRequestActual := make([]byte, len(authRequestExpected))
Expand Down Expand Up @@ -530,9 +527,7 @@ func testDialer(t *testing.T, l net.Listener, dialer tarantool.Dialer,
require.Equal(t, idRequestExpected, actual.IdRequest)

authRequestExpected := authRequestExpectedChapSha1
if opts.isPapSha256Auth {
authRequestExpected = authRequestExpectedPapSha256
} else if opts.isEmptyAuth {
if opts.isEmptyAuth {
authRequestExpected = []byte{}
}
require.Equal(t, authRequestExpected, actual.AuthRequest)
Expand Down Expand Up @@ -749,11 +744,44 @@ func TestAuthDialer_Dial(t *testing.T) {
conn.Close()
}

assert.Nil(t, err)
assert.NoError(t, err)
assert.NotNil(t, conn)
assert.Equal(t, authRequestExpectedChapSha1[:41], dialer.conn.writebuf.Bytes()[:41])
}

func TestAuthDialer_Dial_PapSha256Auth(t *testing.T) {
salt := fmt.Sprintf("%s", testDialSalt)
salt = base64.StdEncoding.EncodeToString([]byte(salt))
dialer := mockIoDialer{
init: func(conn *mockIoConn) {
conn.greeting.Salt = salt
conn.writeWgDelay = 1
conn.readWgDelay = 2
conn.readbuf.Write(okResponse)
},
}
defer func() {
dialer.conn.writeWg.Done()
}()

authDialer := tarantool.AuthDialer{
Dialer: &dialer,
Username: "test",
Password: "test",
Auth: tarantool.PapSha256Auth,
}
ctx, cancel := test_helpers.GetConnectContext()
defer cancel()
conn, err := authDialer.Dial(ctx, tarantool.DialOpts{})
if conn != nil {
conn.Close()
}

assert.NoError(t, err)
assert.NotNil(t, conn)
assert.Equal(t, authRequestExpectedPapSha256[:41], dialer.conn.writebuf.Bytes()[:41])
}

func TestProtocolDialer_Dial_DialerError(t *testing.T) {
dialer := tarantool.ProtocolDialer{
Dialer: mockErrorDialer{
Expand Down Expand Up @@ -847,7 +875,7 @@ func TestProtocolDialer_Dial(t *testing.T) {
conn.Close()
}

assert.Nil(t, err)
assert.NoError(t, err)
assert.NotNil(t, conn)
assert.Equal(t, protoInfo, conn.ProtocolInfo())
}
Expand Down Expand Up @@ -913,7 +941,7 @@ func TestGreetingDialer_Dial(t *testing.T) {
conn.Close()
}

assert.Nil(t, err)
assert.NoError(t, err)
assert.NotNil(t, conn)
assert.Equal(t, string(testDialVersion[:]), conn.Greeting().Version)
assert.Equal(t, string(testDialSalt[:44]), conn.Greeting().Salt)
Expand Down
Loading

0 comments on commit df9254c

Please sign in to comment.