golint/gofmt the code

This commit is contained in:
Teoman Soygul 2014-12-13 15:28:57 +01:00
parent 0a3375a6ad
commit 0655f5913b

69
xmpp.go
View File

@ -38,11 +38,13 @@ const (
nsSASL = "urn:ietf:params:xml:ns:xmpp-sasl" nsSASL = "urn:ietf:params:xml:ns:xmpp-sasl"
nsBind = "urn:ietf:params:xml:ns:xmpp-bind" nsBind = "urn:ietf:params:xml:ns:xmpp-bind"
nsClient = "jabber:client" nsClient = "jabber:client"
NsSession = "urn:ietf:params:xml:ns:xmpp-session" nsSession = "urn:ietf:params:xml:ns:xmpp-session"
) )
// Default TLS configuration options
var DefaultConfig tls.Config var DefaultConfig tls.Config
// Cookie is a unique XMPP session identifier
type Cookie uint64 type Cookie uint64
func getCookie() Cookie { func getCookie() Cookie {
@ -53,6 +55,7 @@ func getCookie() Cookie {
return Cookie(binary.LittleEndian.Uint64(buf[:])) return Cookie(binary.LittleEndian.Uint64(buf[:]))
} }
// Client holds XMPP connection opitons
type Client struct { type Client struct {
conn net.Conn // connection to server conn net.Conn // connection to server
jid string // Jabber ID for our connection jid string // Jabber ID for our connection
@ -211,6 +214,7 @@ func NewClient(host, user, passwd string, debug bool) (*Client, error) {
return opts.NewClient() return opts.NewClient()
} }
// NewClientNoTLS creates a new client without TLS
func NewClientNoTLS(host, user, passwd string, debug bool) (*Client, error) { func NewClientNoTLS(host, user, passwd string, debug bool) (*Client, error) {
opts := Options{ opts := Options{
Host: host, Host: host,
@ -223,16 +227,15 @@ func NewClientNoTLS(host, user, passwd string, debug bool) (*Client, error) {
return opts.NewClient() return opts.NewClient()
} }
// Close closes the XMPP connection
func (c *Client) Close() error { func (c *Client) Close() error {
if c.conn != (*tls.Conn)(nil) { if c.conn != (*tls.Conn)(nil) {
return c.conn.Close() return c.conn.Close()
} else { }
return nil return nil
} }
}
func saslDigestResponse(username, realm, passwd, nonce, cnonceStr, func saslDigestResponse(username, realm, passwd, nonce, cnonceStr, authenticate, digestURI, nonceCountStr string) string {
authenticate, digestUri, nonceCountStr string) string {
h := func(text string) []byte { h := func(text string) []byte {
h := md5.New() h := md5.New()
h.Write([]byte(text)) h.Write([]byte(text))
@ -245,12 +248,9 @@ func saslDigestResponse(username, realm, passwd, nonce, cnonceStr,
return h(secret + ":" + data) return h(secret + ":" + data)
} }
a1 := string(h(username+":"+realm+":"+passwd)) + ":" + a1 := string(h(username+":"+realm+":"+passwd)) + ":" + nonce + ":" + cnonceStr
nonce + ":" + cnonceStr a2 := authenticate + ":" + digestURI
a2 := authenticate + ":" + digestUri response := hex(kd(hex(h(a1)), nonce+":"+nonceCountStr+":"+cnonceStr+":auth:"+hex(h(a2))))
response := hex(kd(hex(h(a1)), nonce+":"+
nonceCountStr+":"+cnonceStr+":auth:"+
hex(h(a2))))
return response return response
} }
@ -265,10 +265,11 @@ func cnonce() string {
} }
func (c *Client) init(o *Options) error { func (c *Client) init(o *Options) error {
c.p = xml.NewDecoder(c.conn)
// For debugging: the following causes the plaintext of the connection to be duplicated to stdout.
if o.Debug { if o.Debug {
c.p = xml.NewDecoder(tee{c.conn, os.Stdout}) // For debugging: the following causes the plaintext of the connection to be duplicated to stderr.
c.p = xml.NewDecoder(tee{c.conn, os.Stderr})
} else {
c.p = xml.NewDecoder(c.conn)
} }
a := strings.SplitN(o.User, "@", 2) a := strings.SplitN(o.User, "@", 2)
@ -284,7 +285,7 @@ func (c *Client) init(o *Options) error {
} }
// If the server requires we STARTTLS, attempt to do so. // If the server requires we STARTTLS, attempt to do so.
if f, err = c.startTlsIfRequired(f, o, domain); err != nil { if f, err = c.startTLSIfRequired(f, o, domain); err != nil {
return err return err
} }
@ -316,15 +317,13 @@ func (c *Client) init(o *Options) error {
raw := "\x00" + user + "\x00" + o.Password raw := "\x00" + user + "\x00" + o.Password
enc := make([]byte, base64.StdEncoding.EncodedLen(len(raw))) enc := make([]byte, base64.StdEncoding.EncodedLen(len(raw)))
base64.StdEncoding.Encode(enc, []byte(raw)) base64.StdEncoding.Encode(enc, []byte(raw))
fmt.Fprintf(c.conn, "<auth xmlns='%s' mechanism='PLAIN'>%s</auth>\n", fmt.Fprintf(c.conn, "<auth xmlns='%s' mechanism='PLAIN'>%s</auth>\n", nsSASL, enc)
nsSASL, enc)
break break
} }
if m == "DIGEST-MD5" { if m == "DIGEST-MD5" {
mechanism = m mechanism = m
// Digest-MD5 authentication // Digest-MD5 authentication
fmt.Fprintf(c.conn, "<auth xmlns='%s' mechanism='DIGEST-MD5'/>\n", fmt.Fprintf(c.conn, "<auth xmlns='%s' mechanism='DIGEST-MD5'/>\n", nsSASL)
nsSASL)
var ch saslChallenge var ch saslChallenge
if err = c.p.DecodeElement(&ch, nil); err != nil { if err = c.p.DecodeElement(&ch, nil); err != nil {
return errors.New("unmarshal <challenge>: " + err.Error()) return errors.New("unmarshal <challenge>: " + err.Error())
@ -348,10 +347,11 @@ func (c *Client) init(o *Options) error {
qop, _ := tokens["qop"] qop, _ := tokens["qop"]
charset, _ := tokens["charset"] charset, _ := tokens["charset"]
cnonceStr := cnonce() cnonceStr := cnonce()
digestUri := "xmpp/" + domain digestURI := "xmpp/" + domain
nonceCount := fmt.Sprintf("%08x", 1) nonceCount := fmt.Sprintf("%08x", 1)
digest := saslDigestResponse(user, realm, o.Password, nonce, cnonceStr, "AUTHENTICATE", digestUri, nonceCount) digest := saslDigestResponse(user, realm, o.Password, nonce, cnonceStr, "AUTHENTICATE", digestURI, nonceCount)
message := "username=\"" + user + "\", realm=\"" + realm + "\", nonce=\"" + nonce + "\", cnonce=\"" + cnonceStr + "\", nc=" + nonceCount + ", qop=" + qop + ", digest-uri=\"" + digestUri + "\", response=" + digest + ", charset=" + charset message := "username=\"" + user + "\", realm=\"" + realm + "\", nonce=\"" + nonce + "\", cnonce=\"" + cnonceStr +
"\", nc=" + nonceCount + ", qop=" + qop + ", digest-uri=\"" + digestURI + "\", response=" + digest + ", charset=" + charset
fmt.Fprintf(c.conn, "<response xmlns='%s'>%s</response>\n", nsSASL, base64.StdEncoding.EncodeToString([]byte(message))) fmt.Fprintf(c.conn, "<response xmlns='%s'>%s</response>\n", nsSASL, base64.StdEncoding.EncodeToString([]byte(message)))
@ -368,7 +368,7 @@ func (c *Client) init(o *Options) error {
} }
} }
if mechanism == "" { if mechanism == "" {
return errors.New(fmt.Sprintf("PLAIN authentication is not an option: %v", f.Mechanisms.Mechanism)) return fmt.Errorf("PLAIN authentication is not an option: %v", f.Mechanisms.Mechanism)
} }
// Next message should be either success or failure. // Next message should be either success or failure.
@ -392,7 +392,7 @@ func (c *Client) init(o *Options) error {
return err return err
} }
//Generate uniq cookie // Generate a uniqe cookie
cookie := getCookie() cookie := getCookie()
// Send IQ message asking to bind to the local user name. // Send IQ message asking to bind to the local user name.
@ -412,7 +412,7 @@ func (c *Client) init(o *Options) error {
if o.Session { if o.Session {
//if server support session, open it //if server support session, open it
fmt.Fprintf(c.conn, "<iq to='%s' type='set' id='%x'><session xmlns='%s'/></iq>", xmlEscape(domain), cookie, NsSession) fmt.Fprintf(c.conn, "<iq to='%s' type='set' id='%x'><session xmlns='%s'/></iq>", xmlEscape(domain), cookie, nsSession)
} }
// We're connected and can now receive and send messages. // We're connected and can now receive and send messages.
@ -423,7 +423,7 @@ func (c *Client) init(o *Options) error {
// startTlsIfRequired examines the server's stream features and, if STARTTLS is required or supported, performs the TLS handshake. // startTlsIfRequired examines the server's stream features and, if STARTTLS is required or supported, performs the TLS handshake.
// f will be updated if the handshake completes, as the new stream's features are typically different from the original. // f will be updated if the handshake completes, as the new stream's features are typically different from the original.
func (c *Client) startTlsIfRequired(f *streamFeatures, o *Options, domain string) (*streamFeatures, error) { func (c *Client) startTLSIfRequired(f *streamFeatures, o *Options, domain string) (*streamFeatures, error) {
// whether we start tls is a matter of opinion: the server's and the user's. // whether we start tls is a matter of opinion: the server's and the user's.
switch { switch {
case f.StartTLS == nil: case f.StartTLS == nil:
@ -465,12 +465,13 @@ func (c *Client) startTlsIfRequired(f *streamFeatures, o *Options, domain string
} }
// startStream will start a new XML decoder for the connection, signal the start of a stream to the server and verify that the server has // startStream will start a new XML decoder for the connection, signal the start of a stream to the server and verify that the server has
// also started the stream; if o.Debug is true, startStream will tee decoded XML data to stdout. The features advertised by the server // also started the stream; if o.Debug is true, startStream will tee decoded XML data to stderr. The features advertised by the server
// will be returned. // will be returned.
func (c *Client) startStream(o *Options, domain string) (*streamFeatures, error) { func (c *Client) startStream(o *Options, domain string) (*streamFeatures, error) {
c.p = xml.NewDecoder(c.conn)
if o.Debug { if o.Debug {
c.p = xml.NewDecoder(tee{c.conn, os.Stdout}) c.p = xml.NewDecoder(tee{c.conn, os.Stderr})
} else {
c.p = xml.NewDecoder(c.conn)
} }
_, err := fmt.Fprintf(c.conn, "<?xml version='1.0'?>\n"+ _, err := fmt.Fprintf(c.conn, "<?xml version='1.0'?>\n"+
@ -508,6 +509,7 @@ func (c *Client) IsEncrypted() bool {
return ok return ok
} }
// Chat is an incoming or outgoing XMPP chat message
type Chat struct { type Chat struct {
Remote string Remote string
Type string Type string
@ -515,6 +517,7 @@ type Chat struct {
Other []string Other []string
} }
// Presence is an XMPP presence message
type Presence struct { type Presence struct {
From string From string
To string To string
@ -546,7 +549,7 @@ func (c *Client) Send(chat Chat) (n int, err error) {
xmlEscape(chat.Remote), xmlEscape(chat.Type), xmlEscape(chat.Text)) xmlEscape(chat.Remote), xmlEscape(chat.Type), xmlEscape(chat.Text))
} }
// Send origin // SendOrg sends the original text without being wrapped in an XMPP message stanza.
func (c *Client) SendOrg(org string) (n int, err error) { func (c *Client) SendOrg(org string) (n int, err error) {
return fmt.Fprint(c.conn, org) return fmt.Fprint(c.conn, org)
} }
@ -625,7 +628,7 @@ type bindBind struct {
type clientMessage struct { type clientMessage struct {
XMLName xml.Name `xml:"jabber:client message"` XMLName xml.Name `xml:"jabber:client message"`
From string `xml:"from,attr"` From string `xml:"from,attr"`
Id string `xml:"id,attr"` ID string `xml:"id,attr"`
To string `xml:"to,attr"` To string `xml:"to,attr"`
Type string `xml:"type,attr"` // chat, error, groupchat, headline, or normal Type string `xml:"type,attr"` // chat, error, groupchat, headline, or normal
@ -647,7 +650,7 @@ type clientText struct {
type clientPresence struct { type clientPresence struct {
XMLName xml.Name `xml:"jabber:client presence"` XMLName xml.Name `xml:"jabber:client presence"`
From string `xml:"from,attr"` From string `xml:"from,attr"`
Id string `xml:"id,attr"` ID string `xml:"id,attr"`
To string `xml:"to,attr"` To string `xml:"to,attr"`
Type string `xml:"type,attr"` // error, probe, subscribe, subscribed, unavailable, unsubscribe, unsubscribed Type string `xml:"type,attr"` // error, probe, subscribe, subscribed, unavailable, unsubscribe, unsubscribed
Lang string `xml:"lang,attr"` Lang string `xml:"lang,attr"`
@ -661,7 +664,7 @@ type clientPresence struct {
type clientIQ struct { // info/query type clientIQ struct { // info/query
XMLName xml.Name `xml:"jabber:client iq"` XMLName xml.Name `xml:"jabber:client iq"`
From string `xml:",attr"` From string `xml:",attr"`
Id string `xml:",attr"` ID string `xml:",attr"`
To string `xml:",attr"` To string `xml:",attr"`
Type string `xml:",attr"` // error, get, result, set Type string `xml:",attr"` // error, get, result, set
Error clientError Error clientError