~samwhited/xmpp

3ca280202eb041adb381e0177c480615ebd2c97d — Sam Whited 1 year, 1 month ago ac511d7
xmpp, sasl2: use Session ConnectionState for SASL

Previously we attempted to pull the tls.ConnectionState out of the
Session's underlying net.Conn, however, even if the underlying
connection is a *tls.Conn if it is wrapped at all the connection state
would become unavailable. Instead, use the new ConnectionState method on
Session which will always proxy down into the top most *tls.Conn.

Fixes #45

Signed-off-by: Sam Whited <sam@samwhited.com>
4 files changed, 13 insertions(+), 6 deletions(-)

M CHANGELOG.md
M sasl.go
M sasl2/sasl.go
M session.go
M CHANGELOG.md => CHANGELOG.md +7 -0
@@ 5,8 5,15 @@ All notable changes to this project will be documented in this file.

## Unreleased

### Added

- xmpp: `ConnectionState` method


### Fixed

- sasl2: using TeeIn/TeeOut no longer breaks SCRAM based SASL mechanisms
- xmpp: using TeeIn/TeeOut no longer breaks SCRAM based SASL mechanisms
- xmpp: stream negotiation no longer fails when the only required features
  cannot yet be negotiated because they depend on optional features


M sasl.go => sasl.go +2 -3
@@ 6,7 6,6 @@ package xmpp

import (
	"context"
	"crypto/tls"
	"encoding/base64"
	"encoding/xml"
	"errors"


@@ 102,8 101,8 @@ func SASL(identity, password string, mechanisms ...sasl.Mechanism) StreamFeature
				sasl.RemoteMechanisms(data.([]string)...),
			}

			if tlsConn, ok := c.(*tls.Conn); ok {
				opts = append(opts, sasl.TLSState(tlsConn.ConnectionState()))
			if connState := session.ConnectionState(); connState.Version != 0 {
				opts = append(opts, sasl.TLSState(connState))
			}
			client := sasl.NewClient(selected, opts...)


M sasl2/sasl.go => sasl2/sasl.go +2 -3
@@ 12,7 12,6 @@ package sasl2 // import "mellium.im/xmpp/sasl2"

import (
	"context"
	"crypto/tls"
	"encoding/base64"
	"encoding/xml"
	"errors"


@@ 120,8 119,8 @@ func SASL(identity, password string, mechanisms ...sasl.Mechanism) xmpp.StreamFe
				sasl.RemoteMechanisms(data.([]string)...),
			}

			if tlsConn, ok := conn.(*tls.Conn); ok {
				opts = append(opts, sasl.TLSState(tlsConn.ConnectionState()))
			if connState := session.ConnectionState(); connState.Version != 0 {
				opts = append(opts, sasl.TLSState(connState))
			}

			client := sasl.NewClient(selected, opts...)

M session.go => session.go +2 -0
@@ 103,6 103,8 @@ type Session struct {
	}
}

var _ tlsConn = (*Session)(nil)

// ConnectionState returns the underlying connections TLS state or the zero
// value if TLS has not been negotiated.
func (s *Session) ConnectionState() tls.ConnectionState {