Implement (untested) EXTERNAL auth, and fix bugs from my previous commit.
authorChris Jones <christian.jones@sri.com>
Thu, 19 Jan 2012 22:18:58 -0700
changeset 82 7ce2432dd66a
parent 81 a74e7fc4ecee
child 83 a264cb0129e2
Implement (untested) EXTERNAL auth, and fix bugs from my previous commit.
stream.go
--- a/stream.go	Thu Jan 19 22:32:26 2012 -0600
+++ b/stream.go	Thu Jan 19 22:18:58 2012 -0700
@@ -11,6 +11,7 @@
 package xmpp
 
 import (
+	"bytes"
 	"crypto/md5"
 	"crypto/rand"
 	"crypto/tls"
@@ -398,6 +399,9 @@
 	}
 }
 
+// BUG(cjyar): Server certificate is not checked against the provided
+// hostname.
+
 // readTransport() is running concurrently. We need to stop it,
 // negotiate TLS, then start it again. It calls waitForSocket() in
 // its inner loop; see below.
@@ -430,7 +434,7 @@
 
 	// Now re-send the initial handshake message to start the new
 	// session.
-		hsOut := openStream()
+	hsOut := openStream(&cl.Jid)
 	cl.xmlOut <- hsOut
 }
 
@@ -449,19 +453,40 @@
 	cl.socketSync.Done()
 }
 
-// BUG(cjyar): Doesn't implement TLS/SASL EXTERNAL.
 func (cl *Client) chooseSasl(fe *Features) {
-	var digestMd5 bool
+	var digestMd5, external bool
 	for _, m := range fe.Mechanisms.Mechanism {
 		switch strings.ToLower(m) {
 		case "digest-md5":
 			digestMd5 = true
+		case "external":
+			external = true
 		}
 	}
 
-	if digestMd5 {
+	if external {
+		auth := &auth{XMLName: xml.Name{Space: NsSASL, Local:
+				"auth"}, Mechanism: "EXTERNAL"}
+		cl.xmlOut <- auth
+	} else if digestMd5 {
 		auth := &auth{XMLName: xml.Name{Space: NsSASL, Local: "auth"}, Mechanism: "DIGEST-MD5"}
 		cl.xmlOut <- auth
+	} else {
+		if Log != nil {
+			buf := bytes.NewBuffer(nil)
+			xml.Marshal(buf, fe)
+			Log.Printf("No supported mechanisms: %s",
+				buf.String())
+		}
+		abort := Generic{XMLName: xml.Name{Local: "abort",
+			Space: NsSASL}}
+		cl.xmlOut <- abort
+		se := streamError{Any: Generic{XMLName:
+				xml.Name{Local: "undefined-condition",
+				Space: NsStreams}}, Text:
+			&errText{Lang: "en", Text: "No supported mechs"}}
+		cl.xmlOut <- se
+		close(cl.xmlOut)
 	}
 }
 
@@ -493,7 +518,7 @@
 			Log.Println("Sasl authentication succeeded")
 		}
 		cl.Features = nil
-		cl.xmlOut <- openStream(cl.Jid)
+		cl.xmlOut <- openStream(&cl.Jid)
 	}
 }
 
@@ -524,8 +549,8 @@
 	nonceCount := int32(1)
 	nonceCountStr := fmt.Sprintf("%08x", nonceCount)
 
-	// Begin building the response. Username is
-	// user@domain or just domain.
+	// Begin building the response. Username is user (with no
+	// @domain) or just domain.
 	var username string
 	if cl.Jid.Node == "" {
 		username = cl.Jid.Domain