equal
deleted
inserted
replaced
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 |