xmpp

package module
v0.3.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 1, 2018 License: BSD-2-Clause Imports: 18 Imported by: 17

README

XMPP

GoDoc License

Buy Me A Coffee

An XMPP library in Go.

To use it in your project, import it (or one of its subproject's) like so:

import mellium.im/xmpp

Issues and feature requests

To file a bug report or submit a feature request, please use the issue tracker.

License

The package may be used under the terms of the BSD 2-Clause License a copy of which may be found in the file LICENSE.md.

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you shall be licensed as above, without any additional terms or conditions.

Documentation

Overview

Package xmpp provides functionality from the Extensible Messaging and Presence Protocol, formerly known as "Jabber".

It is subdivided into several packages; this package provides functionality for establishing an XMPP session, feature negotiation (including an API for defining your own stream features), and low-level connection and stream manipulation. The jid package provides an implementation of the XMPP address format defined in RFC 7622.

Be advised: This API is still unstable and is subject to change.

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrInputStreamClosed  = errors.New("xmpp: attempted to read token from closed stream")
	ErrOutputStreamClosed = errors.New("xmpp: attempted to write token to closed stream")
)

Errors returned by the XMPP package.

Functions

This section is empty.

Types

type Conn

type Conn struct {
	// contains filtered or unexported fields
}

Conn is a net.Conn created for the purpose of establishing an XMPP session.

func DialClient

func DialClient(ctx context.Context, network string, addr *jid.JID) (*Conn, error)

DialClient discovers and connects to the address on the named network with a client-to-server (c2s) connection.

If the context expires before the connection is complete, an error is returned. Once successfully connected, any expiration of the context will not affect the connection.

addr is a JID with a domainpart of the server we wish to connect too. DialClient will attempt to look up SRV records for the given JIDs domainpart or connect to the domainpart directly.

Network may be any of the network types supported by net.Dial, but you almost certainly want to use one of the tcp connection types ("tcp", "tcp4", or "tcp6").

func DialServer

func DialServer(ctx context.Context, network string, addr *jid.JID) (*Conn, error)

DialServer discovers and connects to the address on the named network with a server-to-server connection (s2s).

For more info see the DialClient function.

func (*Conn) Close added in v0.2.0

func (c *Conn) Close() error

Close closes the connection.

func (*Conn) ConnectionState added in v0.2.0

func (c *Conn) ConnectionState() (connState tls.ConnectionState, ok bool)

ConnectionState returns basic TLS details about the connection if TLS has been negotiated. If TLS has not been negotiated, ok is false.

func (*Conn) LocalAddr added in v0.2.0

func (c *Conn) LocalAddr() net.Addr

LocalAddr returns the local network address.

func (*Conn) Read added in v0.2.0

func (c *Conn) Read(b []byte) (n int, err error)

Read can be made to time out and return a net.Error with Timeout() == true after a fixed time limit; see SetDeadline and SetReadDeadline.

func (*Conn) RemoteAddr added in v0.2.0

func (c *Conn) RemoteAddr() net.Addr

RemoteAddr returns the remote network address.

func (*Conn) SetDeadline added in v0.2.0

func (c *Conn) SetDeadline(t time.Time) error

SetDeadline sets the read and write deadlines associated with the connection. A zero value for t means Read and Write will not time out. After a Write has timed out, the TLS state is corrupt and all future writes will return the same error.

func (*Conn) SetReadDeadline added in v0.2.0

func (c *Conn) SetReadDeadline(t time.Time) error

SetReadDeadline sets the read deadline on the underlying connection. A zero value for t means Read will not time out.

func (*Conn) SetWriteDeadline added in v0.2.0

func (c *Conn) SetWriteDeadline(t time.Time) error

SetWriteDeadline sets the write deadline on the underlying connection. A zero value for t means Write will not time out. After a Write has timed out, the TLS state is corrupt and all future writes will return the same error.

func (*Conn) Write added in v0.2.0

func (c *Conn) Write(b []byte) (int, error)

Write writes data to the connection.

type Dialer

type Dialer struct {
	net.Dialer

	// NoLookup stops the dialer from looking up SRV or TXT records for the given
	// domain. It also prevents fetching of the host metadata file.
	// Instead, it will try to connect to the domain directly.
	NoLookup bool

	// Attempt to dial a server-to-server connection.
	S2S bool
}

A Dialer contains options for connecting to an XMPP address.

