Categorygithub.com/cspengl/saslconn
repositorypackage
1.0.0
Repository: https://github.com/cspengl/saslconn.git
Documentation: pkg.go.dev

# Packages

No description provided by the author
No description provided by the author

# README

saslconn

A connection based SASL protocol definition + implementation according to RFC-4422


Go Reference

This repository serves two purposes:

  • Proposing a SASL connection protocol described via protobuf files
  • Containing a implementation of the proposed protocol in Golang based on the go-sasl library

Since the protocol is described through protobuf messages it should be relatively easy to implement the protocol in other programming languages.

Usage

The implementation of the protocol is inspired by golang's TLS implementation. Hence establishing connections hopefully feels very familiar.

Note: The following example transfers credentials in plain-text via the network. To ensure confidentiality and integrity you should consider combining the SASL connection with other protective mechanisms like TLS (see next section).

Client

import (
    "github.com/cspengl/saslconn"
    "github.com/emersion/go-sasl"
)

func main() {
    config := &saslconn.Config{
        Mechanisms: []*saslconn.Mechanism{
            {
                Name: sasl.Plain,
                Client: sasl.NewPlainClient("userident", "username", "secret"),
            },
        },
    }

    conn, err := saslconn.Dial("tcp", ":9000", config)
    defer func() {
        if err := conn.Close(); err != nil {
            panic(err)
        }
    }()
    if err != nil {
        panic(err)
    }
    if _, err := conn.Write([]byte("Hello World!")); err != nil {
        panic(err)
    }
}

Server

import (
    "fmt"

    "github.com/cspengl/saslconn"
    "github.com/emersion/go-sasl"
)

func main() {
    config := &saslconn.Config{
        Mechanisms: []*saslconn.Mechanism{
            {
                Name: sasl.Plain,
                Server: sasl.NewPlainServer(
					func(identity, username, password string) error {
                        // always successful
						return nil
					},
				),
            },
            
        },
    }

    listener, err := saslconn.Listen("tcp", ":9000", config)
    defer func() {
        if err := listener.Close(); err != nil {
            panic(err)
        }
    }()
    conn, err := listener.Accept()
    if err != nil {
        panic(err)
    }
    helloWorldFromClient := make([]byte, 12)
    if _, err := conn.Read(helloWorldFromClient); err != nil {
        panic(err)
    }
    fmt.Println(string(helloWorldFromClient))
}

Combination with TLS

Neither SASL mechanisms nor the proposed connection protocol itself provide adequate integrity and/or confidentialty protection of the authentication exchange it is highly recommended to combine it with other protective mechanisms like TLS.

Example

import (
    "fmt"
    "crypto/tls"

    "github.com/cspengl/saslconn"
    "github.com/emersion/go-sasl"
)

func main() {
    config := &saslconn.Config{
        Mechanisms: []*saslconn.Mechanism{
            {
                Name: sasl.Plain,
                Server: sasl.NewPlainServer(
					func(identity, username, password string) error {
                        // always successful
						return nil
					},
				),
            },
            
        },
    }

    cert, err := tls.LoadX509KeyPair("example-cert.pem", "example-key.pem")
	if err != nil {
		log.Fatal(err)
	}
	tlsConfig := &tls.Config{Certificates: []tls.Certificate{cert}}

    listener, err := saslconn.ListenTLS("tcp", ":9000", tlsConfig, config)
    defer func() {
        if err := listener.Close(); err != nil {
            panic(err)
        }
    }()
    //...
}

License

MIT