15 |
15 |
16 // Server is advertising auth mechanisms it supports. Choose one and |
16 // Server is advertising auth mechanisms it supports. Choose one and |
17 // respond. |
17 // respond. |
18 // BUG(cjyar): Doesn't implement TLS/SASL EXTERNAL. |
18 // BUG(cjyar): Doesn't implement TLS/SASL EXTERNAL. |
19 func (cl *Client) chooseSasl(fe *Features) { |
19 func (cl *Client) chooseSasl(fe *Features) { |
20 var digestMd5 bool |
20 var digestMd5, plain bool |
|
21 var mechs []string |
21 for _, m := range fe.Mechanisms.Mechanism { |
22 for _, m := range fe.Mechanisms.Mechanism { |
|
23 mechs = append(mechs, m) |
22 switch strings.ToLower(m) { |
24 switch strings.ToLower(m) { |
23 case "digest-md5": |
25 case "digest-md5": |
24 digestMd5 = true |
26 digestMd5 = true |
|
27 case "plain": |
|
28 plain = true |
25 } |
29 } |
26 } |
30 } |
27 |
31 |
28 if digestMd5 { |
32 if digestMd5 { |
29 auth := &auth{XMLName: xml.Name{Space: NsSASL, Local: "auth"}, |
33 auth := &auth{XMLName: xml.Name{Space: NsSASL, Local: "auth"}, |
30 Mechanism: "DIGEST-MD5"} |
34 Mechanism: "DIGEST-MD5"} |
31 cl.sendRaw <- auth |
35 cl.sendRaw <- auth |
|
36 } else if plain { |
|
37 raw := "\x00" + cl.Jid.Node() + "\x00" + cl.password |
|
38 enc := base64.StdEncoding.EncodeToString([]byte(raw)) |
|
39 auth := &auth{XMLName: xml.Name{Space: NsSASL, Local: "auth"}, |
|
40 Mechanism: "PLAIN", Chardata: enc} |
|
41 cl.sendRaw <- auth |
|
42 } else { |
|
43 cl.setError(fmt.Errorf("No supported auth mechanism in %v", |
|
44 mechs)) |
32 } |
45 } |
33 } |
46 } |
34 |
47 |
35 // Server is responding to our auth request. |
48 // Server is responding to our auth request. |
36 func (cl *Client) handleSasl(srv *auth) { |
49 func (cl *Client) handleSasl(srv *auth) { |