396 cl.bind(fe.Bind) |
397 cl.bind(fe.Bind) |
397 return |
398 return |
398 } |
399 } |
399 } |
400 } |
400 |
401 |
|
402 // BUG(cjyar): Server certificate is not checked against the provided |
|
403 // hostname. |
|
404 |
401 // readTransport() is running concurrently. We need to stop it, |
405 // readTransport() is running concurrently. We need to stop it, |
402 // negotiate TLS, then start it again. It calls waitForSocket() in |
406 // negotiate TLS, then start it again. It calls waitForSocket() in |
403 // its inner loop; see below. |
407 // its inner loop; see below. |
404 func (cl *Client) handleTls(t *starttls) { |
408 func (cl *Client) handleTls(t *starttls) { |
405 tcp := cl.socket |
409 tcp := cl.socket |
447 |
451 |
448 // Signal that we're going back to the read loop. |
452 // Signal that we're going back to the read loop. |
449 cl.socketSync.Done() |
453 cl.socketSync.Done() |
450 } |
454 } |
451 |
455 |
452 // BUG(cjyar): Doesn't implement TLS/SASL EXTERNAL. |
|
453 func (cl *Client) chooseSasl(fe *Features) { |
456 func (cl *Client) chooseSasl(fe *Features) { |
454 var digestMd5 bool |
457 var digestMd5, external bool |
455 for _, m := range fe.Mechanisms.Mechanism { |
458 for _, m := range fe.Mechanisms.Mechanism { |
456 switch strings.ToLower(m) { |
459 switch strings.ToLower(m) { |
457 case "digest-md5": |
460 case "digest-md5": |
458 digestMd5 = true |
461 digestMd5 = true |
459 } |
462 case "external": |
460 } |
463 external = true |
461 |
464 } |
462 if digestMd5 { |
465 } |
|
466 |
|
467 if external { |
|
468 auth := &auth{XMLName: xml.Name{Space: NsSASL, Local: |
|
469 "auth"}, Mechanism: "EXTERNAL"} |
|
470 cl.xmlOut <- auth |
|
471 } else if digestMd5 { |
463 auth := &auth{XMLName: xml.Name{Space: NsSASL, Local: "auth"}, Mechanism: "DIGEST-MD5"} |
472 auth := &auth{XMLName: xml.Name{Space: NsSASL, Local: "auth"}, Mechanism: "DIGEST-MD5"} |
464 cl.xmlOut <- auth |
473 cl.xmlOut <- auth |
|
474 } else { |
|
475 if Log != nil { |
|
476 buf := bytes.NewBuffer(nil) |
|
477 xml.Marshal(buf, fe) |
|
478 Log.Printf("No supported mechanisms: %s", |
|
479 buf.String()) |
|
480 } |
|
481 abort := Generic{XMLName: xml.Name{Local: "abort", |
|
482 Space: NsSASL}} |
|
483 cl.xmlOut <- abort |
|
484 se := streamError{Any: Generic{XMLName: |
|
485 xml.Name{Local: "undefined-condition", |
|
486 Space: NsStreams}}, Text: |
|
487 &errText{Lang: "en", Text: "No supported mechs"}} |
|
488 cl.xmlOut <- se |
|
489 close(cl.xmlOut) |
465 } |
490 } |
466 } |
491 } |
467 |
492 |
468 func (cl *Client) handleSasl(srv *auth) { |
493 func (cl *Client) handleSasl(srv *auth) { |
469 switch strings.ToLower(srv.XMLName.Local) { |
494 switch strings.ToLower(srv.XMLName.Local) { |
491 case "success": |
516 case "success": |
492 if Log != nil && Loglevel >= syslog.LOG_INFO { |
517 if Log != nil && Loglevel >= syslog.LOG_INFO { |
493 Log.Println("Sasl authentication succeeded") |
518 Log.Println("Sasl authentication succeeded") |
494 } |
519 } |
495 cl.Features = nil |
520 cl.Features = nil |
496 cl.xmlOut <- openStream(cl.Jid) |
521 cl.xmlOut <- openStream(&cl.Jid) |
497 } |
522 } |
498 } |
523 } |
499 |
524 |
500 func (cl *Client) saslDigest1(srvMap map[string]string) { |
525 func (cl *Client) saslDigest1(srvMap map[string]string) { |
501 // Make sure it supports qop=auth |
526 // Make sure it supports qop=auth |
522 nonce := srvMap["nonce"] |
547 nonce := srvMap["nonce"] |
523 digestUri := "xmpp/" + cl.Jid.Domain |
548 digestUri := "xmpp/" + cl.Jid.Domain |
524 nonceCount := int32(1) |
549 nonceCount := int32(1) |
525 nonceCountStr := fmt.Sprintf("%08x", nonceCount) |
550 nonceCountStr := fmt.Sprintf("%08x", nonceCount) |
526 |
551 |
527 // Begin building the response. Username is |
552 // Begin building the response. Username is user (with no |
528 // user@domain or just domain. |
553 // @domain) or just domain. |
529 var username string |
554 var username string |
530 if cl.Jid.Node == "" { |
555 if cl.Jid.Node == "" { |
531 username = cl.Jid.Domain |
556 username = cl.Jid.Domain |
532 } else { |
557 } else { |
533 username = cl.Jid.Node |
558 username = cl.Jid.Node |