forked from jshiffer/go-xmpp
Merge pull request #58 from skiz/master
Add OAuth2 support & Use provided host for certificate verification
This commit is contained in:
commit
84b9ced4e9
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.
|
// from the server. Use "" to let the server generate one for your client.
|
||||||
Resource string
|
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
|
// TLS Config
|
||||||
TLSConfig *tls.Config
|
TLSConfig *tls.Config
|
||||||
|
|
||||||
@ -163,6 +173,9 @@ func (o Options) NewClient() (*Client, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
if strings.LastIndex(o.Host, ":") > 0 {
|
||||||
|
host = host[:strings.LastIndex(o.Host, ":")]
|
||||||
|
}
|
||||||
|
|
||||||
client := new(Client)
|
client := new(Client)
|
||||||
if o.NoTLS {
|
if o.NoTLS {
|
||||||
@ -172,15 +185,12 @@ func (o Options) NewClient() (*Client, error) {
|
|||||||
if o.TLSConfig != nil {
|
if o.TLSConfig != nil {
|
||||||
tlsconn = tls.Client(c, o.TLSConfig)
|
tlsconn = tls.Client(c, o.TLSConfig)
|
||||||
} else {
|
} else {
|
||||||
DefaultConfig.ServerName = strings.Split(o.User, "@")[1]
|
DefaultConfig.ServerName = host
|
||||||
tlsconn = tls.Client(c, &DefaultConfig)
|
tlsconn = tls.Client(c, &DefaultConfig)
|
||||||
}
|
}
|
||||||
if err = tlsconn.Handshake(); err != nil {
|
if err = tlsconn.Handshake(); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if strings.LastIndex(o.Host, ":") > 0 {
|
|
||||||
host = host[:strings.LastIndex(o.Host, ":")]
|
|
||||||
}
|
|
||||||
insecureSkipVerify := DefaultConfig.InsecureSkipVerify
|
insecureSkipVerify := DefaultConfig.InsecureSkipVerify
|
||||||
if o.TLSConfig != nil {
|
if o.TLSConfig != nil {
|
||||||
insecureSkipVerify = o.TLSConfig.InsecureSkipVerify
|
insecureSkipVerify = o.TLSConfig.InsecureSkipVerify
|
||||||
@ -274,11 +284,13 @@ func (c *Client) init(o *Options) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var domain string
|
var domain string
|
||||||
|
var user string
|
||||||
a := strings.SplitN(o.User, "@", 2)
|
a := strings.SplitN(o.User, "@", 2)
|
||||||
if len(o.User) > 0 {
|
if len(o.User) > 0 {
|
||||||
if len(a) != 2 {
|
if len(a) != 2 {
|
||||||
return errors.New("xmpp: invalid username (want user@domain): " + o.User)
|
return errors.New("xmpp: invalid username (want user@domain): " + o.User)
|
||||||
}
|
}
|
||||||
|
user = a[0]
|
||||||
domain = a[1]
|
domain = a[1]
|
||||||
} // Otherwise, we'll be attempting ANONYMOUS
|
} // Otherwise, we'll be attempting ANONYMOUS
|
||||||
|
|
||||||
@ -315,19 +327,16 @@ func (c *Client) init(o *Options) error {
|
|||||||
|
|
||||||
mechanism := ""
|
mechanism := ""
|
||||||
for _, m := range f.Mechanisms.Mechanism {
|
for _, m := range f.Mechanisms.Mechanism {
|
||||||
if m == "ANONYMOUS" {
|
if m == "X-OAUTH2" && o.OAuthToken != "" && o.OAuthScope != "" {
|
||||||
mechanism = m
|
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
|
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" {
|
if m == "PLAIN" {
|
||||||
mechanism = m
|
mechanism = m
|
||||||
// Plain authentication: send base64-encoded \x00 user \x00 password.
|
// Plain authentication: send base64-encoded \x00 user \x00 password.
|
||||||
|
12
xmpp_ping.go
12
xmpp_ping.go
@ -4,16 +4,16 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (c* Client) PingC2S(jid, server string) {
|
func (c *Client) PingC2S(jid, server string) {
|
||||||
fmt.Fprintf(c.conn, "<iq from='%s' to='%s' id='c2s1' type='get'>\n" +
|
fmt.Fprintf(c.conn, "<iq from='%s' to='%s' id='c2s1' type='get'>\n"+
|
||||||
"<ping xmlns='urn:xmpp:ping'/>\n" +
|
"<ping xmlns='urn:xmpp:ping'/>\n"+
|
||||||
"</iq>",
|
"</iq>",
|
||||||
xmlEscape(jid), xmlEscape(server))
|
xmlEscape(jid), xmlEscape(server))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c* Client) PingS2S(fromServer, toServer string) {
|
func (c *Client) PingS2S(fromServer, toServer string) {
|
||||||
fmt.Fprintf(c.conn, "<iq from='%s' to='%s' id='s2s1' type='get'>\n" +
|
fmt.Fprintf(c.conn, "<iq from='%s' to='%s' id='s2s1' type='get'>\n"+
|
||||||
"<ping xmlns='urn:xmpp:ping'/>\n" +
|
"<ping xmlns='urn:xmpp:ping'/>\n"+
|
||||||
"</iq>",
|
"</iq>",
|
||||||
xmlEscape(fromServer), xmlEscape(toServer))
|
xmlEscape(fromServer), xmlEscape(toServer))
|
||||||
}
|
}
|
||||||
|
@ -4,17 +4,17 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (c* Client) ApproveSubscription(jid string) {
|
func (c *Client) ApproveSubscription(jid string) {
|
||||||
fmt.Fprintf(c.conn, "<presence to='%s' type='subscribed'/>",
|
fmt.Fprintf(c.conn, "<presence to='%s' type='subscribed'/>",
|
||||||
xmlEscape(jid))
|
xmlEscape(jid))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c* Client) RevokeSubscription(jid string) {
|
func (c *Client) RevokeSubscription(jid string) {
|
||||||
fmt.Fprintf(c.conn, "<presence to='%s' type='unsubscribed'/>",
|
fmt.Fprintf(c.conn, "<presence to='%s' type='unsubscribed'/>",
|
||||||
xmlEscape(jid))
|
xmlEscape(jid))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c* Client) RequestSubscription(jid string) {
|
func (c *Client) RequestSubscription(jid string) {
|
||||||
fmt.Fprintf(c.conn, "<presence to='%s' type='subscribe'/>",
|
fmt.Fprintf(c.conn, "<presence to='%s' type='subscribe'/>",
|
||||||
xmlEscape(jid))
|
xmlEscape(jid))
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user