The zero value for each field is equivalent to dialing without that option. Dialing with the zero value of Dialer is therefore equivalent to just calling the DialClient function.

func (*Dialer) Dial

func (d *Dialer) Dial(ctx context.Context, network string, addr *jid.JID) (*Conn, error)

Dial discovers and connects to the address on the named network.

For a description of the arguments see the DialClient function.

type Handler

type Handler interface {
	HandleXMPP(t xmlstream.TokenReadWriter, start *xml.StartElement) error
}

A Handler triggers events or responds to incoming elements in an XML stream.

type HandlerFunc

type HandlerFunc func(t xmlstream.TokenReadWriter, start *xml.StartElement) error

The HandlerFunc type is an adapter to allow the use of ordinary functions as XMPP handlers. If f is a function with the appropriate signature, HandlerFunc(f) is a Handler that calls f.

func (HandlerFunc) HandleXMPP

func (f HandlerFunc) HandleXMPP(t xmlstream.TokenReadWriter, start *xml.StartElement) error

HandleXMPP calls f(t, start).

type Negotiator

type Negotiator func(ctx context.Context, session *Session, data interface{}) (mask SessionState, rw io.ReadWriter, cache interface{}, err error)

Negotiator is a function that can be passed to NegotiateSession to perform custom session negotiation. This can be used for creating custom stream initialization logic that does not use XMPP feature negotiation such as the connection mechanism described in XEP-0114: Jabber Component Protocol. Normally NewClientSession or NewServerSession should be used instead.

If a Negotiator is passed into NegotiateSession it will be called repeatedly until a mask is returned with the Ready bit set. Each time Negotiator is called any bits set in the state mask that it returns will be set on the session state and any cache value that is returned will be passed back in during the next iteration. If a new io.ReadWriter is returned, it is set as the session's underlying io.ReadWriter and the internal session state (encoders, decoders, etc.) will be reset.

type Session

type Session struct {
	// contains filtered or unexported fields
}

A Session represents an XMPP session comprising an input and an output XML stream.

func NegotiateSession

func NegotiateSession(ctx context.Context, location, origin *jid.JID, rw io.ReadWriter, negotiate Negotiator) (*Session, error)

NegotiateSession creates an XMPP session using a custom negotiate function. Calling NegotiateSession with a nil Negotiator panics.

For more information see the Negotiator type.

func NewClientSession added in v0.2.0

func NewClientSession(ctx context.Context, origin *jid.JID, lang string, rw io.ReadWriter, features ...StreamFeature) (*Session, error)

NewClientSession attempts to use an existing connection (or any io.ReadWriter) to negotiate an XMPP client-to-server session. If the provided context is canceled before stream negotiation is complete an error is returned. After stream negotiation if the context is canceled it has no effect.

func NewServerSession added in v0.2.0

func NewServerSession(ctx context.Context, location, origin *jid.JID, lang string, rw io.ReadWriter, features ...StreamFeature) (*Session, error)

NewServerSession attempts to use an existing connection (or any io.ReadWriter) to negotiate an XMPP server-to-server session. If the provided context is canceled before stream negotiation is complete an error is returned. After stream negotiation if the context is canceled it has no effect.

func (*Session) Close

func (s *Session) Close() error

Close ends the output stream (by sending a closing </stream:stream> token). It does not close the underlying connection. Calling Close() multiple times will only result in one closing </stream:stream> being sent.

func (*Session) Conn

func (s *Session) Conn() *Conn

Conn returns the Session's backing connection.

This should almost never be read from or written to, but is useful during stream negotiation for wrapping the existing connection in a new layer (eg. compression or TLS).

func (*Session) EncodeToken added in v0.2.0

func (s *Session) EncodeToken(t xml.Token) error

EncodeToken satisfies the xmlstream.TokenWriter interface.

func (*Session) Feature

func (s *Session) Feature(namespace string) (data interface{}, ok bool)

Feature checks if a feature with the given namespace was advertised by the server for the current stream. If it was data will be the canonical representation of the feature as returned by the feature's Parse function.

func (*Session) Flush added in v0.2.0

func (s *Session) Flush() error

Flush satisfies the xmlstream.TokenWriter interface.

func (*Session) LocalAddr

func (s *Session) LocalAddr() *jid.JID

LocalAddr returns the Origin address for initiated connections, or the Location for received connections.

func (*Session) RemoteAddr

func (s *Session) RemoteAddr() *jid.JID

