forked from jshiffer/go-xmpp
Add OAuth2 support
Use provided host for certificate verification Remove redundant ANONYMOUS mechanism support
This commit is contained in:
parent
222c8f8fd0
commit
88f429802e
37
xmpp.go
37
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, "<auth xmlns='%s' mechanism='ANONYMOUS' />\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, "<auth xmlns='%s' mechanism='X-OAUTH2' auth:service='oauth2' "+
|
||||
"xmlns:auth='%s'>%s</auth>\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.
|
||||
|
22
xmpp_ping.go
22
xmpp_ping.go
@ -1,19 +1,19 @@
|
||||
package xmpp
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
func (c* Client) PingC2S(jid, server string) {
|
||||
fmt.Fprintf(c.conn, "<iq from='%s' to='%s' id='c2s1' type='get'>\n" +
|
||||
"<ping xmlns='urn:xmpp:ping'/>\n" +
|
||||
"</iq>",
|
||||
xmlEscape(jid), xmlEscape(server))
|
||||
func (c *Client) PingC2S(jid, server string) {
|
||||
fmt.Fprintf(c.conn, "<iq from='%s' to='%s' id='c2s1' type='get'>\n"+
|
||||
"<ping xmlns='urn:xmpp:ping'/>\n"+
|
||||
"</iq>",
|
||||
xmlEscape(jid), xmlEscape(server))
|
||||
}
|
||||
|
||||
func (c* Client) PingS2S(fromServer, toServer string) {
|
||||
fmt.Fprintf(c.conn, "<iq from='%s' to='%s' id='s2s1' type='get'>\n" +
|
||||
"<ping xmlns='urn:xmpp:ping'/>\n" +
|
||||
"</iq>",
|
||||
xmlEscape(fromServer), xmlEscape(toServer))
|
||||
func (c *Client) PingS2S(fromServer, toServer string) {
|
||||
fmt.Fprintf(c.conn, "<iq from='%s' to='%s' id='s2s1' type='get'>\n"+
|
||||
"<ping xmlns='urn:xmpp:ping'/>\n"+
|
||||
"</iq>",
|
||||
xmlEscape(fromServer), xmlEscape(toServer))
|
||||
}
|
||||
|
@ -1,20 +1,20 @@
|
||||
package xmpp
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
func (c* Client) ApproveSubscription(jid string) {
|
||||
fmt.Fprintf(c.conn, "<presence to='%s' type='subscribed'/>",
|
||||
xmlEscape(jid))
|
||||
func (c *Client) ApproveSubscription(jid string) {
|
||||
fmt.Fprintf(c.conn, "<presence to='%s' type='subscribed'/>",
|
||||
xmlEscape(jid))
|
||||
}
|
||||
|
||||
func (c* Client) RevokeSubscription(jid string) {
|
||||
fmt.Fprintf(c.conn, "<presence to='%s' type='unsubscribed'/>",
|
||||
xmlEscape(jid))
|
||||
func (c *Client) RevokeSubscription(jid string) {
|
||||
fmt.Fprintf(c.conn, "<presence to='%s' type='unsubscribed'/>",
|
||||
xmlEscape(jid))
|
||||
}
|
||||
|
||||
func (c* Client) RequestSubscription(jid string) {
|
||||
fmt.Fprintf(c.conn, "<presence to='%s' type='subscribe'/>",
|
||||
xmlEscape(jid))
|
||||
func (c *Client) RequestSubscription(jid string) {
|
||||
fmt.Fprintf(c.conn, "<presence to='%s' type='subscribe'/>",
|
||||
xmlEscape(jid))
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user