diff --git a/xmpp.go b/xmpp.go
index 73d87d6..629449e 100644
--- a/xmpp.go
+++ b/xmpp.go
@@ -127,6 +127,16 @@ type Options struct {
// from the server. Use "" to let the server generate one for your client.
Resource string
+ // OAuthScope provides go-xmpp the required scope for OAuth2 authentication.
+ OAuthScope string
+
+ // OAuthToken provides go-xmpp with the required OAuth2 token used to authenticate
+ OAuthToken string
+
+ // OAuthXmlNs provides go-xmpp with the required namespaced used for OAuth2 authentication. This is
+ // provided to the server as the xmlns:auth attribute of the OAuth2 authentication request.
+ OAuthXmlNs string
+
// TLS Config
TLSConfig *tls.Config
@@ -163,6 +173,9 @@ func (o Options) NewClient() (*Client, error) {
if err != nil {
return nil, err
}
+ if strings.LastIndex(o.Host, ":") > 0 {
+ host = host[:strings.LastIndex(o.Host, ":")]
+ }
client := new(Client)
if o.NoTLS {
@@ -172,15 +185,12 @@ func (o Options) NewClient() (*Client, error) {
if o.TLSConfig != nil {
tlsconn = tls.Client(c, o.TLSConfig)
} else {
- DefaultConfig.ServerName = strings.Split(o.User, "@")[1]
+ DefaultConfig.ServerName = host
tlsconn = tls.Client(c, &DefaultConfig)
}
if err = tlsconn.Handshake(); err != nil {
return nil, err
}
- if strings.LastIndex(o.Host, ":") > 0 {
- host = host[:strings.LastIndex(o.Host, ":")]
- }
insecureSkipVerify := DefaultConfig.InsecureSkipVerify
if o.TLSConfig != nil {
insecureSkipVerify = o.TLSConfig.InsecureSkipVerify
@@ -274,11 +284,13 @@ func (c *Client) init(o *Options) error {
}
var domain string
+ var user string
a := strings.SplitN(o.User, "@", 2)
if len(o.User) > 0 {
if len(a) != 2 {
return errors.New("xmpp: invalid username (want user@domain): " + o.User)
}
+ user = a[0]
domain = a[1]
} // Otherwise, we'll be attempting ANONYMOUS
@@ -315,19 +327,16 @@ func (c *Client) init(o *Options) error {
mechanism := ""
for _, m := range f.Mechanisms.Mechanism {
- if m == "ANONYMOUS" {
+ if m == "X-OAUTH2" && o.OAuthToken != "" && o.OAuthScope != "" {
mechanism = m
- fmt.Fprintf(c.conn, "\n", nsSASL)
+ // Oauth authentication: send base64-encoded \x00 user \x00 token.
+ raw := "\x00" + user + "\x00" + o.OAuthToken
+ enc := make([]byte, base64.StdEncoding.EncodedLen(len(raw)))
+ base64.StdEncoding.Encode(enc, []byte(raw))
+ fmt.Fprintf(c.conn, "%s\n", nsSASL, o.OAuthXmlNs, enc)
break
}
-
- a := strings.SplitN(o.User, "@", 2)
- if len(a) != 2 {
- return errors.New("xmpp: invalid username (want user@domain): " + o.User)
- }
- user := a[0]
- domain := a[1]
-
if m == "PLAIN" {
mechanism = m
// Plain authentication: send base64-encoded \x00 user \x00 password.
diff --git a/xmpp_ping.go b/xmpp_ping.go
index 88b07cc..05a3a84 100644
--- a/xmpp_ping.go
+++ b/xmpp_ping.go
@@ -1,19 +1,19 @@
package xmpp
import (
- "fmt"
+ "fmt"
)
-func (c* Client) PingC2S(jid, server string) {
- fmt.Fprintf(c.conn, "\n" +
- "\n" +
- "",
- xmlEscape(jid), xmlEscape(server))
+func (c *Client) PingC2S(jid, server string) {
+ fmt.Fprintf(c.conn, "\n"+
+ "\n"+
+ "",
+ xmlEscape(jid), xmlEscape(server))
}
-func (c* Client) PingS2S(fromServer, toServer string) {
- fmt.Fprintf(c.conn, "\n" +
- "\n" +
- "",
- xmlEscape(fromServer), xmlEscape(toServer))
+func (c *Client) PingS2S(fromServer, toServer string) {
+ fmt.Fprintf(c.conn, "\n"+
+ "\n"+
+ "",
+ xmlEscape(fromServer), xmlEscape(toServer))
}
diff --git a/xmpp_subscription.go b/xmpp_subscription.go
index b714c12..eb29314 100644
--- a/xmpp_subscription.go
+++ b/xmpp_subscription.go
@@ -1,20 +1,20 @@
package xmpp
import (
- "fmt"
+ "fmt"
)
-func (c* Client) ApproveSubscription(jid string) {
- fmt.Fprintf(c.conn, "",
- xmlEscape(jid))
+func (c *Client) ApproveSubscription(jid string) {
+ fmt.Fprintf(c.conn, "",
+ xmlEscape(jid))
}
-func (c* Client) RevokeSubscription(jid string) {
- fmt.Fprintf(c.conn, "",
- xmlEscape(jid))
+func (c *Client) RevokeSubscription(jid string) {
+ fmt.Fprintf(c.conn, "",
+ xmlEscape(jid))
}
-func (c* Client) RequestSubscription(jid string) {
- fmt.Fprintf(c.conn, "",
- xmlEscape(jid))
+func (c *Client) RequestSubscription(jid string) {
+ fmt.Fprintf(c.conn, "",
+ xmlEscape(jid))
}