72 p := make([]byte, 1024) |
71 p := make([]byte, 1024) |
73 for { |
72 for { |
74 nr, err := r.Read(p) |
73 nr, err := r.Read(p) |
75 if nr == 0 { |
74 if nr == 0 { |
76 if Log != nil { |
75 if Log != nil { |
77 Log.Err("write: " + err.String()) |
76 Log.Err("write: " + err.Error()) |
78 } |
77 } |
79 break |
78 break |
80 } |
79 } |
81 nw, err := cl.socket.Write(p[:nr]) |
80 nw, err := cl.socket.Write(p[:nr]) |
82 if nw < nr { |
81 if nw < nr { |
83 if Log != nil { |
82 if Log != nil { |
84 Log.Err("write: " + err.String()) |
83 Log.Err("write: " + err.Error()) |
85 } |
84 } |
86 break |
85 break |
87 } |
86 } |
88 } |
87 } |
89 } |
88 } |
90 |
89 |
91 func readXml(r io.Reader, ch chan<- interface{}, |
90 func readXml(r io.Reader, ch chan<- interface{}, |
92 extStanza map[string]func(*xml.Name) interface{}) { |
91 extStanza map[string]func(*xml.Name) interface{}) { |
93 if Loglevel >= syslog.LOG_DEBUG { |
92 if Loglevel >= syslog.LOG_DEBUG { |
94 pr, pw := io.Pipe() |
93 pr, pw := io.Pipe() |
95 go tee(r, pw, "S: ") |
94 go tee(r, pw, "S: ") |
96 r = pr |
95 r = pr |
97 } |
96 } |
155 |
154 |
156 // Read the complete XML stanza. |
155 // Read the complete XML stanza. |
157 err = p.Unmarshal(obj, &se) |
156 err = p.Unmarshal(obj, &se) |
158 if err != nil { |
157 if err != nil { |
159 if Log != nil { |
158 if Log != nil { |
160 Log.Err("unmarshal: " + err.String()) |
159 Log.Err("unmarshal: " + err.Error()) |
161 } |
160 } |
162 break Loop |
161 break Loop |
163 } |
162 } |
164 |
163 |
165 // If it's a Stanza, we try to unmarshal its innerxml |
164 // If it's a Stanza, we try to unmarshal its innerxml |
168 if st, ok := obj.(Stanza); ok { |
167 if st, ok := obj.(Stanza); ok { |
169 err = parseExtended(st, extStanza) |
168 err = parseExtended(st, extStanza) |
170 if err != nil { |
169 if err != nil { |
171 if Log != nil { |
170 if Log != nil { |
172 Log.Err("ext unmarshal: " + |
171 Log.Err("ext unmarshal: " + |
173 err.String()) |
172 err.Error()) |
174 } |
173 } |
175 break Loop |
174 break Loop |
176 } |
175 } |
177 } |
176 } |
178 |
177 |
179 // Put it on the channel. |
178 // Put it on the channel. |
180 ch <- obj |
179 ch <- obj |
181 } |
180 } |
182 } |
181 } |
183 |
182 |
184 func parseExtended(st Stanza, extStanza map[string]func(*xml.Name) interface{}) os.Error { |
183 func parseExtended(st Stanza, extStanza map[string]func(*xml.Name) interface{}) error { |
185 // Now parse the stanza's innerxml to find the string that we |
184 // Now parse the stanza's innerxml to find the string that we |
186 // can unmarshal this nested element from. |
185 // can unmarshal this nested element from. |
187 reader := strings.NewReader(st.innerxml()) |
186 reader := strings.NewReader(st.innerxml()) |
188 p := xml.NewParser(reader) |
187 p := xml.NewParser(reader) |
189 for { |
188 for { |
190 t, err := p.Token() |
189 t, err := p.Token() |
191 if err == os.EOF { |
190 if err == io.EOF { |
192 break |
191 break |
193 } |
192 } |
194 if err != nil { |
193 if err != nil { |
195 return err |
194 return err |
196 } |
195 } |
290 // This loop is paused until resource binding is complete. Otherwise |
289 // This loop is paused until resource binding is complete. Otherwise |
291 // the app might inject something inappropriate into our negotiations |
290 // the app might inject something inappropriate into our negotiations |
292 // with the server. The control channel controls this loop's |
291 // with the server. The control channel controls this loop's |
293 // activity. |
292 // activity. |
294 func writeStream(srvOut chan<- interface{}, cliIn <-chan Stanza, |
293 func writeStream(srvOut chan<- interface{}, cliIn <-chan Stanza, |
295 control <-chan int) { |
294 control <-chan int) { |
296 defer close(srvOut) |
295 defer close(srvOut) |
297 |
296 |
298 var input <-chan Stanza |
297 var input <-chan Stanza |
299 Loop: |
298 Loop: |
300 for { |
299 for { |
325 } |
324 } |
326 |
325 |
327 // Stanzas from the remote go up through a stack of filters to the |
326 // Stanzas from the remote go up through a stack of filters to the |
328 // app. This function manages the filters. |
327 // app. This function manages the filters. |
329 func filterTop(filterOut <-chan <-chan Stanza, filterIn chan<- <-chan Stanza, |
328 func filterTop(filterOut <-chan <-chan Stanza, filterIn chan<- <-chan Stanza, |
330 topFilter <-chan Stanza, app chan<- Stanza) { |
329 topFilter <-chan Stanza, app chan<- Stanza) { |
331 defer close(app) |
330 defer close(app) |
332 Loop: |
331 Loop: |
333 for { |
332 for { |
334 select { |
333 select { |
335 case newFilterOut := <-filterOut: |
334 case newFilterOut := <-filterOut: |
529 randSize := big.NewInt(0) |
528 randSize := big.NewInt(0) |
530 randSize.Lsh(big.NewInt(1), 64) |
529 randSize.Lsh(big.NewInt(1), 64) |
531 cnonce, err := rand.Int(rand.Reader, randSize) |
530 cnonce, err := rand.Int(rand.Reader, randSize) |
532 if err != nil { |
531 if err != nil { |
533 if Log != nil { |
532 if Log != nil { |
534 Log.Err("SASL rand: " + err.String()) |
533 Log.Err("SASL rand: " + err.Error()) |
535 } |
534 } |
536 return |
535 return |
537 } |
536 } |
538 cnonceStr := fmt.Sprintf("%016x", cnonce) |
537 cnonceStr := fmt.Sprintf("%016x", cnonce) |
539 |
538 |
603 return strings.Join(terms, ",") |
602 return strings.Join(terms, ",") |
604 } |
603 } |
605 |
604 |
606 // Computes the response string for digest authentication. |
605 // Computes the response string for digest authentication. |
607 func saslDigestResponse(username, realm, passwd, nonce, cnonceStr, |
606 func saslDigestResponse(username, realm, passwd, nonce, cnonceStr, |
608 authenticate, digestUri, nonceCountStr string) string { |
607 authenticate, digestUri, nonceCountStr string) string { |
609 h := func(text string) []byte { |
608 h := func(text string) []byte { |
610 h := md5.New() |
609 h := md5.New() |
611 h.Write([]byte(text)) |
610 h.Write([]byte(text)) |
612 return h.Sum() |
611 return h.Sum(nil) |
613 } |
612 } |
614 hex := func(bytes []byte) string { |
613 hex := func(bytes []byte) string { |
615 return fmt.Sprintf("%x", bytes) |
614 return fmt.Sprintf("%x", bytes) |
616 } |
615 } |
617 kd := func(secret, data string) []byte { |
616 kd := func(secret, data string) []byte { |