xmpp/stream.go
changeset 127 a8f9a0c07fc8
parent 126 367e76b3028e
child 128 8342afcffc92
equal deleted inserted replaced
126:367e76b3028e 127:a8f9a0c07fc8
   303 func handleStream(ss *stream) {
   303 func handleStream(ss *stream) {
   304 }
   304 }
   305 
   305 
   306 func (cl *Client) handleStreamError(se *streamError) {
   306 func (cl *Client) handleStreamError(se *streamError) {
   307 	Info.Logf("Received stream error: %v", se)
   307 	Info.Logf("Received stream error: %v", se)
   308 	close(cl.Out)
   308 	close(cl.Send)
   309 }
   309 }
   310 
   310 
   311 func (cl *Client) handleFeatures(fe *Features) {
   311 func (cl *Client) handleFeatures(fe *Features) {
   312 	cl.Features = fe
   312 	cl.Features = fe
   313 	if fe.Starttls != nil {
   313 	if fe.Starttls != nil {
   314 		start := &starttls{XMLName: xml.Name{Space: NsTLS,
   314 		start := &starttls{XMLName: xml.Name{Space: NsTLS,
   315 			Local: "starttls"}}
   315 			Local: "starttls"}}
   316 		cl.xmlOut <- start
   316 		cl.sendXml <- start
   317 		return
   317 		return
   318 	}
   318 	}
   319 
   319 
   320 	if len(fe.Mechanisms.Mechanism) > 0 {
   320 	if len(fe.Mechanisms.Mechanism) > 0 {
   321 		cl.chooseSasl(fe)
   321 		cl.chooseSasl(fe)
   353 	cl.Features = nil
   353 	cl.Features = nil
   354 
   354 
   355 	// Now re-send the initial handshake message to start the new
   355 	// Now re-send the initial handshake message to start the new
   356 	// session.
   356 	// session.
   357 	hsOut := &stream{To: cl.Jid.Domain, Version: XMPPVersion}
   357 	hsOut := &stream{To: cl.Jid.Domain, Version: XMPPVersion}
   358 	cl.xmlOut <- hsOut
   358 	cl.sendXml <- hsOut
   359 }
   359 }
   360 
   360 
   361 // Synchronize with handleTls(). Called from readTransport() when
   361 // Synchronize with handleTls(). Called from readTransport() when
   362 // cl.socket is nil.
   362 // cl.socket is nil.
   363 func (cl *Client) waitForSocket() {
   363 func (cl *Client) waitForSocket() {
   383 		}
   383 		}
   384 	}
   384 	}
   385 
   385 
   386 	if digestMd5 {
   386 	if digestMd5 {
   387 		auth := &auth{XMLName: xml.Name{Space: NsSASL, Local: "auth"}, Mechanism: "DIGEST-MD5"}
   387 		auth := &auth{XMLName: xml.Name{Space: NsSASL, Local: "auth"}, Mechanism: "DIGEST-MD5"}
   388 		cl.xmlOut <- auth
   388 		cl.sendXml <- auth
   389 	}
   389 	}
   390 }
   390 }
   391 
   391 
   392 func (cl *Client) handleSasl(srv *auth) {
   392 func (cl *Client) handleSasl(srv *auth) {
   393 	switch strings.ToLower(srv.XMLName.Local) {
   393 	switch strings.ToLower(srv.XMLName.Local) {
   409 		Info.Log("SASL authentication failed")
   409 		Info.Log("SASL authentication failed")
   410 	case "success":
   410 	case "success":
   411 		Info.Log("Sasl authentication succeeded")
   411 		Info.Log("Sasl authentication succeeded")
   412 		cl.Features = nil
   412 		cl.Features = nil
   413 		ss := &stream{To: cl.Jid.Domain, Version: XMPPVersion}
   413 		ss := &stream{To: cl.Jid.Domain, Version: XMPPVersion}
   414 		cl.xmlOut <- ss
   414 		cl.sendXml <- ss
   415 	}
   415 	}
   416 }
   416 }
   417 
   417 
   418 func (cl *Client) saslDigest1(srvMap map[string]string) {
   418 func (cl *Client) saslDigest1(srvMap map[string]string) {
   419 	// Make sure it supports qop=auth
   419 	// Make sure it supports qop=auth
   483 
   483 
   484 	// Encode the map and send it.
   484 	// Encode the map and send it.
   485 	clStr := packSasl(clMap)
   485 	clStr := packSasl(clMap)
   486 	b64 := base64.StdEncoding
   486 	b64 := base64.StdEncoding
   487 	clObj := &auth{XMLName: xml.Name{Space: NsSASL, Local: "response"}, Chardata: b64.EncodeToString([]byte(clStr))}
   487 	clObj := &auth{XMLName: xml.Name{Space: NsSASL, Local: "response"}, Chardata: b64.EncodeToString([]byte(clStr))}
   488 	cl.xmlOut <- clObj
   488 	cl.sendXml <- clObj
   489 }
   489 }
   490 
   490 
   491 func (cl *Client) saslDigest2(srvMap map[string]string) {
   491 func (cl *Client) saslDigest2(srvMap map[string]string) {
   492 	if cl.saslExpected == srvMap["rspauth"] {
   492 	if cl.saslExpected == srvMap["rspauth"] {
   493 		clObj := &auth{XMLName: xml.Name{Space: NsSASL, Local: "response"}}
   493 		clObj := &auth{XMLName: xml.Name{Space: NsSASL, Local: "response"}}
   494 		cl.xmlOut <- clObj
   494 		cl.sendXml <- clObj
   495 	} else {
   495 	} else {
   496 		clObj := &auth{XMLName: xml.Name{Space: NsSASL, Local: "failure"}, Any: &Generic{XMLName: xml.Name{Space: NsSASL,
   496 		clObj := &auth{XMLName: xml.Name{Space: NsSASL, Local: "failure"}, Any: &Generic{XMLName: xml.Name{Space: NsSASL,
   497 			Local: "abort"}}}
   497 			Local: "abort"}}}
   498 		cl.xmlOut <- clObj
   498 		cl.sendXml <- clObj
   499 	}
   499 	}
   500 }
   500 }
   501 
   501 
   502 // Takes a string like `key1=value1,key2="value2"...` and returns a
   502 // Takes a string like `key1=value1,key2="value2"...` and returns a
   503 // key/value map.
   503 // key/value map.
   592 		Info.Logf("Bound resource: %s", cl.Jid.String())
   592 		Info.Logf("Bound resource: %s", cl.Jid.String())
   593 		cl.bindDone()
   593 		cl.bindDone()
   594 		return false
   594 		return false
   595 	}
   595 	}
   596 	cl.HandleStanza(msg.Id, f)
   596 	cl.HandleStanza(msg.Id, f)
   597 	cl.xmlOut <- msg
   597 	cl.sendXml <- msg
   598 }
   598 }
   599 
   599 
   600 // Register a callback to handle the next XMPP stanza (iq, message, or
   600 // Register a callback to handle the next XMPP stanza (iq, message, or
   601 // presence) with a given id. The provided function will not be called
   601 // presence) with a given id. The provided function will not be called
   602 // more than once. If it returns false, the stanza will not be made
   602 // more than once. If it returns false, the stanza will not be made