RemoteAddr returns the Location address for initiated connections, or the Origin address for received connections.

func (*Session) Serve

func (s *Session) Serve(h Handler) error

Serve decodes incoming XML tokens from the connection and delegates handling them to h. If an error is returned from the handler and it is of type stanza.Error or stream.Error, the error is marshaled and sent over the XML stream. If any other error type is returned, it is marshaled as an undefined-condition StreamError. If a stream error is received while serving it is not passed to the handler. Instead, Serve unmarshals the error, closes the session, and returns it (h handles stanza level errors, the session handles stream level errors).

If Serve is called concurrently the second invocation blocks until the first returns. If the input stream is closed, Serve returns. Serve does not close the output stream.

func (*Session) State

func (s *Session) State() SessionState

State returns the current state of the session. For more information, see the SessionState type.

func (*Session) Token added in v0.1.0

func (s *Session) Token() (xml.Token, error)

Token satisfies the xml.TokenReader interface for Session.

type SessionState

type SessionState uint8

SessionState is a bitmask that represents the current state of an XMPP session. For a description of each bit, see the various SessionState typed constants.

const (
	// Secure indicates that the underlying connection has been secured. For
	// instance, after STARTTLS has been performed or if a pre-secured connection
	// is being used such as websockets over HTTPS.
	Secure SessionState = 1 << iota

	// Authn indicates that the session has been authenticated (probably with
	// SASL).
	Authn

	// Ready indicates that the session is fully negotiated and that XMPP stanzas
	// may be sent and received.
	Ready

	// Received indicates that the session was initiated by a foreign entity.
	Received

	// OutputStreamClosed indicates that the output stream has been closed with a
	// stream end tag.  When set all write operations will return an error even if
	// the underlying TCP connection is still open.
	OutputStreamClosed

	// InputStreamClosed indicates that the input stream has been closed with a
	// stream end tag. When set all read operations will return an error.
	InputStreamClosed
)

type StreamFeature

type StreamFeature struct {
	// The XML name of the feature in the <stream:feature/> list. If a start
	// element with this name is seen while the connection is reading the features
	// list, it will trigger this StreamFeature's Parse function as a callback.
	Name xml.Name

	// Bits that are required before this feature is advertised. For instance, if
	// this feature should only be advertised after the user is authenticated we
	// might set this to "Authn" or if it should be advertised only after the
	// feature is authenticated and encrypted we might set this to "Authn|Secure".
	Necessary SessionState

	// Bits that must be off for this feature to be advertised. For instance, if
	// this feature should only be advertised before the connection is
	// authenticated (eg. if the feature performs authentication itself), we might
	// set this to "Authn".
	Prohibited SessionState

	// Used to send the feature in a features list for server connections. The
	// start element will have a name that matches the features name and should be
	// used as the outermost tag in the stream (but also may be ignored). List
	// implementations that call e.EncodeToken directly need to call e.Flush when
	// finished to ensure that the XML is written to the underlying writer.
	List func(ctx context.Context, e xmlstream.TokenWriter, start xml.StartElement) (req bool, err error)

	// Used to parse the feature that begins with the given xml start element
	// (which should have a Name that matches this stream feature's Name).
	// Returns whether or not the feature is required, and any data that will be
	// needed if the feature is selected for negotiation (eg. the list of
	// mechanisms if the feature was SASL).
	Parse func(ctx context.Context, r xml.TokenReader, start *xml.StartElement) (req bool, data interface{}, err error)

	// A function that will take over the session temporarily while negotiating
	// the feature. The "mask" SessionState represents the state bits that should
	// be flipped after negotiation of the feature is complete. For instance, if
	// this feature creates a security layer (such as TLS) and performs
	// authentication, mask would be set to Authn|Secure, but if it does not
	// authenticate the connection it would just return Secure. If negotiate
	// returns a new io.ReadWriter (probably wrapping the old session.Conn()) the
	// stream will be restarted automatically after Negotiate returns using the
	// new ReadWriter. If this is an initiated connection and the features List
	// call returned a value, that value is passed to the data parameter when
	// Negotiate is called. For instance, in the case of compression this data
	// parameter might be the list of supported algorithms as a slice of strings
	// (or in whatever format the feature implementation has decided upon).
	Negotiate func(ctx context.Context, session *Session, data interface{}) (mask SessionState, rw io.ReadWriter, err error)
}

