Skip to content

Support of SSL protocol #170

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 2, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 60 additions & 4 deletions .github/workflows/testing.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ on:
workflow_dispatch:

jobs:
linux:
run-tests-ce:
# We want to run on external PRs, but not on our own internal
# PRs as they'll be run by the push to the branch.
#
Expand All @@ -26,9 +26,6 @@ jobs:
- '2.9'
- '2.x-latest'
coveralls: [false]
include:
- tarantool: '2.x-latest'
coveralls: true

steps:
- name: Clone the connector
Expand Down Expand Up @@ -66,3 +63,62 @@ jobs:

- name: Check workability of benchmark tests
run: make bench-deps bench DURATION=1x COUNT=1

run-tests-ee:
if: github.event_name == 'push' ||
github.event.pull_request.head.repo.full_name != github.repository

runs-on: ubuntu-latest

strategy:
fail-fast: false
matrix:
sdk-version:
- '1.10.11-0-gf0b0e7ecf-r470'
- '2.8.3-21-g7d35cd2be-r470'
coveralls: [false]
ssl: [false]
include:
- sdk-version: '2.10.0-1-gfa775b383-r486-linux-x86_64'
coveralls: true
ssl: true

steps:
- name: Clone the connector
uses: actions/checkout@v2

- name: Setup Tarantool ${{ matrix.sdk-version }}
run: |
ARCHIVE_NAME=tarantool-enterprise-bundle-${{ matrix.sdk-version }}.tar.gz
curl -O -L https://${{ secrets.SDK_DOWNLOAD_TOKEN }}@download.tarantool.io/enterprise/${ARCHIVE_NAME}
tar -xzf ${ARCHIVE_NAME}
rm -f ${ARCHIVE_NAME}

- name: Setup golang for the connector and tests
uses: actions/setup-go@v2
with:
go-version: 1.13

- name: Install test dependencies
run: |
source tarantool-enterprise/env.sh
make deps

- name: Run tests
run: |
source tarantool-enterprise/env.sh
make test
env:
TEST_TNT_SSL: ${{matrix.ssl}}

- name: Run tests, collect code coverage data and send to Coveralls
if: ${{ matrix.coveralls }}
env:
COVERALLS_TOKEN: ${{ secrets.GITHUB_TOKEN }}
TEST_TNT_SSL: ${{matrix.ssl}}
run: |
source tarantool-enterprise/env.sh
make coveralls

- name: Check workability of benchmark tests
run: make bench-deps bench DURATION=1x COUNT=1
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ Versioning](http://semver.org/spec/v2.0.0.html) except to the first release.

### Added

- SSL support (#155)

### Changed

### Fixed
Expand Down
7 changes: 7 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,13 @@ make test
The tests set up all required `tarantool` processes before run and clean up
afterwards.

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
```

If you want to run the tests for a specific package:
```bash
make test-<SUBDIR>
Expand Down
4 changes: 4 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ golangci-lint:
test:
go test ./... -v -p 1

.PHONY: testdata
testdata:
(cd ./testdata; ./generate.sh)

.PHONY: test-connection-pool
test-connection-pool:
@echo "Running tests in connection_pool package"
Expand Down
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ faster than other packages according to public benchmarks.
## Table of contents

* [Installation](#installation)
* [Build tags](#build-tags)
* [Documentation](#documentation)
* [API reference](#api-reference)
* [Walking\-through example](#walking-through-example)
Expand Down Expand Up @@ -51,6 +52,13 @@ This should put the source and binary files in subdirectories of
`github.com/tarantool/go-tarantool` to the `import {...}` section at the start
of any Go program.

### Build tags

To disable SSL support and linking with OpenSSL, you can use the tag:
```
go_tarantool_ssl_disable
```

## Documentation

Read the [Tarantool documentation][tarantool-doc-data-model-url]
Expand Down
49 changes: 44 additions & 5 deletions connection.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@ const (
connClosed = 2
)

const (
connTransportNone = ""
connTransportSsl = "ssl"
)

type ConnEventKind int
type ConnLogKind int

Expand Down Expand Up @@ -207,6 +212,32 @@ type Opts struct {
Handle interface{}
// Logger is user specified logger used for error messages.
Logger Logger
// Transport is the connection type, by default the connection is unencrypted.
Transport string
// SslOpts is used only if the Transport == 'ssl' is set.
Ssl SslOpts
}

// SslOpts is a way to configure ssl transport.
type SslOpts struct {
// KeyFile is a path to a private SSL key file.
KeyFile string
// CertFile is a path to an SSL sertificate file.
CertFile string
// CaFile is a path to a trusted certificate authorities (CA) file.
CaFile string
// Ciphers 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
Ciphers string
}

// Connect creates and configures a new Connection.
Expand Down Expand Up @@ -358,8 +389,10 @@ func (conn *Connection) Handle() interface{} {
func (conn *Connection) dial() (err error) {
var connection net.Conn
network := "tcp"
opts := conn.opts
address := conn.addr
timeout := conn.opts.Reconnect / 2
timeout := opts.Reconnect / 2
transport := opts.Transport
if timeout == 0 {
timeout = 500 * time.Millisecond
} else if timeout > 5*time.Second {
Expand All @@ -383,11 +416,17 @@ func (conn *Connection) dial() (err error) {
} else if addrLen >= 4 && address[0:4] == "tcp:" {
address = address[4:]
}
connection, err = net.DialTimeout(network, address, timeout)
if transport == connTransportNone {
connection, err = net.DialTimeout(network, address, timeout)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we're missing libssl, libcrypto and never use transport == connTransportSsl, will application with go-tarantool work is it was built with default flags? I'm not well up in linking.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The resulting executable will have the dynamic dependency on libssl and libcrypto (shown in ldd or otool -L). The dynamic loader will refuse to load a dynamic executable if any library is missing.

It is safe while given executable is used within a distro of particular version (because distros guarantees ABI compatibility -- where we had openssl 1.1, it will not be updated to openssl 3; at least not from base repositories). So if you build an application for each distro or at least have separate builds for openssl 1.1 and openssl 3 distros, everything should be fine.

If you want to build an executable that would work on, say, Fedora 35 and Fedora 36 both (or Ubuntu Impish and Ubuntu Jammy both), you're in the trouble.

So the question is actually about ways to deliver the resulting application. I can't judge about some 'usual way' here.

} else if transport == connTransportSsl {
connection, err = sslDialTimeout(network, address, timeout, opts.Ssl)
} else {
err = errors.New("An unsupported transport type: " + transport)
}
if err != nil {
return
}
dc := &DeadlineIO{to: conn.opts.Timeout, c: connection}
dc := &DeadlineIO{to: opts.Timeout, c: connection}
r := bufio.NewReaderSize(dc, 128*1024)
w := bufio.NewWriterSize(dc, 128*1024)
greeting := make([]byte, 128)
Expand All @@ -400,8 +439,8 @@ func (conn *Connection) dial() (err error) {
conn.Greeting.auth = bytes.NewBuffer(greeting[64:108]).String()

// Auth
if conn.opts.User != "" {
scr, err := scramble(conn.Greeting.auth, conn.opts.Pass)
if opts.User != "" {
scr, err := scramble(conn.Greeting.auth, opts.Pass)
if err != nil {
err = errors.New("auth: scrambling failure " + err.Error())
connection.Close()
Expand Down
20 changes: 19 additions & 1 deletion example_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,29 @@ type Tuple struct {
func example_connect() *tarantool.Connection {
conn, err := tarantool.Connect(server, opts)
if err != nil {
panic("Connection is not established")
panic("Connection is not established: " + err.Error())
}
return conn
}

// Example demonstrates how to use SSL transport.
func ExampleSslOpts() {
var opts = tarantool.Opts{
User: "test",
Pass: "test",
Transport: "ssl",
Ssl: tarantool.SslOpts{
KeyFile: "testdata/localhost.key",
CertFile: "testdata/localhost.crt",
CaFile: "testdata/ca.crt",
},
}
_, err := tarantool.Connect("127.0.0.1:3013", opts)
if err != nil {
panic("Connection is not established: " + err.Error())
}
}

func ExampleConnection_Select() {
conn := example_connect()
defer conn.Close()
Expand Down
14 changes: 14 additions & 0 deletions export_test.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,19 @@
package tarantool

import (
"net"
"time"
)

func (schema *Schema) ResolveSpaceIndex(s interface{}, i interface{}) (spaceNo, indexNo uint32, err error) {
return schema.resolveSpaceIndex(s, i)
}

func SslDialTimeout(network, address string, timeout time.Duration,
opts SslOpts) (connection net.Conn, err error) {
return sslDialTimeout(network, address, timeout, opts)
}

func SslCreateContext(opts SslOpts) (ctx interface{}, err error) {
return sslCreateContext(opts)
}
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ require (
github.com/google/uuid v1.3.0
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect
github.com/stretchr/testify v1.7.1 // indirect
github.com/tarantool/go-openssl v0.0.8-0.20220419150948-be4921aa2f87
google.golang.org/appengine v1.6.7 // indirect
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f // indirect
gopkg.in/vmihailenco/msgpack.v2 v2.9.2
Expand Down
8 changes: 8 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,25 @@ github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
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 h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
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/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.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/tarantool/go-openssl v0.0.8-0.20220419150948-be4921aa2f87 h1:JGzuBxNBq5saVtPUcuu5Y4+kbJON6H02//OT+RNqGts=
github.com/tarantool/go-openssl v0.0.8-0.20220419150948-be4921aa2f87/go.mod h1:M7H4xYSbzqpW/ZRBMyH0eyqQBsnhAMfsYk5mv0yid7A=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/net v0.0.0-20190603091049-60506f45cf65 h1:+rhAzEzT3f4JtomfC371qB+0Ola2caSKcY69NUBZrRQ=
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
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/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
Expand Down
Loading