A StreamFeature represents a feature that may be selected during stream negotiation, eg. STARTTLS, compression, and SASL authentication are all stream features. Features should be stateless as they may be reused between connection attempts.

func BindCustom

func BindCustom(server func(*jid.JID, string) (*jid.JID, error)) StreamFeature

BindCustom is identical to BindResource when used on a client session, but for server sessions the server function is called to generate the JID that should be returned to the client. If server is nil, BindCustom is identical to BindResource.

The server function is passed the current client JID and the resource requested by the client (or an empty string if a specific resource was not requested). Resources generated by the server function should be random to prevent certain security issues related to guessing resourceparts.

func BindResource

func BindResource() StreamFeature

BindResource is a stream feature that can be used for binding a resource (the name by which an individual client can be addressed) to the stream.

Resource binding is the final feature negotiated when setting up a new session and is required to allow communication with other clients and servers in the network. Resource binding is mandatory-to-negotiate.

If used on a server connection, BindResource generates and assigns random resourceparts, however this default is subject to change.

func SASL

func SASL(identity, password string, mechanisms ...sasl.Mechanism) StreamFeature

SASL returns a stream feature for performing authentication using the Simple Authentication and Security Layer (SASL) as defined in RFC 4422. It panics if no mechanisms are specified. The order in which mechanisms are specified will be the preferred order, so stronger mechanisms should be listed first.

Identity is used when a user wants to act on behalf of another user. For instance, an admin might want to log in as another user to help them troubleshoot an issue. Normally it is left blank and the localpart of the Origin JID is used.

func StartTLS

func StartTLS(required bool, cfg *tls.Config) StreamFeature

StartTLS returns a new stream feature that can be used for negotiating TLS. For StartTLS to work, the underlying connection must support TLS (it must implement net.Conn).

Notes

Bugs

  • This package only supports Go 1.10.

  • SASL feature does not have security layer byte precision.

  • STARTTLS feature does not have security layer byte precision.

Directories

Path Synopsis
Package color implements XEP-0392: Consistent Color Generation.
Package color implements XEP-0392: Consistent Color Generation.
Package component is used to establish XEP-0114: Jabber Component Protocol connections.
Package component is used to establish XEP-0114: Jabber Component Protocol connections.
Package compress implements XEP-0138: Stream Compression and XEP-0229: Stream Compression with LZW.
Package compress implements XEP-0138: Stream Compression and XEP-0229: Stream Compression with LZW.
examples module
commands Module
echobot Module
im Module
msgrepl Module
Package form is an implementation of XEP-0004: Data Forms.
Package form is an implementation of XEP-0004: Data Forms.
Package ibr2 implements the Extensible In-Band Registration ProtoXEP.
Package ibr2 implements the Extensible In-Band Registration ProtoXEP.
Package internal provides non-exported functionality used by xmpp and its child packages.
Package internal provides non-exported functionality used by xmpp and its child packages.
ns
Package ns provides namespace constants that are used by the xmpp package and other internal packages.
Package ns provides namespace constants that are used by the xmpp package and other internal packages.
saslerr
Package saslerr provides error conditions for the XMPP profile of SASL as defined by RFC 6120 §6.5.
Package saslerr provides error conditions for the XMPP profile of SASL as defined by RFC 6120 §6.5.
xmpptest
Package xmpptest provides utilities for XMPP testing.
Package xmpptest provides utilities for XMPP testing.
Package jid implements the XMPP address format.
Package jid implements the XMPP address format.
Package mux implements an XMPP multiplexer.
Package mux implements an XMPP multiplexer.
Package oob implements XEP-0066: Out of Band Data.
Package oob implements XEP-0066: Out of Band Data.
Package ping implements XEP-0199: XMPP Ping.
Package ping implements XEP-0199: XMPP Ping.
Package sasl2 is an experimental implementation of XEP-0388: Extensible SASL Profile.
Package sasl2 is an experimental implementation of XEP-0388: Extensible SASL Profile.
Package stanza contains functionality for dealing with XMPP stanzas and stanza level errors.
Package stanza contains functionality for dealing with XMPP stanzas and stanza level errors.
Package stream contains XMPP stream errors as defined by RFC 6120 §4.9.
Package stream contains XMPP stream errors as defined by RFC 6120 §4.9.
Package x509 parses X.509-encoded keys and certificates.
Package x509 parses X.509-encoded keys and certificates.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL