pijul_org / thrussh

Tokio 0.2, async/await

By pmeunier on February 24, 2020
This patch is not signed.
9awta7AdzhPKoaZnfpwS1E7pC37yFJhhUAVNBctNoXrcdgPx5FgZPEye7QvejVbSSBv8uHtSJNFMdUYvzaLwusrf
This patch is in the following branches:
master
In file Cargo.toml
1
2

3
4
5
6







7
8
9
10
[workspace]

members = [ "thrussh-keys", "thrussh", "thrussh-libsodium", "thrussh-agent", "thrussh-config" ]
members = [ "thrussh-keys", "thrussh", "thrussh-libsodium", "thrussh-config", "cryptovec" ]

[replace]

"thrussh-keys:0.11.1" = { path = "thrussh-keys" }
"thrussh-config:0.1.0" = { path = "thrussh-config" }
"thrussh-config:0.1.0" = { path = "thrussh-config" }
"thrussh-config:0.1.0" = { path = "thrussh-config" }
"thrussh-libsodium:0.1.2" = { path = "thrussh-libsodium" }
"thrussh-libsodium:0.1.2" = { path = "thrussh-libsodium" }
"thrussh-libsodium:0.1.2" = { path = "thrussh-libsodium" }
"thrussh:0.22.0" = { path = "thrussh" }
"thrussh-keys:0.13.0" = { path = "thrussh-keys" }
"thrussh-libsodium:0.1.4" = { path = "thrussh-libsodium" }
"cryptovec:0.5.0" = { path = "cryptovec" }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202

                                 Apache License
                           Version 2.0, January 2004
                        http://www.apache.org/licenses/

   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

   1. Definitions.

      "License" shall mean the terms and conditions for use, reproduction,
      and distribution as defined by Sections 1 through 9 of this document.

      "Licensor" shall mean the copyright owner or entity authorized by
      the copyright owner that is granting the License.

      "Legal Entity" shall mean the union of the acting entity and all
      other entities that control, are controlled by, or are under common
      control with that entity. For the purposes of this definition,
      "control" means (i) the power, direct or indirect, to cause the
      direction or management of such entity, whether by contract or
      otherwise, or (ii) ownership of fifty percent (50%) or more of the
      outstanding shares, or (iii) beneficial ownership of such entity.

      "You" (or "Your") shall mean an individual or Legal Entity
      exercising permissions granted by this License.

      "Source" form shall mean the preferred form for making modifications,
      including but not limited to software source code, documentation
      source, and configuration files.

      "Object" form shall mean any form resulting from mechanical
      transformation or translation of a Source form, including but
      not limited to compiled object code, generated documentation,
      and conversions to other media types.

      "Work" shall mean the work of authorship, whether in Source or
      Object form, made available under the License, as indicated by a
      copyright notice that is included in or attached to the work
      (an example is provided in the Appendix below).

      "Derivative Works" shall mean any work, whether in Source or Object
      form, that is based on (or derived from) the Work and for which the
      editorial revisions, annotations, elaborations, or other modifications
      represent, as a whole, an original work of authorship. For the purposes
      of this License, Derivative Works shall not include works that remain
      separable from, or merely link (or bind by name) to the interfaces of,
      the Work and Derivative Works thereof.

      "Contribution" shall mean any work of authorship, including
      the original version of the Work and any modifications or additions
      to that Work or Derivative Works thereof, that is intentionally
      submitted to Licensor for inclusion in the Work by the copyright owner
      or by an individual or Legal Entity authorized to submit on behalf of
      the copyright owner. For the purposes of this definition, "submitted"
      means any form of electronic, verbal, or written communication sent
      to the Licensor or its representatives, including but not limited to
      communication on electronic mailing lists, source code control systems,
      and issue tracking systems that are managed by, or on behalf of, the
      Licensor for the purpose of discussing and improving the Work, but
      excluding communication that is conspicuously marked or otherwise
      designated in writing by the copyright owner as "Not a Contribution."

      "Contributor" shall mean Licensor and any individual or Legal Entity
      on behalf of whom a Contribution has been received by Licensor and
      subsequently incorporated within the Work.

   2. Grant of Copyright License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      copyright license to reproduce, prepare Derivative Works of,
      publicly display, publicly perform, sublicense, and distribute the
      Work and such Derivative Works in Source or Object form.

   3. Grant of Patent License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      (except as stated in this section) patent license to make, have made,
      use, offer to sell, sell, import, and otherwise transfer the Work,
      where such license applies only to those patent claims licensable
      by such Contributor that are necessarily infringed by their
      Contribution(s) alone or by combination of their Contribution(s)
      with the Work to which such Contribution(s) was submitted. If You
      institute patent litigation against any entity (including a
      cross-claim or counterclaim in a lawsuit) alleging that the Work
      or a Contribution incorporated within the Work constitutes direct
      or contributory patent infringement, then any patent licenses
      granted to You under this License for that Work shall terminate
      as of the date such litigation is filed.

   4. Redistribution. You may reproduce and distribute copies of the
      Work or Derivative Works thereof in any medium, with or without
      modifications, and in Source or Object form, provided that You
      meet the following conditions:

      (a) You must give any other recipients of the Work or
          Derivative Works a copy of this License; and

      (b) You must cause any modified files to carry prominent notices
          stating that You changed the files; and

      (c) You must retain, in the Source form of any Derivative Works
          that You distribute, all copyright, patent, trademark, and
          attribution notices from the Source form of the Work,
          excluding those notices that do not pertain to any part of
          the Derivative Works; and

      (d) If the Work includes a "NOTICE" text file as part of its
          distribution, then any Derivative Works that You distribute must
          include a readable copy of the attribution notices contained
          within such NOTICE file, excluding those notices that do not
          pertain to any part of the Derivative Works, in at least one
          of the following places: within a NOTICE text file distributed
          as part of the Derivative Works; within the Source form or
          documentation, if provided along with the Derivative Works; or,
          within a display generated by the Derivative Works, if and
          wherever such third-party notices normally appear. The contents
          of the NOTICE file are for informational purposes only and
          do not modify the License. You may add Your own attribution
          notices within Derivative Works that You distribute, alongside
          or as an addendum to the NOTICE text from the Work, provided
          that such additional attribution notices cannot be construed
          as modifying the License.

      You may add Your own copyright statement to Your modifications and
      may provide additional or different license terms and conditions
      for use, reproduction, or distribution of Your modifications, or
      for any such Derivative Works as a whole, provided Your use,
      reproduction, and distribution of the Work otherwise complies with
      the conditions stated in this License.

   5. Submission of Contributions. Unless You explicitly state otherwise,
      any Contribution intentionally submitted for inclusion in the Work
      by You to the Licensor shall be under the terms and conditions of
      this License, without any additional terms or conditions.
      Notwithstanding the above, nothing herein shall supersede or modify
      the terms of any separate license agreement you may have executed
      with Licensor regarding such Contributions.

   6. Trademarks. This License does not grant permission to use the trade
      names, trademarks, service marks, or product names of the Licensor,
      except as required for reasonable and customary use in describing the
      origin of the Work and reproducing the content of the NOTICE file.

   7. Disclaimer of Warranty. Unless required by applicable law or
      agreed to in writing, Licensor provides the Work (and each
      Contributor provides its Contributions) on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
      implied, including, without limitation, any warranties or conditions
      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
      PARTICULAR PURPOSE. You are solely responsible for determining the
      appropriateness of using or redistributing the Work and assume any
      risks associated with Your exercise of permissions under this License.

   8. Limitation of Liability. In no event and under no legal theory,
      whether in tort (including negligence), contract, or otherwise,
      unless required by applicable law (such as deliberate and grossly
      negligent acts) or agreed to in writing, shall any Contributor be
      liable to You for damages, including any direct, indirect, special,
      incidental, or consequential damages of any character arising as a
      result of this License or out of the use or inability to use the
      Work (including but not limited to damages for loss of goodwill,
      work stoppage, computer failure or malfunction, or any and all
      other commercial damages or losses), even if such Contributor
      has been advised of the possibility of such damages.

   9. Accepting Warranty or Additional Liability. While redistributing
      the Work or Derivative Works thereof, You may choose to offer,
      and charge a fee for, acceptance of support, warranty, indemnity,
      or other liability obligations and/or rights consistent with this
      License. However, in accepting such obligations, You may act only
      on Your own behalf and on Your sole responsibility, not on behalf
      of any other Contributor, and only if You agree to indemnify,
      defend, and hold each Contributor harmless for any liability
      incurred by, or claims asserted against, such Contributor by reason
      of your accepting any such warranty or additional liability.

   END OF TERMS AND CONDITIONS

   APPENDIX: How to apply the Apache License to your work.

      To apply the Apache License to your work, attach the following
      boilerplate notice, with the fields enclosed by brackets "[]"
      replaced with your own identifying information. (Don't include
      the brackets!)  The text should be enclosed in the appropriate
      comment syntax for the file format. We also recommend that a
      file or class name and description of purpose be included on the
      same "printed page" as the copyright notice for easier
      identification within third-party archives.

   Copyright [yyyy] [name of copyright owner]

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
[package]
name = "cryptovec"
description = "A vector which zeroes its memory on clears and reallocations."
version = "0.5.0"
authors = ["Pierre-Étienne Meunier <pe@pijul.org>"]
repository = "https://pijul.org/cryptovec"
documentation = "https://pijul.org/cryptovec/doc/cryptovec"
license = "Apache-2.0"
include = ["Cargo.toml", "src/lib.rs"]

[dependencies]
libc = "0.2"
winapi = "0.3"
kernel32-sys = "0.2"
1
2
3
4
5
6
7
8
9
10
11
12
13
# Cryptovec

Unswappable byte vectors that get cleared on `drop` (the Rust equivalent of `free`). On resize (`realloc`), the former version also gets cleared.

This is used for example to hold keys and sessions in [Thrussh](//nest.pijul.com/pijul_org/thrussh).

## Contributing

We welcome contributions.

By contributing, you agree to license all your contributions under the Apache 2.0 license.

Moreover, the main platform for contributing is [the Nest](//nest.pijul.com/pijul_org/cryptovec), which is still at an experimental stage. Therefore, even though we do our best to avoid it, our repository might be reset, causing the patches of all contributors to be merged.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
// Copyright 2016 Pierre-Étienne Meunier
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
extern crate libc;
extern crate winapi;
extern crate kernel32;
use libc::{malloc, free, c_void};
#[cfg(not(windows))]
use libc::size_t;
use std::ops::{Index, IndexMut, Deref, DerefMut, Range, RangeFrom, RangeTo, RangeFull};

/// A buffer which zeroes its memory on `.clear()`, `.resize()` and
/// reallocations, to avoid copying secrets around.
#[derive(Debug)]
pub struct CryptoVec {
    p: *mut u8,
    size: usize,
    capacity: usize,
    zero: u8,
}

impl Unpin for CryptoVec {}

unsafe impl Send for CryptoVec {}
unsafe impl Sync for CryptoVec {}

impl AsRef<[u8]> for CryptoVec {
    fn as_ref(&self) -> &[u8] {
        self.deref()
    }
}
impl AsMut<[u8]> for CryptoVec {
    fn as_mut(&mut self) -> &mut [u8] {
        self.deref_mut()
    }
}
impl Deref for CryptoVec {
    type Target = [u8];
    fn deref(&self) -> &[u8] {
        unsafe { std::slice::from_raw_parts(self.p, self.size) }
    }
}
impl DerefMut for CryptoVec {
    fn deref_mut(&mut self) -> &mut [u8] {
        unsafe { std::slice::from_raw_parts_mut(self.p, self.size) }
    }
}

impl Index<RangeFrom<usize>> for CryptoVec {
    type Output = [u8];
    fn index(&self, index: RangeFrom<usize>) -> &[u8] {
        self.deref().index(index)
    }
}
impl Index<RangeTo<usize>> for CryptoVec {
    type Output = [u8];
    fn index(&self, index: RangeTo<usize>) -> &[u8] {
        self.deref().index(index)
    }
}
impl Index<Range<usize>> for CryptoVec {
    type Output = [u8];
    fn index(&self, index: Range<usize>) -> &[u8] {
        self.deref().index(index)
    }
}
impl Index<RangeFull> for CryptoVec {
    type Output = [u8];
    fn index(&self, _: RangeFull) -> &[u8] {
        self.deref()
    }
}
impl IndexMut<RangeFull> for CryptoVec {
    fn index_mut(&mut self, _: RangeFull) -> &mut [u8] {
        self.deref_mut()
    }
}

impl IndexMut<RangeFrom<usize>> for CryptoVec {
    fn index_mut(&mut self, index: RangeFrom<usize>) -> &mut [u8] {
        self.deref_mut().index_mut(index)
    }
}
impl IndexMut<RangeTo<usize>> for CryptoVec {
    fn index_mut(&mut self, index: RangeTo<usize>) -> &mut [u8] {
        self.deref_mut().index_mut(index)
    }
}
impl IndexMut<Range<usize>> for CryptoVec {
    fn index_mut(&mut self, index: Range<usize>) -> &mut [u8] {
        self.deref_mut().index_mut(index)
    }
}


impl Index<usize> for CryptoVec {
    type Output = u8;
    fn index(&self, index: usize) -> &u8 {
        self.deref().index(index)
    }
}

impl std::io::Write for CryptoVec {
    fn write(&mut self, buf: &[u8]) -> Result<usize, std::io::Error> {
        self.extend(buf);
        Ok(buf.len())
    }
    fn flush(&mut self) -> Result<(), std::io::Error> {
        Ok(())
    }
}


impl Default for CryptoVec {
    fn default() -> Self {
        let mut buf = CryptoVec {
            p: std::ptr::null_mut(),
            size: 0,
            capacity: 0,
            zero: 0,
        };
        // This avoids potential problems in as_slice().
        buf.p = &mut buf.zero;
        //
        buf
    }
}

#[cfg(not(windows))]
unsafe fn mlock(ptr: *const u8, len: usize) {
    libc::mlock(ptr as *const c_void, len as size_t);
}
#[cfg(not(windows))]
unsafe fn munlock(ptr: *const u8, len: usize) {
    libc::munlock(ptr as *const c_void, len as size_t);
}

#[cfg(windows)]
use winapi::{LPVOID, SIZE_T};
#[cfg(windows)]
use kernel32::{VirtualLock, VirtualUnlock};
#[cfg(windows)]
unsafe fn mlock(ptr: *const u8, len: usize) {
    VirtualLock(ptr as LPVOID, len as SIZE_T);
}
#[cfg(windows)]
unsafe fn munlock(ptr: *const u8, len: usize) {
    VirtualUnlock(ptr as LPVOID, len as SIZE_T);
}

impl Clone for CryptoVec {
    fn clone(&self) -> Self {
        let mut v = Self::new();
        v.extend(self);
        v
    }
}

impl CryptoVec {
    /// Creates a new `CryptoVec`.
    pub fn new() -> CryptoVec {
        CryptoVec::default()
    }

    /// Length of this `CryptoVec`.
    ///
    /// ```
    /// assert_eq!(cryptovec::CryptoVec::new().len(), 0)
    /// ```
    pub fn len(&self) -> usize {
        self.size
    }

    /// Returns `true` if and only if this CryptoVec is empty.
    ///
    /// ```
    /// assert!(cryptovec::CryptoVec::new().is_empty())
    /// ```
    pub fn is_empty(&self) -> bool {
        self.len() == 0
    }

    /// Resize this CryptoVec, appending zeros at the end. This may
    /// perform at most one reallocation, overwriting the previous
    /// version with zeros.
    pub fn resize(&mut self, size: usize) {
        if size <= self.capacity && size > self.size {
            // If this is an expansion, just resize.
            self.size = size
        } else if size <= self.size {
            // If this is a truncation, resize and erase the extra memory.
            self.size = size;
            unsafe {
                libc::memset(
                    self.p.offset(size as isize) as *mut c_void,
                    0,
                    self.size - size,
                );
            }
        } else {
            // realloc ! and erase the previous memory.
            unsafe {
                let next_capacity = size.next_power_of_two();
                let old_ptr = self.p;
                self.p = malloc(next_capacity) as *mut u8;
                mlock(self.p, next_capacity);

                if self.capacity > 0 {
                    std::ptr::copy_nonoverlapping(old_ptr, self.p, self.size);
                    for i in 0..self.size {
                        std::ptr::write_volatile(old_ptr.offset(i as isize), 0)
                    }
                    munlock(old_ptr, self.size);
                    free(old_ptr as *mut c_void);
                }

                if self.p.is_null() {
                    panic!("Realloc failed, pointer = {:?} {:?}", self, size)
                } else {
                    self.capacity = next_capacity;
                    self.size = size;
                }
            }
        }
    }

    /// Clear this CryptoVec (retaining the memory).
    ///
    /// ```
    /// let mut v = cryptovec::CryptoVec::new();
    /// v.extend(b"blabla");
    /// v.clear();
    /// assert!(v.is_empty())
    /// ```
    pub fn clear(&mut self) {
        self.resize(0);
    }

    /// Append a new byte at the end of this CryptoVec.
    pub fn push(&mut self, s: u8) {
        let size = self.size;
        self.resize(size + 1);
        unsafe { *(self.p.offset(size as isize)) = s }
    }

    /// Append a new u32, big endian-encoded, at the end of this CryptoVec.
    ///
    /// ```
    /// let mut v = cryptovec::CryptoVec::new();
    /// let n = 43554;
    /// v.push_u32_be(n);
    /// assert_eq!(n, v.read_u32_be(0))
    /// ```
    pub fn push_u32_be(&mut self, s: u32) {
        let s = s.to_be();
        let x: [u8; 4] = unsafe { std::mem::transmute(s) };
        self.extend(&x)
    }

    /// Read a big endian-encoded u32 from this CryptoVec, with the
    /// first byte at position `i`.
    ///
    /// ```
    /// let mut v = cryptovec::CryptoVec::new();
    /// let n = 99485710;
    /// v.push_u32_be(n);
    /// assert_eq!(n, v.read_u32_be(0))
    /// ```
    pub fn read_u32_be(&self, i: usize) -> u32 {
        assert!(i + 4 <= self.size);
        let mut x: u32 = 0;
        unsafe {
            libc::memcpy(
                (&mut x) as *mut u32 as *mut c_void,
                self.p.offset(i as isize) as *const c_void,
                4,
            );
        }
        u32::from_be(x)
    }

    /// Read `n_bytes` from `r`, and append them at the end of this
    /// `CryptoVec`. Returns the number of bytes read (and appended).
    pub fn read<R: std::io::Read>(
        &mut self,
        n_bytes: usize,
        mut r: R,
    ) -> Result<usize, std::io::Error> {
        let cur_size = self.size;
        self.resize(cur_size + n_bytes);
        let s =
            unsafe { std::slice::from_raw_parts_mut(self.p.offset(cur_size as isize), n_bytes) };
        // Resize the buffer to its appropriate size.
        match r.read(s) {
            Ok(n) => {
                self.resize(cur_size + n);
                Ok(n)
            }
            Err(e) => {
                self.resize(cur_size);
                Err(e)
            }
        }
    }

    /// Write all this CryptoVec to the provided `Write`. Returns the
    /// number of bytes actually written.
    ///
    /// ```
    /// let mut v = cryptovec::CryptoVec::new();
    /// v.extend(b"blabla");
    /// let mut s = std::io::stdout();
    /// v.write_all_from(0, &mut s).unwrap();
    /// ```
    pub fn write_all_from<W: std::io::Write>(
        &self,
        offset: usize,
        mut w: W,
    ) -> Result<usize, std::io::Error> {
        assert!(offset < self.size);
        // if we're past this point, self.p cannot be null.
        unsafe {
            let s = std::slice::from_raw_parts(self.p.offset(offset as isize), self.size - offset);
            w.write(s)
        }
    }

    /// Resize this CryptoVec, returning a mutable borrow to the extra bytes.
    ///
    /// ```
    /// let mut v = cryptovec::CryptoVec::new();
    /// v.resize_mut(4).clone_from_slice(b"test");
    /// ```
    pub fn resize_mut(&mut self, n: usize) -> &mut [u8] {
        let size = self.size;
        self.resize(size + n);
        unsafe { std::slice::from_raw_parts_mut(self.p.offset(size as isize), n) }
    }

    /// Append a slice at the end of this CryptoVec.
    ///
    /// ```
    /// let mut v = cryptovec::CryptoVec::new();
    /// v.extend(b"test");
    /// ```
    pub fn extend(&mut self, s: &[u8]) {
        let size = self.size;
        self.resize(size + s.len());
        unsafe {
            std::ptr::copy_nonoverlapping(s.as_ptr(), self.p.offset(size as isize), s.len());
        }
    }

    /// Create a `CryptoVec` from a slice
    ///
    /// ```
    /// CryptoVec::from_slice(b"test");
    /// ```
    pub fn from_slice(s: &[u8]) -> CryptoVec {
        let mut v = CryptoVec::new();
        v.resize(s.len());
        unsafe {
            std::ptr::copy_nonoverlapping(s.as_ptr(), v.p, s.len());
        }
        v
    }
}

impl Drop for CryptoVec {
    fn drop(&mut self) {
        if self.capacity > 0 {
            unsafe {
                for i in 0..self.size {
                    std::ptr::write_volatile(self.p.offset(i as isize), 0)
                }
                munlock(self.p, self.size);
                free(self.p as *mut c_void)
            }
        }
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
with import <nixpkgs> {};

let src = fetchFromGitHub {
      owner = "mozilla";
      repo = "nixpkgs-mozilla";
      rev = "36455d54de0b40d9432bba6d8207a5582210b3eb";
      sha256 = "0ll0ws3jpidhrcz70hzq1l46y0bbzm87spw03x4zdpacq0n1yqrn";
   };
in
with import "${src.out}/rust-overlay.nix" pkgs pkgs;

stdenv.mkDerivation {
  name = "rust-pijul";
  buildInputs = [ rustChannels.stable.rust libsodium pkgconfig openssl ];
}
3
4

5
6
7
8
9
10
11


































12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40



41
42
43

44
45
46




47
48
49
50
51
52

53
54
description = "A client and server SSH library."
keywords = ["ssh"]
version = "0.21.5"
version = "0.22.0"
authors = ["Pierre-Étienne Meunier <pe@pijul.org>"]
repository = "https://nest.pijul.com/pijul_org/thrussh"
homepage = "https://pijul.org/thrussh"
documentation = "https://docs.rs/thrussh"
license = "Apache-2.0"
include = [
        "Cargo.toml",
        "src/auth.rs",
        "src/kex.rs",
        "src/key.rs",
        "src/lib.rs",
        "src/msg.rs",
        "src/negotiation.rs",
        "src/pty.rs",
        "src/session.rs",
        "src/sshbuffer.rs",
        "src/ssh_read.rs",
        "src/tcp.rs",
        "src/bin/client.rs",
        "src/bin/server.rs",
        "src/cipher/chacha20poly1305.rs",
        "src/cipher/clear.rs",
        "src/cipher/mod.rs",
        "src/client/mod.rs",
        "src/client/encrypted.rs",
        "src/client/authenticate.rs",
        "src/client/channel_open.rs",
        "src/client/connection.rs",
        "src/client/data.rs",
        "src/client/kex.rs",
        "src/client/session.rs",
        "src/client/wait.rs",
        "src/server/mod.rs",
        "src/server/encrypted.rs",
        "src/server/connection.rs",
        "src/server/kex.rs",
        "src/server/session.rs",
        "src/sodium.rs",
        "src/read_exact_from.rs"
        ]
"Cargo.toml",
"src/auth.rs",
"src/kex.rs",
"src/key.rs",
"src/lib.rs",
"src/msg.rs",
"src/negotiation.rs",
"src/pty.rs",
"src/session.rs",
"src/sshbuffer.rs",
"src/ssh_read.rs",
"src/tcp.rs",
"src/cipher/chacha20poly1305.rs",
"src/cipher/clear.rs",
"src/cipher/mod.rs",
"src/client/mod.rs",
"src/client/session.rs",
"src/client/encrypted.rs",
"src/client/kex.rs",
"src/client/proxy.rs",
"src/server/mod.rs",
"src/server/encrypted.rs",
"src/server/kex.rs",
"src/server/session.rs",
"src/sodium.rs",
]
edition = "2018"

[dependencies]
byteorder = "1.2"
bitflags = "1.0"
bitflags = "1.0"
byteorder = "1.3"
bitflags = "1.2"
log = "0.4"
thrussh-keys = "0.11.3"
thrussh-keys = "0.13.0"
openssl = "0.10"
thrussh-libsodium = "0.1"
cryptovec = "0.4.1"
tokio = "0.1"
tokio-io = "0.1"
futures = "0.1"
cryptovec = "0.5.0"
tokio = { version = "0.2", features = [ "io-util", "rt-threaded", "time", "stream", "tcp", "sync", "macros" ] }
futures = "0.3"
failure = "0.1"

[dev-dependencies]
env_logger = "0.5"
env_logger = "0.7"
tokio = { version = "0.2", features = [ "io-util", "rt-threaded", "time", "stream", "tcp", "sync", "macros" ] }
14
15

16

17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42






43
44
45
46
47

48
49

50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91



92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147

148
149
150
151
//

use thrussh_keys::encoding;
use cryptovec::CryptoVec;
use thrussh_keys::key;
use std::sync::Arc;
use thrussh_keys::encoding;
use thrussh_keys::key;
use tokio::io::{AsyncRead, AsyncWrite};

bitflags! {
    /// Set of methods, represented by bit flags.
    pub struct MethodSet: u32 {
        /// The SSH `none` method (no authentication).
        const NONE = 1;
        /// The SSH `password` method (plaintext passwords).
        const PASSWORD = 2;
        /// The SSH `publickey` method (sign a challenge sent by the
        /// server).
        const PUBLICKEY = 4;
        /// The SSH `hostbased` method (certain hostnames are allowed
        /// by the server).
        const HOSTBASED = 8;
        /// The SSH `keyboard-interactive` method (answer to a
        /// challenge, where the "challenge" can be a password prompt,
        /// a bytestring to sign with a smartcard, or something else).
        const KEYBOARD_INTERACTIVE = 16;
    }
}

macro_rules! iter {
    ( $y:expr, $x:expr ) => {
        {
            if $y.contains($x) {
                $y.remove($x);
                return Some($x)
            }
    ( $y:expr, $x:expr ) => {{
        if $y.contains($x) {
            $y.remove($x);
            return Some($x);
        }
    };
    }};
}


impl Iterator for MethodSet {
    type Item = MethodSet;
    fn next(&mut self) -> Option<MethodSet> {
        iter!(self, MethodSet::NONE);
        iter!(self, MethodSet::PASSWORD);
        iter!(self, MethodSet::PUBLICKEY);
        iter!(self, MethodSet::HOSTBASED);
        iter!(self, MethodSet::KEYBOARD_INTERACTIVE);
        None
    }
}

pub trait Signer<'a> {
    fn auth_publickey_sign(
        &mut self,
        key: &'a key::PublicKey,
        to_sign: &'a mut CryptoVec,
    ) -> std::pin::Pin<Box<dyn futures::Future<Output = Result<(), failure::Error>> + Send + 'a>>;
}

impl<'a, R: AsyncRead + AsyncWrite> Signer<'a> for thrussh_keys::agent::client::AgentClient<R> {
    fn auth_publickey_sign(
        &mut self,
        key: &'a key::PublicKey,
        to_sign: &'a mut CryptoVec,
    ) -> std::pin::Pin<Box<dyn futures::Future<Output = Result<(), failure::Error>> + Send + 'a>>
    {
        futures::FutureExt::boxed(async move {
            thrussh_keys::agent::client::AgentClient::connect_env()
                .await
                .unwrap()
                .sign_request(key, to_sign)
                .await
                .unwrap();
            Ok(())
        })
    }
}

pub enum Method {
    // None,
    Password { password: String },
    PublicKey { key: Arc<key::KeyPair> },
    FuturePublicKey { key: key::PublicKey },
    Password {
        password: String,
    },
    PublicKey {
        key: Arc<key::KeyPair>,
    },
    FuturePublicKey {
        key: key::PublicKey,
        future: Box<dyn for<'a> Signer<'a> + Send>,
    },
    // Hostbased,
}

impl encoding::Bytes for MethodSet {
    fn bytes(&self) -> &'static [u8] {
        match *self {
            MethodSet::NONE => b"none",
            MethodSet::PASSWORD => b"password",
            MethodSet::PUBLICKEY => b"publickey",
            MethodSet::HOSTBASED => b"hostbased",
            MethodSet::KEYBOARD_INTERACTIVE => b"keyboard-interactive",
            _ => b"",
        }
    }
}

impl MethodSet {
    pub(crate) fn from_bytes(b: &[u8]) -> Option<MethodSet> {
        match b {
            b"none" => Some(MethodSet::NONE),
            b"password" => Some(MethodSet::PASSWORD),
            b"publickey" => Some(MethodSet::PUBLICKEY),
            b"hostbased" => Some(MethodSet::HOSTBASED),
            b"keyboard-interactive" => Some(MethodSet::KEYBOARD_INTERACTIVE),
            _ => None,
        }
    }
}

#[doc(hidden)]
#[derive(Debug)]
pub struct AuthRequest {
    pub methods: MethodSet,
    pub partial_success: bool,
    pub current: Option<CurrentRequest>,
    pub rejection_count: usize,
}

#[doc(hidden)]
#[derive(Debug)]
pub enum CurrentRequest {
    PublicKey {
        key: CryptoVec,
        algo: CryptoVec,
        sent_pk_ok: bool,
    },
    KeyboardInteractive { submethods: String },
    KeyboardInteractive {
        submethods: String,
    },
}
18
19
20
21


22


23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49

50
51
52
53
54
55
56
57
58
59
60
61

62
63
64
65
66
67
68
69
70

71
72
73
74
75
76

77
78
79
80
81
82

83
84
85
86
87
88
89
90
91
92
93
94
95
96
97

98
99
100
101
102
103
104


105
106
107
108
109
110
111

112
113
114
115
116
117
118

119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164

165
166
167
168
use super::super::Error;
use byteorder::{BigEndian, ByteOrder};
use sodium::chacha20::{Key, Nonce, KEY_BYTES, NONCE_BYTES};
use sodium::Sodium;
use sodium::chacha20::{KEY_BYTES, NONCE_BYTES, Nonce, Key};
use byteorder::{ByteOrder, BigEndian};

pub struct OpeningKey { k1: Key, k2: Key, sodium: Sodium }
pub struct SealingKey { k1: Key, k2: Key, sodium: Sodium }
pub struct OpeningKey {
    k1: Key,
    k2: Key,
    sodium: Sodium,
}
pub struct SealingKey {
    k1: Key,
    k2: Key,
    sodium: Sodium,
}

const TAG_LEN: usize = 16;

pub static CIPHER: super::Cipher = super::Cipher {
    name: NAME,
    key_len: 64,
    make_sealing_cipher,
    make_opening_cipher,
};

pub const NAME: super::Name = super::Name("chacha20-poly1305@openssh.com");

fn make_sealing_cipher(k: &[u8]) -> super::SealingCipher {
    let mut k1 = Key([0; KEY_BYTES]);
    let mut k2 = Key([0; KEY_BYTES]);
    k1.0.clone_from_slice(&k[KEY_BYTES..]);
    k2.0.clone_from_slice(&k[..KEY_BYTES]);
    super::SealingCipher::Chacha20Poly1305(SealingKey { k1, k2, sodium: Sodium::new() })
    super::SealingCipher::Chacha20Poly1305(SealingKey {
        k1,
        k2,
        sodium: Sodium::new(),
    })
}

fn make_opening_cipher(k: &[u8]) -> super::OpeningCipher {
    let mut k1 = Key([0; KEY_BYTES]);
    let mut k2 = Key([0; KEY_BYTES]);
    k1.0.clone_from_slice(&k[KEY_BYTES..]);
    k2.0.clone_from_slice(&k[..KEY_BYTES]);
    super::OpeningCipher::Chacha20Poly1305(OpeningKey { k1, k2, sodium: Sodium::new() })
    super::OpeningCipher::Chacha20Poly1305(OpeningKey {
        k1,
        k2,
        sodium: Sodium::new(),
    })
}

fn make_counter(sequence_number: u32) -> Nonce {
    let mut nonce = Nonce([0; NONCE_BYTES]);
    let i0 = NONCE_BYTES-4;
    let i0 = NONCE_BYTES - 4;
    BigEndian::write_u32(&mut nonce.0[i0..], sequence_number);
    nonce
}

impl super::OpeningKey for OpeningKey {

    fn decrypt_packet_length(
        &self,
        sequence_number: u32,
        mut encrypted_packet_length: [u8; 4],
    ) -> [u8; 4] {
        let nonce = make_counter(sequence_number);
        self.sodium.chacha20_xor(&mut encrypted_packet_length, &nonce, &self.k1);
        self.sodium
            .chacha20_xor(&mut encrypted_packet_length, &nonce, &self.k1);
        encrypted_packet_length
    }

    fn tag_len(&self) -> usize {
        TAG_LEN
    }

    fn open<'a>(
        &self,
        sequence_number: u32,
        ciphertext_in_plaintext_out: &'a mut [u8],
        tag: &[u8],
    ) -> Result<&'a [u8], Error> {

        let nonce = make_counter(sequence_number);
        {
            use sodium::poly1305::Key;
            let mut poly_key = Key([0; 32]);
            self.sodium.chacha20_xor(&mut poly_key.0, &nonce, &self.k2);
            // let mut tag_ = Tag([0; 16]);
            // tag_.0.clone_from_slice(tag);
            if !self.sodium.poly1305_verify(&tag, ciphertext_in_plaintext_out, &poly_key) {
                return Err(Error::PacketAuth)
            if !self
                .sodium
                .poly1305_verify(&tag, ciphertext_in_plaintext_out, &poly_key)
            {
                return Err(Error::PacketAuth);
            }
        }
        self.sodium.chacha20_xor_ic(&mut ciphertext_in_plaintext_out[4..], &nonce, 1, &self.k2);
        self.sodium
            .chacha20_xor_ic(&mut ciphertext_in_plaintext_out[4..], &nonce, 1, &self.k2);
        Ok(&ciphertext_in_plaintext_out[4..])
    }
}

impl super::SealingKey for SealingKey {

    fn padding_length(&self, payload: &[u8]) -> usize {
        let block_size = 8;
        let extra_len = super::PACKET_LENGTH_LEN + super::PADDING_LENGTH_LEN;
        let padding_len = if payload.len() + extra_len <= super::MINIMUM_PACKET_LEN {
            super::MINIMUM_PACKET_LEN - payload.len() - super::PADDING_LENGTH_LEN
        } else {
            (block_size - ((super::PADDING_LENGTH_LEN + payload.len()) % block_size))
        };
        if padding_len < super::PACKET_LENGTH_LEN {
            padding_len + block_size
        } else {
            padding_len
        }
    }

    // As explained in "SSH via CTR mode with stateful decryption" in
    // https://openvpn.net/papers/ssh-security.pdf, the padding doesn't need to
    // be random because we're doing stateful counter-mode encryption. Use
    // fixed padding to avoid PRNG overhead.
    fn fill_padding(&self, padding_out: &mut [u8]) {
        for padding_byte in padding_out {
            *padding_byte = 0;
        }
    }

    fn tag_len(&self) -> usize {
        TAG_LEN
    }

    /// Append an encrypted packet with contents `packet_content` at the end of `buffer`.
    fn seal(
        &self,
        sequence_number: u32,
        plaintext_in_ciphertext_out: &mut [u8],
        tag_out: &mut [u8],
    ) {
        let mut nonce = make_counter(sequence_number);
        {
            let (a, b) = plaintext_in_ciphertext_out.split_at_mut(4);
            self.sodium.chacha20_xor(a, &nonce, &self.k1);
            self.sodium.chacha20_xor_ic(b, &nonce, 1, &self.k2);
        }
        nonce.0[0] = 0;
        use sodium::poly1305::Key;
        let mut poly_key = Key([0; 32]);
        self.sodium.chacha20_xor(&mut poly_key.0, &nonce, &self.k2);
        let tag = self.sodium.poly1305_auth(plaintext_in_ciphertext_out, &poly_key);
        let tag = self
            .sodium
            .poly1305_auth(plaintext_in_ciphertext_out, &poly_key);
        tag_out.clone_from_slice(&tag.0);
14
15

16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35

//

use Error;
use crate::Error;

#[derive(Debug)]
pub struct Key;

impl super::OpeningKey for Key {
    fn decrypt_packet_length(&self, _seqn: u32, packet_length: [u8; 4]) -> [u8; 4] {
        packet_length
    }

    fn tag_len(&self) -> usize {
        0
    }

    fn open<'a>(
        &self,
        _seqn: u32,
        ciphertext_in_plaintext_out: &'a mut [u8],
        tag: &[u8],
    ) -> Result<&'a [u8], Error> {

13
14




15
16
17
18
19



20
21


22
23
24
25
26
27
28
29
30
31
32
33
34
35
36

37
38
39
40
41
42
43
44
45
46
47
48
49
50

51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73

74
75
76
77
78
79
80
81
82
83

84
85
86
87
88
89
90
91
92
93
94
95
96

97
98
99
100
101
102
103
104
105































106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123

124
125
126
127
128
129
130


















































131
132
133
134
135
136
137









138
139
140
141
142












143
144
145






146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185

// limitations under the License.
//
use byteorder::{ByteOrder, BigEndian};
use Error;
use std;
use sshbuffer::SSHBuffer;
use crate::sshbuffer::SSHBuffer;
use crate::Error;
use byteorder::{BigEndian, ByteOrder};
use std::num::Wrapping;
use tokio::io::AsyncRead;
use read_exact_from::*;
use futures::{Future, Async, Poll};
use std::sync::Arc;
pub mod chacha20poly1305;
pub mod clear;
use cryptovec::CryptoVec;

use tokio::prelude::*;

pub struct Cipher {
    pub name: Name,
    pub key_len: usize,
    pub make_opening_cipher: fn(key: &[u8]) -> OpeningCipher,
    pub make_sealing_cipher: fn(key: &[u8]) -> SealingCipher,
}

pub enum OpeningCipher {
    Clear(clear::Key),
    Chacha20Poly1305(chacha20poly1305::OpeningKey),
}

impl<'a> OpeningCipher {
    fn as_opening_key(&self) -> &OpeningKey {
    fn as_opening_key(&self) -> &dyn OpeningKey {
        match *self {
            OpeningCipher::Clear(ref key) => key,
            OpeningCipher::Chacha20Poly1305(ref key) => key,
        }
    }
}

pub enum SealingCipher {
    Clear(clear::Key),
    Chacha20Poly1305(chacha20poly1305::SealingKey),
}

impl<'a> SealingCipher {
    fn as_sealing_key(&'a self) -> &'a SealingKey {
    fn as_sealing_key(&'a self) -> &'a dyn SealingKey {
        match *self {
            SealingCipher::Clear(ref key) => key,
            SealingCipher::Chacha20Poly1305(ref key) => key,
        }
    }
}

#[derive(Debug, PartialEq, Eq, Copy, Clone)]
pub struct Name(&'static str);
impl AsRef<str> for Name {
    fn as_ref(&self) -> &str {
        self.0
    }
}

pub struct CipherPair {
    pub local_to_remote: SealingCipher,
    pub remote_to_local: OpeningCipher,
}

impl std::fmt::Debug for CipherPair {
    fn fmt(&self, _: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
        Ok(()) // TODO?
        Ok(())
    }
}

pub const CLEAR_PAIR: CipherPair = CipherPair {
    local_to_remote: SealingCipher::Clear(clear::Key),
    remote_to_local: OpeningCipher::Clear(clear::Key),
};

pub trait OpeningKey {

    fn decrypt_packet_length(&self, seqn: u32, encrypted_packet_length: [u8; 4]) -> [u8; 4];

    fn tag_len(&self) -> usize;

    fn open<'a>(
        &self,
        seqn: u32,
        ciphertext_in_plaintext_out: &'a mut [u8],
        tag: &[u8],
    ) -> Result<&'a [u8], Error>;
}

pub trait SealingKey {

    fn padding_length(&self, plaintext: &[u8]) -> usize;

    fn fill_padding(&self, padding_out: &mut [u8]);

    fn tag_len(&self) -> usize;

    fn seal(&self, seqn: u32, plaintext_in_ciphertext_out: &mut [u8], tag_out: &mut [u8]);
}

enum CipherReadState<R: AsyncRead> {
    Len {
        len: ReadExact<R, [u8; 4]>,
        buffer: SSHBuffer,
        pair: Arc<CipherPair>,
    },
    Body {
        body: ReadExact<R, CryptoVec>,
        buffer: SSHBuffer,
        pair: Arc<CipherPair>,
    },
}

pub struct CipherRead<R: AsyncRead>(Option<CipherReadState<R>>);

impl<R: AsyncRead> CipherRead<R> {
    pub fn try_abort(&mut self) -> Option<(R, SSHBuffer)> {
        if let Some(CipherReadState::Len {
                        mut len,
                        buffer,
                        pair,
                    }) = self.0.take()
        {
            // Aborting, and abandoning the 4 bytes of buffer.
            if let Some((r, _)) = len.try_abort() {
                return Some((r, buffer));
            } else {
                self.0 = Some(CipherReadState::Len { len, buffer, pair })
            }
        }
        None
pub async fn read<'a, R: AsyncRead + Unpin>(
    stream: &'a mut R,
    buffer: &'a mut SSHBuffer,
    pair: &'a CipherPair,
) -> Result<usize, failure::Error> {
    let mut len = [0; 4];
    stream.read_exact(&mut len).await?;
    debug!("len = {:?}", len);
    {
        let key = pair.remote_to_local.as_opening_key();
        let seqn = buffer.seqn.0;
        buffer.buffer.clear();
        buffer.buffer.extend(&len);
        let len = key.decrypt_packet_length(seqn, len);
        let len = BigEndian::read_u32(&len) as usize + key.tag_len();
        debug!("clear len = {:?}", len);
        buffer.buffer.resize(len + 4);
    }
}
    stream.read_exact(&mut buffer.buffer[4..]).await?;
    let key = pair.remote_to_local.as_opening_key();
    let seqn = buffer.seqn.0;
    let ciphertext_len = buffer.buffer.len() - key.tag_len();
    let (ciphertext, tag) = buffer.buffer.split_at_mut(ciphertext_len);
    let plaintext = key.open(seqn, ciphertext, tag)?;

impl<R: AsyncRead> Future for CipherRead<R> {
    type Item = (R, SSHBuffer, usize);
    type Error = Error;
    fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
        loop {
            debug!("cipherread poll");
            match self.0.take() {
                None => panic!("future is over"),
                Some(CipherReadState::Len {
                         mut len,
                         mut buffer,
                         pair,
                     }) => {
                    if let Async::Ready((stream, len_)) = len.poll()? {
                        {
                            let key = pair.remote_to_local.as_opening_key();
                            let seqn = buffer.seqn.0;
                            buffer.buffer.clear();
                            buffer.buffer.extend(&len_);
                            let len = key.decrypt_packet_length(seqn, len_);
                            let len = BigEndian::read_u32(&len) as usize + key.tag_len();
                            buffer.buffer.resize(len + 4);
                        }
                        self.0 = Some(CipherReadState::Body {
                            body: read_exact_from(
                                stream,
                                std::mem::replace(&mut buffer.buffer, CryptoVec::new()),
                                4,
                            ),
                            buffer,
                            pair,
                        })
                    } else {
                        self.0 = Some(CipherReadState::Len { len, buffer, pair });
                        return Ok(Async::NotReady);
                    }
                }
                Some(CipherReadState::Body {
                         mut body,
                         mut buffer,
                         pair,
                     }) => {
                    if let Async::Ready((stream, body)) = body.poll()? {
                        let plaintext_end = {
                            buffer.buffer = body;
                            let key = pair.remote_to_local.as_opening_key();
                            let seqn = buffer.seqn.0;
                            let ciphertext_len = buffer.buffer.len() - key.tag_len();
                            let (ciphertext, tag) = buffer.buffer.split_at_mut(ciphertext_len);
                            let plaintext = key.open(seqn, ciphertext, tag)?;
    let padding_length = plaintext[0] as usize;
    debug!("padding_length {:?}", padding_length);
    let plaintext_end = plaintext
        .len()
        .checked_sub(padding_length)
        .ok_or(Error::IndexOutOfBounds)?;

                            let padding_length = plaintext[0] as usize;
                            let plaintext_end = plaintext.len().checked_sub(padding_length).ok_or(
                                Error::IndexOutOfBounds,
                            )?;

                            // Sequence numbers are on 32 bits and wrap.
                            // https://tools.ietf.org/html/rfc4253#section-6.4
                            buffer.seqn += Wrapping(1);
                            buffer.len = 0;
    // Sequence numbers are on 32 bits and wrap.
    // https://tools.ietf.org/html/rfc4253#section-6.4
    buffer.seqn += Wrapping(1);
    buffer.len = 0;

                            plaintext_end
                        };
                        return Ok(Async::Ready((stream, buffer, plaintext_end + 4)));
                    } else {
                        self.0 = Some(CipherReadState::Body { body, buffer, pair });
                        return Ok(Async::NotReady);
                    }
                }
            }
        }
    }
}
    // Remove the padding
    buffer.buffer.resize(plaintext_end + 4);

pub fn read<R: AsyncRead>(stream: R, buffer: SSHBuffer, pair: Arc<CipherPair>) -> CipherRead<R> {
    CipherRead(Some(CipherReadState::Len {
        len: read_exact_from(stream, [0; 4], 0),
        buffer,
        pair,
    }))
    Ok(plaintext_end + 4)
}

impl CipherPair {
    pub fn write(&self, payload: &[u8], buffer: &mut SSHBuffer) {
        // https://tools.ietf.org/html/rfc4253#section-6
        //
        // The variables `payload`, `packet_length` and `padding_length` refer
        // to the protocol fields of the same names.

        let key = self.local_to_remote.as_sealing_key();

        let padding_length = key.padding_length(payload);
        debug!("padding length {:?}", padding_length);
        let packet_length = PADDING_LENGTH_LEN + payload.len() + padding_length;
        debug!("packet_length {:?}", packet_length);
        let offset = buffer.buffer.len();

        // Maximum packet length:
        // https://tools.ietf.org/html/rfc4253#section-6.1
        assert!(packet_length <= std::u32::MAX as usize);
        buffer.buffer.push_u32_be(packet_length as u32);

        assert!(padding_length <= std::u8::MAX as usize);
        buffer.buffer.push(padding_length as u8);
        buffer.buffer.extend(payload);
        key.fill_padding(buffer.buffer.resize_mut(padding_length));
        buffer.buffer.resize_mut(key.tag_len());

        let (plaintext, tag) =
            buffer.buffer[offset..].split_at_mut(PACKET_LENGTH_LEN + packet_length);

        key.seal(buffer.seqn.0, plaintext, tag);

        // Sequence numbers are on 32 bits and wrap.
        // https://tools.ietf.org/html/rfc4253#section-6.4
        buffer.seqn += Wrapping(1);
    }
}































































































use super::connection::Connection;
use tokio::io::{AsyncRead, AsyncWrite};
use super::Handler;
use {HandlerError, Status, AtomicPoll};
use futures::{Poll, Async, Future};
use thrussh_keys::key;
use std::sync::Arc;
use tcp::Tcp;
use auth;

impl<R: AsyncRead + AsyncWrite + Tcp, H: Handler> Connection<R, H> {

    /// Try to authenticate this client using a password.
    pub fn authenticate_password(mut self, user: &str, password: String) -> Authenticate<R, H> {
        let is_waiting = if let Some(ref mut s) = self.session {
            let meth = auth::Method::Password { password };
            s.write_auth_request_if_needed(user, meth)
        } else { false };
        if is_waiting {
            self.abort_read().unwrap_or(());
        }
        Authenticate(Some(self))
    }

    /// Try to authenticate this client using a key pair.
    pub fn authenticate_key(mut self, user: &str, key: Arc<key::KeyPair>) -> Authenticate<R, H> {
        let is_waiting = if let Some(ref mut s) = self.session {
            let meth = auth::Method::PublicKey { key };
            s.write_auth_request_if_needed(user, meth)
        } else { false };
        if is_waiting {
            self.abort_read().unwrap_or(());
        }
        Authenticate(Some(self))
    }

    /// Try to authenticate this client using a key pair.
    pub fn authenticate_key_future(
        mut self,
        user: &str,
        key: key::PublicKey,
    ) -> Authenticate<R, H>
    {
        let is_waiting = if let Some(ref mut s) = self.session {
            let meth = auth::Method::FuturePublicKey { key };
            s.write_auth_request_if_needed(user, meth)
        } else { false };
        if is_waiting {
            self.abort_read().unwrap_or(());
        }
        Authenticate(Some(self))
    }
}

/// An authenticating future, ultimately resolving into an authenticated connection.
pub struct Authenticate<R: AsyncRead + AsyncWrite + Tcp, H: Handler>(Option<Connection<R, H>>);

impl<R: AsyncRead + AsyncWrite + Tcp, H: Handler> Future for Authenticate<R, H> {
    type Item = Connection<R, H>;
    type Error = HandlerError<H::Error>;

    fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
        loop {
            debug!("authenticated loop");
            let done = if let Some(ref c) = self.0 {
                c.is_reading() && {
                    if let Some(ref session) = c.session {
                        session.is_authenticated() || session.0.auth_method.is_none()
                    } else {
                        false
                    }
                }
            } else {
                false
            };
            if done {
                return Ok(Async::Ready(self.0.take().unwrap()))
            }
            let status = if let Some(ref mut c) = self.0 {
                debug!("atomic poll");
                try_ready!(c.atomic_poll())
            } else {
                unreachable!()
            };
            debug!("/atomic poll");

            if let Status::Disconnect = status {
                debug!("disconnect");
                return Ok(Async::Ready(self.0.take().unwrap()));
            }
        }
    }
}































































































































use super::*;
use tokio::io::{AsyncRead, AsyncWrite};
use tcp::Tcp;

impl<R: AsyncRead + AsyncWrite, H: Handler> Connection<R, H> {
    /// Ask the server to open a session channel.
    pub fn channel_open_session(mut self) -> ChannelOpen<R, H, SessionChannel> {
        let num = if let Some(ref mut s) = self.session {
            s.channel_open_session().unwrap()
        } else {
            unreachable!()
        };
        ChannelOpen {
            connection: Some(self),
            channel: num,
            channel_type: PhantomData,
            first_round: true,
        }
    }

    /// Ask the server to open an X11 forwarding channel.
    pub fn channel_open_x11(
        mut self,
        originator_address: &str,
        originator_port: u32,
    ) -> ChannelOpen<R, H, X11Channel> {
        let num = if let Some(ref mut s) = self.session {
            s.channel_open_x11(originator_address, originator_port)
                .unwrap()
        } else {
            unreachable!()
        };
        ChannelOpen {
            connection: Some(self),
            channel: num,
            channel_type: PhantomData,
            first_round: true,
        }
    }

    /// Ask the server to open a direct TCP/IP forwarding channel.
    pub fn channel_open_direct_tcpip(
        mut self,
        host_to_connect: &str,
        port_to_connect: u32,
        originator_address: &str,
        originator_port: u32,
    ) -> ChannelOpen<R, H, DirectTcpIpChannel> {
        let num = if let Some(ref mut s) = self.session {
            s.channel_open_direct_tcpip(
                host_to_connect,
                port_to_connect,
                originator_address,
                originator_port,
            ).unwrap()
        } else {
            unreachable!()
        };
        ChannelOpen {
            connection: Some(self),
            channel: num,
            channel_type: PhantomData,
            first_round: true,
        }
    }
}
use std::marker::PhantomData;

#[doc(hidden)]
pub enum X11Channel {}
#[doc(hidden)]
pub enum SessionChannel {}
#[doc(hidden)]
pub enum DirectTcpIpChannel {}

/// A future resolving into an open channel number of type
/// `ChannelType`, which can be either `SessionChannel`, `X11Channel`
/// or `DirectTcpIdChannel`.
pub struct ChannelOpen<R: AsyncRead + AsyncWrite, H: Handler, ChannelType> {
    connection: Option<Connection<R, H>>,
    channel: ChannelId,
    channel_type: PhantomData<ChannelType>,
    first_round: bool,
}

impl<R: AsyncRead + AsyncWrite + Tcp, H: Handler, ChannelType> Future
    for ChannelOpen<R, H, ChannelType> {
    type Item = (Connection<R, H>, ChannelId);
    type Error = HandlerError<H::Error>;

    fn poll(&mut self) -> Poll<Self::Item, Self::Error> {

        if self.first_round {
            if let Some(ref mut c) = self.connection {
                c.abort_read()?;
            }
            self.first_round = false
        }
        loop {
            debug!("channelopen loop");
            let is_open = if let Some(ref c) = self.connection {
                if let Some(ref s) = c.session {
                    s.channel_is_open(self.channel) && c.is_reading()
                } else {
                    false
                }
            } else {
                false
            };
            if is_open {
                return Ok(Async::Ready(
                    (self.connection.take().unwrap(), self.channel),
                ));
            }

            let status = if let Some(ref mut c) = self.connection {
                try_ready!(c.atomic_poll())
            } else {
                unreachable!()
            };

            if let Status::Disconnect = status {
                return Err(HandlerError::Error(Error::Disconnect));
            }
        }
    }
}
















































































































































































































































































































































































































































































































































































































































































































use super::*;
use cipher;
use msg;
use thrussh_keys::encoding::Reader;
use std::sync::Arc;
use tokio::io::{AsyncRead, AsyncWrite};
use ssh_read::SshRead;
use tcp::Tcp;
use tokio_io;
use tokio::timer::Delay;


pub(crate) enum ConnectionState<R: AsyncRead + AsyncWrite, H: Handler> {
    ReadSshId(SshRead<R>),
    ReadSshId(SshRead<R>),
    WriteSshId(WriteAll<R, CryptoVec>),
    Read(cipher::CipherRead<SshRead<R>>),
    Write(WriteAll<SshRead<R>, CryptoVec>),
    Flush(Flush<SshRead<R>>),
    Pending {
        pending: PendingFuture<H>,
        stream: SshRead<R>,
    },
    Shutdown {
        read: tokio_io::io::Read<SshRead<R>, CryptoVec>,
        read_buffer: SSHBuffer,
    },
}

pub(crate) enum PendingFuture<H: Handler> {
    ServerKeyCheck {
    ServerKeyCheck {
        check: H::FutureBool,
        kexdhdone: KexDhDone,
        buf_len: usize,
        session: Session,
    },
    AgentSign {
        sign: H::FutureSign,
        session: Session,
        request_index: usize,
        buffer_len: usize,
    },
    SessionUnit(H::SessionUnit),
    Done(H, Session),
}

/// Client connection. A connection implements `Future`, returning
/// `()` when it finishes (for instance if the client and server agree
/// to close the connection).
pub struct Connection<R: AsyncRead + AsyncWrite, H: Handler> {
    pub(crate) read_buffer: Option<SSHBuffer>,
    /// Session of this connection.
    /// Session of this connection.
    pub(crate) session: Option<Session>,
    pub(crate) state: Option<ConnectionState<R, H>>,
    pub(crate) buffer: CryptoVec,
    /// Handler for this connection.
    /// Handler for this connection.
    pub(crate) handler: Option<H>,
    pub(crate) timeout: Option<Delay>,
}
}
}


impl<R: AsyncRead + AsyncWrite, H: Handler> std::ops::Deref
    for Connection<R, H> {
    type Target = Session;
    fn deref(&self) -> &Self::Target {
        self.session.as_ref().unwrap()
    }
}

impl<R: AsyncRead + AsyncWrite, H: Handler> std::ops::DerefMut
    for Connection<R, H> {
    fn deref_mut(&mut self) -> &mut Self::Target {
        self.session.as_mut().unwrap()
    }
}

impl<
    R: AsyncRead + AsyncWrite + Tcp,
    H: Handler,
> AtomicPoll<HandlerError<H::Error>> for Connection<R, H> {
    /// Process all packets available in the buffer, and returns
    /// whether the connection should continue.
    fn atomic_poll(&mut self) -> Poll<Status, HandlerError<H::Error>> {

        match self.state.take() {
            None => Ok(Async::Ready(Status::Disconnect)),
            Some(ConnectionState::WriteSshId(mut write)) => {
                if let Async::Ready((stream, mut buf)) = write.poll()? {
                    if let Some(ref mut session) = self.session {
                        buf.clear();
                        session.0.write_buffer.buffer = buf;
                    }
                    self.state = Some(ConnectionState::ReadSshId(SshRead::new(stream)));
                    Ok(Async::Ready(Status::Ok))
                } else {
                    Ok(Async::NotReady)
                }
            }
            Some(ConnectionState::ReadSshId(mut stream)) => {
                let is_ready = if let Async::Ready(sshid) = stream.read_ssh_id()? {
                    self.read_ssh_id(sshid)?;
                    true
                } else {
                    false
                };
                debug!("SSH- read {:?}", is_ready);
                if is_ready {
                    if let Some(ref mut session) = self.session {
                        session.flush()?;
                        self.state = Some(ConnectionState::Write(
                            session.0.write_buffer.write_all(stream),
                        ));
                    }
                    Ok(Async::Ready(Status::Ok))
                } else {
                    self.state = Some(ConnectionState::ReadSshId(stream));
                    Ok(Async::NotReady)
                }
            }
            Some(ConnectionState::Pending { pending, stream }) => {
                debug!("atomic pending");
                self.poll_pending(pending, stream)
            }
            Some(ConnectionState::Write(mut write)) => {
                debug!("atomic writing");
                if let Async::Ready((stream, mut buf)) = write.poll()? {
                    if let Some(ref mut session) = self.session {
                        buf.clear();
                        session.0.write_buffer.buffer = buf;

                        session.flush()?;
                        self.state = Some(ConnectionState::Flush(flush(stream)));
                        Ok(Async::Ready(Status::Ok))
                    } else {
                        unreachable!()
                    }
                } else {
                    self.state = Some(ConnectionState::Write(write));
                    Ok(Async::NotReady)
                }
            }
            Some(ConnectionState::Flush(mut flush)) => {
                debug!("atomic flushing");
                if let Async::Ready(mut stream) = flush.poll()? {

                    if let Some(ref mut session) = self.session {
                        if session.0.disconnected {
                            stream.tcp_shutdown()?;
                            let mut read_buffer = self.read_buffer.take().unwrap();
                            let buffer =
                                std::mem::replace(&mut read_buffer.buffer, CryptoVec::new());
                            self.state = Some(ConnectionState::Shutdown {
                                read: tokio_io::io::read(stream, buffer),
                                read_buffer,
                            });
                        } else {
                            let mut buf = self.read_buffer.take().unwrap();
                            buf.buffer.clear();
                            self.state = Some(ConnectionState::Read(
                                cipher::read(stream, buf, session.0.cipher.clone()),
                            ));
                        }
                    }
                    Ok(Async::Ready(Status::Ok))
                } else {
                    self.state = Some(ConnectionState::Flush(flush));
                    Ok(Async::NotReady)
                }
            }
            Some(ConnectionState::Read(mut read)) => {
                debug!("atomic reading");
                if let Async::Ready((stream, mut buf, end)) = read.poll()? {
                    debug!("buf: {:?}", buf.buffer.as_ref());
                    // Handle the transport layer.
                    if buf.buffer.len() < 5 || buf.buffer[5] == msg::DISCONNECT {
                        // Disconnect.
                        let buffer = std::mem::replace(&mut buf.buffer, CryptoVec::new());
                        self.state = Some(ConnectionState::Shutdown {
                            read: tokio_io::io::read(stream, buffer),
                            read_buffer: buf,
                        });
                        return Ok(Async::Ready(Status::Ok));
                    } else if buf.buffer[5] <= 4 {
                        let session = self.session.as_ref().unwrap();
                        buf.buffer.clear();
                        self.state = Some(ConnectionState::Read(
                            cipher::read(stream, buf, session.0.cipher.clone()),
                        ));
                        return Ok(Async::Ready(Status::Ok));
                    } else {
                        let result = self.read(&buf.buffer[5..end], stream);
                        self.read_buffer = Some(buf);
                        return result;
                    }
                } else {
                    debug!("atomic reading not ready");
                    self.state = Some(ConnectionState::Read(read));
                    Ok(Async::NotReady)
                }
            }
            Some(ConnectionState::Shutdown {
                     mut read,
                     mut read_buffer,
                 }) => {
                debug!("atomic shutdown");
                if let Async::Ready((stream, mut buf, n)) = read.poll()? {
                    if n == 0 {
                        read_buffer.buffer = buf;
                        self.read_buffer = Some(read_buffer);
                        Ok(Async::Ready(Status::Disconnect))
                    } else {
                        buf.clear();
                        self.state = Some(ConnectionState::Shutdown {
                            read: tokio_io::io::read(stream, buf),
                            read_buffer,
                        });
                        Ok(Async::Ready(Status::Ok))
                    }
                } else {
                    self.state = Some(ConnectionState::Shutdown { read, read_buffer });
                    Ok(Async::NotReady)
                }
            }
        }
    }
}


impl<R: AsyncRead + AsyncWrite, H: Handler> Connection<R, H> {
    fn poll_pending(
        &mut self,
        pending: PendingFuture<H>,
        stream: SshRead<R>,
    ) -> Poll<Status, HandlerError<H::Error>> {

        match pending {
            PendingFuture::SessionUnit(mut f) => {
                if let Async::Ready((h, mut session)) = f.poll().map_err(HandlerError::Handler)? {
                    self.handler = Some(h);
                    session.flush()?;
                    self.state = Some(ConnectionState::Write(
                        session.0.write_buffer.write_all(stream),
                    ));
                    self.session = Some(session);
                    Ok(Async::Ready(Status::Ok))
                } else {
                    self.state = Some(ConnectionState::Pending {
                        pending: PendingFuture::SessionUnit(f),
                        stream,
                    });
                    Ok(Async::NotReady)
                }
            }
            PendingFuture::Done(h, mut session) => {
                self.handler = Some(h);
                session.flush()?;
                self.state = Some(ConnectionState::Write(
                    session.0.write_buffer.write_all(stream),
                ));
                self.session = Some(session);
                Ok(Async::Ready(Status::Ok))
            }
            PendingFuture::ServerKeyCheck {
                mut check,
                kexdhdone,
                buf_len,
                mut session,
            } => {
                match check.poll().map_err(HandlerError::Handler)? {
                    Async::Ready((h, true)) => {
                        self.pending_server_key_check(
                            buf_len,
                            kexdhdone,
                            &mut session,
                        )?;
                        self.handler = Some(h);
                        session.flush()?;
                        self.state = Some(ConnectionState::Write(
                            session.0.write_buffer.write_all(stream),
                        ));
                        self.session = Some(session);
                        Ok(Async::Ready(Status::Ok))
                    }
                    Async::Ready((h, false)) => {
                        self.handler = Some(h);
                        session.flush()?;
                        self.state = Some(ConnectionState::Write(
                            session.0.write_buffer.write_all(stream),
                        ));
                        self.session = Some(session);
                        Err(HandlerError::Error(Error::UnknownKey))
                    }
                    Async::NotReady => {
                        self.state = Some(ConnectionState::Pending {
                            pending: PendingFuture::ServerKeyCheck {
                                check: check,
                                kexdhdone: kexdhdone,
                                buf_len: buf_len,
                                session,
                            },
                            stream,
                        });
                        Ok(Async::NotReady)
                    }
                }
            }
            PendingFuture::AgentSign { mut sign, mut session, request_index, buffer_len } => {
                if let Async::Ready((h, signature)) = sign.poll().map_err(HandlerError::Handler)? {

                    if signature.len() != buffer_len {
                        // The buffer was modified.
                        if let Some(ref mut enc) = session.0.encrypted {
                            push_packet!(enc.write, {
                                enc.write.extend(&signature[request_index..]);
                            })
                        }
                    } else {
                        session.0.auth_method = None;
                    }
                    session.0.buffer = Some(signature);
                    session.flush()?;
                    self.state = Some(ConnectionState::Write(
                        session.0.write_buffer.write_all(stream),
                    ));

                    self.handler = Some(h);
                    self.session = Some(session);
                    Ok(Async::Ready(Status::Ok))
                } else {
                    self.state = Some(ConnectionState::Pending {
                        pending: PendingFuture::AgentSign { sign, session, request_index, buffer_len },
                        stream,
                    });
                    Ok(Async::NotReady)
                }
            }
        }
    }

    fn read(
        &mut self,
        buf: &[u8],
        stream: SshRead<R>,
    ) -> Poll<Status, HandlerError<<H as Handler>::Error>> {

        let mut session = self.session.take().unwrap();
        // Handle key exchange/re-exchange.
        match session.0.kex.take() {
            Some(Kex::KexInit(kexinit)) => {
                if kexinit.algo.is_some() || buf[0] == msg::KEXINIT ||
                    session.0.encrypted.is_none()
                {
                    let kexdhdone = kexinit.client_parse(
                        session.0.config.as_ref(),
                        &session.0.cipher,
                        buf,
                        &mut session.0.write_buffer,
                    );
                    match kexdhdone {
                        Ok(kexdhdone) => {
                            session.0.kex = Some(Kex::KexDhDone(kexdhdone));
                            session.flush()?;
                            debug!("calling write_all");
                            self.state = Some(ConnectionState::Write(
                                session.0.write_buffer.write_all(stream),
                            ));
                            self.session = Some(session);
                            return Ok(Async::Ready(Status::Ok));
                        }
                        Err(e) => {
                            self.session = Some(session);
                            return Err(HandlerError::Error(e));
                        }
                    }
                } else {
                    unreachable!()
                }
            }
            Some(Kex::KexDhDone(mut kexdhdone)) => {
                if kexdhdone.names.ignore_guessed {
                    kexdhdone.names.ignore_guessed = false;
                    session.0.kex = Some(Kex::KexDhDone(kexdhdone));
                    session.flush()?;
                    debug!("calling write_all");
                    self.state = Some(ConnectionState::Write(
                        session.0.write_buffer.write_all(stream),
                    ));
                    self.session = Some(session);
                    return Ok(Async::Ready(Status::Ok));
                } else {
                    // We've sent ECDH_INIT, waiting for ECDH_REPLY
                    if buf[0] == msg::KEX_ECDH_REPLY {
                        let mut reader = buf.reader(1);
                        let pubkey = reader.read_string()?; // server public key.
                        let pubkey = parse_public_key(pubkey)?;
                        self.state = Some(ConnectionState::Pending {
                            pending: PendingFuture::ServerKeyCheck {
                                check: self.handler.take().unwrap().check_server_key(&pubkey),
                                kexdhdone: kexdhdone,
                                buf_len: buf.len(),
                                session: session,
                            },
                            stream,
                        });
                        return Ok(Async::Ready(Status::Ok));
                    } else {
                        self.state = Some(ConnectionState::Write(
                            session.0.write_buffer.write_all(stream),
                        ));
                        self.session = Some(session);
                        return Err(HandlerError::Error(Error::Inconsistent));
                    }
                }
            }
            Some(Kex::NewKeys(newkeys)) => {
                if buf[0] != msg::NEWKEYS {
                    return Err(HandlerError::Error(Error::Kex));
                }
                session.0.encrypted(
                    EncryptedState::WaitingServiceRequest,
                    newkeys,
                );
                // Ok, NEWKEYS received, now encrypted.
                let p = b"\x05\0\0\0\x0Cssh-userauth";
                session.0.cipher.write(p, &mut session.0.write_buffer);
                session.flush()?;
                self.state = Some(ConnectionState::Write(
                    session.0.write_buffer.write_all(stream),
                ));
                self.session = Some(session);
                return Ok(Async::Ready(Status::Ok));
            }
            Some(kex) => {
                session.0.kex = Some(kex);
                self.state = Some(ConnectionState::Write(
                    session.0.write_buffer.write_all(stream),
                ));
                self.session = Some(session);
                return Ok(Async::Ready(Status::Ok));
            }
            None => {}
        }
        debug!("atomic poll: take 2");
        self.state = Some(ConnectionState::Pending {
            pending: session.client_read_encrypted(
                self.handler.take().unwrap(),
                &buf
            )?,
            stream,
        });
        Ok(Async::Ready(Status::Ok))
    }
}

impl<R: AsyncRead + AsyncWrite, H: Handler> Connection<R, H> {
    #[doc(hidden)]
    pub fn is_reading(&self) -> bool {
        match self.state {
            Some(ConnectionState::Read(_)) => true,
            _ => false,
        }
    }

    #[doc(hidden)]
    pub fn abort_read(&mut self) -> Result<(), Error> {
        match self.state.take() {
            Some(ConnectionState::Read(mut read)) => {
                if let Some((stream, read_buffer)) = read.try_abort() {
                    self.read_buffer = Some(read_buffer);
                    if let Some(ref mut session) = self.session {
                        session.flush()?;
                    }
                    self.state = Some(ConnectionState::Write(
                        self.session.as_mut().unwrap().0.write_buffer.write_all(
                            stream,
                        ),
                    ))
                } else {
                    self.state = Some(ConnectionState::Read(read))
                }
            }
            st => self.state = st,
        }
        Ok(())
    }

    fn poll_timeout(&mut self) -> Poll<(), HandlerError<H::Error>> {
        if let Some(ref mut timeout) = self.timeout {
            if let Async::Ready(()) = timeout.poll()? {
                debug!("Timeout, shutdown");
                if let Some(ref mut s) = self.session {
                    s.0.disconnected = true;
                }
                return Err(HandlerError::Error(Error::ConnectionTimeout))
            }
        }
        Ok(Async::Ready(()))
    }

    fn pending_server_key_check(
        &mut self,
        buf_len: usize,
        mut kexdhdone: KexDhDone,
        session: &mut Session,
    ) -> Result<(), HandlerError<H::Error>> {

        let hash = {
            let buf = &self.read_buffer.as_ref().unwrap().buffer[5..5 + buf_len];
            let mut reader = buf.reader(1);
            let pubkey = reader.read_string()?; // server public key.
            let pubkey = parse_public_key(pubkey)?;
            debug!("server_public_Key: {:?}", pubkey);
            let server_ephemeral = reader.read_string()?;
            kexdhdone.exchange.server_ephemeral.extend(server_ephemeral);
            let signature = reader.read_string()?;

            kexdhdone.kex.compute_shared_secret(
                &kexdhdone.exchange.server_ephemeral,
            )?;

            let hash = kexdhdone.kex.compute_exchange_hash(
                &pubkey,
                &kexdhdone.exchange,
                &mut self.buffer,
            )?;
            debug!("exchange hash: {:?}", hash);
            let signature = {
                let mut sig_reader = signature.reader(0);
                let sig_type = sig_reader.read_string()?;
                debug!("sig_type: {:?}", sig_type);
                sig_reader.read_string()?
            };
            use thrussh_keys::key::Verify;
            debug!("signature: {:?}", signature);
            assert!(pubkey.verify_server_auth(hash.as_ref(), signature));
            hash
        };
        if let Some(ref mut buffer) = session.0.buffer {
            let mut newkeys = kexdhdone.compute_keys(
                hash,
                &mut self.buffer,
                buffer,
                false,
            )?;
            session.0.cipher.write(
                &[msg::NEWKEYS],
                &mut session.0.write_buffer,
            );
            newkeys.sent = true;
            newkeys.sent = true;
        }
        }
        Ok(())
    }


    /// Ask the server to close a channel, finishing any pending write and read.
    pub fn channel_close(&mut self, channel: ChannelId) {
        if let Some(ref mut s) = self.session {
            s.0.byte(channel, msg::CHANNEL_CLOSE);
        }
    }

    /// Gets a borrow to the connection's handler.
    pub fn handler(&self) -> &H {
        self.handler.as_ref().unwrap()
    }

    /// Gets a mutable borrow to the connection's handler.
    pub fn handler_mut(&mut self) -> &mut H {
        self.handler.as_mut().unwrap()
    }


    /// Tests whether a channel is open.
    pub fn is_channel_open(&self, channel: ChannelId) -> bool {
        if let Some(ref session) = self.session {
            if let Some(ref enc) = session.0.encrypted {
                return enc.channels.contains_key(&channel);
            }
        }
        false
    }


    /// Create a new client connection.
    pub fn new(
        config: Arc<Config>,
        stream: R,
        handler: H,
        timeout: Option<Delay>,
    ) -> Result<Self, Error> {
    ) -> Result<Self, Error> {
        let mut write_buffer = SSHBuffer::new();
        write_buffer.send_ssh_id(config.as_ref().client_id.as_bytes());
        let write = write_buffer.write_all(stream);
        let mut connection = Connection {
            read_buffer: Some(SSHBuffer::new()),
            timeout: timeout,
            session: Some(Session(CommonSession {
                write_buffer: write_buffer,
                kex: None,
                auth_user: String::new(),
                auth_method: None, // Client only.
                cipher: Arc::new(cipher::CLEAR_PAIR),
                encrypted: None,
                config: config,
                wants_reply: false,
                disconnected: false,
                buffer: Some(CryptoVec::new()),
            })),
            state: Some(ConnectionState::WriteSshId(write)),
            handler: Some(handler),
            buffer: CryptoVec::new(),
        };
        if let Some(ref mut s) = connection.session {
            try!(s.flush())
        }
        Ok(connection)
    }

    fn read_ssh_id(&mut self, sshid: &[u8]) -> Result<(), Error> {
    fn read_ssh_id(&mut self, sshid: &[u8]) -> Result<(), Error> {
        // self.read_buffer.bytes += sshid.bytes_read + 2;
        let mut exchange = Exchange::new();
        exchange.server_id.extend(sshid);
        // Preparing the response
        if let Some(ref mut s) = self.session {
            exchange.client_id.extend(
                s.0.config.as_ref().client_id.as_bytes(),
            );
            let mut kexinit = KexInit {
                exchange: exchange,
                algo: None,
                sent: false,
                session_id: None,
            };
            kexinit.client_write(
                s.0.config.as_ref(),
                &mut s.0.cipher,
                &mut s.0.write_buffer,
            )?;
            s.0.kex = Some(Kex::KexInit(kexinit));
        }
        Ok(())
    }
}




impl<R: AsyncRead + AsyncWrite + Tcp, H: Handler> Future for Connection<R, H> {
    type Item = ();
    type Error = HandlerError<H::Error>;

    fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
        // If timeout, shutdown the socket.
        try_ready!(self.poll_timeout()); // returns an error if there's a timeout.
        debug!("no timeout");
        if self.is_reading() {
            // the write buffer is in the connection, we can flush.
            self.flush()?;
            let needs_write = if let Some(ref mut session) = self.session {
                !session.0.write_buffer.buffer.is_empty()
            } else {
                false
            };
            if needs_write {
                self.abort_read()?
            }
        }
        loop {
            debug!("client polling");
            if let Status::Disconnect = try_ready!(self.atomic_poll()) {
                return Ok(Async::Ready(()));
            }
        }
    }
}
            session.0.kex = Some(Kex::NewKeys(newkeys));

unsafe impl<R:AsyncRead+AsyncWrite+Sync, H: Handler+Sync> Sync for Connection<R, H> {}
unsafe impl<R:AsyncRead+AsyncWrite+Send, H: Handler+Send> Send for Connection<R, H> {}











































































































use super::connection::{Connection, ConnectionState};
use tokio::io::{AsyncRead, AsyncWrite};
use super::Handler;
use {ChannelId, HandlerError, Error, Status, AtomicPoll};
use futures::{Poll, Async, Future};
use tcp::Tcp;

impl<R: AsyncRead + AsyncWrite, H: Handler> Connection<R, H> {
    /// Send data to a channel. On session channels, `extended` can be
    /// used to encode standard error by passing `Some(1)`, and stdout
    /// by passing `None`.
    pub fn data<T: AsRef<[u8]>>(
        self,
        channel: ChannelId,
        extended: Option<u32>,
        data: T,
    ) -> Data<R, H, T> {

        debug!("data: {:?}", data.as_ref().len());
        Data {
            connection: Some(self),
            channel: channel,
            extended: extended,
            data: Some(data),
            position: 0,
            first_round: true,
        }
    }
}

/// Future for sending data.
pub struct Data<R: AsyncRead + AsyncWrite, H: Handler, T: AsRef<[u8]>> {
    connection: Option<Connection<R, H>>,
    data: Option<T>,
    extended: Option<u32>,
    channel: ChannelId,
    position: usize,
    first_round: bool,
}

// We are careful here, to leave the connection in the Read state (the
// only cancellable one) before returning Async::Ready.
impl<R: AsyncRead + AsyncWrite + Tcp, H: Handler, T: AsRef<[u8]>> Future for Data<R, H, T> {
    type Item = (Connection<R, H>, T);
    type Error = HandlerError<H::Error>;
    fn poll(&mut self) -> Poll<Self::Item, Self::Error> {

        let mut connection = self.connection.take().unwrap();
        if self.first_round {
            connection.abort_read()?;
            self.first_round = false
        }
        let data = self.data.take().unwrap();

        loop {
            debug!("Data loop");
            // Do everything we can do.
            let status = connection.atomic_poll()?;
            let mut not_ready = false;
            match status {
                Async::Ready(Status::Disconnect) => return Err(From::from(Error::Disconnect)),
                Async::Ready(Status::Ok) if connection.is_reading() => {}
                Async::Ready(Status::Ok) => continue,
                Async::NotReady if connection.is_reading() => not_ready = true,
                Async::NotReady => {
                    self.connection = Some(connection);
                    self.data = Some(data);
                    return Ok(Async::NotReady);
                }
            }

            let mut session = connection.session.take().unwrap();
            {
                let data_ = data.as_ref();
                let enc = session.0.encrypted.as_mut().unwrap();
                self.position += enc.data(self.channel, self.extended, &data_[self.position..]);
            }
            session.flush()?;
            if !session.0.write_buffer.buffer.is_empty() {
                if let Some(ConnectionState::Read(mut read)) = connection.state {
                    if let Some((stream, read_buffer)) = read.try_abort() {
                        connection.read_buffer = Some(read_buffer);
                        connection.state = Some(ConnectionState::Write(
                            session.0.write_buffer.write_all(stream),
                        ));
                        connection.session = Some(session);
                    } else {
                        connection.state = Some(ConnectionState::Read(read));
                        connection.session = Some(session);
                    }
                } else {
                    connection.session = Some(session);
                }
            } else if self.position < data.as_ref().len() {
                connection.session = Some(session);
                if not_ready {
                    self.connection = Some(connection);
                    self.data = Some(data);
                    return Ok(Async::NotReady);
                }
            } else {
                connection.session = Some(session);
                return Ok(Async::Ready((connection, data)));
            }
        }
    }
}
14
15
16
17
18
19
20
21
22
23
24





25
26






27




28
29
30
31





32
33
34
35
36

37
38
39
40
41


42
43
44
45
46




47
48
49



50
51
52
53

54
55
56
57
58
59

60
61
62
63





64
65
66
67
68
69
70
71
72
73
74
75

76
77
78
79
80
81
82
83

84
85
86


87
88


89


90
91
92

93
94
95

96
97

98


99
100
101
102
103
104

105
106
107
108

109
110
111
112
113
114
115
116
117
118
119


120
121
122
123
124
125
126

127
128
129
130
131


132
133
134
135
136
137

















138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169

170
171

172
173
174





175
176
177
















178
179
180
181
182
183



184
185
186
187


188
189
190
191
192






193
194
195
196
197
198
199

200
201
202
203

204
205

206
207
208



209
210
211
212
213


214
215
216
217



218
219
220
221
222




223
224
225
226
227
228





229
230
231
232
233
234
235







236
237
238
239
240
241
242




243
244
245
246
247
248


249
250
251
252
253





254
255
256
257
258
259
260


261
262
263
264
265
266
267


268
269
270
271














272
273
274
275
276
277
278
279
280





281
282
283
284
285





286
287
288
289
290













291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308

309
310
311
312
313
314
315


316
317
318
319

320
321
322
323
324

325
326
327





328
329
330
331
332
333

334
335

336
337
338
339

340
341
342
343
344
345
346

347
348


349
350
351
352

353
354
355
356
357
358
359
360



361
362
363
364
365
366
367
368





369
370
371
372
373
374
375
376

377
378
379
380
381
382
383

384

385
386
387
388
389
390
391
392
393
394
395

396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419

420
421
422
423
424
425
426
427
428
429
430
431
432


433
434
//
use super::Reply;
use crate::auth;
use crate::key::PubKey;
use crate::msg;
use crate::negotiation;
use crate::negotiation::Named;
use crate::negotiation::Select;
use crate::session::*;
use crate::{ChannelId, ChannelOpenFailure, Error, Sig};
use cryptovec::CryptoVec;
use {Sig, Error, HandlerError, ChannelOpenFailure, ChannelId};
use std;
use auth;
use session::*;
use msg;
use std::cell::RefCell;
use thrussh_keys::encoding::{Encoding, Reader};
use negotiation::Named;
use key::PubKey;
use negotiation;
use negotiation::Select;
use super::connection::PendingFuture;
const SSH_CONNECTION: &'static [u8] = b"ssh-connection";

enum ReadEncrypted {
    Authenticated,
    AgentSign(usize),
    None
thread_local! {
    static SIGNATURE_BUFFER: RefCell<CryptoVec> = RefCell::new(CryptoVec::new());
}

impl super::session::Session {
    pub(crate) fn client_read_encrypted<C: super::Handler>(
        mut self,
        mut self,
        client: C,
impl super::Session {
    pub(crate) async fn client_read_encrypted<C: super::Handler>(
        &mut self,
        client: &mut C,
        buf: &[u8],
    ) -> Result<PendingFuture<C>, HandlerError<C::Error>> {
    ) -> Result<(), failure::Error> {
        debug!("client_read_encrypted");
        // Either this packet is a KEXINIT, in which case we start a key re-exchange.
        if buf[0] == msg::KEXINIT {
            // Now, if we're encrypted:
            if let Some(ref mut enc) = self.0.encrypted {

            if let Some(ref mut enc) = self.common.encrypted {
                // If we're not currently rekeying, but buf is a rekey request
                if let Some(exchange) = std::mem::replace(&mut enc.exchange, None) {
                    let kexinit = KexInit::received_rekey(
                        exchange,
                        negotiation::Client::read_kex(
                            buf,
                            &self.0.config.as_ref().preferred,
                        )?,
                        negotiation::Client::read_kex(buf, &self.common.config.as_ref().preferred)?,
                        &enc.session_id,
                    );
                    self.0.kex = Some(Kex::KexDhDone(kexinit.client_parse(
                        self.0.config.as_ref(),
                        &mut self.0.cipher,
                    self.common.kex = Some(Kex::KexDhDone(kexinit.client_parse(
                        self.common.config.as_ref(),
                        &mut self.common.cipher,
                        buf,
                        &mut self.0.write_buffer,
                        &mut self.common.write_buffer,
                    )?));
                }
            } else {
                unreachable!()
            }
            return Ok(PendingFuture::Done(client, self));
            return Ok(());
        }
        // If we've successfully read a packet.
        debug!("buf = {:?}", buf);
        let mut state = ReadEncrypted::None;
        if let Some(ref mut enc) = self.0.encrypted {

            match enc.state.take() {
                 Some(EncryptedState::WaitingServiceRequest) => {
        let mut is_authenticated = false;
        if let Some(ref mut enc) = self.common.encrypted {
            match enc.state {
                EncryptedState::WaitingServiceRequest { ref mut accepted } => {
                    debug!(
                        "waiting service request, {:?} {:?}",
                        buf[0],
                        msg::SERVICE_ACCEPT
                    );
                    if buf[0] == msg::SERVICE_ACCEPT {
                        let mut r = buf.reader(1);
                        if r.read_string()? == b"ssh-userauth" {
                            if let Some(ref meth) = self.0.auth_method {
                            if let Some(ref meth) = self.common.auth_method {
                                let auth_request = auth::AuthRequest {
                                    methods: auth::MethodSet::all(),
                                    partial_success: false,
                                    current: None,
                                    rejection_count: 0,
                                };
                                let len = enc.write.len();
                                if enc.write_auth_request(&self.0.auth_user, meth) {
                                *accepted = true;
                                if enc.write_auth_request(&self.common.auth_user, meth) {
                                    debug!("enc: {:?}", &enc.write[len..]);
                                    enc.state =
                                        Some(EncryptedState::WaitingAuthRequest(auth_request));
                                    enc.state = EncryptedState::WaitingAuthRequest(auth_request)
                                }
                            } else {
                                return Err(HandlerError::Error(Error::NoAuthMethod));
                            }
                        } else {
                            enc.state = Some(EncryptedState::WaitingServiceRequest)
                        }
                    } else {
                        debug!("unknown message: {:?}", buf);
                        return Err(HandlerError::Error(Error::Inconsistent));
                        return Err(Error::Inconsistent.into());
                    }
                }
                Some(EncryptedState::WaitingAuthRequest(mut auth_request)) => {
                EncryptedState::WaitingAuthRequest(ref mut auth_request) => {
                    if buf[0] == msg::USERAUTH_SUCCESS {

                        debug!("userauth_success");
                        enc.state = Some(EncryptedState::Authenticated);

                        self.sender
                            .send(Reply::AuthSuccess)
                            .map_err(|_| Error::SendError)?;
                        enc.state = EncryptedState::Authenticated;
                        return Ok(());
                    } else if buf[0] == msg::USERAUTH_FAILURE {

                        debug!("userauth_failure");

                        let mut r = buf.reader(1);
                        let remaining_methods = r.read_string()?;
                        debug!("remaining methods {:?}", std::str::from_utf8(remaining_methods));
                        debug!(
                            "remaining methods {:?}",
                            std::str::from_utf8(remaining_methods)
                        );
                        auth_request.methods = auth::MethodSet::empty();
                        for method in remaining_methods.split(|&c| c == b',') {
                            if let Some(m) = auth::MethodSet::from_bytes(method) {
                                auth_request.methods |= m
                            }
                        }
                        let no_more_methods = auth_request.methods.is_empty();
                        self.0.auth_method = None;
                        enc.state = Some(EncryptedState::WaitingAuthRequest(auth_request));
                        self.common.auth_method = None;
                        self.sender
                            .send(Reply::AuthFailure)
                            .map_err(|_| Error::SendError)?;

                        // If no other authentication method is allowed by the server, give up.
                        if no_more_methods {
                            return Err(HandlerError::Error(Error::NoAuthMethod));
                            return Err(Error::NoAuthMethod.into());
                        }
                    } else if buf[0] == msg::USERAUTH_PK_OK {
                        debug!("userauth_pk_ok");
                        if let Some(auth::CurrentRequest::PublicKey {
                                        ref mut sent_pk_ok, ..
                                    }) = auth_request.current
                            ref mut sent_pk_ok, ..
                        }) = auth_request.current
                        {
                            *sent_pk_ok = true;
                        }

                        if let Some(ref mut buffer) = self.0.buffer {
                            match self.0.auth_method {
                                Some(ref auth_method @ auth::Method::PublicKey { .. }) =>
                                    enc.client_send_signature(
                                        &self.0.auth_user,
                                        auth_method,
                                        buffer,
                                    )?,
                                Some(auth::Method::FuturePublicKey { ref key }) =>
                                    state = ReadEncrypted::AgentSign(
                                        enc.client_make_to_sign(
                                            &self.0.auth_user,
                                            key,
                                            buffer
                                        )
                                    ),
                                _ => {}
                        match self.common.auth_method.take() {
                            Some(auth_method @ auth::Method::PublicKey { .. }) => {
                                self.common.buffer.clear();
                                enc.client_send_signature(
                                    &self.common.auth_user,
                                    &auth_method,
                                    &mut self.common.buffer,
                                )?
                            }
                            Some(auth::Method::FuturePublicKey { key, mut future }) => {
                                // let mut buffer = std::mem::replace(&mut self.common.buffer, CryptoVec::new());
                                self.common.buffer.clear();
                                let i = enc.client_make_to_sign(
                                    &self.common.auth_user,
                                    &key,
                                    &mut self.common.buffer,
                                );
                                let len = self.common.buffer.len();

                                future
                                    .auth_publickey_sign(&key, &mut self.common.buffer)
                                    .await?;

                                if self.common.buffer.len() != len {
                                    // The buffer was modified.
                                    push_packet!(enc.write, {
                                        enc.write.extend(&self.common.buffer[i..]);
                                    })
                                }
                            }
                            _ => {}
                        }
                        enc.state = Some(EncryptedState::WaitingAuthRequest(auth_request));
                    } else {
                        debug!("unknown message: {:?}", buf);
                        return Err(HandlerError::Error(Error::Inconsistent));
                        return Err(Error::Inconsistent.into());
                    }
                }
                Some(EncryptedState::Authenticated) => {
                    enc.state = Some(EncryptedState::Authenticated);
                    state = ReadEncrypted::Authenticated
                }
                None => unreachable!(),
                EncryptedState::Authenticated => is_authenticated = true,
            }
        }
        match state {
            ReadEncrypted::Authenticated => {
                self.client_read_authenticated(client, buf)
            },
            ReadEncrypted::AgentSign(request_index) => {
                let (sign, buffer_len) = match self.0.auth_method {
                    Some(auth::Method::FuturePublicKey { ref key }) => {
                        let buf = self.0.buffer.take().unwrap();
                        let len = buf.len();
                        (client.auth_publickey_sign(key, buf), len)
                    },
                    _ => unreachable!()
                };
                Ok(PendingFuture::AgentSign { sign, session: self, request_index, buffer_len })
            }
            ReadEncrypted::None => Ok(PendingFuture::Done(client, self))
        if is_authenticated {
            self.client_read_authenticated(client, buf).await?
        }
        Ok(())
    }

    fn client_read_authenticated<C: super::Handler>(
        mut self,
        client: C,
    async fn client_read_authenticated<C: super::Handler>(
        &mut self,
        client: &mut C,
        buf: &[u8],
    ) -> Result<PendingFuture<C>, HandlerError<C::Error>> {

    ) -> Result<(), failure::Error> {
        match buf[0] {
            msg::CHANNEL_OPEN_CONFIRMATION => {
                debug!("channel_open_confirmation");
                let mut reader = buf.reader(1);
                let id_send = ChannelId(try!(reader.read_u32()));
                let id_recv = try!(reader.read_u32());
                let window = try!(reader.read_u32());
                let max_packet = try!(reader.read_u32());

                if let Some(ref mut enc) = self.0.encrypted {
                let id_send = ChannelId(reader.read_u32()?);
                let id_recv = reader.read_u32()?;
                let window = reader.read_u32()?;
                let max_packet = reader.read_u32()?;

                if let Some(ref mut enc) = self.common.encrypted {
                    if let Some(parameters) = enc.channels.get_mut(&id_send) {

                        parameters.recipient_channel = id_recv;
                        parameters.recipient_window_size = window;
                        parameters.recipient_maximum_packet_size = max_packet;
                        parameters.confirmed = true;

                    } else {
                        // We've not requested this channel, close connection.
                        return Err(HandlerError::Error(Error::Inconsistent));
                        return Err(Error::Inconsistent.into());
                    }
                }
                Ok(PendingFuture::SessionUnit(
                    client.channel_open_confirmation(id_send, self),
                ))
                client.channel_open_confirmation(id_send, self).await
            }
            msg::CHANNEL_CLOSE => {
                debug!("channel_close");
                let mut r = buf.reader(1);
                let channel_num = ChannelId(try!(r.read_u32()));
                if let Some(ref mut enc) = self.0.encrypted {
                let channel_num = ChannelId(r.read_u32()?);
                if let Some(ref mut enc) = self.common.encrypted {
                    enc.channels.remove(&channel_num);
                }
                Ok(PendingFuture::SessionUnit(
                    client.channel_close(channel_num, self),
                ))
                client.channel_close(channel_num, self).await
            }
            msg::CHANNEL_EOF => {
                debug!("channel_close");
                let mut r = buf.reader(1);
                let channel_num = ChannelId(try!(r.read_u32()));
                Ok(PendingFuture::SessionUnit(
                    client.channel_eof(channel_num, self),
                ))
                let channel_num = ChannelId(r.read_u32()?);
                client.channel_eof(channel_num, self).await
            }
            msg::CHANNEL_OPEN_FAILURE => {
                debug!("channel_open_failure");
                let mut r = buf.reader(1);
                let channel_num = ChannelId(try!(r.read_u32()));
                let reason_code = ChannelOpenFailure::from_u32(try!(r.read_u32())).unwrap();
                let descr = try!(std::str::from_utf8(try!(r.read_string())));
                let language = try!(std::str::from_utf8(try!(r.read_string())));
                if let Some(ref mut enc) = self.0.encrypted {
                let channel_num = ChannelId(r.read_u32()?);
                let reason_code = ChannelOpenFailure::from_u32(r.read_u32()?).unwrap();
                let descr = std::str::from_utf8(r.read_string()?)?;
                let language = std::str::from_utf8(r.read_string()?)?;
                if let Some(ref mut enc) = self.common.encrypted {
                    enc.channels.remove(&channel_num);
                }
                Ok(PendingFuture::SessionUnit(client.channel_open_failure(
                    channel_num,
                    reason_code,
                    descr,
                    language,
                    self,
                )))
                client
                    .channel_open_failure(channel_num, reason_code, descr, language, self)
                    .await
            }
            msg::CHANNEL_DATA => {
                debug!("channel_data");
                let mut r = buf.reader(1);
                let channel_num = ChannelId(try!(r.read_u32()));
                let data = try!(r.read_string());
                let target = self.0.config.window_size;
                if let Some(ref mut enc) = self.0.encrypted {
                let channel_num = ChannelId(r.read_u32()?);
                let data = r.read_string()?;
                let target = self.common.config.window_size;
                if let Some(ref mut enc) = self.common.encrypted {
                    enc.adjust_window_size(channel_num, data, target);
                }
                let unit = client.data(channel_num, None, &data, self);
                Ok(PendingFuture::SessionUnit(unit))
                client.data(channel_num, &data, self).await
            }
            msg::CHANNEL_EXTENDED_DATA => {
                debug!("channel_extended_data");
                let mut r = buf.reader(1);
                let channel_num = ChannelId(try!(r.read_u32()));
                let extended_code = try!(r.read_u32());
                let data = try!(r.read_string());
                let target = self.0.config.window_size;
                if let Some(ref mut enc) = self.0.encrypted {
                let channel_num = ChannelId(r.read_u32()?);
                let extended_code = r.read_u32()?;
                let data = r.read_string()?;
                let target = self.common.config.window_size;
                if let Some(ref mut enc) = self.common.encrypted {
                    enc.adjust_window_size(channel_num, data, target);
                }
                let unit = client.data(channel_num, Some(extended_code), &data, self);
                Ok(PendingFuture::SessionUnit(unit))
                client
                    .extended_data(channel_num, extended_code, &data, self)
                    .await
            }
            msg::CHANNEL_REQUEST => {
                debug!("channel_request");
                let mut r = buf.reader(1);
                let channel_num = ChannelId(try!(r.read_u32()));
                let req = try!(r.read_string());
                let channel_num = ChannelId(r.read_u32()?);
                let req = r.read_string()?;
                match req {
                    b"forwarded_tcpip" => {
                        let a = try!(std::str::from_utf8(try!(r.read_string())));
                        let b = try!(r.read_u32());
                        let c = try!(std::str::from_utf8(try!(r.read_string())));
                        let d = try!(r.read_u32());
                        Ok(PendingFuture::SessionUnit(
                            client.channel_open_forwarded_tcpip(
                                channel_num,
                                a,
                                b,
                                c,
                                d,
                                self,
                            ),
                        ))
                        let a = std::str::from_utf8(r.read_string()?)?;
                        let b = r.read_u32()?;
                        let c = std::str::from_utf8(r.read_string()?)?;
                        let d = r.read_u32()?;
                        client
                            .channel_open_forwarded_tcpip(channel_num, a, b, c, d, self)
                            .await
                    }
                    b"xon-xoff" => {
                        try!(r.read_byte()); // should be 0.
                        let client_can_do = try!(r.read_byte());
                        Ok(PendingFuture::SessionUnit(
                            client.xon_xoff(channel_num, client_can_do != 0, self),
                        ))
                        r.read_byte()?; // should be 0.
                        let client_can_do = r.read_byte()?;
                        client.xon_xoff(channel_num, client_can_do != 0, self).await
                    }
                    b"exit-status" => {
                        try!(r.read_byte()); // should be 0.
                        let exit_status = try!(r.read_u32());
                        Ok(PendingFuture::SessionUnit(
                            client.exit_status(channel_num, exit_status, self),
                        ))
                        r.read_byte()?; // should be 0.
                        let exit_status = r.read_u32()?;
                        client.exit_status(channel_num, exit_status, self).await
                    }
                    b"exit-signal" => {
                        try!(r.read_byte()); // should be 0.
                        let signal_name = try!(Sig::from_name(try!(r.read_string())));
                        let core_dumped = try!(r.read_byte());
                        let error_message = try!(std::str::from_utf8(try!(r.read_string())));
                        let lang_tag = try!(std::str::from_utf8(try!(r.read_string())));
                        Ok(PendingFuture::SessionUnit(client.exit_signal(
                            channel_num,
                            signal_name,
                            core_dumped != 0,
                            error_message,
                            lang_tag,
                            self,
                        )))
                        r.read_byte()?; // should be 0.
                        let signal_name = Sig::from_name(r.read_string()?)?;
                        let core_dumped = r.read_byte()?;
                        let error_message = std::str::from_utf8(r.read_string()?)?;
                        let lang_tag = std::str::from_utf8(r.read_string()?)?;
                        client
                            .exit_signal(
                                channel_num,
                                signal_name,
                                core_dumped != 0,
                                error_message,
                                lang_tag,
                                self,
                            )
                            .await
                    }
                    _ => {
                        info!("Unknown channel request {:?}", std::str::from_utf8(req));
                        Ok(PendingFuture::Done(client, self))
                        Ok(())
                    }
                }
            }
            msg::CHANNEL_WINDOW_ADJUST => {
                debug!("channel_window_adjust");
                let mut r = buf.reader(1);
                let channel_num = ChannelId(try!(r.read_u32()));
                let amount = try!(r.read_u32());
                let channel_num = ChannelId(r.read_u32()?);
                let amount = r.read_u32()?;
                let mut new_value = 0;
                debug!("amount: {:?}", amount);
                if let Some(ref mut enc) = self.0.encrypted {
                if let Some(ref mut enc) = self.common.encrypted {
                    if let Some(ref mut channel) = enc.channels.get_mut(&channel_num) {
                        channel.recipient_window_size += amount;
                        new_value = channel.recipient_window_size;
                    } else {
                        return Err(HandlerError::Error(Error::WrongChannel));
                        return Err(Error::WrongChannel.into());
                    }
                }
                Ok(PendingFuture::SessionUnit(client.window_adjusted(
                    channel_num,
                    new_value as usize,
                    self,
                )))
                client
                    .window_adjusted(channel_num, new_value as usize, self)
                    .await
            }
            msg::GLOBAL_REQUEST => {
                let mut r = buf.reader(1);
                let req = try!(r.read_string());
                let req = r.read_string()?;
                info!("Unhandled global request: {:?}", std::str::from_utf8(req));
                Ok(PendingFuture::Done(client, self))
                Ok(())
            }
            _ => {
                info!("Unhandled packet: {:?}", buf);
                Ok(PendingFuture::Done(client, self))
                Ok(())
            }
        }
    }

    pub(crate) fn write_auth_request_if_needed(&mut self, user: &str, meth: auth::Method) -> bool {
        let mut is_waiting = false;
        if let Some(ref mut enc) = self.0.encrypted {
        if let Some(ref mut enc) = self.common.encrypted {
            is_waiting = match enc.state {
                Some(EncryptedState::WaitingAuthRequest(_)) => true,
                _ => false
                EncryptedState::WaitingAuthRequest(_) => true,
                EncryptedState::WaitingServiceRequest { accepted } => accepted,
                _ => false,
            };
            debug!("write_auth_request_if_needed: is_waiting = {:?}", is_waiting);
            debug!(
                "write_auth_request_if_needed: is_waiting = {:?}",
                is_waiting
            );
            if is_waiting {
                enc.write_auth_request(user, &meth);
            }
        }
        self.0.auth_user.clear();
        self.0.auth_user.push_str(user);
        self.0.auth_method = Some(meth);
        self.common.auth_user.clear();
        self.common.auth_user.push_str(user);
        self.common.auth_method = Some(meth);
        is_waiting
    }
}

impl Encrypted {
    fn write_auth_request(
        &mut self,
        user: &str,
        auth_method: &auth::Method,
    ) -> bool {
    fn write_auth_request(&mut self, user: &str, auth_method: &auth::Method) -> bool {
        // The server is waiting for our USERAUTH_REQUEST.
        push_packet!(self.write, {
            self.write.push(msg::USERAUTH_REQUEST);

            match *auth_method {
                auth::Method::Password { ref password } => {
                    self.write.extend_ssh_string(user.as_bytes());
                    self.write.extend_ssh_string(SSH_CONNECTION);
                    self.write.extend_ssh_string(b"ssh-connection");
                    self.write.extend_ssh_string(b"password");
                    self.write.push(1);
                    self.write.extend_ssh_string(password.as_bytes());
                    true
                }
                auth::Method::PublicKey { ref key } => {

                    self.write.extend_ssh_string(user.as_bytes());
                    self.write.extend_ssh_string(SSH_CONNECTION);
                    self.write.extend_ssh_string(b"ssh-connection");
                    self.write.extend_ssh_string(b"publickey");
                    self.write.push(0); // This is a probe

                    debug!("write_auth_request: {:?}", key.name());
                    self.write.extend_ssh_string(key.name().as_bytes());
                    key.push_to(&mut self.write);
                    true
                }
                auth::Method::FuturePublicKey { ref key, .. } => {
                    self.write.extend_ssh_string(user.as_bytes());
                    self.write.extend_ssh_string(SSH_CONNECTION);
                    self.write.extend_ssh_string(b"ssh-connection");
                    self.write.extend_ssh_string(b"publickey");
                    self.write.push(0); // This is a probe

                    self.write.extend_ssh_string(key.name().as_bytes());
                    key.push_to(&mut self.write);
                    true
                }
            }
        })
    }

    fn client_make_to_sign<Key: Named + PubKey>(
        &mut self,
        user: &str,
        key: &Key,
        buffer: &mut CryptoVec,
    ) -> usize {
        buffer.clear();
        buffer.extend_ssh_string(self.session_id.as_ref());

        let i0 = buffer.len();
        buffer.push(msg::USERAUTH_REQUEST);
        buffer.extend_ssh_string(user.as_bytes());
        buffer.extend_ssh_string(SSH_CONNECTION);
        buffer.extend_ssh_string(b"ssh-connection");
        buffer.extend_ssh_string(b"publickey");
        buffer.push(1);
        buffer.extend_ssh_string(key.name().as_bytes());
        key.push_to(buffer);
        i0
    }

    fn client_send_signature(
        &mut self,
        user: &str,
        method: &auth::Method,
        buffer: &mut CryptoVec,
    ) -> Result<(), Error> {

    ) -> Result<(), failure::Error> {
        match method {
1



2
3
4
5

6
7
8
9
10
11
12
13
14


15
16
17
18
19
20
21

22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46

47
48
49
50
51
52
53
54
55
56
57
58
59
60
61

62
63




64
65
use super::*;
use negotiation::Select;
use cipher::CipherPair;
use negotiation;
use crate::cipher::CipherPair;
use crate::negotiation::Select;
use crate::{negotiation, Error};

use kex;
use crate::kex;

impl KexInit {
    pub fn client_parse(
        mut self,
        config: &Config,
        cipher: &CipherPair,
        buf: &[u8],
        write_buffer: &mut SSHBuffer,
    ) -> Result<KexDhDone, Error> {
        debug!("client parse");
    ) -> Result<KexDhDone, failure::Error> {
        debug!("client parse {:?} {:?}", buf.len(), buf);
        let algo = if self.algo.is_none() {
            // read algorithms from packet.
            self.exchange.server_kex_init.extend(buf);
            super::negotiation::Client::read_kex(buf, &config.preferred)?
        } else {
            return Err(Error::Kex);
            return Err(Error::Kex.into());
        };
        debug!("algo = {:?}", algo);
        debug!("write = {:?}", &write_buffer.buffer[..]);
        if !self.sent {
            self.client_write(config, cipher, write_buffer)?
        }

        // This function is called from the public API.
        //
        // In order to simplify the public API, we reuse the
        // self.exchange.client_kex buffer to send an extra packet,
        // then truncate that buffer. Without that, we would need an
        // extra buffer.
        let i0 = self.exchange.client_kex_init.len();
        debug!("i0 = {:?}", i0);
        let kex = kex::Algorithm::client_dh(
            algo.kex,
            &mut self.exchange.client_ephemeral,
            &mut self.exchange.client_kex_init,
        )?;

        cipher.write(&self.exchange.client_kex_init[i0..], write_buffer);
        self.exchange.client_kex_init.resize(i0);

        debug!("moving to kexdhdone");
        debug!("moving to kexdhdone, exchange = {:?}", self.exchange);
        Ok(KexDhDone {
            exchange: self.exchange,
            names: algo,
            kex: kex,
            key: 0,
            session_id: self.session_id,
        })
    }

    pub fn client_write(
        &mut self,
        config: &Config,
        cipher: &CipherPair,
        write_buffer: &mut SSHBuffer,
    ) -> Result<(), Error> {
    ) -> Result<(), failure::Error> {
        self.exchange.client_kex_init.clear();
        negotiation::write_kex(
            &config.preferred,
            &mut self.exchange.client_kex_init,
        )?;
        negotiation::write_kex(&config.preferred, &mut self.exchange.client_kex_init)?;
        self.sent = true;
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29




30
31
32
33
34
35













36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52









53
54
55
56
57
58





59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999

1000
1001
1002
1003



1004
1005

1006
1007
1008
1009

1010
1011





1012
1013
1014
1015



1016
1017
1018
1019

1020
1021
1022
1023
1024
















1025
1026
1027
1028
1029
1030
1031
1032


1033
1034
1035
1036
1037
1038
1039
1040


1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053


1054
1055
1056
1057
1058
1059
1060


1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071

1072
1073
1074
1075
1076



1077
1078
1079
1080
1081
1082
1083
1084
1085
1086

1087
1088
1089
1090
1091
1092



1093
1094
1095
1096
1097
1098
1099
1100
1101
1102


1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120

1121
1122



1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139

1140
1141
1142



1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154

1155
1156
1157



1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169

1170
1171
1172
1173
1174
1175



1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196

1197
1198
1199



1200
1201
1202
1203
1204




















































































use crate::auth;
use crate::negotiation;
use crate::pty::Pty;
use crate::session::*;
use crate::ssh_read::SshRead;
use crate::sshbuffer::*;
use crate::{ChannelId, ChannelMsg, ChannelOpenFailure, Disconnect, Limits, Sig};
use cryptovec::CryptoVec;
use futures::task::{Context, Poll};
use futures::Future;
use std::cell::RefCell;
use std::collections::HashMap;
use std::pin::Pin;
use std::sync::Arc;
use std;
use futures::{Poll, Async};
use futures::future::Future;
use tokio::timer::Delay;
use thrussh_keys::encoding::{Encoding, Reader};
use thrussh_keys::key;
use thrussh_keys::key::parse_public_key;
use tokio;
use tokio::io::{AsyncRead, AsyncWrite, AsyncWriteExt};
use tokio::net::TcpStream;
use tokio::io::{WriteAll, Flush, flush};
use tokio;
use std::net::ToSocketAddrs;
use {Disconnect, Error, Limits, Sig, ChannelOpenFailure, ChannelId,
     FromFinished, HandlerError, Status, AtomicPoll};
use thrussh_keys::key::parse_public_key;
use thrussh_keys::key;
use auth;
use negotiation;
use cryptovec::CryptoVec;
use session::*;
use sshbuffer::*;
use pty::Pty;

mod kex;
use crate::cipher;
use crate::tcp::Tcp;
use crate::{msg, Error};
mod encrypted;
mod session;

use tokio::sync::mpsc::*;
pub mod proxy;
pub struct Session {
    common: CommonSession<Arc<Config>>,
    receiver: Receiver<Msg>,
    sender: UnboundedSender<Reply>,
    channels: HashMap<ChannelId, UnboundedSender<OpenChannelMsg>>,
}

mod session;
pub use self::session::*;
mod connection;
pub use self::connection::*;
mod data;
mod authenticate;
mod kex;
mod channel_open;
mod wait;
enum Reply {
    AuthSuccess,
    AuthFailure,
    ChannelOpenFailure,
}

pub use self::data::*;
pub use self::authenticate::*;
pub use self::kex::*;
pub use self::channel_open::*;
pub use self::wait::*;
enum Msg {
    Authenticate {
        user: String,
        method: auth::Method,
    },
    ChannelOpenSession {
        sender: UnboundedSender<OpenChannelMsg>,
    },
    ChannelOpenX11 {
        originator_address: String,
        originator_port: u32,
        sender: UnboundedSender<OpenChannelMsg>,
    },
    ChannelOpenDirectTcpIp {
        host_to_connect: String,
        port_to_connect: u32,
        originator_address: String,
        originator_port: u32,
        sender: UnboundedSender<OpenChannelMsg>,
    },
    TcpIpForward {
        want_reply: bool,
        address: String,
        port: u32,
    },
    CancelTcpIpForward {
        want_reply: bool,
        address: String,
        port: u32,
    },
    Disconnect {
        reason: Disconnect,
        description: String,
        language_tag: String,
    },
    Data {
        id: ChannelId,
        data: CryptoVec,
    },
    ExtendedData {
        id: ChannelId,
        data: CryptoVec,
        ext: u32,
    },
    Eof {
        id: ChannelId,
    },
    RequestPty {
        id: ChannelId,
        want_reply: bool,
        term: String,
        col_width: u32,
        row_height: u32,
        pix_width: u32,
        pix_height: u32,
        terminal_modes: Vec<(Pty, u32)>,
    },
    RequestShell {
        id: ChannelId,
        want_reply: bool,
    },
    Exec {
        id: ChannelId,
        want_reply: bool,
        command: String,
    },
    Signal {
        id: ChannelId,
        signal: Sig,
    },
    RequestSubsystem {
        id: ChannelId,
        want_reply: bool,
        name: String,
    },
    RequestX11 {
        id: ChannelId,
        want_reply: bool,
        single_connection: bool,
        x11_authentication_protocol: String,
        x11_authentication_cookie: String,
        x11_screen_number: u32,
    },
    SetEnv {
        id: ChannelId,
        want_reply: bool,
        variable_name: String,
        variable_value: String,
    },
    WindowChange {
        id: ChannelId,
        col_width: u32,
        row_height: u32,
        pix_width: u32,
        pix_height: u32,
    },
}

enum OpenChannelMsg {
    Open { id: ChannelId },
    Msg(ChannelMsg),
}

/// Handle to a session, used to send messages to a client outside of
/// the request/response cycle.
pub struct Handle {
    sender: Sender<Msg>,
    receiver: UnboundedReceiver<Reply>,
    join: tokio::task::JoinHandle<Result<(), failure::Error>>,
}

#[derive(Clone)]
pub struct ChannelSender {
    sender: Sender<Msg>,
    id: ChannelId,
}

pub struct Channel {
    sender: ChannelSender,
    receiver: UnboundedReceiver<OpenChannelMsg>,
}

impl Handle {
    pub async fn authenticate_password<U: Into<String>, P: Into<String>>(
        &mut self,
        user: U,
        password: P,
    ) -> Result<bool, failure::Error> {
        let user = user.into();
        debug!("sending {:?}", user);
        self.sender
            .send(Msg::Authenticate {
                user,
                method: auth::Method::Password {
                    password: password.into(),
                },
            })
            .await
            .map_err(|_| Error::SendError)?;
        loop {
            match self.receiver.recv().await {
                Some(Reply::AuthSuccess) => return Ok(true),
                Some(Reply::AuthFailure) => return Ok(false),
                None => return Ok(false),
                _ => {}
            }
        }
    }

    pub async fn authenticate_publickey<U: Into<String>>(
        &mut self,
        user: U,
        key: Arc<key::KeyPair>,
    ) -> Result<bool, failure::Error> {
        let user = user.into();
        debug!("sending {:?}", user);
        self.sender
            .send(Msg::Authenticate {
                user,
                method: auth::Method::PublicKey { key },
            })
            .await
            .map_err(|_| Error::SendError)?;
        loop {
            match self.receiver.recv().await {
                Some(Reply::AuthSuccess) => return Ok(true),
                Some(Reply::AuthFailure) => return Ok(false),
                None => return Ok(false),
                _ => {}
            }
        }
    }

    pub async fn authenticate_future<
        U: Into<String>,
        S: for<'a> auth::Signer<'a> + Sync + Send + 'static,
    >(
        &mut self,
        user: U,
        key: key::PublicKey,
        future: S,
    ) -> Result<bool, failure::Error> {
        let user = user.into();
        debug!("sending {:?}", user);
        self.sender
            .send(Msg::Authenticate {
                user,
                method: auth::Method::FuturePublicKey {
                    key,
                    future: Box::new(future),
                },
            })
            .await
            .map_err(|_| Error::SendError)?;
        loop {
            match self.receiver.recv().await {
                Some(Reply::AuthSuccess) => return Ok(true),
                Some(Reply::AuthFailure) => return Ok(false),
                None => return Ok(false),
                _ => {}
            }
        }
    }

    async fn wait_channel_confirmation(
        &self,
        mut receiver: UnboundedReceiver<OpenChannelMsg>,
    ) -> Result<Channel, failure::Error> {
        loop {
            match receiver.recv().await {
                Some(OpenChannelMsg::Open { id }) => {
                    return Ok(Channel {
                        sender: ChannelSender {
                            sender: self.sender.clone(),
                            id,
                        },
                        receiver,
                    })
                }
                None => return Err(Error::Disconnect.into()),
                _ => {}
            }
        }
    }

    /// Request a session channel (the most basic type of
    /// channel). This function returns `Some(..)` immediately if the
    /// connection is authenticated, but the channel only becomes
    /// usable when it's confirmed by the server, as indicated by the
    /// `confirmed` field of the corresponding `Channel`.
    pub async fn channel_open_session(&mut self) -> Result<Channel, failure::Error> {
        let (sender, receiver) = unbounded_channel();
        self.sender
            .send(Msg::ChannelOpenSession { sender })
            .await
            .map_err(|_| Error::SendError)?;
        self.wait_channel_confirmation(receiver).await
    }

    /// Request an X11 channel, on which the X11 protocol may be tunneled.
    pub async fn channel_open_x11<A: Into<String>>(
        &mut self,
        originator_address: A,
        originator_port: u32,
    ) -> Result<Channel, failure::Error> {
        let (sender, receiver) = unbounded_channel();
        self.sender
            .send(Msg::ChannelOpenX11 {
                originator_address: originator_address.into(),
                originator_port,
                sender,
            })
            .await
            .map_err(|_| Error::SendError)?;
        self.wait_channel_confirmation(receiver).await
    }

    /// Open a TCP/IP forwarding channel. This is usually done when a
    /// connection comes to a locally forwarded TCP/IP port. See
    /// [RFC4254](https://tools.ietf.org/html/rfc4254#section-7). The
    /// TCP/IP packets can then be tunneled through the channel using
    /// `.data()`.
    pub async fn channel_open_direct_tcpip<A: Into<String>, B: Into<String>>(
        &mut self,
        host_to_connect: A,
        port_to_connect: u32,
        originator_address: B,
        originator_port: u32,
    ) -> Result<Channel, failure::Error> {
        let (sender, receiver) = unbounded_channel();
        self.sender
            .send(Msg::ChannelOpenDirectTcpIp {
                host_to_connect: host_to_connect.into(),
                port_to_connect,
                originator_address: originator_address.into(),
                originator_port,
                sender,
            })
            .await
            .map_err(|_| Error::SendError)?;
        self.wait_channel_confirmation(receiver).await
    }

    /// Sends a disconnect message.
    pub async fn disconnect(
        &mut self,
        reason: Disconnect,
        description: &str,
        language_tag: &str,
    ) -> Result<(), failure::Error> {
        self.sender
            .send(Msg::Disconnect {
                reason,
                description: description.into(),
                language_tag: language_tag.into(),
            })
            .await
            .map_err(|_| Error::SendError)?;
        Ok(())
    }
}

impl ChannelSender {
    pub fn id(&self) -> ChannelId {
        self.id
    }

    /// Request a pseudo-terminal with the given characteristics.
    pub async fn request_pty(
        &mut self,
        want_reply: bool,
        term: &str,
        col_width: u32,
        row_height: u32,
        pix_width: u32,
        pix_height: u32,
        terminal_modes: &[(Pty, u32)],
    ) -> Result<(), failure::Error> {
        self.sender
            .send(Msg::RequestPty {
                id: self.id,
                want_reply,
                term: term.to_string(),
                col_width,
                row_height,
                pix_width,
                pix_height,
                terminal_modes: terminal_modes.to_vec(),
            })
            .await
            .map_err(|_| Error::SendError)?;
        Ok(())
    }

    /// Request a remote shell.
    pub async fn request_shell(&mut self, want_reply: bool) -> Result<(), failure::Error> {
        self.sender
            .send(Msg::RequestShell {
                id: self.id,
                want_reply,
            })
            .await
            .map_err(|_| Error::SendError)?;
        Ok(())
    }

    /// Execute a remote program (will be passed to a shell). This can
    /// be used to implement scp (by calling a remote scp and
    /// tunneling to its standard input).
    pub async fn exec<A: Into<String>>(
        &mut self,
        want_reply: bool,
        command: A,
    ) -> Result<(), failure::Error> {
        self.sender
            .send(Msg::Exec {
                id: self.id,
                want_reply,
                command: command.into(),
            })
            .await
            .map_err(|_| Error::SendError)?;
        Ok(())
    }

    /// Signal a remote process.
    pub async fn signal(&mut self, signal: Sig) -> Result<(), failure::Error> {
        self.sender
            .send(Msg::Signal {
                id: self.id,
                signal,
            })
            .await
            .map_err(|_| Error::SendError)?;
        Ok(())
    }

    /// Request the start of a subsystem with the given name.
    pub async fn request_subsystem<A: Into<String>>(
        &mut self,
        want_reply: bool,
        name: A,
    ) -> Result<(), failure::Error> {
        self.sender
            .send(Msg::RequestSubsystem {
                id: self.id,
                want_reply,
                name: name.into(),
            })
            .await
            .map_err(|_| Error::SendError)?;
        Ok(())
    }

    /// Request the forwarding of a remote port to the client. The
    /// server will then open forwarding channels (which cause the
    /// client to call `.channel_open_forwarded_tcpip()`).
    pub async fn tcpip_forward<A: Into<String>>(
        &mut self,
        want_reply: bool,
        address: A,
        port: u32,
    ) -> Result<(), failure::Error> {
        self.sender
            .send(Msg::TcpIpForward {
                want_reply,
                address: address.into(),
                port,
            })
            .await
            .map_err(|_| Error::SendError)?;
        Ok(())
    }

    /// Cancel a previous forwarding request.
    pub async fn cancel_tcpip_forward<A: Into<String>>(
        &mut self,
        want_reply: bool,
        address: A,
        port: u32,
    ) -> Result<(), failure::Error> {
        self.sender
            .send(Msg::CancelTcpIpForward {
                want_reply,
                address: address.into(),
                port,
            })
            .await
            .map_err(|_| Error::SendError)?;
        Ok(())
    }

    /// Request X11 forwarding through an already opened X11
    /// channel. See
    /// [RFC4254](https://tools.ietf.org/html/rfc4254#section-6.3.1)
    /// for security issues related to cookies.
    pub async fn request_x11<A: Into<String>, B: Into<String>>(
        &mut self,
        want_reply: bool,
        single_connection: bool,
        x11_authentication_protocol: A,
        x11_authentication_cookie: B,
        x11_screen_number: u32,
    ) -> Result<(), failure::Error> {
        self.sender
            .send(Msg::RequestX11 {
                id: self.id,
                want_reply,
                single_connection,
                x11_authentication_protocol: x11_authentication_protocol.into(),
                x11_authentication_cookie: x11_authentication_cookie.into(),
                x11_screen_number,
            })
            .await
            .map_err(|_| Error::SendError)?;
        Ok(())
    }

    /// Set a remote environment variable.
    pub async fn set_env<A: Into<String>, B: Into<String>>(
        &mut self,
        want_reply: bool,
        variable_name: A,
        variable_value: B,
    ) -> Result<(), failure::Error> {
        self.sender
            .send(Msg::SetEnv {
                id: self.id,
                want_reply,
                variable_name: variable_name.into(),
                variable_value: variable_value.into(),
            })
            .await
            .map_err(|_| Error::SendError)?;
        Ok(())
    }

    /// Inform the server that our window size has changed.
    pub async fn window_change(
        &mut self,
        col_width: u32,
        row_height: u32,
        pix_width: u32,
        pix_height: u32,
    ) -> Result<(), failure::Error> {
        self.sender
            .send(Msg::WindowChange {
                id: self.id,
                col_width,
                row_height,
                pix_width,
                pix_height,
            })
            .await
            .map_err(|_| Error::SendError)?;
        Ok(())
    }

    /// Send data to a channel. The number of bytes added to the
    /// "sending pipeline" (to be processed by the event loop) is
    /// returned.
    pub async fn data<B: AsRef<[u8]>>(&mut self, data: B) -> Result<(), failure::Error> {
        self.sender
            .send(Msg::Data {
                id: self.id,
                data: CryptoVec::from_slice(data.as_ref()),
            })
            .await
            .map_err(|_| Error::SendError)?;
        Ok(())
    }

    /// Send data to a channel. The number of bytes added to the
    /// "sending pipeline" (to be processed by the event loop) is
    /// returned.
    pub async fn extended_data(&mut self, ext: u32, data: &[u8]) -> Result<(), failure::Error> {
        self.sender
            .send(Msg::ExtendedData {
                id: self.id,
                ext,
                data: CryptoVec::from_slice(data.as_ref()),
            })
            .await
            .map_err(|_| Error::SendError)?;
        Ok(())
    }

    pub async fn eof(&mut self) -> Result<(), failure::Error> {
        self.sender
            .send(Msg::Eof { id: self.id })
            .await
            .map_err(|_| Error::SendError)?;
        Ok(())
    }
}

impl Channel {
    /// Wait for data to come.
    pub async fn wait(&mut self) -> Option<ChannelMsg> {
        loop {
            match self.receiver.recv().await {
                Some(OpenChannelMsg::Msg(msg)) => return Some(msg),
                None => return None,
                _ => {}
            }
        }
    }
}

impl std::ops::Deref for Channel {
    type Target = ChannelSender;
    fn deref(&self) -> &Self::Target {
        &self.sender
    }
}

impl std::ops::DerefMut for Channel {
    fn deref_mut(&mut self) -> &mut Self::Target {
        &mut self.sender
    }
}

impl Future for Handle {
    type Output = Result<(), failure::Error>;
    fn poll(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output> {
        match Future::poll(Pin::new(&mut self.join), cx) {
            Poll::Ready(r) => Poll::Ready(match r {
                Ok(Ok(x)) => Ok(x),
                Err(e) => Err(e.into()),
                Ok(Err(e)) => Err(e),
            }),
            Poll::Pending => Poll::Pending,
        }
    }
}

pub async fn connect<H: Handler + Send + 'static>(
    config: Arc<Config>,
    addr: &str,
    handler: H,
) -> Result<Handle, failure::Error> {
    use std::net::ToSocketAddrs;
    let addr = addr.to_socket_addrs().unwrap().next().unwrap();
    let socket = TcpStream::connect(addr).await?;
    connect_stream(config, socket, handler).await
}

async fn connect_stream<H, R>(
    config: Arc<Config>,
    mut stream: R,
    handler: H,
) -> Result<Handle, failure::Error>
where
    H: Handler + Send + 'static,
    R: AsyncRead + AsyncWrite + Tcp + Unpin + Send + 'static,
{
    // Writing SSH id.
    let mut write_buffer = SSHBuffer::new();
    write_buffer.send_ssh_id(config.as_ref().client_id.as_bytes());
    stream.write_all(&write_buffer.buffer).await?;

    // Reading SSH id and allocating a session if correct.
    let mut stream = SshRead::new(stream);
    let sshid = stream.read_ssh_id().await?;
    let (sender, receiver) = channel(10);
    let (sender2, receiver2) = unbounded_channel();
    let mut session = Session {
        common: CommonSession {
            write_buffer,
            kex: None,
            auth_user: String::new(),
            auth_method: None, // Client only.
            cipher: Arc::new(cipher::CLEAR_PAIR),
            encrypted: None,
            config: config,
            wants_reply: false,
            disconnected: false,
            buffer: CryptoVec::new(),
        },
        receiver,
        sender: sender2,
        channels: HashMap::new(),
    };
    session.read_ssh_id(sshid)?;
    Ok(Handle {
        sender,
        receiver: receiver2,
        join: tokio::spawn(session.run(stream, handler)),
    })
}

impl Session {
    async fn run<H: Handler + Send, R: AsyncRead + AsyncWrite + Tcp + Unpin + Send>(
        mut self,
        mut stream: R,
        mut handler: H,
    ) -> Result<(), failure::Error> {
        self.flush()?;
        stream.write_all(&self.common.write_buffer.buffer).await?;
        self.common.write_buffer.buffer.clear();
        let mut buffer = SSHBuffer::new();
        while !self.common.disconnected {
            tokio::select! {
                _ = cipher::read(&mut stream, &mut buffer, &self.common.cipher) => {
                    debug!("client read");
                    if buffer.buffer.len() < 5 || buffer.buffer[5] == crate::msg::DISCONNECT {
                        break;
                    } else if buffer.buffer[5] <= 4 {
                        continue;
                    }
                    debug!("buffer = {:?}", &buffer.buffer[..]);
                    reply(&mut self, &mut handler, &buffer.buffer[5..]).await?;
                }
                msg = self.receiver.recv() => {
                    debug!("client recv");
                    match msg {
                        Some(Msg::Authenticate { user, method }) => {
                            debug!("authenticate");
                            self.write_auth_request_if_needed(&user, method);
                        }
                        Some(Msg::ChannelOpenSession { sender }) => {
                            debug!("authenticate");
                            let id = self.channel_open_session()?;
                            self.channels.insert(id, sender);
                        }
                        Some(Msg::ChannelOpenX11 { originator_address, originator_port, sender }) => {
                            debug!("authenticate");
                            let id = self.channel_open_x11(&originator_address, originator_port)?;
                            self.channels.insert(id, sender);
                        }
                        Some(Msg::ChannelOpenDirectTcpIp { host_to_connect, port_to_connect, originator_address, originator_port, sender }) => {
                            debug!("authenticate");
                            let id = self.channel_open_direct_tcpip(&host_to_connect, port_to_connect, &originator_address, originator_port)?;
                            self.channels.insert(id, sender);
                        }
                        Some(Msg::TcpIpForward { want_reply, address, port }) => {
                            self.tcpip_forward(want_reply, &address, port)
                        },
                        Some(Msg::CancelTcpIpForward { want_reply, address, port }) => {
                            self.cancel_tcpip_forward(want_reply, &address, port)
                        },
                        Some(Msg::Disconnect { reason, description, language_tag }) => {
                            self.disconnect(reason, &description, &language_tag)
                        },
                        Some(Msg::Data { data, id }) => { self.data(id, &data); },
                        Some(Msg::Eof { id }) => { self.eof(id); },
                        Some(Msg::ExtendedData { data, ext, id }) => { self.extended_data(id, ext, &data); },
                        Some(Msg::RequestPty { id, want_reply, term, col_width, row_height, pix_width, pix_height, terminal_modes }) => {
                            self.request_pty(id, want_reply, &term, col_width, row_height, pix_width, pix_height, &terminal_modes)
                        },
                        Some(Msg::WindowChange { id, col_width, row_height, pix_width, pix_height }) => {
                            self.window_change(id, col_width, row_height, pix_width, pix_height)
                        },
                        Some(Msg::RequestX11 { id, want_reply, single_connection, x11_authentication_protocol, x11_authentication_cookie, x11_screen_number }) => {
                            self.request_x11(id, want_reply, single_connection, &x11_authentication_protocol, &x11_authentication_cookie, x11_screen_number)
                        },
                        Some(Msg::SetEnv { id, want_reply, variable_name, variable_value }) => {
                            self.set_env(id, want_reply, &variable_name, &variable_value)
                        },
                        Some(Msg::RequestShell { id, want_reply }) => {
                            self.request_shell(want_reply, id)
                        },
                        Some(Msg::Exec { id, want_reply, command }) => {
                            self.exec(id, want_reply, &command)
                        },
                        Some(Msg::Signal { id, signal }) => {
                            self.signal(id, signal)
                        },
                        Some(Msg::RequestSubsystem { id, want_reply, name }) => {
                            self.request_subsystem(want_reply, id, &name)
                        },
                        None => {
                            self.common.disconnected = true;
                            break
                        }
                    }
                }
            }
            self.flush()?;
            stream.write_all(&self.common.write_buffer.buffer).await?;
            buffer.buffer.clear();
            self.common.write_buffer.buffer.clear();
        }
        if self.common.disconnected {
            stream.tcp_shutdown()?;

            // Shutdown
            buffer.buffer.clear();
            while cipher::read(&mut stream, &mut buffer, &self.common.cipher).await? != 0 {
                buffer.buffer.clear();
            }
        }
        Ok(())
    }
}

impl Session {
    fn read_ssh_id(&mut self, sshid: &[u8]) -> Result<(), failure::Error> {
        // self.read_buffer.bytes += sshid.bytes_read + 2;
        let mut exchange = Exchange::new();
        exchange.server_id.extend(sshid);
        // Preparing the response
        exchange
            .client_id
            .extend(self.common.config.as_ref().client_id.as_bytes());
        let mut kexinit = KexInit {
            exchange: exchange,
            algo: None,
            sent: false,
            session_id: None,
        };
        self.common.write_buffer.buffer.clear();
        kexinit.client_write(
            self.common.config.as_ref(),
            &mut self.common.cipher,
            &mut self.common.write_buffer,
        )?;
        self.common.kex = Some(Kex::KexInit(kexinit));
        Ok(())
    }

    /// Flush the temporary cleartext buffer into the encryption
    /// buffer. This does *not* flush to the socket.
    fn flush(&mut self) -> Result<(), failure::Error> {
        if let Some(ref mut enc) = self.common.encrypted {
            if enc.flush(
                &self.common.config.as_ref().limits,
                &mut self.common.cipher,
                &mut self.common.write_buffer,
            ) {
                if let Some(exchange) = std::mem::replace(&mut enc.exchange, None) {
                    let mut kexinit = KexInit::initiate_rekey(exchange, &enc.session_id);
                    kexinit.client_write(
                        &self.common.config.as_ref(),
                        &mut self.common.cipher,
                        &mut self.common.write_buffer,
                    )?;
                    enc.rekey = Some(Kex::KexInit(kexinit))
                }
            }
        }
        Ok(())
    }
}
thread_local! {
    static HASH_BUFFER: RefCell<CryptoVec> = RefCell::new(CryptoVec::new());
}
impl Session {
    async fn server_key_check<H: Handler>(
        &mut self,
        handler: &mut H,
        mut kexdhdone: KexDhDone,
        buf: &[u8],
    ) -> Result<(), failure::Error> {
        let mut reader = buf.reader(1);
        let pubkey = reader.read_string()?; // server public key.
        let pubkey = parse_public_key(pubkey)?;
        debug!("server_public_Key: {:?}", pubkey);
        if !handler.check_server_key(&pubkey).await? {
            return Err(Error::UnknownKey.into());
        }
        HASH_BUFFER.with(|buffer| {
            let mut buffer = buffer.borrow_mut();
            buffer.clear();
            let hash = {
                let server_ephemeral = reader.read_string()?;
                kexdhdone.exchange.server_ephemeral.extend(server_ephemeral);
                let signature = reader.read_string()?;

                kexdhdone
                    .kex
                    .compute_shared_secret(&kexdhdone.exchange.server_ephemeral)?;
                debug!("kexdhdone.exchange = {:?}", kexdhdone.exchange);
                let hash = kexdhdone.kex.compute_exchange_hash(
                    &pubkey,
                    &kexdhdone.exchange,
                    &mut buffer,
                )?;
                debug!("exchange hash: {:?}", hash);
                let signature = {
                    let mut sig_reader = signature.reader(0);
                    let sig_type = sig_reader.read_string()?;
                    debug!("sig_type: {:?}", sig_type);
                    sig_reader.read_string()?
                };
                use thrussh_keys::key::Verify;
                debug!("signature: {:?}", signature);
                if !pubkey.verify_server_auth(hash.as_ref(), signature) {
                    return Err(Error::WrongServerSig.into());
                }
                hash
            };
            let mut newkeys = kexdhdone.compute_keys(hash, false)?;
            self.common
                .cipher
                .write(&[msg::NEWKEYS], &mut self.common.write_buffer);
            newkeys.sent = true;
            self.common.kex = Some(Kex::NewKeys(newkeys));
            Ok::<(), failure::Error>(())
        })?;
        Ok(())
    }
}

async fn reply<H: Handler>(
    session: &mut Session,
    handler: &mut H,
    buf: &[u8],
) -> Result<(), failure::Error> {
    match session.common.kex.take() {
        Some(Kex::KexInit(kexinit)) => {
            if kexinit.algo.is_some()
                || buf[0] == msg::KEXINIT
                || session.common.encrypted.is_none()
            {
                session.common.kex = Some(Kex::KexDhDone(kexinit.client_parse(
                    session.common.config.as_ref(),
                    &session.common.cipher,
                    buf,
                    &mut session.common.write_buffer,
                )?));
                session.flush()?;
            }
            Ok(())
        }
        Some(Kex::KexDhDone(mut kexdhdone)) => {
            if kexdhdone.names.ignore_guessed {
                kexdhdone.names.ignore_guessed = false;
                session.common.kex = Some(Kex::KexDhDone(kexdhdone));
                Ok(())
            } else if buf[0] == msg::KEX_ECDH_REPLY {
                // We've sent ECDH_INIT, waiting for ECDH_REPLY
                session.server_key_check(handler, kexdhdone, buf).await?;
                session.flush()?;
                Ok(())
            } else {
                error!("Wrong packet received");
                Err(Error::Inconsistent.into())
            }
        }
        Some(Kex::NewKeys(newkeys)) => {
            debug!("newkeys received");
            if buf[0] != msg::NEWKEYS {
                return Err(Error::Kex.into());
            }
            session.common.encrypted(
                EncryptedState::WaitingServiceRequest { accepted: false },
                newkeys,
            );
            // Ok, NEWKEYS received, now encrypted.
            let p = b"\x05\0\0\0\x0Cssh-userauth";
            session
                .common
                .cipher
                .write(p, &mut session.common.write_buffer);
            Ok(())
        }
        Some(kex) => {
            session.common.kex = Some(kex);
            Ok(())
        }
        None => {
            session.client_read_encrypted(handler, buf).await?;
            Ok(())
        }
    }
}

/// The configuration of clients.
#[derive(Debug)]
pub struct Config {
    /// The client ID string sent at the beginning of the protocol.
    pub client_id: String,
    /// The bytes and time limits before key re-exchange.
    pub limits: Limits,
    /// The initial size of a channel (used for flow control).
    pub window_size: u32,
    /// The maximal size of a single packet.
    pub maximum_packet_size: u32,
    /// Lists of preferred algorithms.
    pub preferred: negotiation::Preferred,
    /// Time after which the connection is garbage-collected.
    pub connection_timeout: Option<std::time::Duration>,
}

impl Default for Config {
    fn default() -> Config {
        Config {
            client_id: format!(
                "SSH-2.0-{}_{}",
                env!("CARGO_PKG_NAME"),
                env!("CARGO_PKG_VERSION")
            ),
            limits: Limits::default(),
            window_size: 200000,
            maximum_packet_size: 200000,
            preferred: Default::default(),
            connection_timeout: None,
        }
    }
}


/// A client handler. Note that messages can be received from the
/// server at any time during a session.
pub trait Handler: Sized {
    /// Error type returned by the futures.
    type Error: std::fmt::Debug;

    /// A future ultimately resolving into a boolean, which can be
    /// returned by some parts of this handler.
    type FutureBool: Future<Item = (Self, bool), Error = Self::Error> + FromFinished<(Self, bool), Self::Error>;
    type FutureBool: Future<Output = Result<bool, failure::Error>> + Send;

    /// A future ultimately resolving into a boolean, which can be
    /// returned by some parts of this handler.
    type FutureUnit: Future<Item = Self, Error = Self::Error> + FromFinished<Self, Self::Error>;
    type FutureUnit: Future<Output = Result<(), failure::Error>> + Send;

    /// A future that computes the signature of a `CryptoVec`, appends
    /// that signature to that `CryptoVec`, and resolves to the
    /// `CryptoVec`. Useful for instance to implement SSH agent
    /// clients.
    type FutureSign: Future<Item = (Self, CryptoVec), Error = Self::Error> + FromFinished<(Self, CryptoVec), Self::Error>;
    /// Convert a `bool` to `Self::FutureBool`. This is used to
    /// produce the default handlers.
    fn finished_bool(&mut self, b: bool) -> Self::FutureBool;

    /// A future ultimately resolving into unit, which can be returned
    /// by some parts of this handler.
    type SessionUnit: Future<Item = (Self, Session), Error = Self::Error> + FromFinished<(Self, Session), Self::Error>;
    /// Produce a `Self::FutureUnit`. This is used to produce the
    /// default handlers.
    fn finished(&mut self) -> Self::FutureUnit;


    /// Called when the server sends us an authentication banner. This
    /// is usually meant to be shown to the user, see
    /// [RFC4252](https://tools.ietf.org/html/rfc4252#section-5.4) for
    /// more details.
    #[allow(unused_variables)]
    fn auth_banner(self, banner: &str) -> Self::FutureUnit {
        Self::FutureUnit::finished(self)
    }

    /// Called when using the `FuturePublicKey` method, used for
    /// instance to implement SSH agent. This can be used for instance
    /// to implement an interface to SSH agents.
    ///
    /// When successful, this method appends a signature to
    /// `to_sign`. Else, it just returns `to_sign` without touching
    /// it. The default implementation just returns `to_sign`
    /// (i.e. always behaves as if the signature failed).
    #[allow(unused_variables)]
    #[allow(unused_variables)]
    fn auth_publickey_sign(self, key: &key::PublicKey, to_sign: CryptoVec) -> Self::FutureSign {
        Self::FutureSign::finished((self, to_sign))
    fn auth_banner(&mut self, banner: &str) -> Self::FutureUnit {
        self.finished()
    }

    /// Called to check the server's public key. This is a very important
    /// step to help prevent man-in-the-middle attacks. The default
    /// implementation rejects all keys.
    #[allow(unused_variables)]
    fn check_server_key(self, server_public_key: &key::PublicKey) -> Self::FutureBool {
        Self::FutureBool::finished((self, false))
    fn check_server_key(&mut self, server_public_key: &key::PublicKey) -> Self::FutureBool {
        self.finished_bool(false)
    }

    /// Called when the server confirmed our request to open a
    /// channel. A channel can only be written to after receiving this
    /// message (this library panics otherwise).
    #[allow(unused_variables)]
    fn channel_open_confirmation(self, channel: ChannelId, session: Session) -> Self::SessionUnit {
        Self::SessionUnit::finished((self, session))
    fn channel_open_confirmation(
        &mut self,
        id: ChannelId,
        session: &mut Session,
    ) -> Self::FutureUnit {
        if let Some(channel) = session.channels.get(&id) {
            channel.send(OpenChannelMsg::Open { id }).unwrap_or(());
        }
        self.finished()
    }

    /// Called when the server closes a channel.
    #[allow(unused_variables)]
    fn channel_close(self, channel: ChannelId, session: Session) -> Self::SessionUnit {
        Self::SessionUnit::finished((self, session))
    fn channel_close(&mut self, channel: ChannelId, session: &mut Session) -> Self::FutureUnit {
        session.channels.remove(&channel);
        self.finished()
    }

    /// Called when the server sends EOF to a channel.
    #[allow(unused_variables)]
    fn channel_eof(self, channel: ChannelId, session: Session) -> Self::SessionUnit {
        Self::SessionUnit::finished((self, session))
    fn channel_eof(&mut self, channel: ChannelId, session: &mut Session) -> Self::FutureUnit {
        if let Some(chan) = session.channels.get(&channel) {
            chan.send(OpenChannelMsg::Msg(ChannelMsg::Eof))
                .unwrap_or(())
        }
        self.finished()
    }

    /// Called when the server rejected our request to open a channel.
    #[allow(unused_variables)]
    fn channel_open_failure(
        self,
        &mut self,
        channel: ChannelId,
        reason: ChannelOpenFailure,
        description: &str,
        language: &str,
        session: Session,
    ) -> Self::SessionUnit {
        Self::SessionUnit::finished((self, session))
        session: &mut Session,
    ) -> Self::FutureUnit {
        session.channels.remove(&channel);
        session.sender.send(Reply::ChannelOpenFailure).unwrap_or(());
        self.finished()
    }

    /// Called when a new channel is created.
    #[allow(unused_variables)]
    fn channel_open_forwarded_tcpip(
        self,
        &mut self,
        channel: ChannelId,
        connected_address: &str,
        connected_port: u32,
        originator_address: &str,
        originator_port: u32,
        session: Session,
    ) -> Self::SessionUnit {
        Self::SessionUnit::finished((self, session))
        session: &mut Session,
    ) -> Self::FutureUnit {
        self.finished()
    }

    /// Called when the server sends us data. The `extended_code`
    /// parameter is a stream identifier, `None` is usually the
    /// standard output, and `Some(1)` is the standard error. See
    /// [RFC4254](https://tools.ietf.org/html/rfc4254#section-5.2).
    #[allow(unused_variables)]
    fn data(
        self,
    fn data(&mut self, channel: ChannelId, data: &[u8], session: &mut Session) -> Self::FutureUnit {
        if let Some(chan) = session.channels.get(&channel) {
            chan.send(OpenChannelMsg::Msg(ChannelMsg::Data {
                data: CryptoVec::from_slice(data),
            }))
            .unwrap_or(())
        }
        self.finished()
    }

    /// Called when the server sends us data. The `extended_code`
    /// parameter is a stream identifier, `None` is usually the
    /// standard output, and `Some(1)` is the standard error. See
    /// [RFC4254](https://tools.ietf.org/html/rfc4254#section-5.2).
    #[allow(unused_variables)]
    fn extended_data(
        &mut self,
        channel: ChannelId,
        extended_code: Option<u32>,
        ext: u32,
        data: &[u8],
        session: Session,
    ) -> Self::SessionUnit {
        Self::SessionUnit::finished((self, session))
        session: &mut Session,
    ) -> Self::FutureUnit {
        if let Some(chan) = session.channels.get(&channel) {
            chan.send(OpenChannelMsg::Msg(ChannelMsg::ExtendedData {
                ext,
                data: CryptoVec::from_slice(data),
            }))
            .unwrap_or(())
        }
        self.finished()
    }

    /// The server informs this client of whether the client may
    /// perform control-S/control-Q flow control. See
    /// [RFC4254](https://tools.ietf.org/html/rfc4254#section-6.8).
    #[allow(unused_variables)]
    fn xon_xoff(
        self,
        &mut self,
        channel: ChannelId,
        client_can_do: bool,
        session: Session,
    ) -> Self::SessionUnit {
        Self::SessionUnit::finished((self, session))
        session: &mut Session,
    ) -> Self::FutureUnit {
        if let Some(chan) = session.channels.get(&channel) {
            chan.send(OpenChannelMsg::Msg(ChannelMsg::XonXoff { client_can_do }))
                .unwrap_or(())
        }
        self.finished()
    }

    /// The remote process has exited, with the given exit status.
    #[allow(unused_variables)]
    fn exit_status(
        self,
        &mut self,
        channel: ChannelId,
        exit_status: u32,
        session: Session,
    ) -> Self::SessionUnit {
        Self::SessionUnit::finished((self, session))
        session: &mut Session,
    ) -> Self::FutureUnit {
        if let Some(chan) = session.channels.get(&channel) {
            chan.send(OpenChannelMsg::Msg(ChannelMsg::ExitStatus { exit_status }))
                .unwrap_or(())
        }
        self.finished()
    }

    /// The remote process exited upon receiving a signal.
    #[allow(unused_variables)]
    fn exit_signal(
        self,
        &mut self,
        channel: ChannelId,
        signal_name: Sig,
        core_dumped: bool,
        error_message: &str,
        lang_tag: &str,
        session: Session,
    ) -> Self::SessionUnit {
        Self::SessionUnit::finished((self, session))
        session: &mut Session,
    ) -> Self::FutureUnit {
        if let Some(chan) = session.channels.get(&channel) {
            chan.send(OpenChannelMsg::Msg(ChannelMsg::ExitSignal {
                signal_name,
                core_dumped,
                error_message: error_message.to_string(),
                lang_tag: lang_tag.to_string(),
            }))
            .unwrap_or(())
        }
        self.finished()
    }

    /// Called when the network window is adjusted, meaning that we
    /// can send more bytes. This is useful if this client wants to
    /// send huge amounts of data, for instance if we have called
    /// `Session::data` before, and it returned less than the
    /// full amount of data.
    #[allow(unused_variables)]
    fn window_adjusted(
        self,
        &mut self,
        channel: ChannelId,
        new_window_size: usize,
        session: Session,
    ) -> Self::SessionUnit {
        Self::SessionUnit::finished((self, session))
        session: &mut Session,
    ) -> Self::FutureUnit {
        self.finished()
    }
}

/// Create a new client connection to the given address.
pub fn connect_future<
    Addr: ToSocketAddrs,
    H: Handler,
    I,
    E,
    X: Future<Item = I, Error = E>,
    F: FnOnce(Connection<TcpStream, H>) -> X,
    >(
    addr: Addr,
    config: Arc<Config>,
    timeout: Option<Delay>,
    handler: H,
    handler: H,
    f: F,
) -> Result<ConnectFuture<H, I, E, X, F>, Error> {

    Ok(ConnectFuture {
        state: Some(ConnectFutureState::TcpConnect(
            TcpStream::connect(&addr.to_socket_addrs()?.next().unwrap())
        )),
        handler: Some(handler),
        config,
        timeout,
        f: Some(f),
    })
}

/// Future returned by `connect_future`.
pub struct ConnectFuture<H: Handler, I, E, X: Future<Item = I, Error = E>, F: FnOnce(Connection<TcpStream, H>) -> X> {
    handler: Option<H>,
    config: Arc<Config>,
    state: Option<ConnectFutureState<X>>,
    timeout: Option<Delay>,
    f: Option<F>
    f: Option<F>
}

enum ConnectFutureState<X> {
    TcpConnect(tokio::net::tcp::ConnectFuture),
    Connect(X)
    Connect(X)
}

impl<H: Handler, I, E, X: Future<Item = I, Error = E>, F: FnOnce(Connection<TcpStream, H>) -> X> Future for ConnectFuture<H, I, E, X, F> {
    type Item = I;
    type Error = HandlerError<E>;
    fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
        loop {
            match self.state.take() {
                Some(ConnectFutureState::TcpConnect(mut connect)) => {
                    if let Async::Ready(socket) = connect.poll()? {

                        self.state = Some(ConnectFutureState::Connect(
                            (self.f.take().unwrap())(Connection::new(
                                self.config.clone(),
                                socket,
                                self.handler.take().unwrap(),
                                self.timeout.take(),
                            )?)
                        ))

                    } else {
                        self.state = Some(ConnectFutureState::TcpConnect(connect));
                        return Ok(Async::NotReady)
                    }
                }
                Some(ConnectFutureState::Connect(mut connect)) => {
                    match connect.poll() {
                        Ok(Async::Ready(f)) => return Ok(Async::Ready(f)),
                        Ok(Async::NotReady) => {
                            self.state = Some(ConnectFutureState::Connect(connect));
                            return Ok(Async::NotReady)
                        }
                        Err(e) => return Err(HandlerError::Handler(e))
                    }
                }
                None => panic!("Future polled after completion")
            }
        }
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
use crate::tcp;
use futures::task::{Context, Poll};
use std::io::{Read, Write};
use std::net::SocketAddr;
use std::pin::Pin;
use std::process::Command;
use tokio;
use tokio::io::{AsyncRead, AsyncWrite};
use tokio::net::TcpStream;

/// A type to implement either a TCP socket, or proxying through an external command.
pub enum Stream {
    #[allow(missing_docs)]
    Child(std::process::Child),
    #[allow(missing_docs)]
    Tcp(TcpStream),
}

impl Stream {
    /// Connect a direct TCP stream (as opposed to a proxied one).
    pub async fn tcp_connect(addr: &SocketAddr) -> Result<Stream, tokio::io::Error> {
        TcpStream::connect(addr).await.map(Stream::Tcp)
    }
    /// Connect through a proxy command.
    pub fn proxy_connect(cmd: &str, args: &[&str]) -> Result<Stream, failure::Error> {
        Ok(Stream::Child(Command::new(cmd).args(args).spawn()?))
    }
}

impl AsyncRead for Stream {
    fn poll_read(
        mut self: Pin<&mut Self>,
        cx: &mut Context,
        buf: &mut [u8],
    ) -> Poll<Result<usize, tokio::io::Error>> {
        match *self {
            Stream::Child(ref mut c) => Poll::Ready(c.stdout.as_mut().unwrap().read(buf)),
            Stream::Tcp(ref mut t) => AsyncRead::poll_read(Pin::new(t), cx, buf),
        }
    }
}

impl AsyncWrite for Stream {
    fn poll_write(
        mut self: Pin<&mut Self>,
        cx: &mut Context,
        buf: &[u8],
    ) -> Poll<Result<usize, tokio::io::Error>> {
        match *self {
            Stream::Child(ref mut c) => Poll::Ready(c.stdin.as_mut().unwrap().write(buf)),
            Stream::Tcp(ref mut t) => AsyncWrite::poll_write(Pin::new(t), cx, buf),
        }
    }

    fn poll_flush(
        mut self: Pin<&mut Self>,
        cx: &mut Context,
    ) -> Poll<Result<(), tokio::io::Error>> {
        match *self {
            Stream::Child(_) => Poll::Ready(Ok(())),
            Stream::Tcp(ref mut t) => AsyncWrite::poll_flush(Pin::new(t), cx),
        }
    }

    fn poll_shutdown(
        mut self: Pin<&mut Self>,
        cx: &mut Context,
    ) -> Poll<Result<(), tokio::io::Error>> {
        match *self {
            Stream::Child(_) => Poll::Ready(Ok(())),
            Stream::Tcp(ref mut t) => AsyncWrite::poll_shutdown(Pin::new(t), cx),
        }
    }
}

impl tcp::Tcp for Stream {
    fn tcp_shutdown(&mut self) -> Result<(), std::io::Error> {
        match *self {
            Stream::Child(_) => Ok(()),
            Stream::Tcp(ref mut t) => t.tcp_shutdown(),
        }
    }
}
1



2



3




























































































4
5
6

7
8
9
10


11
12
13
14
15
16
17
18
19
20
21

22
23
24
25



26
27
28
29
30

31
32
33

34
35
36
37

38

39
40
41
42


43
44
45


46
47


48
49
50
51
52
53
54
55
56
57
58

59
60
61
62



63
64
65
66
67
68
69
70

71
72
73

74
75
76
77
78





79
80
81
82
83
84


85
86
87


88
89


90
91
92
93
94
95
96
97
98
99
100

101
102
103
104



105
106
107
108
109
110
111
112
113
114

115
116
117

118
119
120





121
122

123
124
125
126
127
128
129
130
131
132
133

134
135
136
137
138
139
140
141
142
143
144
145
146
147
148




149
150
151
152
153
154
155
156
157
158
159
160




161
162
163
164
165
166
167
168
169

170
171
172
173
174
175
176
177
178






179
180
181
182
183
184
185
186
187
188

189
190
191
192
193
194
195

196
197
198
199
200
201
202
203
204
205
206
207
208
209

210

211

212
213
214
215
216
217
218
219
220
221
222
223
224



225

226
227
228
229
230
231
232
233
234
235
236
237
238
239

240

241
242
243
244
245
246
247
248
249
250
251
252
253
254

255

256
257
258
259
260
261
262
263
264
265
266
267
268
269

270
271
272
273
274
275
276
277

278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294



295

296
297
298
299
300
301
302
303
304
305
306

307

308
309
310
311
312
313
314
315
316
317
318






319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
use super::*;
use msg;
use thrussh_keys::encoding::Encoding;
use std::sync::Arc;

/// The type of a client session.
pub struct Session(pub(crate) CommonSession<Arc<Config>>);

impl Session {
    /// Flush the temporary cleartext buffer into the encryption
    /// buffer. This does *not* flush to the socket.
    pub fn flush(&mut self) -> Result<(), Error> {
        if let Some(ref mut enc) = self.0.encrypted {
            if enc.flush(
                &self.0.config.as_ref().limits,
                &mut self.0.cipher,
                &mut self.0.write_buffer,
            )
            {
                if let Some(exchange) = std::mem::replace(&mut enc.exchange, None) {
                    let mut kexinit = KexInit::initiate_rekey(exchange, &enc.session_id);
                    kexinit.client_write(
                        &self.0.config.as_ref(),
                        &mut self.0.cipher,
                        &mut self.0.write_buffer,
                    )?;
                    enc.rekey = Some(Kex::KexInit(kexinit))
                }
            }
        }
        Ok(())
    }

    /// Retrieves the configuration of this session.
    pub fn config(&self) -> &Config {
        &self.0.config
    }

    /// Retrieves the current user.
    pub fn auth_user(&self) -> &str {
        &self.0.auth_user
    }

    /// Sends a disconnect message.
    pub fn disconnect(&mut self, reason: Disconnect, description: &str, language_tag: &str) {
        self.0.disconnect(reason, description, language_tag);
    }

    /// Whether the client is authenticated.
    pub fn is_authenticated(&self) -> bool {
        if let Some(ref enc) = self.0.encrypted {
            if let Some(EncryptedState::Authenticated) = enc.state {
                return true;
            }
        }
        false
    }

    /// Whether the client is disconnected.
    pub fn is_disconnected(&self) -> bool {
        self.0.disconnected
    }

    /// Check whether a channel has been confirmed.
    pub fn channel_is_open(&self, channel: ChannelId) -> bool {
        if let Some(ref enc) = self.0.encrypted {
            if let Some(ref channel) = enc.channels.get(&channel) {
                return channel.confirmed;
            }
        }
        false
    }

    /// Tests whether we need an authentication method (for instance
    /// if the last attempt failed).
    pub fn has_auth_method(&self) -> bool {
        self.0.auth_method.is_some()
    }

    /// Returns the set of authentication methods that can continue, or None if this is not valid.
    pub fn valid_auth_methods(&self) -> Option<auth::MethodSet> {
        if let Some(ref enc) = self.0.encrypted {
            match enc.state {
                Some(EncryptedState::WaitingAuthRequest(ref auth_request)) => {
                    Some(auth_request.methods)
                }
                _ => None,
            }
        } else {
            None
        }
    }


    /// Request a session channel (the most basic type of
    /// channel). This function returns `Some(..)` immediately if the
    /// connection is authenticated, but the channel only becomes
    /// usable when it's confirmed by the server, as indicated by the
    /// `confirmed` field of the corresponding `Channel`.
    pub fn channel_open_session(&mut self) -> Result<ChannelId, Error> {
        let result = if let Some(ref mut enc) = self.0.encrypted {
    pub fn channel_open_session(&mut self) -> Result<ChannelId, failure::Error> {
        let result = if let Some(ref mut enc) = self.common.encrypted {
            match enc.state {
                Some(EncryptedState::Authenticated) => {
                EncryptedState::Authenticated => {
                    debug!("sending open request");

                    let sender_channel = enc.new_channel(
                        self.0.config.window_size,
                        self.0.config.maximum_packet_size,
                        self.common.config.window_size,
                        self.common.config.maximum_packet_size,
                    );
                    push_packet!(enc.write, {
                        enc.write.push(msg::CHANNEL_OPEN);
                        enc.write.extend_ssh_string(b"session");

                        // sender channel id.
                        enc.write.push_u32_be(sender_channel.0);

                        // window.
                        enc.write.push_u32_be(self.0.config.as_ref().window_size);
                        enc.write
                            .push_u32_be(self.common.config.as_ref().window_size);

                        // max packet size.
                        enc.write.push_u32_be(
                            self.0.config.as_ref().maximum_packet_size,
                        );
                        enc.write
                            .push_u32_be(self.common.config.as_ref().maximum_packet_size);
                    });
                    sender_channel
                }
                _ => return Err(Error::NotAuthenticated),
                _ => return Err(Error::NotAuthenticated.into()),
            }
        } else {
            return Err(Error::Inconsistent);
            return Err(Error::Inconsistent.into());
        };
        Ok(result)
    }


    /// Request an X11 channel, on which the X11 protocol may be tunneled.
    pub fn channel_open_x11(
        &mut self,
        originator_address: &str,
        originator_port: u32,
    ) -> Result<ChannelId, Error> {
        let result = if let Some(ref mut enc) = self.0.encrypted {
    ) -> Result<ChannelId, failure::Error> {
        let result = if let Some(ref mut enc) = self.common.encrypted {
            match enc.state {
                Some(EncryptedState::Authenticated) => {

                EncryptedState::Authenticated => {
                    let sender_channel = enc.new_channel(
                        self.0.config.window_size,
                        self.0.config.maximum_packet_size,
                        self.common.config.window_size,
                        self.common.config.maximum_packet_size,
                    );
                    push_packet!(enc.write, {
                        enc.write.push(msg::CHANNEL_OPEN);
                        enc.write.extend_ssh_string(b"x11");

                        // sender channel id.
                        enc.write.push_u32_be(sender_channel.0);

                        // window.
                        enc.write.push_u32_be(self.0.config.as_ref().window_size);
                        enc.write
                            .push_u32_be(self.common.config.as_ref().window_size);

                        // max packet size.
                        enc.write.push_u32_be(
                            self.0.config.as_ref().maximum_packet_size,
                        );
                        enc.write
                            .push_u32_be(self.common.config.as_ref().maximum_packet_size);

                        enc.write.extend_ssh_string(originator_address.as_bytes());
                        enc.write.push_u32_be(originator_port); // sender channel id.
                    });
                    sender_channel
                }
                _ => return Err(Error::NotAuthenticated),
                _ => return Err(Error::NotAuthenticated.into()),
            }
        } else {
            return Err(Error::Inconsistent);
            return Err(Error::Inconsistent.into());
        };
        Ok(result)
    }

    /// Open a TCP/IP forwarding channel. This is usually done when a
    /// connection comes to a locally forwarded TCP/IP port. See
    /// [RFC4254](https://tools.ietf.org/html/rfc4254#section-7). The
    /// TCP/IP packets can then be tunneled through the channel using
    /// `.data()`.
    pub fn channel_open_direct_tcpip(
        &mut self,
        host_to_connect: &str,
        port_to_connect: u32,
        originator_address: &str,
        originator_port: u32,
    ) -> Result<ChannelId, Error> {
        let result = if let Some(ref mut enc) = self.0.encrypted {
    ) -> Result<ChannelId, failure::Error> {
        let result = if let Some(ref mut enc) = self.common.encrypted {
            match enc.state {
                Some(EncryptedState::Authenticated) => {

                EncryptedState::Authenticated => {
                    let sender_channel = enc.new_channel(
                        self.0.config.window_size,
                        self.0.config.maximum_packet_size,
                        self.common.config.window_size,
                        self.common.config.maximum_packet_size,
                    );
                    push_packet!(enc.write, {
                        enc.write.push(msg::CHANNEL_OPEN);
                        enc.write.extend_ssh_string(b"direct-tcpip");

                        // sender channel id.
                        enc.write.push_u32_be(sender_channel.0);

                        // window.
                        enc.write.push_u32_be(self.0.config.as_ref().window_size);
                        enc.write
                            .push_u32_be(self.common.config.as_ref().window_size);

                        // max packet size.
                        enc.write.push_u32_be(
                            self.0.config.as_ref().maximum_packet_size,
                        );
                        enc.write
                            .push_u32_be(self.common.config.as_ref().maximum_packet_size);

                        enc.write.extend_ssh_string(host_to_connect.as_bytes());
                        enc.write.push_u32_be(port_to_connect); // sender channel id.
                        enc.write.extend_ssh_string(originator_address.as_bytes());
                        enc.write.push_u32_be(originator_port); // sender channel id.
                    });
                    sender_channel
                }
                _ => return Err(Error::NotAuthenticated),
                _ => return Err(Error::NotAuthenticated.into()),
            }
        } else {
            return Err(Error::Inconsistent);
            return Err(Error::Inconsistent.into());
        };
        Ok(result)
    }

    /// Send EOF to a channel
    pub fn channel_eof(&mut self, channel: ChannelId) {
        self.0.byte(channel, msg::CHANNEL_EOF);
    }

    /// Request a pseudo-terminal with the given characteristics.
    pub fn request_pty(
        &mut self,
        channel: ChannelId,
        want_reply: bool,
        term: &str,
        col_width: u32,
        row_height: u32,
        pix_width: u32,
        pix_height: u32,
        terminal_modes: &[(Pty, u32)],
    ) {
        if let Some(ref mut enc) = self.0.encrypted {
        if let Some(ref mut enc) = self.common.encrypted {
            if let Some(channel) = enc.channels.get(&channel) {
                push_packet!(enc.write, {
                    enc.write.push(msg::CHANNEL_REQUEST);

                    enc.write.push_u32_be(channel.recipient_channel);
                    enc.write.extend_ssh_string(b"pty-req");
                    enc.write.push(if want_reply { 1 } else { 0 });

                    enc.write.extend_ssh_string(term.as_bytes());
                    enc.write.push_u32_be(col_width);
                    enc.write.push_u32_be(row_height);
                    enc.write.push_u32_be(pix_width);
                    enc.write.push_u32_be(pix_height);

                    enc.write.push_u32_be(
                        (1 + 5 * terminal_modes.len()) as u32,
                    );
                    );
                    enc.write.push_u32_be((1 + 5 * terminal_modes.len()) as u32);
                    for &(code, value) in terminal_modes {
                        enc.write.push(code as u8);
                        enc.write.push_u32_be(value)
                    }
                    // 0 code (to terminate the list)
                    enc.write.push(0);
                });
            }
        }
    }

    /// Request X11 forwarding through an already opened X11
    /// channel. See
    /// [RFC4254](https://tools.ietf.org/html/rfc4254#section-6.3.1)
    /// for security issues related to cookies.
    pub fn request_x11(
        &mut self,
        channel: ChannelId,
        want_reply: bool,
        single_connection: bool,
        x11_authentication_protocol: &str,
        x11_authentication_cookie: &str,
        x11_screen_number: u32,
    ) {
        if let Some(ref mut enc) = self.0.encrypted {
        if let Some(ref mut enc) = self.common.encrypted {
            if let Some(channel) = enc.channels.get(&channel) {
                push_packet!(enc.write, {
                    enc.write.push(msg::CHANNEL_REQUEST);

                    enc.write.push_u32_be(channel.recipient_channel);
                    enc.write.extend_ssh_string(b"x11-req");
                    enc.write.push(if want_reply { 1 } else { 0 });
                    enc.write.push(if single_connection { 1 } else { 0 });
                    enc.write.extend_ssh_string(
                        x11_authentication_protocol.as_bytes(),
                    );
                    enc.write.extend_ssh_string(
                        x11_authentication_cookie.as_bytes(),
                    );
                    enc.write
                        .extend_ssh_string(x11_authentication_protocol.as_bytes());
                    enc.write
                        .extend_ssh_string(x11_authentication_cookie.as_bytes());
                    enc.write.push_u32_be(x11_screen_number);
                });
            }
        }
    }

    /// Set a remote environment variable.
    pub fn set_env(
        &mut self,
        channel: ChannelId,
        want_reply: bool,
        variable_name: &str,
        variable_value: &str,
    ) {
        if let Some(ref mut enc) = self.0.encrypted {
        if let Some(ref mut enc) = self.common.encrypted {
            if let Some(channel) = enc.channels.get(&channel) {
                push_packet!(enc.write, {
                    enc.write.push(msg::CHANNEL_REQUEST);

                    enc.write.push_u32_be(channel.recipient_channel);
                    enc.write.extend_ssh_string(b"env");
                    enc.write.push(if want_reply { 1 } else { 0 });
                    enc.write.extend_ssh_string(variable_name.as_bytes());
                    enc.write.extend_ssh_string(variable_value.as_bytes());
                });
            }
        }
    }


    /// Request a remote shell.
    pub fn request_shell(&mut self, want_reply: bool, channel: ChannelId) {
        if let Some(ref mut enc) = self.0.encrypted {
        if let Some(ref mut enc) = self.common.encrypted {
            if let Some(channel) = enc.channels.get(&channel) {
                push_packet!(enc.write, {
                    enc.write.push(msg::CHANNEL_REQUEST);

                    enc.write.push_u32_be(channel.recipient_channel);
                    enc.write.extend_ssh_string(b"shell");
                    enc.write.push(if want_reply { 1 } else { 0 });
                });
            }
        }
    }

    /// Execute a remote program (will be passed to a shell). This can
    /// be used to implement scp (by calling a remote scp and
    /// tunneling to its standard input).
    pub fn exec(&mut self, channel: ChannelId, want_reply: bool, command: &str) {
        if let Some(ref mut enc) = self.0.encrypted {
        if let Some(ref mut enc) = self.common.encrypted {
            if let Some(channel) = enc.channels.get(&channel) {
                push_packet!(enc.write, {
                    enc.write.push(msg::CHANNEL_REQUEST);

                    enc.write.push_u32_be(channel.recipient_channel);
                    enc.write.extend_ssh_string(b"exec");
                    enc.write.push(if want_reply { 1 } else { 0 });
                    enc.write.extend_ssh_string(command.as_bytes());
                });
            }
        }
    }

    /// Signal a remote process.
    pub fn signal(&mut self, channel: ChannelId, signal: Sig) {
        if let Some(ref mut enc) = self.0.encrypted {
        if let Some(ref mut enc) = self.common.encrypted {
            if let Some(channel) = enc.channels.get(&channel) {
                push_packet!(enc.write, {
                    enc.write.push(msg::CHANNEL_REQUEST);

                    enc.write.push_u32_be(channel.recipient_channel);
                    enc.write.extend_ssh_string(b"signal");
                    enc.write.push(0);
                    enc.write.extend_ssh_string(signal.name().as_bytes());
                });
            }
        }
    }

    /// Request the start of a subsystem with the given name.
    pub fn request_subsystem(&mut self, want_reply: bool, channel: ChannelId, name: &str) {
        if let Some(ref mut enc) = self.0.encrypted {
        if let Some(ref mut enc) = self.common.encrypted {
            if let Some(channel) = enc.channels.get(&channel) {
                push_packet!(enc.write, {
                    enc.write.push(msg::CHANNEL_REQUEST);

                    enc.write.push_u32_be(channel.recipient_channel);
                    enc.write.extend_ssh_string(b"subsystem");
                    enc.write.push(if want_reply { 1 } else { 0 });
                    enc.write.extend_ssh_string(name.as_bytes());
                });
            }
        }
    }

    /// Inform the server that our window size has changed.
    pub fn window_change(
        &mut self,
        channel: ChannelId,
        col_width: u32,
        row_height: u32,
        pix_width: u32,
        pix_height: u32,
    ) {
        if let Some(ref mut enc) = self.0.encrypted {
        if let Some(ref mut enc) = self.common.encrypted {
            if let Some(channel) = enc.channels.get(&channel) {
                push_packet!(enc.write, {
                    enc.write.push(msg::CHANNEL_REQUEST);

                    enc.write.push_u32_be(channel.recipient_channel);
                    enc.write.extend_ssh_string(b"window-change");
                    enc.write.push(0); // this packet never wants reply
                    enc.write.push_u32_be(col_width);
                    enc.write.push_u32_be(row_height);
                    enc.write.push_u32_be(pix_width);
                    enc.write.push_u32_be(pix_height);
                });
            }
        }
    }

    /// Request the forwarding of a remote port to the client. The
    /// server will then open forwarding channels (which cause the
    /// client to call `.channel_open_forwarded_tcpip()`).
    pub fn tcpip_forward(&mut self, want_reply: bool, address: &str, port: u32) {
        if let Some(ref mut enc) = self.0.encrypted {
        if let Some(ref mut enc) = self.common.encrypted {
            push_packet!(enc.write, {
                enc.write.push(msg::GLOBAL_REQUEST);
                enc.write.extend_ssh_string(b"tcpip-forward");
                enc.write.push(if want_reply { 1 } else { 0 });
                enc.write.extend_ssh_string(address.as_bytes());
                enc.write.push_u32_be(port);
            });
        }
    }

    /// Cancel a previous forwarding request.
    pub fn cancel_tcpip_forward(&mut self, want_reply: bool, address: &str, port: u32) {
        if let Some(ref mut enc) = self.0.encrypted {
        if let Some(ref mut enc) = self.common.encrypted {
            push_packet!(enc.write, {
                enc.write.push(msg::GLOBAL_REQUEST);
                enc.write.extend_ssh_string(b"cancel-tcpip-forward");
                enc.write.push(if want_reply { 1 } else { 0 });
                enc.write.extend_ssh_string(address.as_bytes());
                enc.write.push_u32_be(port);
            });
        }
    }

    /// Send data to a channel. The number of bytes added to the
    /// "sending pipeline" (to be processed by the event loop) is
    /// returned.
    pub fn data(&mut self, channel: ChannelId, extended: Option<u32>, data: &[u8]) -> usize {
        if let Some(ref mut enc) = self.0.encrypted {
            enc.data(channel, extended, data)
    pub fn data(&mut self, channel: ChannelId, data: &[u8]) -> usize {
        if let Some(ref mut enc) = self.common.encrypted {
            enc.data(channel, data)
        } else {
            unreachable!()
        }
    }

    pub fn eof(&mut self, channel: ChannelId) {
        if let Some(ref mut enc) = self.common.encrypted {
            enc.eof(channel)
        } else {
            unreachable!()
        }
    }

    pub fn extended_data(&mut self, channel: ChannelId, ext: u32, data: &[u8]) -> usize {
        if let Some(ref mut enc) = self.common.encrypted {
            enc.extended_data(channel, ext, data)
        } else {
            unreachable!()
        }
    }

    pub fn disconnect(&mut self, reason: Disconnect, description: &str, language_tag: &str) {
        self.common.disconnect(reason, description, language_tag);
    }












































































































use super::*;
use tokio::io::{AsyncRead, AsyncWrite};
use tcp::Tcp;

impl<R: AsyncRead + AsyncWrite, H: Handler> Connection<R, H> {
    /// Wait until a condition is met on the connection.
    pub fn wait<F: Fn(&Connection<R, H>) -> bool>(self, f: F) -> Wait<R, H, F> {
        Wait {
            connection: Some(self),
            condition: f,
            first_round: true,
        }
    }

    /// Flush the session, sending any pending message.
    pub fn wait_flush(self) -> WaitFlush<R, H> {
        WaitFlush {
            connection: Some(self),
            first_round: true,
        }
    }
}

/// A future waiting for a channel to be closed.
pub struct Wait<R: AsyncRead + AsyncWrite, H: Handler, F> {
    connection: Option<Connection<R, H>>,
    condition: F,
    first_round: bool,
}

impl<R: AsyncRead + AsyncWrite + Tcp, H: Handler, F: Fn(&Connection<R, H>) -> bool> Future
    for Wait<R, H, F> {
    type Item = Connection<R, H>;
    type Error = HandlerError<H::Error>;

    fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
        if self.first_round {
            if let Some(ref mut c) = self.connection {
                c.abort_read()?
            }
            self.first_round = false
        }

        loop {
            debug!("wait loop");
            if let Some(mut connection) = self.connection.take() {
                if connection.handler.is_some() && (self.condition)(&connection) &&
                    connection.is_reading()
                {
                    return Ok(Async::Ready(connection));
                } else {
                    match try!(connection.atomic_poll()) {
                        Async::Ready(Status::Ok) => {
                            self.connection = Some(connection);
                        }
                        Async::Ready(Status::Disconnect) => return Ok(Async::Ready(connection)),
                        Async::NotReady => {
                            self.connection = Some(connection);
                            return Ok(Async::NotReady);
                        }
                    }
                }
            }
        }
    }
}


/// A future waiting for a flush request to complete.
pub struct WaitFlush<R: AsyncRead + AsyncWrite, H: Handler> {
    connection: Option<Connection<R, H>>,
    first_round: bool,
}


impl<R: AsyncRead + AsyncWrite + Tcp, H: Handler> Future for WaitFlush<R, H> {
    type Item = Connection<R, H>;
    type Error = HandlerError<H::Error>;

    fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
        if self.first_round {
            if let Some(ref mut c) = self.connection {
                c.abort_read()?
            }
            self.first_round = false
        }
        loop {
            debug!("WaitFlush loop");
            if let Some(mut c) = self.connection.take() {
                match try!(c.atomic_poll()) {
                    Async::Ready(Status::Disconnect) => return Ok(Async::Ready(c)),
                    Async::NotReady => {
                        self.connection = Some(c);
                        return Ok(Async::NotReady);
                    }
                    Async::Ready(Status::Ok) => {
                        match c.state {
                            Some(ConnectionState::Read(_)) => return Ok(Async::Ready(c)),
                            _ => self.connection = Some(c),
                        }
                    }
                }
            } else {
                unreachable!()
            }
        }
    }
}


























































































































































































// Copyright 2016 Pierre-Étienne Meunier
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

use byteorder::{ByteOrder, BigEndian};
use Error;
use cryptovec::CryptoVec;

#[doc(hidden)]
pub trait Bytes {
    fn bytes(&self) -> &[u8];
}

impl<A: AsRef<str>> Bytes for A {
    fn bytes(&self) -> &[u8] {
        self.as_ref().as_bytes()
    }
}

/// Encode in the SSH format.
pub trait Encoding {
    /// Push an SSH-encoded string to `self`.
    fn extend_ssh_string(&mut self, s: &[u8]);
    /// Push an SSH-encoded blank string of length `s` to `self`.
    fn extend_ssh_string_blank(&mut self, s: usize) -> &mut [u8];
    /// Push an SSH-encoded multiple-precision integer.
    fn extend_ssh_mpint(&mut self, s: &[u8]);
    /// Push an SSH-encoded list.
    fn extend_list<A: Bytes, I: Iterator<Item = A>>(&mut self, list: I);
    /// Push an SSH-encoded empty list.
    fn write_empty_list(&mut self);
}

/// Encoding length of the given mpint.
pub fn mpint_len(s: &[u8]) -> usize {
    let mut i = 0;
    while i < s.len() && s[i] == 0 {
        i += 1
    }
    (if s[i] & 0x80 != 0 { 5 } else { 4 }) + s.len() - i
}


impl Encoding for CryptoVec {
    fn extend_ssh_string(&mut self, s: &[u8]) {
        self.push_u32_be(s.len() as u32);
        self.extend(s);
    }
    fn extend_ssh_string_blank(&mut self, len: usize) -> &mut [u8] {
        self.push_u32_be(len as u32);
        let current = self.len();
        self.resize(current + len);
        &mut self[current..]
    }
    fn extend_ssh_mpint(&mut self, s: &[u8]) {
        // Skip initial 0s.
        let mut i = 0;
        while i < s.len() && s[i] == 0 {
            i += 1
        }
        // If the first non-zero is >= 128, write its length (u32, BE), followed by 0.
        if s[i] & 0x80 != 0 {

            self.push_u32_be((s.len() - i + 1) as u32);
            self.push(0)

        } else {

            self.push_u32_be((s.len() - i) as u32);

        }
        self.extend(&s[i..]);
    }


    fn extend_list<A: Bytes, I: Iterator<Item = A>>(&mut self, list: I) {
        let len0 = self.len();
        self.extend(&[0, 0, 0, 0]);
        let mut first = true;
        for i in list {
            if !first {
                self.push(b',')
            } else {
                first = false;
            }
            self.extend(i.bytes())
        }
        let len = (self.len() - len0 - 4) as u32;

        BigEndian::write_u32(&mut self[len0..], len);
    }

    fn write_empty_list(&mut self) {
        self.extend(&[0, 0, 0, 0]);
    }
}

/// A cursor-like trait to read SSH-encoded things.
pub trait Reader {
    /// Create an SSH reader for `self`.
    fn reader<'a>(&'a self, starting_at: usize) -> Position<'a>;
}

impl Reader for CryptoVec {
    fn reader<'a>(&'a self, starting_at: usize) -> Position<'a> {
        Position {
            s: &self,
            position: starting_at,
        }
    }
}

impl Reader for [u8] {
    fn reader<'a>(&'a self, starting_at: usize) -> Position<'a> {
        Position {
            s: self,
            position: starting_at,
        }
    }
}

/// A cursor-like type to read SSH-encoded values.
#[derive(Debug)]
pub struct Position<'a> {
    s: &'a [u8],
    #[doc(hidden)]
    pub position: usize,
}
impl<'a> Position<'a> {
    /// Read one string from this reader.
    pub fn read_string(&mut self) -> Result<&'a [u8], Error> {
        let len = self.read_u32()? as usize;
        if self.position + len <= self.s.len() {
            let result = &self.s[self.position..(self.position + len)];
            self.position += len;
            Ok(result)
        } else {
            Err(Error::IndexOutOfBounds)
        }
    }
    /// Read a `u32` from this reader.
    pub fn read_u32(&mut self) -> Result<u32, Error> {
        if self.position + 4 <= self.s.len() {
            let u = BigEndian::read_u32(&self.s[self.position..]);
            self.position += 4;
            Ok(u)
        } else {
            Err(Error::IndexOutOfBounds)
        }
    }
    /// Read one byte from this reader.
    pub fn read_byte(&mut self) -> Result<u8, Error> {
        if self.position + 1 <= self.s.len() {
            let u = self.s[self.position];
            self.position += 1;
            Ok(u)
        } else {
            Err(Error::IndexOutOfBounds)
        }
    }

    /// Read one byte from this reader.
    pub fn read_mpint(&mut self) -> Result<&'a [u8], Error> {
        let len = self.read_u32()? as usize;
        if self.position + len <= self.s.len() {
            let result = &self.s[self.position..(self.position + len)];
            self.position += len;
            Ok(result)
        } else {
            Err(Error::IndexOutOfBounds)
        }
    }
}
13
14




15
16
17
18
19




20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63

64
65
66
67
68
69
70



71
72
73
74
75
76
77

78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97



98
99
100
101
102
103
104
105
106
107
108
109
110
111

112
113
114
115
116
117
118

119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135

136
137
138
139
140
141
142
143

144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159

160
161
162
163


164
165

166
167
168
169
170
171
172



173
174
175
176
177
178
179



180
181
182
183










184
185
186
187
188
189
190
191
192
193
194












195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211




212





213
214
215
216
217
218


219
220
221
222


223
224
225



226
227
228
229
230
231
// limitations under the License.
//
use byteorder::{ByteOrder, BigEndian};
use std;
use Error;
use msg;
use crate::{cipher, key, msg};
use byteorder::{BigEndian, ByteOrder};

use crate::session::Exchange;
use cryptovec::CryptoVec;
use session::Exchange;
use key;
use cipher;
use thrussh_keys::encoding::Encoding;
use openssl;
use sodium;
use std::cell::RefCell;
use thrussh_keys::encoding::Encoding;

#[doc(hidden)]
pub struct Algorithm {
    local_secret: Option<sodium::scalarmult::Scalar>,
    shared_secret: Option<sodium::scalarmult::GroupElement>,
}

impl std::fmt::Debug for Algorithm {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        write!(
            f,
            "Algorithm {{ local_secret: [hidden], shared_secret: [hidden] }}",
        )
    }
}

#[derive(Debug, PartialEq, Eq, Copy, Clone)]
pub struct Name(&'static str);
impl AsRef<str> for Name {
    fn as_ref(&self) -> &str {
        self.0
    }
}
pub const CURVE25519: Name = Name("curve25519-sha256@libssh.org");

thread_local! {
    static KEY_BUF: RefCell<CryptoVec> = RefCell::new(CryptoVec::new());
    static BUFFER: RefCell<CryptoVec> = RefCell::new(CryptoVec::new());
}

// We used to support curve "NIST P-256" here, but the security of
// that curve is controversial, see
// http://safecurves.cr.yp.to/rigid.html

impl Algorithm {
    #[doc(hidden)]
    pub fn server_dh(
        _name: Name,
        exchange: &mut Exchange,
        payload: &[u8],
    ) -> Result<Algorithm, Error> {
    ) -> Result<Algorithm, failure::Error> {
        debug!("server_dh");

        assert_eq!(payload[0], msg::KEX_ECDH_INIT);
        let mut client_pubkey = GroupElement([0; 32]);
        {
            let pubkey_len = BigEndian::read_u32(&payload[1..]) as usize;
            client_pubkey.0.clone_from_slice(
                &payload[5..(5 + pubkey_len)],
            )
            client_pubkey
                .0
                .clone_from_slice(&payload[5..(5 + pubkey_len)])
        };
        debug!("client_pubkey: {:?}", client_pubkey);
        use openssl::rand::*;
        use sodium::scalarmult::*;
        use openssl::rand::*;
        let mut server_secret = Scalar([0; 32]);
        rand_bytes(&mut server_secret.0)?;
        let sodium = sodium::Sodium::new();
        let server_pubkey = sodium.scalarmult_base(&server_secret);

        // fill exchange.
        exchange.server_ephemeral.clear();
        exchange.server_ephemeral.extend(&server_pubkey.0);
        let shared = sodium.scalarmult(&server_secret, &client_pubkey);
        Ok(Algorithm {
            local_secret: None,
            shared_secret: Some(shared),
        })
    }

    #[doc(hidden)]
    pub fn client_dh(
        _name: Name,
        client_ephemeral: &mut CryptoVec,
        buf: &mut CryptoVec,
    ) -> Result<Algorithm, Error> {

        use sodium::scalarmult::*;
    ) -> Result<Algorithm, failure::Error> {
        use openssl::rand::*;
        use sodium::scalarmult::*;
        let mut client_secret = Scalar([0; 32]);
        rand_bytes(&mut client_secret.0)?;
        let sodium = sodium::Sodium::new();
        let client_pubkey = sodium.scalarmult_base(&client_secret);

        // fill exchange.
        client_ephemeral.clear();
        client_ephemeral.extend(&client_pubkey.0);

        buf.push(msg::KEX_ECDH_INIT);
        buf.extend_ssh_string(&client_pubkey.0);


        Ok(Algorithm {
            local_secret: Some(client_secret),
            shared_secret: None,
        })
    }

    pub fn compute_shared_secret(&mut self, remote_pubkey_: &[u8]) -> Result<(), Error> {
    pub fn compute_shared_secret(&mut self, remote_pubkey_: &[u8]) -> Result<(), failure::Error> {
        let local_secret = std::mem::replace(&mut self.local_secret, None).unwrap();

        use sodium::scalarmult::*;
        let mut remote_pubkey = GroupElement([0; 32]);
        remote_pubkey.0.clone_from_slice(remote_pubkey_);
        let sodium = sodium::Sodium::new();
        let shared = sodium.scalarmult(&local_secret, &remote_pubkey);
        self.shared_secret = Some(shared);
        Ok(())
    }

    pub fn compute_exchange_hash<K: key::PubKey>(
        &self,
        key: &K,
        exchange: &Exchange,
        buffer: &mut CryptoVec,
    ) -> Result<openssl::hash::DigestBytes, Error> {
    ) -> Result<openssl::hash::DigestBytes, failure::Error> {
        // Computing the exchange hash, see page 7 of RFC 5656.
        buffer.clear();
        buffer.extend_ssh_string(&exchange.client_id);
        buffer.extend_ssh_string(&exchange.server_id);
        buffer.extend_ssh_string(&exchange.client_kex_init);
        buffer.extend_ssh_string(&exchange.server_kex_init);


        key.push_to(buffer);
        buffer.extend_ssh_string(&exchange.client_ephemeral);
        buffer.extend_ssh_string(&exchange.server_ephemeral);

        if let Some(ref shared) = self.shared_secret {
            buffer.extend_ssh_mpint(&shared.0);
        }
        use openssl::hash::*;
        let hash = {
            let mut hasher = Hasher::new(MessageDigest::sha256())?;
            hasher.update(&buffer)?;
            hasher.finish()?
        };
        Ok(hash)
    }


    pub fn compute_keys(
        &self,
        session_id: &openssl::hash::DigestBytes,
        exchange_hash: &openssl::hash::DigestBytes,
        buffer: &mut CryptoVec,
        key: &mut CryptoVec,
        cipher: cipher::Name,
        is_server: bool,
    ) -> Result<super::cipher::CipherPair, Error> {
    ) -> Result<super::cipher::CipherPair, failure::Error> {
        let cipher = match cipher {
            super::cipher::chacha20poly1305::NAME => &super::cipher::chacha20poly1305::CIPHER,
            _ => unreachable!(),
        };

        // https://tools.ietf.org/html/rfc4253#section-7.2
        let mut compute_key = |c, key: &mut CryptoVec, len| -> Result<(), Error> {
            buffer.clear();
            key.clear();
        BUFFER.with(|buffer| {
            KEY_BUF.with(|key| {
                let compute_key = |c, key: &mut CryptoVec, len| -> Result<(), failure::Error> {
                    let mut buffer = buffer.borrow_mut();
                    buffer.clear();
                    key.clear();

            if let Some(ref shared) = self.shared_secret {
                buffer.extend_ssh_mpint(&shared.0);
            }
                    if let Some(ref shared) = self.shared_secret {
                        buffer.extend_ssh_mpint(&shared.0);
                    }

            buffer.extend(exchange_hash.as_ref());
            buffer.push(c);
            buffer.extend(session_id.as_ref());
            use openssl::hash::*;
            let hash = {
                let mut hasher = Hasher::new(MessageDigest::sha256())?;
                hasher.update(&buffer)?;
                hasher.finish()?
            };
            key.extend(hash.as_ref());
                    buffer.extend(exchange_hash.as_ref());
                    buffer.push(c);
                    buffer.extend(session_id.as_ref());
                    use openssl::hash::*;
                    let hash = {
                        let mut hasher = Hasher::new(MessageDigest::sha256())?;
                        hasher.update(&buffer)?;
                        hasher.finish()?
                    };
                    key.extend(hash.as_ref());

            while key.len() < len {
                // extend.
                buffer.clear();
                if let Some(ref shared) = self.shared_secret {
                    buffer.extend_ssh_mpint(&shared.0);
                }
                buffer.extend(exchange_hash.as_ref());
                buffer.extend(key);
                let hash = {
                    let mut hasher = Hasher::new(MessageDigest::sha256())?;
                    hasher.update(&buffer)?;
                    hasher.finish()?
                    while key.len() < len {
                        // extend.
                        buffer.clear();
                        if let Some(ref shared) = self.shared_secret {
                            buffer.extend_ssh_mpint(&shared.0);
                        }
                        buffer.extend(exchange_hash.as_ref());
                        buffer.extend(key);
                        let hash = {
                            let mut hasher = Hasher::new(MessageDigest::sha256())?;
                            hasher.update(&buffer)?;
                            hasher.finish()?
                        };
                        key.extend(&hash.as_ref());
                    }
                    Ok(())
                };
                key.extend(&hash.as_ref());
            }
            Ok(())
        };

        let (local_to_remote, remote_to_local) = if is_server {
            (b'D', b'C')
        } else {
            (b'C', b'D')
        };
                let (local_to_remote, remote_to_local) = if is_server {
                    (b'D', b'C')
                } else {
                    (b'C', b'D')
                };

        compute_key(local_to_remote, key, cipher.key_len)?;
        let local_to_remote = (cipher.make_sealing_cipher)(key);
                let mut key = key.borrow_mut();
                compute_key(local_to_remote, &mut key, cipher.key_len)?;
                let local_to_remote = (cipher.make_sealing_cipher)(&key);

        compute_key(remote_to_local, key, cipher.key_len)?;
        let remote_to_local = (cipher.make_opening_cipher)(key);
                compute_key(remote_to_local, &mut key, cipher.key_len)?;
                let remote_to_local = (cipher.make_opening_cipher)(&key);

        Ok(super::cipher::CipherPair {
            local_to_remote: local_to_remote,
            remote_to_local: remote_to_local,
                Ok(super::cipher::CipherPair {
                    local_to_remote: local_to_remote,
                    remote_to_local: remote_to_local,
                })
            })
        })
14
15
16
17

18
19
20
21
22
23
24
25
26
27

28
29
30
31
32
33
34
35



36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53

54
55
56



57
58
//
use cryptovec::CryptoVec;
use thrussh_keys::encoding::*;
use thrussh_keys::key::*;
use cryptovec::CryptoVec;

#[doc(hidden)]
pub trait PubKey {
    fn push_to(&self, buffer: &mut CryptoVec);
}

impl PubKey for PublicKey {
    fn push_to(&self, buffer: &mut CryptoVec) {
        match self {
            &PublicKey::Ed25519(ref public) => {

                buffer.push_u32_be((ED25519.0.len() + public.key.len() + 8) as u32);
                buffer.extend_ssh_string(ED25519.0.as_bytes());
                buffer.extend_ssh_string(&public.key);
            }
            &PublicKey::RSA { ref key, .. } => {
                let rsa = key.0.rsa().unwrap();
                let e = rsa.e().to_vec();
                let n = rsa.n().to_vec();
                buffer.push_u32_be(
                    (4 + SSH_RSA.len() + mpint_len(&n) + mpint_len(&e)) as u32,
                );
                buffer.push_u32_be((4 + SSH_RSA.len() + mpint_len(&n) + mpint_len(&e)) as u32);
                buffer.extend_ssh_string(SSH_RSA.as_bytes());
                buffer.extend_ssh_mpint(&e);
                buffer.extend_ssh_mpint(&n);
            }
        }
    }
}

impl PubKey for KeyPair {
    fn push_to(&self, buffer: &mut CryptoVec) {
        match self {
            &KeyPair::Ed25519(ref key) => {
                let public = &key.key[32..];
                buffer.push_u32_be((ED25519.0.len() + public.len() + 8) as u32);
                buffer.extend_ssh_string(ED25519.0.as_bytes());
                buffer.extend_ssh_string(public);
            }
            &KeyPair::RSA { ref key, ..} => {
            &KeyPair::RSA { ref key, .. } => {
                let e = key.e().to_vec();
                let n = key.n().to_vec();
                buffer.push_u32_be(
                    (4 + SSH_RSA.len() + mpint_len(&n) + mpint_len(&e)) as u32,
                );
                buffer.push_u32_be((4 + SSH_RSA.len() + mpint_len(&n) + mpint_len(&e)) as u32);
                buffer.extend_ssh_string(SSH_RSA.as_bytes());



















1
2
3
4
5
6
7
8
9
10
11
12
13
14
15





16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73

74
75
76
77
78
79
80
81




82
83
84
85


86
87
88


89
90
91


92
93
94

95
96
97
98
99

100
101


102
103
104

105
106
107
108
109

110
111
112
113


114
115
116
117

















118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
















191
192
193
194
195
196












197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270

271
272









273

274
275
276


277

278
279
280
281
282
283
284
285
286

287
288
289
290
291
292
293
294













295
296
297
298
299
300
301
302
303
304
305
306

307
308
309
310
311
312
313
314








































315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341

342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360



361
362
363
364
365
366
367
368
369
370
371
372
373



374
375
376
377
378
379
380
381
382
383

384
385
386
387
388
389









390
391
392
393
394
395
396
397
398





399
400
401
402










403
404
405
406
407
408







409
410
411
412
413
414




415
416
417
418
419
420
421








































422

































































































423
424
425


426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452

453
454
455
456
457
458
459
460






461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487


488
489
490
491
492
493
494
495
496
497
498
499
500
501

502
503
504


505
506
507
508
509
510
511
512
513
514
515
516
517
518
519

520
521
522

523
524
525
526
527
528
529
530
531
532
533
534
535
536

537
538
539
540

541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562

563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
//!    fn check_server_key(&mut self, server_public_key: &key::PublicKey) -> Self::FutureBool {
//!        self.finished_bool(true)
//!    fn channel_open_confirmation(&mut self, channel: ChannelId, session: &mut client::Session) -> Self::FutureUnit {
//!        self.finished()
//!    fn data(&mut self, channel: ChannelId, data: &[u8], session: &mut client::Session) -> Self::FutureUnit {
//!        println!("data on channel {:?}: {:?}", channel, std::str::from_utf8(data));
//!        self.finished()
//! let config = thrussh::client::Config::default();
//! let config = Arc::new(config);
//! let sh = Client{};
//! let key = thrussh_keys::key::KeyPair::generate_ed25519().unwrap();
//! let mut agent = thrussh_keys::agent::client::AgentClient::connect_env().await.unwrap();
//! agent.add_identity(&key, &[]).await.unwrap();
//! let mut session = thrussh::client::connect(config, "127.0.0.1:2222", sh).await.unwrap();
//! if session.authenticate_future("pe", key.clone_public_key(), agent).await.unwrap() {
//!     let mut channel = session.channel_open_session().await.unwrap();
//!     channel.data("Hello, world!").await.unwrap();
//!     if let Some(msg) = channel.wait().await {
//!         println!("{:?}", msg)
// Copyright 2016 Pierre-Étienne Meunier
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

#![deny(missing_docs,
        trivial_casts,
        unstable_features,
        unused_import_braces)]

//! Server and client SSH asynchronous library, based on tokio/futures.
//!
//! The normal way to use this library, both for clients and for
//! servers, is by creating *handlers*, i.e. types that implement
//! `client::Handler` for clients and `server::Handler` for
//! servers.
//!
//! # Writing servers
//!
//! In the specific case of servers, a server must implement
//! `server::Server`, a trait for creating new `server::Handler`.  The
//! main type to look at in the `server` module is `Session` (and
//! `Config`, of course).
//!
//! Here is an example server, which forwards input from each client
//! to all other clients:
//!
//! ```
//! extern crate thrussh;
//! extern crate thrussh_keys;
//! extern crate futures;
//! extern crate tokio;
//! use std::sync::{Mutex, Arc};
//! use thrussh::*;
//! use thrussh::server::{Auth, Session};
//! use thrussh_keys::*;
//! use std::collections::HashMap;
//! use futures::Future;
//!
//! #[tokio::main]
//! async fn main() {
//!     let client_key = thrussh_keys::key::KeyPair::generate_ed25519().unwrap();
//!     let client_pubkey = Arc::new(client_key.clone_public_key());
//!     let mut config = thrussh::server::Config::default();
//!     config.connection_timeout = Some(std::time::Duration::from_secs(3));
//!     config.auth_rejection_time = std::time::Duration::from_secs(3);
//!     config.keys.push(thrussh_keys::key::KeyPair::generate_ed25519().unwrap());
//!     let config = Arc::new(config);
//!     let sh = Server{
//!         client_pubkey,
//!         clients: Arc::new(Mutex::new(HashMap::new())),
//!         id: 0
//!     };
//!     tokio::time::timeout(
//!        std::time::Duration::from_secs(1),
//!        thrussh::server::run(config, "0.0.0.0:2222", sh)
//!     ).await.unwrap_or(Ok(()));
//! }
//!
//! #[derive(Clone)]
//! struct Server {
//!     client_pubkey: Arc<thrussh_keys::key::PublicKey>,
//!     clients: Arc<Mutex<HashMap<(usize, ChannelId), thrussh::server::Handle>>>,
//!     id: usize,
//! }
//!
//! impl server::Server for Server {
//!     type Handler = Self;
//!     fn new(&mut self) -> Self {
//!     fn new(&mut self, _: Option<std::net::SocketAddr>) -> Self {
//!         let s = self.clone();
//!         self.id += 1;
//!         s
//!     }
//! }
//!
//! impl server::Handler for Server {
//!     type Error = std::io::Error;
//!     type FutureAuth = futures::Finished<(Self, server::Auth), Self::Error>;
//!     type FutureUnit = futures::Finished<(Self, server::Session), Self::Error>;
//!     type FutureBool = futures::Finished<(Self, server::Session, bool), Self::Error>;
//!     type FutureAuth = futures::future::Ready<Result<server::Auth, failure::Error>>;
//!     type FutureUnit = futures::future::Ready<Result<(), failure::Error>>;
//!     type FutureBool = futures::future::Ready<Result<bool, failure::Error>>;
//!
//!     fn finished_auth(self, auth: Auth) -> Self::FutureAuth {
//!         futures::finished((self, auth))
//!     fn finished_auth(&mut self, auth: Auth) -> Self::FutureAuth {
//!         futures::future::ready(Ok(auth))
//!     }
//!     fn finished_bool(self, session: Session, b: bool) -> Self::FutureBool {
//!         futures::finished((self, session, b))
//!     fn finished_bool(&mut self, b: bool, s: &mut Session) -> Self::FutureBool {
//!         futures::future::ready(Ok(b))
//!     }
//!     fn finished(self, session: Session) -> Self::FutureUnit {
//!         futures::finished((self, session))
//!     fn finished(&mut self, s: &mut Session) -> Self::FutureUnit {
//!         futures::future::ready(Ok(()))
//!     }
//!     fn channel_open_session(self, channel: ChannelId, session: Session) -> Self::FutureUnit {
//!     fn channel_open_session(&mut self, channel: ChannelId, session: &mut Session) -> Self::FutureUnit {
//!         {
//!             let mut clients = self.clients.lock().unwrap();
//!             clients.insert((self.id, channel), session.handle());
//!         }
//!         futures::finished((self, session))
//!         self.finished(session)
//!     }
//!     fn auth_publickey(self, _: &str, _: &key::PublicKey) -> Self::FutureAuth {
//!         futures::finished((self, server::Auth::Accept))
//!     fn auth_publickey(&mut self, _: &str, _: &key::PublicKey) -> Self::FutureAuth {
//!         self.finished_auth(server::Auth::Accept)
//!     }
//!     fn data(self, channel: ChannelId, data: &[u8], mut session: server::Session) -> Self::FutureUnit {
//!     fn data(&mut self, channel: ChannelId, data: &[u8], mut session: &mut Session) -> Self::FutureUnit {
//!         {
//!             let mut clients = self.clients.lock().unwrap();
//!             for ((id, channel), ref mut s) in clients.iter_mut() {
//!                 if *id != self.id {
//!                     s.data(*channel, None, CryptoVec::from_slice(data));
//!                     s.data(*channel, CryptoVec::from_slice(data));
//!                 }
//!             }
//!         }
//!         session.data(channel, None, data);
//!         futures::finished((self, session))
//!         session.data(channel, data);
//!         self.finished(session)
//!     }
//! }
//!
//! fn main() {
//!     //! Starting the server thread.
//!     let client_key = thrussh_keys::key::KeyPair::generate_ed25519().unwrap();
//!     let client_pubkey = Arc::new(client_key.clone_public_key());
//!     let mut config = thrussh::server::Config::default();
//!     config.connection_timeout = Some(std::time::Duration::from_secs(600));
//!     config.auth_rejection_time = std::time::Duration::from_secs(3);
//!     config.keys.push(thrussh_keys::key::KeyPair::generate_ed25519().unwrap());
//!     let config = Arc::new(config);
//!     let sh = Server{
//!         client_pubkey,
//!         clients: Arc::new(Mutex::new(HashMap::new())),
//!         id: 0
//!     };
//!     tokio::run(thrussh::server::run(config, "0.0.0.0:2222", sh));
//! }
//! ```
//!
//! Note the call to `session.handle()`, which allows to keep a handle
//! to a client outside the event loop. This feature is internally
//! implemented using `futures::sync::mpsc` channels.
//!
//! Note that this is just a toy server. In particular:
//!
//! - It doesn't handle errors when `s.data` returns an error,
//!   i.e. when the client has disappeared
//!
//! - Each new connection increments the `id` field. Even though we
//! would need a lot of connections per second for a very long time to
//! saturate it, there are probably better ways to handle this to
//! avoid collisions.
//!
//!
//! # Implementing clients
//!
//! Maybe surprisingly, the data types used by Thrussh to implement
//! clients are relatively more complicated than for servers. This is
//! mostly related to the fact that clients are generally used both in
//! a synchronous way (in the case of SSH, we can think of sending a
//! shell command), and asynchronously (because the server may send
//! unsolicited messages sometimes), and hence need to handle
//! multiple interfaces.
//!
//! The important types in the `client` module are `Session` and
//! `Connection`. A `Connection` is typically used to send commands to
//! the server and wait for responses, and contains a `Session`. The
//! `Session` is passed to the `Handler` when the client receives
//! data.
//!
//! ```
//! extern crate thrussh;
//! extern crate thrussh_keys;
//! extern crate futures;
//! extern crate tokio;
//! extern crate env_logger;
//! use std::sync::Arc;
//! use thrussh::*;
//! use thrussh::server::{Auth, Session};
//! use thrussh_keys::*;
//! use futures::Future;
//! use std::io::Read;
//!
//!
//! struct Client { }
//!
//! impl client::Handler for Client {
//!     type FutureUnit = futures::future::Ready<Result<(), failure::Error>>;
//!     type FutureBool = futures::future::Ready<Result<bool, failure::Error>>;
//!
//!     fn finished_bool(&mut self, b: bool) -> Self::FutureBool {
//!         futures::future::ready(Ok(b))
//!     }
//!     fn finished(&mut self) -> Self::FutureUnit {
//!         futures::future::ready(Ok(()))
//!     }
//!     fn check_server_key(&mut self, server_public_key: &key::PublicKey) -> Self::FutureBool {
//!         println!("check_server_key: {:?}", server_public_key);
//!         self.finished_bool(true)
//!     }
//!     fn channel_open_confirmation(&mut self, channel: ChannelId, session: &mut client::Session) -> Self::FutureUnit {
//!         println!("channel_open_confirmation: {:?}", channel);
//!         self.finished()
//!     }
//!     fn data(&mut self, channel: ChannelId, data: &[u8], session: &mut client::Session) -> Self::FutureUnit {
//!         println!("data on channel {:?}: {:?}", channel, std::str::from_utf8(data));
//!         self.finished()
//!     }
//! }
//!
//!       client::connect_future(
//!         "127.0.0.1:2222", config, None, self,
//!         |connection| {
//!           connection.authenticate_key("pe", key)
//!             .and_then(|session| {
//!               session.channel_open_session().and_then(|(session, channelid)| {
//!                 session.data(channelid, None, "Hello, world!").and_then(|(mut session, _)| {
//!                   session.disconnect(Disconnect::ByApplication, "Ciao", "");
//!                   session
//!                 })
//!               })
//!         })
//!       }).unwrap().map_err(|_| ())
//!     )
//!  }
//!}
//! #[tokio::main]
//! async fn main() {
//!     let config = thrussh::client::Config::default();
//!     let config = Arc::new(config);
//!     let sh = Client{};
//!
//!fn main() {
//!    env_logger::init();
//!    // Starting the server thread.
//!    // Starting the server thread.
//!    let client_key = thrussh_keys::key::KeyPair::generate_ed25519().unwrap();
//!    let client_pubkey = Arc::new(client_key.clone_public_key());
//!    let client_pubkey = Arc::new(client_key.clone_public_key());
//!    let mut config = thrussh::client::Config::default();
//!    config.connection_timeout = Some(std::time::Duration::from_secs(600));
//!    let config = Arc::new(config);
//!    let sh = Client { key: Arc::new(client_key) };
//!    sh.run(config, "127.0.0.1:2222");
//!     let key = thrussh_keys::key::KeyPair::generate_ed25519().unwrap();
//!     let mut agent = thrussh_keys::agent::client::AgentClient::connect_env().await.unwrap();
//!     agent.add_identity(&key, &[]).await.unwrap();
//!     let mut session = thrussh::client::connect(config, "127.0.0.1:2222", sh).await.unwrap();
//!     if session.authenticate_future("pe", key.clone_public_key(), agent).await.unwrap() {
//!         let mut channel = session.channel_open_session().await.unwrap();
//!         channel.data("Hello, world!").await.unwrap();
//!         if let Some(msg) = channel.wait().await {
//!             println!("{:?}", msg)
//!         }
//!     }
//! }
//! ```
//! # Using non-socket IO / writing tunnels
//!
//! The easy way to implement SSH tunnels, like `ProxyCommand` for
//! OpenSSH, is to use the `thrussh-config` crate, and use the
//! `Stream::tcp_connect` or `Stream::proxy_command` methods of that
//! crate. That crate is a very lightweight layer above Thrussh, only
//! implementing for external commands the traits used for sockets.
//!
//! # The SSH protocol
//!
//! If we exclude the key exchange and authentication phases, handled
//! by Thrussh behind the scenes, the rest of the SSH protocol is
//! relatively simple: clients and servers open *channels*, which are
//! just integers used to handle multiple requests in parallel in a
//! single connection. Once a client has obtained a `ChannelId` by
//! calling one the many `channel_open_…` methods of
//! `client::Connection`, the client may send exec requests and data
//! to the server.
//!
//! A simple client just asking the server to run one command will
//! usually start by calling
//! `client::Connection::channel_open_session`, then
//! `client::Connection::exec`, then possibly
//! `client::Connection::data` a number of times to send data to the
//! command's standard input, and finally `Connection::channel_eof`
//! and `Connection::channel_close`.
//!
//! # Design principles
//!
//! The main goal of this library is conciseness, and reduced size and
//! readability of the library's code. Moreover, this library is split
//! between Thrussh, which implements the main logic of SSH clients
//! and servers, and Thrussh-keys, which implements calls to
//! cryptographic primitives.
//!
//! One non-goal is to implement all possible cryptographic algorithms
//! published since the initial release of SSH. Technical debt is
//! easily acquired, and we would need a very strong reason to go
//! against this principle. If you are designing a system from
//! scratch, we urge you to consider recent cryptographic primitives
//! such as Ed25519 for public key cryptography, and Chacha20-Poly1305
//! for symmetric cryptography and MAC.
//!
//! # Internal details of the event loop
//!
//! It might seem a little odd that the read/write methods for server
//! or client sessions often return neither `Result` nor
//! `Future`. This is because the data sent to the remote side is
//! buffered, because it needs to be encrypted first, and encryption
//! works on buffers, and for many algorithms, not in place.
//!
//! Hence, the event loop keeps waiting for incoming packets, reacts
//! to them by calling the provided `Handler`, which fills some
//! buffers. If the buffers are non-empty, the event loop then sends
//! them to the socket, flushes the socket, empties the buffers and
//! starts again. In the special case of the server, unsolicited
//! messages sent through a `server::Handle` are processed when there
//! is no incoming packet to read.
//!
#[macro_use]
extern crate bitflags;

#[macro_use]
extern crate log;
extern crate byteorder;

extern crate cryptovec;

extern crate tokio;
extern crate tokio_io;
#[macro_use]
extern crate futures;
extern crate openssl;
extern crate thrussh_libsodium as sodium;
extern crate thrussh_keys;
#[macro_use]
extern crate failure;

mod read_exact_from;

pub use cryptovec::CryptoVec;
mod sshbuffer;
mod auth;
mod cipher;
mod kex;
mod key;
mod msg;
mod negotiation;
mod ssh_read;
mod sshbuffer;
mod tcp;
mod key;

pub use negotiation::{Named, Preferred};
mod pty;
pub use pty::Pty;

pub use tcp::Tcp;

macro_rules! push_packet {
    ( $buffer:expr, $x:expr ) => {
        {
            use byteorder::{BigEndian, ByteOrder};
            let i0 = $buffer.len();
            $buffer.extend(b"\0\0\0\0");
            let x = $x;
            let i1 = $buffer.len();
            use std::ops::DerefMut;
            let buf = $buffer.deref_mut();
            BigEndian::write_u32(&mut buf[i0..], (i1-i0-4) as u32);
            x
        }
    };
    ( $buffer:expr, $x:expr ) => {{
        use byteorder::{BigEndian, ByteOrder};
        let i0 = $buffer.len();
        $buffer.extend(b"\0\0\0\0");
        let x = $x;
        let i1 = $buffer.len();
        use std::ops::DerefMut;
        let buf = $buffer.deref_mut();
        BigEndian::write_u32(&mut buf[i0..], (i1 - i0 - 4) as u32);
        x
    }};
}

mod session;

/// Server side of this library.
pub mod server;

/// Client side of this library.
pub mod client;

#[derive(Clone, Copy)]
enum Status {
    Ok,
    Disconnect,
}

/// Run one step of the protocol. This trait is currently not used,
/// but both the client and the server implement it. It was meant to
/// factor out code in common between client::Data and a former
/// server::Data.
///
/// The reason the server cannot have a useful `Data` future is that
/// the main interactions between the server and the library user are
/// through callbacks (whereas the client is mostly used by
/// manipulating `Connection`s directly).
trait AtomicPoll<E> {
    fn atomic_poll(&mut self) -> futures::Poll<Status, E>;
}

/// Since handlers are large, their associated future types must implement this trait to provide reasonable default implementations (basically, rejecting all requests).
pub trait FromFinished<T, E>: futures::Future<Item = T, Error = E> {
    /// Turns type `T` into `Self`, a future yielding `T`.
    fn finished(t: T) -> Self;
}

impl<T, E> FromFinished<T, E> for futures::Finished<T, E> {
    fn finished(t: T) -> Self {
        futures::finished(t)
    }
}

impl<T: 'static, E: 'static> FromFinished<T, E> for Box<futures::Future<Item = T, Error = E>> {
    fn finished(t: T) -> Self {
        Box::new(futures::finished(t))
    }
}


#[derive(Debug)]
/// Errors.
#[derive(Debug, Fail)]
/// failure::Errors.
pub enum Error {
    /// The key file could not be parsed.
    #[fail(display = "Could not read key")]
    CouldNotReadKey,

    /// Unspecified problem with the beginning of key exchange.
    #[fail(display = "Key exchange init failed")]
    KexInit,

    /// No common key exchange algorithm.
    #[fail(display = "No common key exchange algorithm")]
    NoCommonKexAlgo,

    /// No common signature algorithm.
    #[fail(display = "No common key algorithm")]
    NoCommonKeyAlgo,

    /// No common cipher.
    #[fail(display = "No common key cipher")]
    NoCommonCipher,

    /// Invalid SSH version string.
    #[fail(display = "invalid SSH version string")]
    Version,

    /// Error during key exchange.
    /// failure::Error during key exchange.
    #[fail(display = "Key exchange failed")]
    Kex,

    /// Invalid packet authentication code.
    #[fail(display = "Wrong packet authentication code")]
    PacketAuth,

    /// The protocol is in an inconsistent state.
    #[fail(display = "Inconsistent state of the protocol")]
    Inconsistent,

    /// The client is not yet authenticated.
    #[fail(display = "Not yet authenticated")]
    NotAuthenticated,

    /// Index out of bounds.
    #[fail(display = "Index out of bounds")]
    IndexOutOfBounds,

    /// UTF-8 decoding error (most probably ASCII error).
    Utf8(std::str::Utf8Error),

    /// Unknown server key.
    #[fail(display = "Unknown server key")]
    UnknownKey,

    /// The server provided a wrong signature.
    #[fail(display = "Wrong server signature")]
    WrongServerSig,

    /// Message received/sent on unopened channel.
    #[fail(display = "Channel not open")]
    WrongChannel,

    /// I/O error.
    IO(std::io::Error),

    /// Disconnected
    #[fail(display = "Disconnected")]
    Disconnect,

    /// No home directory found when trying to learn new host key.
    #[fail(display = "No home directory when saving host key")]
    NoHomeDir,

    /// Remote key changed, this could mean a man-in-the-middle attack
    /// is being performed on the connection.
    KeyChanged(usize),
    #[fail(display = "Key changed, line {}", line)]
    KeyChanged { line: usize },

    /// Connection closed by the remote side.
    #[fail(display = "Connection closed by the remote side")]
    HUP,

    /// Error from the cryptography layer.
    OpenSSL(openssl::error::Error),

    /// Error from the cryptography layer.
    OpenSSLStack(openssl::error::ErrorStack),

    /// Unit error (sodiumoxide might return that).
    Unit,

    /// Connection timeout.
    #[fail(display = "Connection timeout")]
    ConnectionTimeout,

    /// Missing authentication method.
    #[fail(display = "No authentication method")]
    NoAuthMethod,

    /// Keys error
    Keys(thrussh_keys::Error),

    /// Timer error
    Timer(tokio::timer::Error),
    #[fail(display = "Channel send error")]
    SendError,
}

/// Errors including those coming from handler. These are not included
/// in this crate's "main" error type to allow for a simpler API (the
/// "handler error" type cannot be inferred by the compiler in some
/// functions).
#[derive(Debug)]
pub enum HandlerError<E> {
    /// Standard errors
    Error(Error),
    /// From handler
    Handler(E),
/// Since handlers are large, their associated future types must implement this trait to provide reasonable default implementations (basically, rejecting all requests).
pub trait FromFinished<T>: futures::Future<Output = Result<T, failure::Error>> {
    /// Turns type `T` into `Self`, a future yielding `T`.
    fn finished(t: T) -> Self;
}

impl<E> std::convert::From<HandlerError<HandlerError<E>>> for HandlerError<E> {
    fn from(e: HandlerError<HandlerError<E>>) -> Self {
        match e {
            HandlerError::Handler(HandlerError::Error(e)) => HandlerError::Error(e),
            HandlerError::Handler(HandlerError::Handler(e)) => HandlerError::Handler(e),
            HandlerError::Error(e) => HandlerError::Error(e)
        }
impl<T> FromFinished<T> for futures::future::Ready<Result<T, failure::Error>> {
    fn finished(t: T) -> Self {
        futures::future::ready(Ok(t))
    }
}

use std::error::Error as StdError;
impl std::fmt::Display for Error {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        write!(f, "{}", self.description())
impl<T: 'static> FromFinished<T>
    for Box<dyn futures::Future<Output = Result<T, failure::Error>> + Unpin>
{
    fn finished(t: T) -> Self {
        Box::new(futures::future::ready(Ok(t)))
    }
}
impl std::error::Error for Error {
    fn description(&self) -> &str {
        match *self {
            Error::Utf8(ref e) => e.description(),
            Error::IO(ref e) => e.description(),
            Error::CouldNotReadKey => "Could not read key",
            Error::KexInit => "KexInit problem",
            Error::NoCommonKexAlgo => "No common key exchange algorithms were found",
            Error::NoCommonKeyAlgo => "No common signature algorithms were found",
            Error::NoCommonCipher => "No common ciphers were found",
            Error::Kex => "Received invalid key exchange packet",
            Error::Version => "Invalid version string from the remote side",
            Error::PacketAuth => "Incorrect packet authentication code",
            Error::Inconsistent => "Unexpected message",
            Error::NotAuthenticated => "Not authenticated",
            Error::IndexOutOfBounds => "Index out of bounds in a packet",
            Error::IndexOutOfBounds => "Index out of bounds in a packet",
            Error::UnknownKey => "Unknown host key",
            Error::WrongChannel => "Inexistent channel",
            Error::Disconnect => "Disconnected",
            Error::NoHomeDir => "Home directory not found",
            Error::KeyChanged(_) => "Server key changed",
            Error::HUP => "Connection closed by the remote side",
            Error::ConnectionTimeout => "Connection timout",
            Error::NoAuthMethod => "No more authentication methods available",
            Error::OpenSSL(ref e) => e.description(),
            Error::OpenSSLStack(ref e) => e.description(),
            Error::Unit => "Unknown (unit) error",
            Error::Keys(ref e) => e.description(),
            Error::Timer(ref e) => e.description(),
        }
    }
    fn cause(&self) -> Option<&std::error::Error> {
        match *self {
            Error::Utf8(ref e) => Some(e),
            Error::IO(ref e) => Some(e),
            _ => None,
        }
    }
}

impl<E:std::error::Error> std::fmt::Display for HandlerError<E> {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        write!(f, "{}", self.description())
    }
}
impl<E:std::error::Error> std::error::Error for HandlerError<E> {
    fn description(&self) -> &str {
        match *self {
            HandlerError::Error(ref e) => e.description(),
            HandlerError::Handler(ref e) => e.description(),
        }
    }
    fn cause(&self) -> Option<&std::error::Error> {
        match *self {
            HandlerError::Error(ref e) => e.source(),
            HandlerError::Handler(ref e) => e.source(),
        }
        }
    }
}



impl From<std::io::Error> for Error {
    fn from(e: std::io::Error) -> Error {
        Error::IO(e)
    }
}

impl From<thrussh_keys::Error> for Error {
    fn from(e: thrussh_keys::Error) -> Error {
        Error::Keys(e)
    }
}

impl From<std::str::Utf8Error> for Error {
    fn from(e: std::str::Utf8Error) -> Error {
        Error::Utf8(e)
    }
}

impl From<openssl::error::ErrorStack> for Error {
    fn from(e: openssl::error::ErrorStack) -> Error {
        Error::OpenSSLStack(e)
    }
}
/*
impl From<tokio_timer::TimerError> for Error {
    fn from(e: tokio_timer::TimerError) -> Error {
        Error::Timer(e)
    }
}
*/
impl From<()> for Error {
    fn from(_: ()) -> Error {
        Error::Unit
    }
}

impl<E> From<Error> for HandlerError<E> {
    fn from(e: Error) -> HandlerError<E> {
        HandlerError::Error(e)
    }
}
impl<E> From<std::io::Error> for HandlerError<E> {
    fn from(e: std::io::Error) -> HandlerError<E> {
        HandlerError::Error(Error::IO(e))
    }
}

impl<E> From<std::str::Utf8Error> for HandlerError<E> {
    fn from(e: std::str::Utf8Error) -> HandlerError<E> {
        HandlerError::Error(Error::Utf8(e))
    }
}
impl<E> From<thrussh_keys::Error> for HandlerError<E> {
    fn from(e: thrussh_keys::Error) -> HandlerError<E> {
        HandlerError::Error(Error::Keys(e))
    }
}

impl<E> From<tokio::timer::Error> for HandlerError<E> {
    fn from(e: tokio::timer::Error) -> HandlerError<E> {
        HandlerError::Error(Error::Timer(e))
        HandlerError::Error(Error::Timer(e))
    }
}


mod negotiation;
pub use negotiation::{Named, Preferred};
mod pty;
pub use pty::Pty;
mod msg;
mod kex;
mod cipher;

// mod mac;
// use mac::*;
// mod compression;

mod auth;

/// The number of bytes read/written, and the number of seconds before a key re-exchange is requested.
#[derive(Debug, Clone)]
pub struct Limits {
    rekey_write_limit: usize,
    rekey_read_limit: usize,
    rekey_time_limit: std::time::Duration,
}

impl Limits {
    /// Create a new `Limits`, checking that the given bounds cannot lead to nonce reuse.
    pub fn new(write_limit: usize, read_limit: usize, time_limit: std::time::Duration) -> Limits {
        assert!(write_limit <= 1 << 30 && read_limit <= 1 << 30);
        Limits {
            rekey_write_limit: write_limit,
            rekey_read_limit: read_limit,
            rekey_time_limit: time_limit,
        }
    }
}

impl Default for Limits {
    fn default() -> Self {
        // Following the recommendations of
        // https://tools.ietf.org/html/rfc4253#section-9
        Limits {
            rekey_write_limit: 1 << 30, // 1 Gb
            rekey_read_limit: 1 << 30, // 1 Gb
            rekey_read_limit: 1 << 30,  // 1 Gb
            rekey_time_limit: std::time::Duration::from_secs(3600),
        }
    }
}

pub use auth::MethodSet;

/// Server side of this library.
pub mod server;

/// Client side of this library.
pub mod client;

/// A reason for disconnection.
#[allow(missing_docs)] // This should be relatively self-explanatory.
pub enum Disconnect {
    HostNotAllowedToConnect = 1,
    ProtocolError = 2,
    KeyExchangeFailed = 3,
    #[doc(hidden)]
    Reserved = 4,
    MACError = 5,
    CompressionError = 6,
    ServiceNotAvailable = 7,
    ProtocolVersionNotSupported = 8,
    HostKeyNotVerifiable = 9,
    ConnectionLost = 10,
    ByApplication = 11,
    TooManyConnections = 12,
    AuthCancelledByUser = 13,
    NoMoreAuthMethodsAvailable = 14,
    IllegalUserName = 15,
}

/// The type of signals that can be sent to a remote process. If you
/// plan to use custom signals, read [the
/// RFC](https://tools.ietf.org/html/rfc4254#section-6.10) to
/// understand the encoding.
#[allow(missing_docs)]
// This should be relatively self-explanatory.
#[derive(Debug, Clone, Copy)]
pub enum Sig<'a> {
#[derive(Debug, Clone)]
pub enum Sig {
    ABRT,
    ALRM,
    FPE,
    HUP,
    ILL,
    INT,
    KILL,
    PIPE,
    QUIT,
    SEGV,
    TERM,
    USR1,
    Custom(&'a str),
    Custom(String),
}

impl<'a> Sig<'a> {
    fn name(&self) -> &'a str {
impl Sig {
    fn name(&self) -> &str {
        match *self {
            Sig::ABRT => "ABRT",
            Sig::ALRM => "ALRM",
            Sig::FPE => "FPE",
            Sig::HUP => "HUP",
            Sig::ILL => "ILL",
            Sig::INT => "INT",
            Sig::KILL => "KILL",
            Sig::PIPE => "PIPE",
            Sig::QUIT => "QUIT",
            Sig::SEGV => "SEGV",
            Sig::TERM => "TERM",
            Sig::USR1 => "USR1",
            Sig::Custom(c) => c,
            Sig::Custom(ref c) => c,
        }
    }
    fn from_name(name: &'a [u8]) -> Result<Sig, Error> {
    fn from_name(name: &[u8]) -> Result<Sig, failure::Error> {
        match name {
            b"ABRT" => Ok(Sig::ABRT),
            b"ALRM" => Ok(Sig::ALRM),
            b"FPE" => Ok(Sig::FPE),
            b"HUP" => Ok(Sig::HUP),
            b"ILL" => Ok(Sig::ILL),
            b"INT" => Ok(Sig::INT),
            b"KILL" => Ok(Sig::KILL),
            b"PIPE" => Ok(Sig::PIPE),
            b"QUIT" => Ok(Sig::QUIT),
            b"SEGV" => Ok(Sig::SEGV),
            b"TERM" => Ok(Sig::TERM),
            b"USR1" => Ok(Sig::USR1),
            x => Ok(Sig::Custom(try!(std::str::from_utf8(x)))),
            x => Ok(Sig::Custom(std::str::from_utf8(x)?.to_string())),
        }
    }
}


/// Reason for not being able to open a channel.
#[derive(Debug, Copy, Clone, PartialEq)]
#[allow(missing_docs)]
pub enum ChannelOpenFailure {
    AdministrativelyProhibited = 1,
    ConnectFailed = 2,
    UnknownChannelType = 3,
    ResourceShortage = 4,
}

impl ChannelOpenFailure {
    fn from_u32(x: u32) -> Option<ChannelOpenFailure> {
        match x {
            1 => Some(ChannelOpenFailure::AdministrativelyProhibited),
            2 => Some(ChannelOpenFailure::ConnectFailed),
            3 => Some(ChannelOpenFailure::UnknownChannelType),
            4 => Some(ChannelOpenFailure::ResourceShortage),
            _ => None,
        }
    }
}


#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
/// The identifier of a channel.
pub struct ChannelId(u32);

/// The parameters of a channel.
#[derive(Debug)]
pub(crate) struct Channel {
    recipient_channel: u32,
    sender_channel: ChannelId,
    recipient_window_size: u32,
    sender_window_size: u32,
    recipient_maximum_packet_size: u32,
    sender_maximum_packet_size: u32,
    /// Has the other side confirmed the channel?
    pub confirmed: bool,
    wants_reply: bool,
}

#[derive(Debug)]
pub enum ChannelMsg {
    Data {
        data: CryptoVec,
    },
    ExtendedData {
        data: CryptoVec,
        ext: u32,
    },
    Eof,
    XonXoff {
        client_can_do: bool,
    },
    ExitStatus {
        exit_status: u32,
    },
    ExitSignal {
        signal_name: Sig,
        core_dumped: bool,
        error_message: String,
        lang_tag: String,
    },
}
26
27

28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43

pub const KEXINIT: u8 = 20;
pub const NEWKEYS: u8 = 21;


// http://tools.ietf.org/html/rfc5656#section-7.1
pub const KEX_ECDH_INIT: u8 = 30;
pub const KEX_ECDH_REPLY: u8 = 31;

// https://tools.ietf.org/html/rfc4250#section-4.1.2
pub const USERAUTH_REQUEST: u8 = 50;
pub const USERAUTH_FAILURE: u8 = 51;
pub const USERAUTH_SUCCESS: u8 = 52;
pub const USERAUTH_BANNER: u8 = 53;
pub const USERAUTH_PK_OK: u8 = 60;

// https://tools.ietf.org/html/rfc4256#section-5
pub const USERAUTH_INFO_REQUEST: u8 = 60;
pub const USERAUTH_INFO_RESPONSE: u8 = 61;


13
14





15
16
17
18
19
20


21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97

98
99

100
101
102
103
104
105
106
107
108

109
110
111

112
113
114
115
116
117
118
119
120

121
122
123

124
125
126
127
128
129
130
131

132
133


134
135
136




137
138
139
140
141

142
143
144
145
146
147
148
149
150
151
152
153

154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191



192
193
// limitations under the License.
//
use Error;
use thrussh_keys::key;
use kex;
use cipher;
use msg;
use crate::{cipher, kex, msg, Error};
use std::str::from_utf8;
use thrussh_keys::key;
// use super::mac; // unimplemented
// use super::compression; // unimplemented
use cryptovec::CryptoVec;
use thrussh_keys::encoding::{Encoding, Reader};
use thrussh_keys::key::{PublicKey, KeyPair};
use openssl::rand;
use thrussh_keys::encoding::{Encoding, Reader};
use thrussh_keys::key::{KeyPair, PublicKey};

#[derive(Debug)]
pub struct Names {
    pub kex: kex::Name,
    pub key: key::Name,
    pub cipher: cipher::Name,
    pub mac: Option<&'static str>,
    pub ignore_guessed: bool,
}

/// Lists of preferred algorithms. This is normally hard-coded into implementations.
#[derive(Debug)]
pub struct Preferred {
    /// Preferred key exchange algorithms.
    pub kex: &'static [kex::Name],
    /// Preferred public key algorithms.
    pub key: &'static [key::Name],
    /// Preferred symmetric ciphers.
    pub cipher: &'static [cipher::Name],
    /// Preferred MAC algorithms.
    pub mac: &'static [&'static str],
    /// Preferred compression algorithms.
    pub compression: &'static [&'static str],
}

pub const DEFAULT: Preferred = Preferred {
    kex: &[kex::CURVE25519],
    key: &[key::ED25519, key::RSA_SHA2_256, key::RSA_SHA2_512],
    cipher: &[cipher::chacha20poly1305::NAME],
    mac: &["none"],
    compression: &["none"],
};

impl Default for Preferred {
    fn default() -> Preferred {
        DEFAULT
    }
}

/// Named algorithms.
pub trait Named {
    /// The name of this algorithm.
    fn name(&self) -> &'static str;
}

impl Named for () {
    fn name(&self) -> &'static str {
        ""
    }
}

use thrussh_keys::key::{ED25519, SSH_RSA};

impl Named for PublicKey {
    fn name(&self) -> &'static str {
        match self {
            &PublicKey::Ed25519(_) => ED25519.0,
            &PublicKey::RSA { .. } => SSH_RSA,
        }
    }
}

impl Named for KeyPair {
    fn name(&self) -> &'static str {
        match self {
            &KeyPair::Ed25519 { .. } => ED25519.0,
            &KeyPair::RSA { ref hash, .. } => hash.name().0,
        }
    }
}

pub trait Select {
    fn select<S: AsRef<str> + Copy>(a: &[S], b: &[u8]) -> Option<(bool, S)>;

    fn read_kex(buffer: &[u8], pref: &Preferred) -> Result<Names, Error> {
    fn read_kex(buffer: &[u8], pref: &Preferred) -> Result<Names, failure::Error> {
        let mut r = buffer.reader(17);
        let kex_string = try!(r.read_string());
        let kex_string = r.read_string()?;
        let (kex_both_first, kex_algorithm) = if let Some(x) = Self::select(pref.kex, kex_string) {
            x
        } else {
            debug!(
                "Could not find common kex algorithm, other side only supports {:?}, we only support {:?}",
                from_utf8(kex_string),
                pref.kex
            );
            return Err(Error::NoCommonKexAlgo);
            return Err(Error::NoCommonKexAlgo.into());
        };

        let key_string = try!(r.read_string());
        let key_string = r.read_string()?;
        let (key_both_first, key_algorithm) = if let Some(x) = Self::select(pref.key, key_string) {
            x
        } else {
            debug!(
                "Could not find common key algorithm, other side only supports {:?}, we only support {:?}",
                from_utf8(key_string),
                pref.key
            );
            return Err(Error::NoCommonKeyAlgo);
            return Err(Error::NoCommonKeyAlgo.into());
        };

        let cipher_string = try!(r.read_string());
        let cipher_string = r.read_string()?;
        let cipher = Self::select(pref.cipher, cipher_string);
        if cipher.is_none() {
            debug!(
                "Could not find common cipher, other side only supports {:?}, we only support {:?}",
                from_utf8(cipher_string),
                pref.cipher
            );
            return Err(Error::NoCommonCipher);
            return Err(Error::NoCommonCipher.into());
        }
        try!(r.read_string()); // SERVER_TO_CLIENT
        let mac = Self::select(pref.mac, try!(r.read_string()));
        r.read_string()?; // SERVER_TO_CLIENT
        let mac = Self::select(pref.mac, r.read_string()?);
        let mac = mac.and_then(|(_, x)| Some(x));
        try!(r.read_string()); // SERVER_TO_CLIENT
        try!(r.read_string()); //
        try!(r.read_string()); //
        try!(r.read_string()); //
        r.read_string()?; // SERVER_TO_CLIENT
        r.read_string()?; //
        r.read_string()?; //
        r.read_string()?; //

        let follows = try!(r.read_byte()) != 0;
        let follows = r.read_byte()? != 0;
        match (cipher, mac, follows) {
            (Some((_, cip)), mac, fol) => {
                Ok(Names {
                    kex: kex_algorithm,
                    key: key_algorithm,
                    cipher: cip,
                    mac: mac,
                    // Ignore the next packet if (1) it follows and (2) it's not the correct guess.
                    ignore_guessed: fol && !(kex_both_first && key_both_first),
                })
            }
            _ => Err(Error::KexInit),
            _ => Err(Error::KexInit.into()),
        }
    }
}

pub struct Server;
pub struct Client;

impl Select for Server {
    fn select<S: AsRef<str> + Copy>(server_list: &[S], client_list: &[u8]) -> Option<(bool, S)> {
        let mut both_first_choice = true;
        for c in client_list.split(|&x| x == b',') {
            for &s in server_list {
                if c == s.as_ref().as_bytes() {
                    return Some((both_first_choice, s));
                }
                both_first_choice = false
            }
        }
        None
    }
}

impl Select for Client {
    fn select<S: AsRef<str> + Copy>(client_list: &[S], server_list: &[u8]) -> Option<(bool, S)> {
        let mut both_first_choice = true;
        for &c in client_list {
            for s in server_list.split(|&x| x == b',') {
                if s == c.as_ref().as_bytes() {
                    return Some((both_first_choice, c));
                }
                both_first_choice = false
            }
        }
        None
    }
}


pub fn write_kex(prefs: &Preferred, buf: &mut CryptoVec) -> Result<(), Error> {

pub fn write_kex(prefs: &Preferred, buf: &mut CryptoVec) -> Result<(), failure::Error> {
    // buf.clear();



































































































use tokio::io::AsyncRead;
use futures::{Future, Poll, Async};
use std::io;
use std::mem;
use std::io::ErrorKind;

#[derive(Debug)]
pub struct ReadExact<A, T> {
    state: State<A, T>,
}

#[derive(Debug)]
enum State<A, T> {
    Reading {
        a: A,
        buf: T,
        pos: usize,
        initial_pos: usize,
    },
    Empty,
}

pub fn read_exact_from<A, T>(a: A, buf: T, pos: usize) -> ReadExact<A, T>
where
    A: AsyncRead,
    T: AsMut<[u8]>,
{
    ReadExact {
        state: State::Reading {
            a,
            buf,
            pos,
            initial_pos: pos,
        },
    }
}

fn eof() -> io::Error {
    io::Error::new(io::ErrorKind::UnexpectedEof, "early eof")
}

impl<A, T> Future for ReadExact<A, T>
where
    A: AsyncRead,
    T: AsMut<[u8]>,
{
    type Item = (A, T);
    type Error = io::Error;

    fn poll(&mut self) -> Poll<(A, T), io::Error> {
        match self.state {
            State::Reading {
                ref mut a,
                ref mut buf,
                ref mut pos,
                ..
            } => {
                let buf = buf.as_mut();
                while *pos < buf.len() {
                    let n = match a.read(&mut buf[*pos..]) {
                        Ok(n) => n,
                        Err(ref e) if e.kind() == ErrorKind::WouldBlock => return Ok(Async::NotReady),
                        Err(e) => return Err(e)
                    };
                    *pos += n;
                    if n == 0 {
                        return Err(eof());
                    }
                }
            }
            State::Empty => panic!("poll a ReadExact after it's done"),
        }

        match mem::replace(&mut self.state, State::Empty) {
            State::Reading { a, buf, .. } => Ok((a, buf).into()),
            State::Empty => panic!(),
        }
    }
}

impl<A, T> ReadExact<A, T> {
    pub fn try_abort(&mut self) -> Option<(A, T)> {
        if let State::Reading {
            a,
            buf,
            pos,
            initial_pos,
        } = mem::replace(&mut self.state, State::Empty)
        {
            if pos == initial_pos {
                Some((a, buf))
            } else {
                None
            }
        } else {
            None
        }
    }
}
1
2
3

4
5


6
7



































































































































































































































































































































































































































































































































































































































8
9
use super::*;
use crate::tcp::Tcp;
use cipher;
use negotiation::Select;
use msg;
use negotiation;
use std::sync::Arc;
use tcp::Tcp;
use negotiation::Select;
use ssh_read::SshRead;
// use tokio_timer::{Timer, Sleep};
use tokio::timer::Delay;


pub(in server) enum ConnectionState<R: AsyncRead + AsyncWrite + Tcp, H: Handler> {
    ReadSshId(SshRead<R>),
    ReadSshId(SshRead<R>),
    WriteSshId(WriteAll<R, CryptoVec>),
    Read(cipher::CipherRead<SshRead<R>>),
    Write(WriteAll<SshRead<R>, CryptoVec>),
    Flush(Flush<SshRead<R>>),
    Pending {
        pending: PendingFuture<H>,
        stream: SshRead<R>,
    },
    Shutdown {
        read: tokio_io::io::Read<SshRead<R>, CryptoVec>,
        read_buffer: SSHBuffer,
    },
}

#[doc(hidden)]
pub enum PendingFuture<H: Handler> {
    Ok { handler: H, session: Session },
    RejectTimeout {
        handler: H,
        session: Session,
        timeout: Delay,
    },
    },
    ReadAuthRequest {
        session: Session,
        auth_request: encrypted::ReadAuthRequest<H>,
    },
    Authenticated(encrypted::Authenticated<H>),
}

/// A `Connection`, representing one client connection to this server. If you don't need to configure your sockets, use [`server::run`](fn.run.html) instead.
pub struct Connection<R: AsyncRead + AsyncWrite + Tcp, H: Handler> {
pub struct Connection<R: AsyncRead + AsyncWrite + Tcp, H: Handler> {
    read_buffer: Option<SSHBuffer>,
    session: Option<Session>,
    state: Option<ConnectionState<R, H>>,
    buffer: CryptoVec,
    buffer2: CryptoVec,
    handler: Option<H>,
    timeout: Option<Delay>,
}
}
}

impl<R: AsyncRead + AsyncWrite + Tcp, H: Handler> Future for Connection<R, H> {
    type Item = ();
    type Error = HandlerError<H::Error>;

    fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
        loop {
            // If timeout, shutdown the socket.
            if let Some(ref mut timeout) = self.timeout {
                match try!(timeout.poll()) {
                    Async::Ready(()) => {
                        // try_nb!(self.stream.get_mut().shutdown(std::net::Shutdown::Both));
                        debug!("Disconnected, shutdown");
                        return Ok(Async::Ready(()));
                    }
                    Async::NotReady => {}
                }
            }
            debug!("polling");
            if let Status::Disconnect = try_ready!(self.atomic_poll()) {
                debug!("disconnect, {}", line!());
                return Ok(Async::Ready(()));
            }
        }
    }
}

impl<R: AsyncRead + AsyncWrite + Tcp, H: Handler> AtomicPoll<HandlerError<H::Error>>
    for Connection<R, H> {
    fn atomic_poll(&mut self) -> Poll<Status, HandlerError<H::Error>> {

        match self.state.take() {
            None => {
                debug!("no state");
                Ok(Async::Ready(Status::Disconnect))
            },
            Some(ConnectionState::WriteSshId(mut write)) => {
                if let Async::Ready((stream, mut buf)) = write.poll()? {
                    // Here we're recycling the buffer used for the
                    // SSH-identification as the write buffer.
                    if let Some(ref mut session) = self.session {
                        buf.clear();
                        session.common.write_buffer.buffer = buf;
                    }
                    }
                    self.state = Some(ConnectionState::ReadSshId(SshRead::new(stream)));
                    Ok(Async::Ready(Status::Ok))
                } else {
                    self.state = Some(ConnectionState::WriteSshId(write));
                    Ok(Async::NotReady)
                    Ok(Async::NotReady)
                }
            }
            Some(ConnectionState::ReadSshId(mut read)) => {
                let is_ready = if let Async::Ready(sshid) = read.read_ssh_id()? {
                    self.read_ssh_id(sshid)?;
                    true
                } else {
                    false
                };
                debug!("SSH- read: {:?}", is_ready);
                if is_ready {
                    if let Some(ref mut session) = self.session {
                        session.flush()?;
                        self.state = Some(ConnectionState::Write(
                            session.common.write_buffer.write_all(read),
                        ));
                        ));
                    }
                    Ok(Async::Ready(Status::Ok))
                } else {
                    self.state = Some(ConnectionState::ReadSshId(read));
                    return Ok(Async::NotReady);
                }
            }
            Some(ConnectionState::Pending { pending, stream }) => {
                debug!("atomic pending");
                self.poll_pending(pending, stream)
            }
            Some(ConnectionState::Write(mut write)) => {
                debug!("atomic writing");
                if let Async::Ready((stream, mut buf)) = write.poll()? {
                    if let Some(ref mut session) = self.session {
                        buf.clear();
                        session.common.write_buffer.buffer = buf;
                        self.state = Some(ConnectionState::Flush(flush(stream)));
                        self.state = Some(ConnectionState::Flush(flush(stream)));
                        Ok(Async::Ready(Status::Ok))
                    } else {
                        unreachable!()
                    }
                } else {
                    self.state = Some(ConnectionState::Write(write));
                    Ok(Async::NotReady)
                }
            }
            Some(ConnectionState::Flush(mut flush)) => {
                debug!("atomic flushing");
                if let Async::Ready(mut stream) = flush.poll()? {

                    if let Some(ref mut session) = self.session {
                        if session.common.disconnected {
                            stream.tcp_shutdown()?;
                            stream.tcp_shutdown()?;
                            let mut read_buffer = self.read_buffer.take().unwrap();
                            let buffer =
                                std::mem::replace(&mut read_buffer.buffer, CryptoVec::new());
                            self.state = Some(ConnectionState::Shutdown {
                                read: tokio_io::io::read(stream, buffer),
                                read_buffer,
                            });
                        } else {
                            let mut buf = self.read_buffer.take().unwrap();
                            buf.buffer.clear();
                            self.state = Some(ConnectionState::Read(
                                cipher::read(stream, buf, session.common.cipher.clone()),
                            ));
                            ));
                        }
                    }
                    Ok(Async::Ready(Status::Ok))
                } else {
                    self.state = Some(ConnectionState::Flush(flush));
                    Ok(Async::NotReady)
                }
            }
            Some(ConnectionState::Read(mut read)) => {
                debug!("atomic reading");
                if let Async::Ready((stream, mut buf, end)) = read.poll()? {
                    debug!("buf: {:?}", buf.buffer.as_ref());
                    // Handle the transport layer.
                    if buf.buffer.len() < 5 || buf.buffer[5] == msg::DISCONNECT {
                        // transport
                        let buffer = std::mem::replace(&mut buf.buffer, CryptoVec::new());
                        debug!("disconnect {}", line!());
                        self.state = Some(ConnectionState::Shutdown {
                            read: tokio_io::io::read(stream, buffer),
                            read_buffer: buf,
                        });
                        return Ok(Async::Ready(Status::Ok));
                    } else if buf.buffer[5] <= 4 {
                        let session = self.session.as_ref().unwrap();
                        self.state = Some(ConnectionState::Read(
                            cipher::read(stream, buf, session.common.cipher.clone()),
                        ));
                        ));
                        return Ok(Async::Ready(Status::Ok));
                    } else {
                        let result = self.read(&buf.buffer[5..end], stream);
                        self.read_buffer = Some(buf);
                        return result;
                    }
                } else {

                    self.state = Some(ConnectionState::Read(read));
                    if let Some(ref mut session) = self.session {
                        match session.receiver.poll() {
                            Ok(Async::Ready(Some(Msg::Data { data, extended, channel }))) => {
                                debug!("session.receiver: received data");
                                session.data(channel, extended, &data);
                                return Ok(Async::Ready(Status::Ok))
                            }
                            Ok(Async::Ready(Some(Msg::Eof { channel }))) => {
                                debug!("session.receiver: received eof");
                                session.eof(channel);
                                return Ok(Async::Ready(Status::Ok))
                            }
                            Ok(Async::Ready(None)) => {
                                debug!("session.receiver: received None");
                            }
                            Ok(Async::NotReady) => {}
                            Err(()) => {}
                        }
                    }
                    debug!("atomic reading not ready");
                    debug!("atomic reading not ready");
                    Ok(Async::NotReady)
                }
            }
            Some(ConnectionState::Shutdown {
                     mut read,
                     mut read_buffer,
                 }) => {
                debug!("atomic shutdown");
                if let Async::Ready((stream, mut buf, n)) = read.poll()? {
                    if n == 0 {
                        read_buffer.buffer = buf;
                        self.read_buffer = Some(read_buffer);
                        Ok(Async::Ready(Status::Disconnect))
                    } else {
                        buf.clear();
                        self.state = Some(ConnectionState::Shutdown {
                            read: tokio_io::io::read(stream, buf),
                            read_buffer,
                        });
                        Ok(Async::Ready(Status::Ok))
                    }
                } else {
                    self.state = Some(ConnectionState::Shutdown { read, read_buffer });
                    Ok(Async::NotReady)
                }
            }
        }
    }
}


impl<H: Handler, R: AsyncRead + AsyncWrite + Tcp> Connection<R, H> {
    /// Create a new `Connection` from the server's configuration, a
    /// stream and a [`Handler`](trait.Handler.html).
    pub fn new(config: Arc<Config>, stream: R, handler: H) -> Result<Self, Error> {
        let mut write_buffer = SSHBuffer::new();
        let mut write_buffer = SSHBuffer::new();
        let mut write_buffer = SSHBuffer::new();
        write_buffer.send_ssh_id(config.as_ref().server_id.as_bytes());
        let timeout = if let Some(t) = config.connection_timeout {
            Some(Delay::new(std::time::Instant::now() + t))
        } else {
        } else {
            None
        };
        let write = write_buffer.write_all(stream);
        let (sender, receiver) = futures::sync::mpsc::unbounded();
        let session = Session {
        let session = Session {
            common: CommonSession {
                write_buffer: SSHBuffer::new(),
                kex: None,
                auth_user: String::new(),
                auth_method: None, // Client only.
                cipher: Arc::new(cipher::CLEAR_PAIR),
                encrypted: None,
                config: config,
                wants_reply: false,
                disconnected: false,
                buffer: Some(CryptoVec::new()),
            },
            receiver,
            sender: server::session::Handle {
                sender
            },
        };
        };
        let connection = Connection {
        let connection = Connection {
            read_buffer: Some(SSHBuffer::new()),
            timeout: timeout,
            session: Some(session),
            state: Some(ConnectionState::WriteSshId(write)),
            handler: Some(handler),
            buffer: CryptoVec::new(),
            buffer2: CryptoVec::new(),
        };
        Ok(connection)
    }

    fn read_ssh_id(&mut self, sshid: &[u8]) -> Result<(), Error> {
        let mut exchange = Exchange::new();
        let mut exchange = Exchange::new();
        let mut exchange = Exchange::new();
        exchange.client_id.extend(sshid);
        // Preparing the response
        if let Some(ref mut session) = self.session {
            exchange.server_id.extend(
                session
                    .common
                    .config
                    .config
                    .as_ref()
                    .server_id
                    .as_bytes(),
            );
            let mut kexinit = KexInit {
                exchange: exchange,
                algo: None,
                sent: false,
                session_id: None,
            };
            kexinit.server_write(
                session.common.config.as_ref(),
                session.common.cipher.as_ref(),
                &mut session.common.write_buffer,
            )?;
            )?;
            session.common.kex = Some(Kex::KexInit(kexinit));
        }
        }
        Ok(())
    }

    fn poll_pending(
        &mut self,
        pending: PendingFuture<H>,
        stream: SshRead<R>,
    ) -> Poll<Status, HandlerError<H::Error>> {
        debug!("Running encrypted future");
        let (handler, mut session) = match pending {
            PendingFuture::Ok { handler, session } => (handler, session),
            PendingFuture::RejectTimeout {
                handler,
                mut timeout,
                session,
            } => {
                debug!("future: rejectTimeout");
                match try!(timeout.poll()) {
                    Async::Ready(()) => (handler, session),
                    Async::NotReady => {
                        self.state = Some(ConnectionState::Pending {
                            pending: PendingFuture::RejectTimeout {
                                session,
                                timeout,
                                handler,
                            },
                            stream,
                        });
                        return Ok(Async::NotReady);
                    }
                }
            }
            PendingFuture::ReadAuthRequest {
                mut session,
                mut auth_request,
            } => {
                debug!("future: read_auth_request");
                let pre_auth = std::time::Instant::now();

                let auth = {
                    let enc = session.common.encrypted.as_mut().unwrap();
                    auth_request.poll(
                    auth_request.poll(
                        enc,
                        &mut session.common.auth_user,
                        &mut self.buffer,
                        &mut self.buffer,
                    )?
                };

                match auth {
                    Async::Ready((handler, Auth::Reject)) => {
                        debug!("reject");
                        let rejection_time = session.common.config.auth_rejection_time;
                        self.state = Some(ConnectionState::Pending {
                        self.state = Some(ConnectionState::Pending {
                            pending: PendingFuture::RejectTimeout {
                                session,
                                handler,
                                timeout: Delay::new(pre_auth + rejection_time)
                            },
                            },
                            stream,
                        });
                        return Ok(Async::Ready(Status::Ok));
                    }
                    Async::Ready((handler, _)) => (handler, session),
                    Async::NotReady => {
                        self.state = Some(ConnectionState::Pending {
                            pending: PendingFuture::ReadAuthRequest {
                                session,
                                auth_request,
                            },
                            stream,
                        });
                        return Ok(Async::NotReady);
                    }
                }
            }
            PendingFuture::Authenticated(mut r) => {
                debug!("future: authenticated");
                if let Async::Ready((handler, session)) = try!(r.poll()) {
                    (handler, session)
                } else {
                    self.state = Some(ConnectionState::Pending {
                        pending: PendingFuture::Authenticated(r),
                        stream,
                    });
                    return Ok(Async::NotReady);
                }
            }
        };


        self.handler = Some(handler);
        session.flush()?;
        self.state = Some(ConnectionState::Write(
            session.common.write_buffer.write_all(stream),
        ));
        ));
        self.session = Some(session);
        Ok(Async::Ready(Status::Ok))
    }


    fn read(
        &mut self,
        buf: &[u8],
        stream: SshRead<R>,
    ) -> Poll<Status, HandlerError<<H as Handler>::Error>> {

        let mut session = self.session.take().unwrap();

        // Handle key exchange/re-exchange.
        match session.common.kex.take() {
            Some(Kex::KexInit(kexinit)) => {
            Some(Kex::KexInit(kexinit)) => {
                if kexinit.algo.is_some() || buf[0] == msg::KEXINIT ||
                    session.common.encrypted.is_none()
                {
                {
                    let next_kex = kexinit.server_parse(
                        session.common.config.as_ref(),
                        &session.common.cipher,
                        &buf,
                        &buf,
                        &mut session.common.write_buffer,
                    );
                    );
                    match next_kex {
                        Ok(next_kex) => {
                            session.common.kex = Some(next_kex);
                            session.flush()?;
                            session.flush()?;
                            self.state = Some(ConnectionState::Write(
                                session.common.write_buffer.write_all(stream),
                            ));
                            ));
                            self.session = Some(session);
                            return Ok(Async::Ready(Status::Ok));
                        }
                        Err(e) => {
                            session.flush()?;
                            self.state = Some(ConnectionState::Write(
                                session.common.write_buffer.write_all(stream),
                            ));
                            ));
                            self.session = Some(session);
                            return Err(HandlerError::Error(e));
                        }
                    }
                }
                // Else, i.e. if the other side has not started
                // the key exchange, process its packets by simple
                // not returning.
            }
            Some(Kex::KexDh(kexdh)) => {
                let next_kex = kexdh.parse(
                    session.common.config.as_ref(),
                    &mut self.buffer,
                    &mut self.buffer,
                    &mut self.buffer2,
                    &session.common.cipher,
                    &buf,
                    &buf,
                    &mut session.common.write_buffer,
                );
                );
                match next_kex {
                    Ok(next_kex) => {
                        session.common.kex = Some(next_kex);
                        session.flush()?;
                        session.flush()?;
                        self.state = Some(ConnectionState::Write(
                            session.common.write_buffer.write_all(stream),
                        ));
                        ));
                        self.session = Some(session);
                        return Ok(Async::Ready(Status::Ok));
                    }
                    Err(e) => {
                        session.flush()?;
                        self.state = Some(ConnectionState::Write(
                            session.common.write_buffer.write_all(stream),
                        ));
                        ));
                        self.session = Some(session);
                        return Err(HandlerError::Error(e));
                    }
                }
            }
            Some(Kex::NewKeys(newkeys)) => {
                if buf[0] != msg::NEWKEYS {
                    session.flush()?;
                    self.state = Some(ConnectionState::Write(
                        session.common.write_buffer.write_all(stream),
                    ));
                    ));
                    self.session = Some(session);
                    return Err(HandlerError::Error(Error::Kex));
                }
                // Ok, NEWKEYS received, now encrypted.
                session.common.encrypted(
                    EncryptedState::WaitingServiceRequest,
                    EncryptedState::WaitingServiceRequest,
                    newkeys,
                );
                session.flush()?;
                self.state = Some(ConnectionState::Write(
                    session.common.write_buffer.write_all(stream),
                ));
                ));
                self.session = Some(session);
                return Ok(Async::Ready(Status::Ok));
            }
            Some(kex) => {
                session.common.kex = Some(kex);
                session.flush()?;
                session.flush()?;
                self.state = Some(ConnectionState::Write(
                    session.common.write_buffer.write_all(stream),
                ));
                ));
                self.session = Some(session);
                return Ok(Async::Ready(Status::Ok));
            }
            None => {}
        }

        // Start a key re-exchange, if the client is asking for it.
        if buf[0] == msg::KEXINIT {
            // Now, if we're encrypted:
            if let Some(ref mut enc) = session.common.encrypted {


                // If we're not currently rekeying, but buf is a rekey request
                if let Some(exchange) = enc.exchange.take() {
                    let pref = &session.common.config.as_ref().preferred;
                    let kexinit = KexInit::received_rekey(
                    let kexinit = KexInit::received_rekey(
                        exchange,
                        negotiation::Server::read_kex(buf, pref)?,
                        &enc.session_id,
                    );
                    session.common.kex = Some(kexinit.server_parse(
                        session.common.config.as_ref(),
                        &mut session.common.cipher,
                        buf,
                        buf,
                        &mut session.common.write_buffer,
                    )?);
                    )?);
                }
            }
            session.flush()?;
            self.state = Some(ConnectionState::Write(
                session.common.write_buffer.write_all(stream),
            ));
            ));
            self.session = Some(session);
            return Ok(Async::Ready(Status::Ok));
        }

        // No kex going on, and the version id is done.
        self.state = Some(ConnectionState::Pending {
            pending: session.server_read_encrypted(
                self.handler.take().unwrap(),
                &buf,
            )?,
            stream,
        });
        Ok(Async::Ready(Status::Ok))
    }
}
use std::sync::Arc;
use tokio::io::AsyncWriteExt;
13
14


15
16
17
18
19

20
21
22
23
24

25





26
27
28
29




30
31
32
33


34
35
36
37
38

39
40
41
42
43
44





45
46
47
48
49
50
51
52
53
54






55
56
57
58


59
60

61
62
63
64



65
66
67
68
69

70
71
72

73
74
75
76
77

78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166


167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182






























183
184
185
186
187
188
189
190
191


192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219



220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329


330
331
332
333
334
335
336
337
338










339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424



425
426
427
428
429

430
431
432
433
434
435





436
437
438

439
440
441
442
443



444
445
446
447

448
449



450
451


452
453

454
455
456
457
458

459
460
461

462
463
464
465
466
467
468



469
470



471
472
473
474
475
476


477
478
479
480
481
482
483
484

485
486
487
488





489
490
491
492
493
494
495



496
497
498
499
500
501
502
503
504
505





506
507
508
509
510
511
512
513

514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530










531
532
533
534
535
536
537
538
539
540
541
542
543
544




545
546
547
548
549








550
551
552
553
554
555
556
557
558
559
560
561


562
563
564






565
566
567
568
569
570



571
572
573

574
575



576
577
578

579
580



581
582

584

586
587
588
589

591








592
593
594
595
596
597
598
599
600
601
602
603


604
605
606



607
608
609
610
611
612
613
614
615
616
617
618
619
620



621
622
623
624
625
626


627
628
629
630


631
632
633



634
635
636
637
638
639
640
641
642
643
644


645
646
647



648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663



664
665
666
667
668
669



670
671
672
673
674



675
676
677
678


679
680
681




682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704

705
706
707

708
709
710
711



712
713
714
715
716
717












718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736

737
738

739
740
741
742
743
744

745
746
747
748





























































































































































































































































































































































































































































































749

// limitations under the License.
//
use std;
use byteorder::{ByteOrder, BigEndian};
use super::super::*;
use super::*;
use auth::*;
use byteorder::{BigEndian, ByteOrder};
use msg;
use thrussh_keys::encoding::{Encoding, Reader};
use negotiation;
use negotiation::Select;
use std::cell::RefCell;
use thrussh_keys::encoding::{Encoding, Position, Reader};
use thrussh_keys::key;
use auth::*;
use thrussh_keys::key::Verify;
use negotiation;
use negotiation::Select;
use futures::{Async, Future};
use futures;
use futures::Poll;
use tokio::time::Instant;

impl Session {
    /// Returns false iff a request was rejected.
    pub(in server) fn server_read_encrypted<H: Handler>(
        mut self,
        mut self,
        handler: H,
    pub(in crate) async fn server_read_encrypted<H: Handler>(
        &mut self,
        handler: &mut H,
        buf: &[u8],
    ) -> Result<PendingFuture<H>, HandlerError<H::Error>> {

    ) -> Result<(), failure::Error> {
        let instant = tokio::time::Instant::now() + self.common.config.auth_rejection_time;
        debug!("read_encrypted");
        // Either this packet is a KEXINIT, in which case we start a key re-exchange.

        let mut enc = self.common.encrypted.take().unwrap();
        let mut enc = self.common.encrypted.as_mut().unwrap();
        if buf[0] == msg::KEXINIT {
            // If we're not currently rekeying, but buf is a rekey request
            if let Some(exchange) = enc.exchange.take() {
                let kexinit = KexInit::received_rekey(
                    exchange,
                    try!(negotiation::Server::read_kex(
                        buf,
                        &self.common.config.as_ref().preferred,
                    )),
                    )),
                    negotiation::Server::read_kex(buf, &self.common.config.as_ref().preferred)?,
                    &enc.session_id,
                );
                self.common.kex = Some(kexinit.server_parse(
                    self.common.config.as_ref(),
                    &mut self.common.cipher,
                    buf,
                    &mut self.common.write_buffer,
                )?);
            }
            self.common.encrypted = Some(enc);
            return Ok(PendingFuture::Ok {
            return Ok(PendingFuture::Ok {
                handler: handler,
                session: self,
            });
            return Ok(());
        }
        // If we've successfully read a packet.
        // debug!("state = {:?}, buf = {:?}", self.0.state, buf);
        let mut is_authenticated = false;
        let state = enc.state.take();
        debug!(
            "state = {:?} {:?} {:?}",
            state,
            enc.state,
            buf[0],
            msg::SERVICE_REQUEST
        );
        match state {
            Some(EncryptedState::WaitingServiceRequest) if buf[0] == msg::SERVICE_REQUEST => {

        match enc.state {
            EncryptedState::WaitingServiceRequest { ref mut accepted }
                if buf[0] == msg::SERVICE_REQUEST =>
            {
                let mut r = buf.reader(1);
                let request = try!(r.read_string());
                let request = r.read_string()?;
                debug!("request: {:?}", std::str::from_utf8(request));
                if request == b"ssh-userauth" {

                    let auth_request = server_accept_service(
                        self.common.config.as_ref().auth_banner,
                        self.common.config.as_ref().methods,
                        &mut enc.write,
                    );
                    enc.state = Some(EncryptedState::WaitingAuthRequest(auth_request));
                    *accepted = true;
                    enc.state = EncryptedState::WaitingAuthRequest(auth_request);
                }
                Ok(())
            }
            EncryptedState::WaitingAuthRequest(_) if buf[0] == msg::USERAUTH_REQUEST => {
                enc.server_read_auth_request(instant, handler, buf, &mut self.common.auth_user)
                    .await
            }
            EncryptedState::WaitingAuthRequest(ref mut auth)
                if buf[0] == msg::USERAUTH_INFO_RESPONSE =>
            {
                if read_userauth_info_response(
                    instant,
                    handler,
                    &mut enc.write,
                    auth,
                    &mut self.common.auth_user,
                    buf,
                )
                .await?
                {
                    enc.state = EncryptedState::Authenticated
                }
                Ok(())
            }
            EncryptedState::Authenticated => {
                enc.state = EncryptedState::Authenticated;
                self.server_read_authenticated(handler, buf).await
            }
            _ => Ok(()),
        }
    }
}

fn server_accept_service(
    banner: Option<&str>,
    methods: MethodSet,
    buffer: &mut CryptoVec,
) -> AuthRequest {
    push_packet!(buffer, {
        buffer.push(msg::SERVICE_ACCEPT);
        buffer.extend_ssh_string(b"ssh-userauth");
    });

    if let Some(ref banner) = banner {
        push_packet!(buffer, {
            buffer.push(msg::USERAUTH_BANNER);
            buffer.extend_ssh_string(banner.as_bytes());
            buffer.extend_ssh_string(b"");
        })
    }

    AuthRequest {
        methods: methods,
        partial_success: false, // not used immediately anway.
        current: None,
        rejection_count: 0,
    }
}

impl Encrypted {
    /// Returns false iff the request was rejected.
    async fn server_read_auth_request<H: Handler>(
        &mut self,
        until: Instant,
        handler: &mut H,
        buf: &[u8],
        auth_user: &mut String,
    ) -> Result<(), failure::Error> {
        // https://tools.ietf.org/html/rfc4252#section-5
        let mut r = buf.reader(1);
        let user = r.read_string()?;
        let user = std::str::from_utf8(user)?;
        let service_name = r.read_string()?;
        let method = r.read_string()?;
        debug!(
            "name: {:?} {:?} {:?}",
            user,
            std::str::from_utf8(service_name),
            std::str::from_utf8(method)
        );

        if service_name == b"ssh-connection" {
            if method == b"password" {
                let auth_request = if let EncryptedState::WaitingAuthRequest(ref mut a) = self.state
                {
                    a
                } else {

                    enc.state = Some(EncryptedState::WaitingServiceRequest)
                    unreachable!()
                };
                auth_user.clear();
                auth_user.push_str(user);
                r.read_byte()?;
                let password = r.read_string()?;
                let password = std::str::from_utf8(password)?;
                if let Auth::Accept = handler.auth_password(user, password).await? {
                    server_auth_request_success(&mut self.write);
                    self.state = EncryptedState::Authenticated;
                } else {
                    auth_user.clear();
                    auth_request.methods = auth_request.methods - MethodSet::PASSWORD;
                    auth_request.partial_success = false;
                    reject_auth_request(until, &mut self.write, auth_request).await;
                }
            }
            Some(EncryptedState::WaitingAuthRequest(auth_request)) => {
                if buf[0] == msg::USERAUTH_REQUEST {
                    let auth_request = enc.server_read_auth_request(
                        handler,
                        buf,
                        &mut self.common.auth_user,
                        auth_request,
                        auth_request,
                    )?;
                    self.common.encrypted = Some(enc);
                    return Ok(PendingFuture::ReadAuthRequest {
                    return Ok(PendingFuture::ReadAuthRequest {
                        session: self,
                        auth_request: auth_request,
                    });
                } else if buf[0] == msg::USERAUTH_INFO_RESPONSE {
                    let auth_request = try!(enc.read_userauth_info_response(
                        handler,
                        &mut self.common.auth_user,
                        auth_request,
                        auth_request,
                        buf,
                    ));
                    self.common.encrypted = Some(enc);
                    return Ok(PendingFuture::ReadAuthRequest {
                    return Ok(PendingFuture::ReadAuthRequest {
                        session: self,
                        auth_request: auth_request,
                    });
                Ok(())
            } else if method == b"publickey" {
                self.server_read_auth_request_pk(until, handler, buf, auth_user, user, r)
                    .await
            } else if method == b"keyboard-interactive" {
                let auth_request = if let EncryptedState::WaitingAuthRequest(ref mut a) = self.state
                {
                    a
                } else {
                    // Wrong request
                    enc.state = Some(EncryptedState::WaitingAuthRequest(auth_request));
                    unreachable!()
                };
                auth_user.clear();
                auth_user.push_str(user);
                let _ = r.read_string()?; // language_tag, deprecated.
                let submethods = std::str::from_utf8(r.read_string()?)?;
                debug!("{:?}", submethods);
                auth_request.current = Some(CurrentRequest::KeyboardInteractive {
                    submethods: submethods.to_string(),
                });
                let auth = handler
                    .auth_keyboard_interactive(user, submethods, None)
                    .await?;
                if reply_userauth_info_response(until, auth_request, &mut self.write, auth).await? {
                    self.state = EncryptedState::Authenticated
                }
                Ok(())
            } else {
                // Other methods of the base specification are insecure or optional.
                let auth_request = if let EncryptedState::WaitingAuthRequest(ref mut a) = self.state
                {
                    a
                } else {
                    unreachable!()
                };
                reject_auth_request(until, &mut self.write, auth_request).await;
                Ok(())
            }
            Some(EncryptedState::Authenticated) => {
                is_authenticated = true;
                enc.state = Some(EncryptedState::Authenticated)
        } else {
            // Unknown service
            Err(Error::Inconsistent.into())
        }
    }
}

thread_local! {
    static SIGNATURE_BUFFER: RefCell<CryptoVec> = RefCell::new(CryptoVec::new());
}

impl Encrypted {
    async fn server_read_auth_request_pk<'a, H: Handler>(
        &mut self,
        until: Instant,
        handler: &mut H,
        buf: &[u8],
        auth_user: &mut String,
        user: &str,
        mut r: Position<'a>,
    ) -> Result<(), failure::Error> {
        let auth_request = if let EncryptedState::WaitingAuthRequest(ref mut a) = self.state {
            a
        } else {
            unreachable!()
        };
        let is_real = r.read_byte()?;
        let pubkey_algo = r.read_string()?;
        let pubkey_key = r.read_string()?;
        debug!("algo: {:?}, key: {:?}", pubkey_algo, pubkey_key);
        match key::PublicKey::parse(pubkey_algo, pubkey_key) {
            Ok(pubkey) => {
                debug!("is_real = {:?}", is_real);

                if is_real != 0 {
                    let pos0 = r.position;
                    let sent_pk_ok = if let Some(CurrentRequest::PublicKey { sent_pk_ok, .. }) =
                        auth_request.current
                    {
                        sent_pk_ok
                    } else {
                        false
                    };

                    let signature = r.read_string()?;
                    debug!("signature = {:?}", signature);
                    let mut s = signature.reader(0);
                    let algo_ = s.read_string()?;
                    debug!("algo_: {:?}", algo_);
                    let sig = s.read_string()?;
                    let init = &buf[0..pos0];

                    let is_valid = if sent_pk_ok && user == auth_user {
                        true
                    } else if auth_user.len() == 0 {
                        auth_user.clear();
                        auth_user.push_str(user);
                        handler.auth_publickey(user, &pubkey).await? == Auth::Accept
                    } else {
                        false
                    };
                    if is_valid {
                        let session_id = self.session_id.as_ref();
                        if SIGNATURE_BUFFER.with(|buf| {
                            let mut buf = buf.borrow_mut();
                            buf.clear();
                            buf.extend_ssh_string(session_id);
                            buf.extend(init);
                            // Verify signature.
                            pubkey.verify_client_auth(&buf, sig)
                        }) {
                            debug!("signature verified");
                            server_auth_request_success(&mut self.write);
                            self.state = EncryptedState::Authenticated;
                        } else {
                            debug!("signature wrong");
                            reject_auth_request(until, &mut self.write, auth_request).await;
                        }
                    }
                    Ok(())
                } else {
                    auth_user.clear();
                    auth_user.push_str(user);
                    if handler.auth_publickey(user, &pubkey).await? == Auth::Accept {
                        let mut public_key = CryptoVec::new();
                        public_key.extend(pubkey_key);

                        let mut algo = CryptoVec::new();
                        algo.extend(pubkey_algo);
                        debug!("pubkey_key: {:?}", pubkey_key);
                        push_packet!(self.write, {
                            self.write.push(msg::USERAUTH_PK_OK);
                            self.write.extend_ssh_string(&pubkey_algo);
                            self.write.extend_ssh_string(&pubkey_key);
                        });

                        auth_request.current = Some(CurrentRequest::PublicKey {
                            key: public_key,
                            algo: algo,
                            sent_pk_ok: true,
                        });
                    } else {
                        debug!("signature wrong");
                        auth_request.partial_success = false;
                        auth_user.clear();
                        reject_auth_request(until, &mut self.write, auth_request).await;
                    }
                    Ok(())
                }
            }
            state => {
                enc.state = state;
            Err(e) => {
                if let Some(thrussh_keys::Error::CouldNotReadKey) = e.downcast_ref() {
                    reject_auth_request(until, &mut self.write, auth_request).await;
                    Ok(())
                } else {
                    Err(e)
                }
            }
        }
        self.common.encrypted = Some(enc);
        if is_authenticated {
        if is_authenticated {
            let auth = self.server_read_authenticated(handler, buf).unwrap();
            Ok(PendingFuture::Authenticated(auth))
        } else {
            Ok(PendingFuture::Ok {
                handler: handler,
                session: self,
            })
    }
}

async fn reject_auth_request(
    until: Instant,
    write: &mut CryptoVec,
    auth_request: &mut AuthRequest,
) {
    debug!("rejecting {:?}", auth_request);
    push_packet!(write, {
        write.push(msg::USERAUTH_FAILURE);
        write.extend_list(auth_request.methods);
        write.push(if auth_request.partial_success { 1 } else { 0 });
    });
    auth_request.current = None;
    auth_request.rejection_count += 1;
    debug!("packet pushed");
    tokio::time::delay_until(until).await
}

fn server_auth_request_success(buffer: &mut CryptoVec) {
    push_packet!(buffer, {
        buffer.push(msg::USERAUTH_SUCCESS);
    })
}

async fn read_userauth_info_response<H: Handler>(
    until: Instant,
    handler: &mut H,
    write: &mut CryptoVec,
    auth_request: &mut AuthRequest,
    user: &mut String,
    b: &[u8],
) -> Result<bool, failure::Error> {
    if let Some(CurrentRequest::KeyboardInteractive { ref submethods }) = auth_request.current {
        let mut r = b.reader(1);
        let n = r.read_u32()?;
        let response = Response { pos: r, n: n };
        let auth = handler
            .auth_keyboard_interactive(user, submethods, Some(response))
            .await?;
        reply_userauth_info_response(until, auth_request, write, auth).await
    } else {
        reject_auth_request(until, write, auth_request).await;
        Ok(false)
    }
}

async fn reply_userauth_info_response(
    until: Instant,
    auth_request: &mut AuthRequest,
    write: &mut CryptoVec,
    auth: Auth,
) -> Result<bool, failure::Error> {
    match auth {
        Auth::Accept => {
            server_auth_request_success(write);
            Ok(true)
        }
        Auth::Reject => {
            auth_request.partial_success = false;
            reject_auth_request(until, write, auth_request).await;
            Ok(false)
        }
        Auth::Partial {
            name,
            instructions,
            prompts,
        } => {
            push_packet!(write, {
                write.push(msg::USERAUTH_INFO_REQUEST);
                write.extend_ssh_string(name.as_bytes());
                write.extend_ssh_string(instructions.as_bytes());
                write.extend_ssh_string(b""); // lang, should be empty
                write.push_u32_be(prompts.len() as u32);
                for &(ref a, b) in prompts.iter() {
                    write.extend_ssh_string(a.as_bytes());
                    write.push(if b { 1 } else { 0 });
                }
            });
            Ok(false)
        }
        Auth::UnsupportedMethod => unreachable!(),
    }
}

    fn server_read_authenticated<H: Handler>(
        mut self,
        handler: H,
impl Session {
    async fn server_read_authenticated<H: Handler>(
        &mut self,
        handler: &mut H,
        buf: &[u8],
    ) -> Result<Authenticated<H>, HandlerError<H::Error>> {
    ) -> Result<(), failure::Error> {
        debug!(
            "authenticated buf = {:?}",
            &buf[..std::cmp::min(buf.len(), 100)]
        );
        match buf[0] {
            msg::CHANNEL_OPEN => {
                Ok(Authenticated::FutureUnit(
                    try!(self.server_handle_channel_open(handler, buf)),
                ))
            }
            msg::CHANNEL_OPEN => self.server_handle_channel_open(handler, buf).await,
            msg::CHANNEL_CLOSE => {
                let mut r = buf.reader(1);
                let channel_num = ChannelId(try!(r.read_u32()));
                let channel_num = ChannelId(r.read_u32()?);
                if let Some(ref mut enc) = self.common.encrypted {
                    enc.channels.remove(&channel_num);
                }
                debug!("handler.channel_close {:?}", channel_num);
                Ok(Authenticated::future_unit(
                    handler.channel_close(channel_num, self),
                ))
                handler.channel_close(channel_num, self).await
            }
            msg::CHANNEL_EOF => {
                let mut r = buf.reader(1);
                let channel_num = ChannelId(try!(r.read_u32()));
                let channel_num = ChannelId(r.read_u32()?);
                debug!("handler.channel_eof {:?}", channel_num);
                Ok(Authenticated::future_unit(
                    handler.channel_eof(channel_num, self),
                ))
                handler.channel_eof(channel_num, self).await
            }
            msg::CHANNEL_EXTENDED_DATA |
            msg::CHANNEL_DATA => {
            msg::CHANNEL_EXTENDED_DATA | msg::CHANNEL_DATA => {
                let mut r = buf.reader(1);
                let channel_num = ChannelId(try!(r.read_u32()));
                let channel_num = ChannelId(r.read_u32()?);

                let ext = if buf[0] == msg::CHANNEL_DATA {
                    None
                } else {
                    Some(try!(r.read_u32()))
                    Some(r.read_u32()?)
                };
                debug!("handler.data {:?} {:?}", ext, channel_num);
                let data = try!(r.read_string());
                let data = r.read_string()?;
                let target = self.common.config.window_size;
                if let Some(ref mut enc) = self.common.encrypted {
                    enc.adjust_window_size(channel_num, data, target);
                }
                self.flush()?;
                if let Some(ext) = ext {
                    Ok(Authenticated::future_unit(
                        handler.extended_data(channel_num, ext, &data, self),
                    ))
                    handler.extended_data(channel_num, ext, &data, self).await
                } else {
                    Ok(Authenticated::future_unit(
                        handler.data(channel_num, &data, self),
                    ))
                    handler.data(channel_num, &data, self).await
                }
            }

            msg::CHANNEL_WINDOW_ADJUST => {
                let mut r = buf.reader(1);
                let channel_num = ChannelId(try!(r.read_u32()));
                let amount = try!(r.read_u32());
                let channel_num = ChannelId(r.read_u32()?);
                let amount = r.read_u32()?;
                let mut new_value = 0;
                if let Some(ref mut enc) = self.common.encrypted {
                    if let Some(channel) = enc.channels.get_mut(&channel_num) {
                        channel.recipient_window_size += amount;
                        new_value = channel.recipient_window_size;
                    } else {
                        return Err(HandlerError::Error(Error::WrongChannel));
                        return Err(Error::WrongChannel.into());
                    }
                }
                debug!("handler.window_adjusted {:?}", channel_num);
                Ok(Authenticated::future_unit(handler.window_adjusted(
                    channel_num,
                    new_value as usize,
                    self,
                )))
                handler
                    .window_adjusted(channel_num, new_value as usize, self)
                    .await
            }

            msg::CHANNEL_REQUEST => {
                let mut r = buf.reader(1);
                let channel_num = ChannelId(try!(r.read_u32()));
                let req_type = try!(r.read_string());
                let wants_reply = try!(r.read_byte());
                let channel_num = ChannelId(r.read_u32()?);
                let req_type = r.read_string()?;
                let wants_reply = r.read_byte()?;
                if let Some(ref mut enc) = self.common.encrypted {
                    if let Some(channel) = enc.channels.get_mut(&channel_num) {
                        channel.wants_reply = wants_reply != 0;
                    }
                }
                match req_type {
                    b"pty-req" => {
                        let term = try!(std::str::from_utf8(try!(r.read_string())));
                        let col_width = try!(r.read_u32());
                        let row_height = try!(r.read_u32());
                        let pix_width = try!(r.read_u32());
                        let pix_height = try!(r.read_u32());
                        let term = std::str::from_utf8(r.read_string()?)?;
                        let col_width = r.read_u32()?;
                        let row_height = r.read_u32()?;
                        let pix_width = r.read_u32()?;
                        let pix_height = r.read_u32()?;
                        let mut modes = [(Pty::TTY_OP_END, 0); 130];
                        let mut i = 0;
                        {
                            let mode_string = try!(r.read_string());
                            let mode_string = r.read_string()?;
                            while 5 * i < mode_string.len() {
                                let code = mode_string[5 * i];
                                if code == 0 {
                                    break;
                                }
                                let num = BigEndian::read_u32(&mode_string[5 * i + 1..]);
                                debug!("code = {:?}", code);
                                if let Some(code) = Pty::from_u8(code) {
                                    modes[i] = (code, num);
                                } else {
                                    info!("pty-req: unknown pty code {:?}", code);
                                }
                                i += 1
                            }
                        }
                        debug!("handler.pty_request {:?}", channel_num);
                        Ok(Authenticated::future_unit(handler.pty_request(
                            channel_num,
                            term,
                            col_width,
                            row_height,
                            pix_width,
                            pix_height,
                            &modes[0..i],
                            self,
                        )))
                        handler
                            .pty_request(
                                channel_num,
                                term,
                                col_width,
                                row_height,
                                pix_width,
                                pix_height,
                                &modes[0..i],
                                self,
                            )
                            .await
                    }
                    b"x11-req" => {
                        let single_connection = try!(r.read_byte()) != 0;
                        let x11_auth_protocol = try!(std::str::from_utf8(try!(r.read_string())));
                        let x11_auth_cookie = try!(std::str::from_utf8(try!(r.read_string())));
                        let x11_screen_number = try!(r.read_u32());
                        let single_connection = r.read_byte()? != 0;
                        let x11_auth_protocol = std::str::from_utf8(r.read_string()?)?;
                        let x11_auth_cookie = std::str::from_utf8(r.read_string()?)?;
                        let x11_screen_number = r.read_u32()?;
                        debug!("handler.x11_request {:?}", channel_num);
                        Ok(Authenticated::future_unit(handler.x11_request(
                            channel_num,
                            single_connection,
                            x11_auth_protocol,
                            x11_auth_cookie,
                            x11_screen_number,
                            self,
                        )))
                        handler
                            .x11_request(
                                channel_num,
                                single_connection,
                                x11_auth_protocol,
                                x11_auth_cookie,
                                x11_screen_number,
                                self,
                            )
                            .await
                    }
                    b"env" => {
                        let env_variable = try!(std::str::from_utf8(try!(r.read_string())));
                        let env_value = try!(std::str::from_utf8(try!(r.read_string())));
                        let env_variable = std::str::from_utf8(r.read_string()?)?;
                        let env_value = std::str::from_utf8(r.read_string()?)?;
                        debug!("handler.env_request {:?}", channel_num);
                        Ok(Authenticated::future_unit(handler.env_request(
                            channel_num,
                            env_variable,
                            env_value,
                            self,
                        )))
                        handler
                            .env_request(channel_num, env_variable, env_value, self)
                            .await
                    }
                    b"shell" => {
                        debug!("handler.shell_request {:?}", channel_num);
                        Ok(Authenticated::future_unit(
                            handler.shell_request(channel_num, self),
                        ))
                        handler.shell_request(channel_num, self).await
                    }
                    b"exec" => {
                        let req = try!(r.read_string());
                        let req = r.read_string()?;
                        debug!("handler.exec_request {:?}", channel_num);
                        Ok(Authenticated::future_unit(
                            handler.exec_request(channel_num, req, self),
                        ))
                        handler.exec_request(channel_num, req, self).await
                    }
                    b"subsystem" => {
                        let name = try!(std::str::from_utf8(try!(r.read_string())));
                        let name = std::str::from_utf8(r.read_string()?)?;
                        debug!("handler.subsystem_request {:?}", channel_num);
                        Ok(Authenticated::future_unit(
                            handler.subsystem_request(channel_num, name, self),
                        ))
                        handler.subsystem_request(channel_num, name, self).await
                    }

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
                    b"window-change" => {

================================
                        let col_width = r.read_u32()?;
                        let row_height = r.read_u32()?;
                        let pix_width = r.read_u32()?;
                        let pix_height = r.read_u32()?;

<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
                        debug!("handler.window_change {:?}", channel_num);
                        Ok(Authenticated::future_unit(handler.window_change_request(
                            channel_num,
                            col_width,
                            row_height,
                            pix_width,
                            pix_height,
                            self,
                        )))
                        handler
                            .window_change_request(
                                channel_num,
                                col_width,
                                row_height,
                                pix_width,
                                pix_height,
                                self,
                            )
                            .await
                    }
                    b"signal" => {
                        try!(r.read_byte()); // should be 0.
                        let signal_name = try!(Sig::from_name(try!(r.read_string())));
                        r.read_byte()?; // should be 0.
                        let signal_name = Sig::from_name(r.read_string()?)?;
                        debug!("handler.signal {:?} {:?}", channel_num, signal_name);
                        Ok(Authenticated::future_unit(
                            handler.signal(channel_num, signal_name, self),
                        ))
                        handler.signal(channel_num, signal_name, self).await
                    }
                    x => {
                        debug!(
                            "{:?}, line {:?} req_type = {:?}",
                            file!(),
                            line!(),
                            std::str::from_utf8(x)
                        );
                        if let Some(ref mut enc) = self.common.encrypted {
                            push_packet!(enc.write, {
                                enc.write.push(msg::CHANNEL_FAILURE);
                            });
                        }
                        Ok(Authenticated::FutureUnit(
                            FutureUnit::Done(futures::done(Ok((handler, self)))),
                        ))
                        Ok(())
                    }
                }
            }
            msg::GLOBAL_REQUEST => {
                let mut r = buf.reader(1);
                let req_type = try!(r.read_string());
                self.common.wants_reply = try!(r.read_byte()) != 0;
                let req_type = r.read_string()?;
                self.common.wants_reply = r.read_byte()? != 0;
                match req_type {
                    b"tcpip-forward" => {
                        let address = try!(std::str::from_utf8(try!(r.read_string())));
                        let port = try!(r.read_u32());
                        let address = std::str::from_utf8(r.read_string()?)?;
                        let port = r.read_u32()?;
                        debug!("handler.tcpip_forward {:?} {:?}", address, port);
                        Ok(Authenticated::Forward(Forward {
                            forward: handler.tcpip_forward(address, port, self),
                        }))
                        let result = handler.tcpip_forward(address, port, self).await?;
                        if let Some(ref mut enc) = self.common.encrypted {
                            if result {
                                push_packet!(enc.write, enc.write.push(msg::REQUEST_SUCCESS))
                            } else {
                                push_packet!(enc.write, enc.write.push(msg::REQUEST_FAILURE))
                            }
                        }
                        Ok(())
                    }
                    b"cancel-tcpip-forward" => {
                        let address = try!(std::str::from_utf8(try!(r.read_string())));
                        let port = try!(r.read_u32());
                        let address = std::str::from_utf8(r.read_string()?)?;
                        let port = r.read_u32()?;
                        debug!("handler.cancel_tcpip_forward {:?} {:?}", address, port);
                        Ok(Authenticated::Forward(Forward {
                            forward: handler.cancel_tcpip_forward(address, port, self),
                        }))
                        let result = handler.cancel_tcpip_forward(address, port, self).await?;
                        if let Some(ref mut enc) = self.common.encrypted {
                            if result {
                                push_packet!(enc.write, enc.write.push(msg::REQUEST_SUCCESS))
                            } else {
                                push_packet!(enc.write, enc.write.push(msg::REQUEST_FAILURE))
                            }
                        }
                        Ok(())
                    }
                    _ => {
                        if let Some(ref mut enc) = self.common.encrypted {
                            push_packet!(enc.write, {
                                enc.write.push(msg::REQUEST_FAILURE);
                            });
                        }
                        Ok(Authenticated::FutureUnit(
                            FutureUnit::Done(futures::done(Ok((handler, self)))),
                        ))
                        Ok(())
                    }
                }
            }
            m => {
                debug!("unknown message received: {:?}", m);
                Ok(Authenticated::FutureUnit(
                    FutureUnit::Done(futures::done(Ok((handler, self)))),
                ))
                Ok(())
            }
        }
    }

    fn server_handle_channel_open<H: Handler>(
        mut self,
        handler: H,
    async fn server_handle_channel_open<H: Handler>(
        &mut self,
        handler: &mut H,
        buf: &[u8],
    ) -> Result<FutureUnit<H>, HandlerError<H::Error>> {

    ) -> Result<(), failure::Error> {
        // https://tools.ietf.org/html/rfc4254#section-5.1
        let mut r = buf.reader(1);
        let typ = try!(r.read_string());
        let sender = try!(r.read_u32());
        let window = try!(r.read_u32());
        let maxpacket = try!(r.read_u32());
        let typ = r.read_string()?;
        let sender = r.read_u32()?;
        let window = r.read_u32()?;
        let maxpacket = r.read_u32()?;

        let sender_channel = if let Some(ref mut enc) = self.common.encrypted {
            enc.new_channel_id()
        } else {
            unreachable!()
        };
        let channel = Channel {
            recipient_channel: sender,

            // "sender" is the local end, i.e. we're the sender, the remote is the recipient.
            sender_channel: sender_channel,

            recipient_window_size: window,
            sender_window_size: self.common.config.window_size,
            recipient_maximum_packet_size: maxpacket,
            sender_maximum_packet_size: self.common.config.maximum_packet_size,
            confirmed: true,
            wants_reply: false,
        };
        Ok(match typ {
        match typ {
            b"session" => {
                self.confirm_channel_open(channel);
                FutureUnit::H(handler.channel_open_session(sender_channel, self))
                handler.channel_open_session(sender_channel, self).await
            }
            b"x11" => {
                self.confirm_channel_open(channel);
                let a = try!(std::str::from_utf8(try!(r.read_string())));
                let b = try!(r.read_u32());
                FutureUnit::H(handler.channel_open_x11(sender_channel, a, b, self))
                let a = std::str::from_utf8(r.read_string()?)?;
                let b = r.read_u32()?;
                handler.channel_open_x11(sender_channel, a, b, self).await
            }
            b"direct-tcpip" => {
                self.confirm_channel_open(channel);
                let a = try!(std::str::from_utf8(try!(r.read_string())));
                let b = try!(r.read_u32());
                let c = try!(std::str::from_utf8(try!(r.read_string())));
                let d = try!(r.read_u32());
                FutureUnit::H(handler.channel_open_direct_tcpip(
                    sender_channel,
                    a,
                    b,
                    c,
                    d,
                    self,
                ))
                let a = std::str::from_utf8(r.read_string()?)?;
                let b = r.read_u32()?;
                let c = std::str::from_utf8(r.read_string()?)?;
                let d = r.read_u32()?;
                handler
                    .channel_open_direct_tcpip(sender_channel, a, b, c, d, self)
                    .await
            }
            t => {
                debug!("unknown channel type: {:?}", t);
                if let Some(ref mut enc) = self.common.encrypted {
                    push_packet!(enc.write, {
                        enc.write.push(msg::CHANNEL_OPEN_FAILURE);
                        enc.write.push_u32_be(sender);
                        enc.write.push_u32_be(3); // SSH_OPEN_UNKNOWN_CHANNEL_TYPE
                        enc.write.extend_ssh_string(b"Unknown channel type");
                        enc.write.extend_ssh_string(b"en");
                    });
                }
                FutureUnit::Done(futures::done(Ok((handler, self))))
                Ok(())
            }
        })
        }
    }
    fn confirm_channel_open(&mut self, channel: Channel) {
        if let Some(ref mut enc) = self.common.encrypted {
            server_confirm_channel_open(&mut enc.write, &channel, self.common.config.as_ref());
            enc.channels.insert(channel.sender_channel, channel);
            enc.state = Some(EncryptedState::Authenticated);
        }
    }
}

pub enum Authenticated<H: Handler> {
    FutureUnit(FutureUnit<H>),
    Forward(Forward<H>),
}

impl<H: Handler> Authenticated<H> {
    pub fn poll(&mut self) -> Poll<(H, Session), HandlerError<H::Error>> {
        match *self {
            Authenticated::FutureUnit(ref mut a) => a.poll(),
            Authenticated::Forward(ref mut a) => a.poll(),
        }
    }
}

impl<H: Handler> Authenticated<H> {
    fn future_unit(h: H::FutureUnit) -> Self {
        Authenticated::FutureUnit(FutureUnit::H(h))
    }
}

pub enum FutureUnit<H: Handler> {
    H(H::FutureUnit),
    Done(futures::Done<(H, Session), HandlerError<H::Error>>),
}
impl<H: Handler> Future for FutureUnit<H> {
    type Item = (H, Session);
    type Error = HandlerError<H::Error>;

    fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
        match *self {
            FutureUnit::H(ref mut a) => a.poll().map_err(HandlerError::Handler),
            FutureUnit::Done(ref mut a) => a.poll(),
        }
    }
}

pub struct Forward<H: Handler> {
    forward: H::FutureBool,
}

impl<H: Handler> Forward<H> {
    pub fn poll(&mut self) -> Poll<(H, Session), HandlerError<H::Error>> {
        let (handler, mut session, result) =
            try_ready!(self.forward.poll().map_err(HandlerError::Handler));
        if let Some(ref mut enc) = session.common.encrypted {
            if result {
            if result {
                push_packet!(enc.write, enc.write.push(msg::REQUEST_SUCCESS))
            } else {
                push_packet!(enc.write, enc.write.push(msg::REQUEST_FAILURE))
            }
        }
        Ok(Async::Ready((handler, session)))
    }
}

pub enum ReadAuthRequest<H: Handler> {
    Req {
        future: FutureAuth<H>,
        auth_request: Option<AuthRequest>,
    },
    Reject(Option<H>),
    Accept(Option<H>),
    UnsupportedMethod(Option<H>),
}

pub enum FutureAuth<H: Handler> {
    Password(H::FutureAuth),
    Pubkey {
        validate: ValidatePubkey<H>,
        sig: Vec<u8>,
        init: Vec<u8>,
        key: key::PublicKey,
    },
    PubkeyProbe {
        probe: H::FutureAuth,
        pubkey_algo: Vec<u8>,
        pubkey_key: Vec<u8>,
        key: key::PublicKey,
    },
    KeyboardInteractive { ki: H::FutureAuth },
}

pub enum ValidatePubkey<H: Handler> {
    Valid(Option<H>),
    Future(H::FutureAuth),
    Invalid(Option<H>),
}

impl<H: Handler> ReadAuthRequest<H> {
    pub(crate) fn poll(
        &mut self,
        enc: &mut Encrypted,
        auth_user: &mut String,
        buffer: &mut CryptoVec,
    ) -> Poll<(H, Auth), HandlerError<H::Error>> {
        match *self {
            ReadAuthRequest::Req {
                ref mut future,
                ref mut auth_request,
            } => {
                match *future {
                    FutureAuth::Password(ref mut fut) => {
                        debug!("ReadAuthRequest.poll(): Password");
                        let (handler, auth) = try_ready!(fut.poll().map_err(HandlerError::Handler));
                        if let Auth::Accept = auth {
                            server_auth_request_success(&mut enc.write);
                            enc.state = Some(EncryptedState::Authenticated);
                            Ok(Async::Ready((handler, Auth::Accept)))
                        } else {
                            auth_user.clear();
                            let mut auth_request = auth_request.take().unwrap();
                            auth_request.methods = auth_request.methods - MethodSet::PASSWORD;
                            auth_request.partial_success = false;
                            enc.reject_auth_request(auth_request);
                            Ok(Async::Ready((handler, Auth::Reject)))
                        }
                    }
                    FutureAuth::Pubkey {
                        ref mut validate,
                        ref sig,
                        ref init,
                        ref key,
                    } => {
                        debug!("ReadAuthRequest.poll(): Pubkey");
                        let (handler, is_valid) = match *validate {
                            ValidatePubkey::Valid(ref mut h) => (h.take().unwrap(), true),
                            ValidatePubkey::Future(ref mut h) => {
                                let (handler, auth) =
                                    try_ready!(h.poll().map_err(HandlerError::Handler));
                                (handler, auth == Auth::Accept)
                            }
                            ValidatePubkey::Invalid(ref mut h) => (h.take().unwrap(), false),
                        };
                        if is_valid {
                            buffer.clear();
                            buffer.extend_ssh_string(enc.session_id.as_ref());
                            buffer.extend(init);
                            // Verify signature.
                            if key.verify_client_auth(buffer, sig) {
                                debug!("signature verified");
                                server_auth_request_success(&mut enc.write);
                                enc.state = Some(EncryptedState::Authenticated);
                                return Ok(Async::Ready((handler, Auth::Accept)));
                            } else {
                                debug!("signature wrong");
                            }
                        }
                        Ok(Async::Ready((handler, Auth::Reject)))
                    }
                    FutureAuth::PubkeyProbe {
                        ref mut probe,
                        ref pubkey_algo,
                        ref pubkey_key,
                        ..
                    } => {
                        debug!("ReadAuthRequest.poll(): PubkeyProbe");
                        let (handler, auth) =
                            try_ready!(probe.poll().map_err(HandlerError::Handler));
                        if let Auth::Accept = auth {

                            let mut public_key = CryptoVec::new();
                            public_key.extend(pubkey_key);

                            let mut algo = CryptoVec::new();
                            algo.extend(pubkey_algo);
                            debug!("pubkey_key: {:?}", pubkey_key);
                            push_packet!(enc.write, {
                                enc.write.push(msg::USERAUTH_PK_OK);
                                enc.write.extend_ssh_string(&pubkey_algo);
                                enc.write.extend_ssh_string(&pubkey_key);
                            });

                            let mut auth_request = auth_request.take().unwrap();
                            auth_request.current = Some(CurrentRequest::PublicKey {
                                key: public_key,
                                algo: algo,
                                sent_pk_ok: true,
                            });

                            enc.state = Some(EncryptedState::WaitingAuthRequest(auth_request));
                            Ok(Async::Ready((handler, Auth::Accept)))
                        } else {
                            let mut auth_request = auth_request.take().unwrap();
                            // auth_request.methods -= MethodSet::PUBLICKEY;
                            auth_request.partial_success = false;
                            auth_user.clear();
                            enc.reject_auth_request(auth_request);
                            Ok(Async::Ready((handler, Auth::Reject)))
                        }
                    }
                    FutureAuth::KeyboardInteractive { ref mut ki } => {

                        match try_ready!(ki.poll().map_err(HandlerError::Handler)) {
                            (handler, Auth::Accept) => {
                                server_auth_request_success(&mut enc.write);
                                enc.state = Some(EncryptedState::Authenticated);
                                Ok(Async::Ready((handler, Auth::Accept)))
                            }
                            (_, Auth::UnsupportedMethod) => unreachable!(),
                            (handler, Auth::Reject) => {
                                let mut auth_request = auth_request.take().unwrap();
                                // auth_request.methods -= KEYBOARD_INTERACTIVE;
                                auth_request.partial_success = false;
                                auth_user.clear();
                                enc.reject_auth_request(auth_request);
                                Ok(Async::Ready((handler, Auth::Reject)))
                            }
                            (handler,
                             Auth::Partial {
                                 name,
                                 instructions,
                                 prompts,
                             }) => {

                                push_packet!(enc.write, {
                                    enc.write.push(msg::USERAUTH_INFO_REQUEST);
                                    enc.write.extend_ssh_string(name.as_bytes());
                                    enc.write.extend_ssh_string(instructions.as_bytes());
                                    enc.write.extend_ssh_string(b""); // lang, should be empty
                                    enc.write.push_u32_be(prompts.len() as u32);
                                    for &(ref a, b) in prompts.iter() {
                                        enc.write.extend_ssh_string(a.as_bytes());
                                        enc.write.push(if b { 1 } else { 0 });
                                    }
                                });
                                let auth_request = auth_request.take().unwrap();
                                enc.state = Some(EncryptedState::WaitingAuthRequest(auth_request));
                                Ok(Async::Ready((
                                    handler,
                                    Auth::Partial {
                                        name: name,
                                        instructions: instructions,
                                        prompts: prompts,
                                    },
                                )))
                            }
                        }

                    }
                }

            }
            ReadAuthRequest::Reject(ref mut h) => {
                Ok(Async::Ready((h.take().unwrap(), Auth::Reject)))
            }
            ReadAuthRequest::UnsupportedMethod(ref mut h) => {
                Ok(Async::Ready((h.take().unwrap(), Auth::UnsupportedMethod)))
            }
            ReadAuthRequest::Accept(ref mut h) => {
                Ok(Async::Ready((h.take().unwrap(), Auth::Accept)))
            }
        }
    }
}

impl Encrypted {
    /// Returns false iff the request was rejected.
    fn server_read_auth_request<H: Handler>(
        &mut self,
        handler: H,
        buf: &[u8],
        auth_user: &mut String,
        mut auth_request: AuthRequest,
    ) -> Result<ReadAuthRequest<H>, HandlerError<H::Error>> {

        // https://tools.ietf.org/html/rfc4252#section-5
        let mut r = buf.reader(1);
        let user = try!(r.read_string());
        let user = try!(std::str::from_utf8(user));
        let service_name = try!(r.read_string());
        let method = try!(r.read_string());
        debug!(
            "name: {:?} {:?} {:?}",
            user,
            std::str::from_utf8(service_name),
            std::str::from_utf8(method)
        );

        if service_name == b"ssh-connection" {

            if method == b"password" {

                auth_user.clear();
                auth_user.push_str(user);

                try!(r.read_byte());
                let password = try!(r.read_string());
                let password = try!(std::str::from_utf8(password));

                Ok(ReadAuthRequest::Req {
                    future: FutureAuth::Password(handler.auth_password(user, password)),
                    auth_request: Some(auth_request),
                })

            } else if method == b"publickey" {

                let is_real = try!(r.read_byte());
                let pubkey_algo = try!(r.read_string());
                let pubkey_key = try!(r.read_string());
                debug!("algo: {:?}, key: {:?}", pubkey_algo, pubkey_key);
                match key::PublicKey::parse(pubkey_algo, pubkey_key) {
                    Ok(pubkey) => {
                        debug!("is_real = {:?}", is_real);

                        if is_real != 0 {

                            let pos0 = r.position;
                            let sent_pk_ok = if let Some(CurrentRequest::PublicKey {
                                                             sent_pk_ok, ..
                                                         }) = auth_request.current
                            {
                                sent_pk_ok
                            } else {
                                false
                            };

                            let signature = try!(r.read_string());
                            let mut s = signature.reader(0);
                            let algo_ = try!(s.read_string());
                            debug!("algo_: {:?}", algo_);
                            let sig = try!(s.read_string());
                            let init = &buf[0..pos0];

                            let validate = if sent_pk_ok && user == auth_user {
                                ValidatePubkey::Valid(Some(handler))
                            } else if auth_user.len() == 0 {
                                auth_user.clear();
                                auth_user.push_str(user);
                                ValidatePubkey::Future(handler.auth_publickey(user, &pubkey))
                            } else {
                                ValidatePubkey::Invalid(Some(handler))
                            };

                            Ok(ReadAuthRequest::Req {
                                future: FutureAuth::Pubkey {
                                    validate: validate,
                                    sig: sig.to_vec(),
                                    init: init.to_vec(),
                                    key: pubkey,
                                },
                                auth_request: Some(auth_request),
                            })

                        } else {
                            auth_user.clear();
                            auth_user.push_str(user);

                            Ok(ReadAuthRequest::Req {
                                future: FutureAuth::PubkeyProbe {
                                    probe: handler.auth_publickey(user, &pubkey),
                                    pubkey_algo: pubkey_algo.to_vec(),
                                    pubkey_key: pubkey_key.to_vec(),
                                    key: pubkey,
                                },
                                auth_request: Some(auth_request),
                            })
                        }
                    }
                    Err(e) => {
                        if let thrussh_keys::Error::CouldNotReadKey = e {
                            self.reject_auth_request(auth_request);
                            self.reject_auth_request(auth_request);
                            Ok(ReadAuthRequest::Reject(Some(handler)))
                        } else {
                            return Err(HandlerError::Error(Error::from(e)))
                        }
                    }
                }
            // Other methods of the base specification are insecure or optional.
            } else if method == b"keyboard-interactive" {

                auth_user.clear();
                auth_user.push_str(user);
                let _ = try!(r.read_string()); // language_tag, deprecated.
                let submethods = try!(std::str::from_utf8(try!(r.read_string())));
                debug!("{:?}", submethods);
                auth_request.current = Some(CurrentRequest::KeyboardInteractive {
                    submethods: submethods.to_string(),
                });
                Ok(ReadAuthRequest::Req {
                    future: FutureAuth::KeyboardInteractive {
                        ki: handler.auth_keyboard_interactive(user, submethods, None),
                    },
                    auth_request: Some(auth_request),
                })

            } else {
                self.reject_auth_request(auth_request);
                Ok(ReadAuthRequest::UnsupportedMethod(Some(handler)))
            }
        } else {
            // Unknown service
            Err(HandlerError::Error(Error::Inconsistent))
        }
    }

    fn read_userauth_info_response<H: Handler>(
        &mut self,
        handler: H,
        user: &mut String,
        auth_request: AuthRequest,
        b: &[u8],
    ) -> Result<ReadAuthRequest<H>, HandlerError<H::Error>> {

        let ki = if let Some(CurrentRequest::KeyboardInteractive { ref submethods }) =
            auth_request.current
        {
            let mut r = b.reader(1);
            let n = try!(r.read_u32());
            let response = Response { pos: r, n: n };
            handler.auth_keyboard_interactive(user, submethods, Some(response))
        } else {
            return Ok(ReadAuthRequest::Reject(Some(handler)));
        };

        Ok(ReadAuthRequest::Req {
            future: FutureAuth::KeyboardInteractive { ki: ki },
            auth_request: Some(auth_request),
        })
    }

    fn reject_auth_request(&mut self, mut auth_request: AuthRequest) {
        debug!("rejecting {:?}", auth_request);
        push_packet!(self.write, {
            self.write.push(msg::USERAUTH_FAILURE);
            self.write.extend_list(auth_request.methods);
            self.write.push(
                if auth_request.partial_success { 1 } else { 0 },
            );
        });
        auth_request.current = None;
        auth_request.rejection_count += 1;
        debug!("packet pushed");
        self.state = Some(EncryptedState::WaitingAuthRequest(auth_request));
    }
}





fn server_accept_service(
    banner: Option<&str>,
    methods: MethodSet,
    buffer: &mut CryptoVec,
) -> AuthRequest {

    push_packet!(buffer, {
        buffer.push(msg::SERVICE_ACCEPT);
        buffer.extend_ssh_string(b"ssh-userauth");
    });

    if let Some(ref banner) = banner {
        push_packet!(buffer, {
            buffer.push(msg::USERAUTH_BANNER);
            buffer.extend_ssh_string(banner.as_bytes());
            buffer.extend_ssh_string(b"");
        })
    }

    AuthRequest {
        methods: methods,
        partial_success: false, // not used immediately anway.
        current: None,
        rejection_count: 0,
    }
}


fn server_auth_request_success(buffer: &mut CryptoVec) {

    push_packet!(buffer, {
        buffer.push(msg::USERAUTH_SUCCESS);
    })
}

fn server_confirm_channel_open(buffer: &mut CryptoVec, channel: &Channel, config: &Config) {

1





2
3
4
5
6
7
8

9
10
11
12
13
14
15
16
17
18
19


20
21

22
23
24
25
26
27

28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45

46
47
48
49
50
51
52
53
54
55
56
57
58
59

60
61
62
63
64
65
66
67
68
69
70
71
72
73


74
75
76

77
78
79
80
81
82
83
84
85
86
87
88





89
90
91
92
93
94
95
96
97
98




















99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124



125
126
use super::*;
use negotiation::Select;
use msg;
use cipher::CipherPair;
use negotiation;
use key::PubKey;
use crate::cipher::CipherPair;
use crate::key::PubKey;
use crate::negotiation::Select;
use crate::{kex, msg, negotiation};
use std::cell::RefCell;
use thrussh_keys::encoding::{Encoding, Reader};

use kex;
thread_local! {
    static HASH_BUF: RefCell<CryptoVec> = RefCell::new(CryptoVec::new());
}

impl KexInit {
    pub fn server_parse(
        mut self,
        config: &Config,
        cipher: &CipherPair,
        buf: &[u8],
        write_buffer: &mut SSHBuffer,
    ) -> Result<Kex, Error> {

    ) -> Result<Kex, failure::Error> {
        if buf[0] == msg::KEXINIT {
            debug!("server parse");
            debug!("server parse {:?}", &write_buffer.buffer[..]);
            let algo = if self.algo.is_none() {
                // read algorithms from packet.
                self.exchange.client_kex_init.extend(buf);
                super::negotiation::Server::read_kex(buf, &config.preferred)?
            } else {
                return Err(Error::Kex);
                return Err(Error::Kex.into());
            };
            if !self.sent {
                self.server_write(config, cipher, write_buffer)?
            }
            let mut key = 0;
            debug!("config {:?} algo {:?}", config.keys, algo.key);
            while key < config.keys.len() && config.keys[key].name() != algo.key.as_ref() {
                key += 1
            }
            let next_kex = if key < config.keys.len() {
                Kex::KexDh(KexDh {
                    exchange: self.exchange,
                    key: key,
                    names: algo,
                    session_id: self.session_id,
                })
            } else {
                return Err(Error::UnknownKey);
                return Err(Error::UnknownKey.into());
            };

            Ok(next_kex)
        } else {
            Ok(Kex::KexInit(self))
        }
    }

    pub fn server_write(
        &mut self,
        config: &Config,
        cipher: &CipherPair,
        write_buffer: &mut SSHBuffer,
    ) -> Result<(), Error> {
    ) -> Result<(), failure::Error> {
        self.exchange.server_kex_init.clear();
        negotiation::write_kex(&config.preferred, &mut self.exchange.server_kex_init)?;
        debug!("server kex init: {:?}", &self.exchange.server_kex_init[..]);
        self.sent = true;
        cipher.write(&self.exchange.server_kex_init, write_buffer);
        Ok(())
    }
}

impl KexDh {
    pub fn parse(
        mut self,
        config: &Config,
        buffer: &mut CryptoVec,
        buffer2: &mut CryptoVec,
        cipher: &CipherPair,
        buf: &[u8],
        write_buffer: &mut SSHBuffer,
    ) -> Result<Kex, Error> {
    ) -> Result<Kex, failure::Error> {
        debug!("KexDh: parse {:?}", self.names.ignore_guessed);
        if self.names.ignore_guessed {
            // If we need to ignore this packet.
            self.names.ignore_guessed = false;
            Ok(Kex::KexDh(self))
        } else {
            // Else, process it.
            debug!("buf = {:?}", buf);
            assert!(buf[0] == msg::KEX_ECDH_INIT);
            let mut r = buf.reader(1);
            self.exchange.client_ephemeral.extend(r.read_string()?);
            let kex = try!(kex::Algorithm::server_dh(
                self.names.kex,
                &mut self.exchange,
                buf,
            ));
            let kex = kex::Algorithm::server_dh(self.names.kex, &mut self.exchange, buf)?;
            // Then, we fill the write buffer right away, so that we
            // can output it immediately when the time comes.
            let kexdhdone = KexDhDone {
                exchange: self.exchange,
                kex: kex,
                key: self.key,
                names: self.names,
                session_id: self.session_id,
            };

            let hash = try!(kexdhdone.kex.compute_exchange_hash(
                &config.keys[kexdhdone.key],
                &kexdhdone.exchange,
                buffer,
            ));
            debug!("exchange hash: {:?}", hash);
            buffer.clear();
            buffer.push(msg::KEX_ECDH_REPLY);
            config.keys[kexdhdone.key].push_to(buffer);
            // Server ephemeral
            buffer.extend_ssh_string(&kexdhdone.exchange.server_ephemeral);
            // Hash signature
            debug!(" >>>>>>>>>>>>>>> signing with key {:?}", kexdhdone.key);
            debug!("hash: {:?}", hash);
            debug!("key: {:?}", config.keys[kexdhdone.key]);
            config.keys[kexdhdone.key].add_signature(buffer, &hash)?;
            cipher.write(&buffer, write_buffer);

            cipher.write(&[msg::NEWKEYS], write_buffer);
            let hash: Result<openssl::hash::DigestBytes, failure::Error> =
                HASH_BUF.with(|buffer| {
                    let mut buffer = buffer.borrow_mut();
                    buffer.clear();
                    debug!("server kexdhdone.exchange = {:?}", kexdhdone.exchange);
                    let hash = kexdhdone.kex.compute_exchange_hash(
                        &config.keys[kexdhdone.key],
                        &kexdhdone.exchange,
                        &mut buffer,
                    )?;
                    debug!("exchange hash: {:?}", hash);
                    buffer.clear();
                    buffer.push(msg::KEX_ECDH_REPLY);
                    config.keys[kexdhdone.key].push_to(&mut buffer);
                    // Server ephemeral
                    buffer.extend_ssh_string(&kexdhdone.exchange.server_ephemeral);
                    // Hash signature
                    debug!(" >>>>>>>>>>>>>>> signing with key {:?}", kexdhdone.key);
                    debug!("hash: {:?}", hash);
                    debug!("key: {:?}", config.keys[kexdhdone.key]);
                    config.keys[kexdhdone.key].add_signature(&mut buffer, &hash)?;
                    cipher.write(&buffer, write_buffer);
                    cipher.write(&[msg::NEWKEYS], write_buffer);
                    Ok(hash)
                });

            Ok(Kex::NewKeys(
                try!(kexdhdone.compute_keys(hash, buffer, buffer2, true)),
            ))
            Ok(Kex::NewKeys(kexdhdone.compute_keys(hash?, true)?))
        }
18
19


20
21
22
23
24



25






26
27
28
29
30
31


32
33

34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134



135
136

137
138
139

140
141
142

143
144
145
146

147
148
149
150

151
152
153
154

155
156
157
158
159
160

161
162
163
164
165
166
167
168
169

170
171
172
173
174
175
176
177
178
179
180
181

182
183
184
185
186
187
188
189
190
191

192
193
194
195
196
197
198
199
200
201

202
203
204
205
206
207

208
209
210
211
212
213

214
215
216
217
218
219
220
221
222
223
224

225
226
227
228

229
230
231
232
233
234
235
236

237
238
239
240
241
242

243
244
245
246
247
248
249
250

251
252
253
254
255
256
257
258
259
260

261
262
263
264

265
266
267
268
269
270
271
272
273

274
275
276

277
278
279
280
281
282
283
284
285

286
287
288
289
290
291
292
293

294
295
296
297
298
299
300
301

302
303
304
305
306
307

308
309
310
311
312
313
314
315
316
317

318
319
320
321

322
323
324
325
326
327
328

329
330
331
332
333
334
335

336
337
338
339
340
341
342
343
344
345
346
347
348

349
350
351

352
353
354
355
356
357
358
359

360
361
362
363
364
365

366
367
368
369
370
371
372
373

374
375
376
377
378
379
380
381
382
383
384
385


386
387
388
389
390
391
392
393
394
395
396


397
398
399
400
401
402
403
404
405
406
407
408
409

410
411

412
413








414
415
416
417
418
419
420
421
422
423

424
425
426
427
428
429
430
431
432
433
434
435
436
437
438







439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
use std::sync::Arc;

use futures::stream::Stream;
use futures::{Poll, Async};
use futures::future::Future;
use futures::stream::TryStreamExt;
use thrussh_keys::key;
use tokio::io::{AsyncRead, AsyncWrite, AsyncWriteExt};
use tokio::net::TcpListener;
use tokio::io::{AsyncRead, AsyncWrite};
use tokio::io::{flush, Flush, WriteAll};
use thrussh_keys::key;

use super::*;
use sshbuffer::*;
use negotiation;

use session::*;
use auth;
use crate::negotiation::Select;
use crate::session::*;
use crate::ssh_read::*;
use crate::sshbuffer::*;
use crate::*;

mod encrypted;
mod connection;
mod kex;
mod session;
pub use self::connection::*;
pub use self::kex::*;
pub use self::session::*;
mod encrypted;

#[derive(Debug)]
/// Configuration of a server.
pub struct Config {
    /// The server ID string sent at the beginning of the protocol.
    pub server_id: String,
    /// Authentication methods proposed to the client.
    pub methods: auth::MethodSet,
    /// The authentication banner, usually a warning message shown to the client.
    pub auth_banner: Option<&'static str>,
    /// Authentication rejections must happen in constant time for
    /// security reasons. Thrussh does not handle this by default.
    pub auth_rejection_time: std::time::Duration,
    /// The server's keys. The first key pair in the client's preference order will be chosen.
    pub keys: Vec<key::KeyPair>,
    /// The bytes and time limits before key re-exchange.
    pub limits: Limits,
    /// The initial size of a channel (used for flow control).
    pub window_size: u32,
    /// The maximal size of a single packet.
    pub maximum_packet_size: u32,
    /// Lists of preferred algorithms.
    pub preferred: Preferred,
    /// Maximal number of allowed authentication attempts.
    pub max_auth_attempts: usize,
    /// Time after which the connection is garbage-collected.
    pub connection_timeout: Option<std::time::Duration>,
}

impl Default for Config {
    fn default() -> Config {
        Config {
            server_id: format!(
                "SSH-2.0-{}_{}",
                env!("CARGO_PKG_NAME"),
                env!("CARGO_PKG_VERSION")
            ),
            methods: auth::MethodSet::all(),
            auth_banner: None,
            auth_rejection_time: std::time::Duration::from_secs(1),
            keys: Vec::new(),
            window_size: 200000,
            maximum_packet_size: 200000,
            limits: Limits::default(),
            preferred: Default::default(),
            max_auth_attempts: 10,
            connection_timeout: Some(std::time::Duration::from_secs(600)),
        }
    }
}

/// A client's response in a challenge-response authentication.
#[derive(Debug)]
pub struct Response<'a> {
    pos: thrussh_keys::encoding::Position<'a>,
    n: u32,
}

impl<'a> Iterator for Response<'a> {
    type Item = &'a [u8];
    fn next(&mut self) -> Option<Self::Item> {
        if self.n == 0 {
            None
        } else {
            self.n -= 1;
            self.pos.read_string().ok()
        }
    }
}

use std::borrow::Cow;
/// An authentication result, in a challenge-response authentication.
#[derive(Debug, PartialEq, Eq)]
pub enum Auth {
    /// Reject the authentication request.
    Reject,
    /// Accept the authentication request.
    Accept,

    /// Method was not accepted, but no other check was performed.
    UnsupportedMethod,

    /// Partially accept the challenge-response authentication
    /// request, providing more instructions for the client to follow.
    Partial {
        /// Name of this challenge.
        name: Cow<'static, str>,
        /// Instructions for this challenge.
        instructions: Cow<'static, str>,
        /// A number of prompts to the user. Each prompt has a `bool`
        /// indicating whether the terminal must echo the characters
        /// typed by the user.
        prompts: Cow<'static, [(Cow<'static, str>, bool)]>,
    },
}

/// Server handler. Each client will have their own handler.
pub trait Handler: Sized {
    /// The type of errors returned by the futures.
    type Error: std::error::Error + Send + Sync;

    /// The type of authentications, which can be a future ultimately
    /// resolving to
    type FutureAuth: Future<Item = (Self, Auth), Error = Self::Error> + Send;
    type FutureAuth: Future<Output = Result<Auth, failure::Error>> + Send;

    /// The type of units returned by some parts of this handler.
    type FutureUnit: Future<Item = (Self, Session), Error = Self::Error> + Send;
    type FutureUnit: Future<Output = Result<(), failure::Error>> + Send;

    /// The type of future bools returned by some parts of this handler.
    type FutureBool: Future<Item = (Self, Session, bool), Error = Self::Error> + Send;
    type FutureBool: Future<Output = Result<bool, failure::Error>> + Send;

    /// Convert an `Auth` to `Self::FutureAuth`. This is used to
    /// produce the default handlers.
    fn finished_auth(self, auth: Auth) -> Self::FutureAuth;
    fn finished_auth(&mut self, auth: Auth) -> Self::FutureAuth;

    /// Convert a `bool` to `Self::FutureBool`. This is used to
    /// produce the default handlers.
    fn finished_bool(self, session: Session, b: bool) -> Self::FutureBool;
    fn finished_bool(&mut self, b: bool, session: &mut Session) -> Self::FutureBool;

    /// Produce a `Self::FutureUnit`. This is used to produce the
    /// default handlers.
    fn finished(self, session: Session) -> Self::FutureUnit;
    fn finished(&mut self, session: &mut Session) -> Self::FutureUnit;

    /// Check authentication using the "none" method. Thrussh makes
    /// sure rejection happens in time `config.auth_rejection_time`,
    /// except if this method takes more than that.
    #[allow(unused_variables)]
    fn auth_none(self, user: &str) -> Self::FutureAuth {
    fn auth_none(&mut self, user: &str) -> Self::FutureAuth {
        self.finished_auth(Auth::Reject)
    }

    /// Check authentication using the "password" method. Thrussh
    /// makes sure rejection happens in time
    /// `config.auth_rejection_time`, except if this method takes more
    /// than that.
    #[allow(unused_variables)]
    fn auth_password(self, user: &str, password: &str) -> Self::FutureAuth {
    fn auth_password(&mut self, user: &str, password: &str) -> Self::FutureAuth {
        self.finished_auth(Auth::Reject)
    }

    /// Check authentication using the "publickey" method. This method
    /// should just check whether the public key matches the
    /// authorized ones. Thrussh then checks the signature. If the key
    /// is unknown, or the signature is invalid, Thrussh guarantees
    /// that rejection happens in constant time
    /// `config.auth_rejection_time`, except if this method takes more
    /// time than that.
    #[allow(unused_variables)]
    fn auth_publickey(self, user: &str, public_key: &key::PublicKey) -> Self::FutureAuth {
    fn auth_publickey(&mut self, user: &str, public_key: &key::PublicKey) -> Self::FutureAuth {
        self.finished_auth(Auth::Reject)
    }

    /// Check authentication using the "keyboard-interactive"
    /// method. Thrussh makes sure rejection happens in time
    /// `config.auth_rejection_time`, except if this method takes more
    /// than that.
    #[allow(unused_variables)]
    fn auth_keyboard_interactive(
        self,
        &mut self,
        user: &str,
        submethods: &str,
        response: Option<Response>,
    ) -> Self::FutureAuth {
        self.finished_auth(Auth::Reject)
    }

    /// Called when the client closes a channel.
    #[allow(unused_variables)]
    fn channel_close(self, channel: ChannelId, session: Session) -> Self::FutureUnit {
    fn channel_close(&mut self, channel: ChannelId, session: &mut Session) -> Self::FutureUnit {
        self.finished(session)
    }

    /// Called when the client sends EOF to a channel.
    #[allow(unused_variables)]
    fn channel_eof(self, channel: ChannelId, session: Session) -> Self::FutureUnit {
    fn channel_eof(&mut self, channel: ChannelId, session: &mut Session) -> Self::FutureUnit {
        self.finished(session)
    }

    /// Called when a new session channel is created.
    #[allow(unused_variables)]
    fn channel_open_session(self, channel: ChannelId, session: Session) -> Self::FutureUnit {
    fn channel_open_session(
        &mut self,
        channel: ChannelId,
        session: &mut Session,
    ) -> Self::FutureUnit {
        self.finished(session)
    }

    /// Called when a new X11 channel is created.
    #[allow(unused_variables)]
    fn channel_open_x11(
        self,
        &mut self,
        channel: ChannelId,
        originator_address: &str,
        originator_port: u32,
        session: Session,
        session: &mut Session,
    ) -> Self::FutureUnit {
        self.finished(session)
    }

    /// Called when a new channel is created.
    #[allow(unused_variables)]
    fn channel_open_direct_tcpip(
        self,
        &mut self,
        channel: ChannelId,
        host_to_connect: &str,
        port_to_connect: u32,
        originator_address: &str,
        originator_port: u32,
        session: Session,
        session: &mut Session,
    ) -> Self::FutureUnit {
        self.finished(session)
    }

    /// Called when a data packet is received. A response can be
    /// written to the `response` argument.
    #[allow(unused_variables)]
    fn data(self, channel: ChannelId, data: &[u8], session: Session) -> Self::FutureUnit {
    fn data(&mut self, channel: ChannelId, data: &[u8], session: &mut Session) -> Self::FutureUnit {
        self.finished(session)
    }

    /// Called when an extended data packet is received. Code 1 means
    /// that this packet comes from stderr, other codes are not
    /// defined (see
    /// [RFC4254](https://tools.ietf.org/html/rfc4254#section-5.2)).
    #[allow(unused_variables)]
    fn extended_data(
        self,
        &mut self,
        channel: ChannelId,
        code: u32,
        data: &[u8],
        session: Session,
        session: &mut Session,
    ) -> Self::FutureUnit {
        self.finished(session)
    }

    /// Called when the network window is adjusted, meaning that we
    /// can send more bytes.
    #[allow(unused_variables)]
    fn window_adjusted(
        self,
        &mut self,
        channel: ChannelId,
        new_window_size: usize,
        session: Session,
        session: &mut Session,
    ) -> Self::FutureUnit {
        self.finished(session)
    }

    /// The client requests a pseudo-terminal with the given
    /// specifications.
    #[allow(unused_variables)]
    fn pty_request(
        self,
        &mut self,
        channel: ChannelId,
        term: &str,
        col_width: u32,
        row_height: u32,
        pix_width: u32,
        pix_height: u32,
        modes: &[(Pty, u32)],
        session: Session,
        session: &mut Session,
    ) -> Self::FutureUnit {
        self.finished(session)
    }

    /// The client requests an X11 connection.
    #[allow(unused_variables)]
    fn x11_request(
        self,
        &mut self,
        channel: ChannelId,
        single_connection: bool,
        x11_auth_protocol: &str,
        x11_auth_cookie: &str,
        x11_screen_number: u32,
        session: Session,
        session: &mut Session,
    ) -> Self::FutureUnit {
        self.finished(session)
    }

    /// The client wants to set the given environment variable. Check
    /// these carefully, as it is dangerous to allow any variable
    /// environment to be set.
    #[allow(unused_variables)]
    fn env_request(
        self,
        &mut self,
        channel: ChannelId,
        variable_name: &str,
        variable_value: &str,
        session: Session,
        session: &mut Session,
    ) -> Self::FutureUnit {
        self.finished(session)
    }

    /// The client requests a shell.
    #[allow(unused_variables)]
    fn shell_request(self, channel: ChannelId, session: Session) -> Self::FutureUnit {
    fn shell_request(&mut self, channel: ChannelId, session: &mut Session) -> Self::FutureUnit {
        self.finished(session)
    }

    /// The client sends a command to execute, to be passed to a
    /// shell. Make sure to check the command before doing so.
    #[allow(unused_variables)]
    fn exec_request(self, channel: ChannelId, data: &[u8], session: Session) -> Self::FutureUnit {
    fn exec_request(
        &mut self,
        channel: ChannelId,
        data: &[u8],
        session: &mut Session,
    ) -> Self::FutureUnit {
        self.finished(session)
    }

    /// The client asks to start the subsystem with the given name
    /// (such as sftp).
    #[allow(unused_variables)]
    fn subsystem_request(
        self,
        &mut self,
        channel: ChannelId,
        name: &str,
        session: Session,
        session: &mut Session,
    ) -> Self::FutureUnit {
        self.finished(session)
    }

    /// The client's pseudo-terminal window size has changed.
    #[allow(unused_variables)]
    fn window_change_request(
        self,
        &mut self,
        channel: ChannelId,
        col_width: u32,
        row_height: u32,
        pix_width: u32,
        pix_height: u32,
        session: Session,
        session: &mut Session,
    ) -> Self::FutureUnit {
        self.finished(session)
    }

    /// The client is sending a signal (usually to pass to the
    /// currently running process).
    #[allow(unused_variables)]
    fn signal(self, channel: ChannelId, signal_name: Sig, session: Session) -> Self::FutureUnit {
    fn signal(
        &mut self,
        channel: ChannelId,
        signal_name: Sig,
        session: &mut Session,
    ) -> Self::FutureUnit {
        self.finished(session)
    }

    /// Used for reverse-forwarding ports, see
    /// [RFC4254](https://tools.ietf.org/html/rfc4254#section-7).
    #[allow(unused_variables)]
    fn tcpip_forward(self, address: &str, port: u32, session: Session) -> Self::FutureBool {
        self.finished_bool(session, false)
    fn tcpip_forward(
        &mut self,
        address: &str,
        port: u32,
        session: &mut Session,
    ) -> Self::FutureBool {
        self.finished_bool(false, session)
    }
    /// Used to stop the reverse-forwarding of a port, see
    /// [RFC4254](https://tools.ietf.org/html/rfc4254#section-7).
    #[allow(unused_variables)]
    fn cancel_tcpip_forward(self, address: &str, port: u32, session: Session) -> Self::FutureBool {
        self.finished_bool(session, false)
    fn cancel_tcpip_forward(
        &mut self,
        address: &str,
        port: u32,
        session: &mut Session,
    ) -> Self::FutureBool {
        self.finished_bool(false, session)
    }
}

/// Trait used to create new handlers when clients connect.
pub trait Server {
    /// The type of handlers.
    type Handler: Handler+Send;
    type Handler: Handler + Send;
    /// Called when a new client connects.
    fn new(&mut self) -> Self::Handler;
    fn new(&mut self, peer_addr: Option<std::net::SocketAddr>) -> Self::Handler;
}

/// Run a server. This function returns a future, which needs to be
/// run by a Tokio event loop:
///
/// ```
/// tokio::run(run(config, "0.0.0.0:2222", my_server));
/// ```
pub fn run<H: Server + Send + 'static>(config: Arc<Config>, addr: &str, mut server: H) -> impl Future<Item = (), Error = std::io::Error> {

/// Run a server.
/// Create a new `Connection` from the server's configuration, a
/// stream and a [`Handler`](trait.Handler.html).
pub async fn run<H: Server + Send + 'static>(
    config: Arc<Config>,
    addr: &str,
    mut server: H,
) -> Result<(), std::io::Error> {
    let addr = addr.to_socket_addrs().unwrap().next().unwrap();
    let socket = TcpListener::bind(&addr).unwrap();
    let mut socket = TcpListener::bind(&addr).await?;
    socket
        .incoming()
        .try_for_each(move |socket| {
            let config = config.clone();
            let server = server.new(socket.peer_addr().ok());
            async move {
                tokio::spawn(run_stream(config, socket, server));
                Ok(())
            }
        })
        .await?;
    Ok(())
}

    socket.incoming().for_each(move |socket| {
        let handler = server.new();
        let handler = server.new();
        let connection = Connection::new(config.clone(), socket, handler).unwrap();
        tokio::spawn(Box::new(connection.map_err(|err|  println!("err {:?}", err))));
        Ok(())
        Ok(())
use std::cell::RefCell;
thread_local! {
    static B1: RefCell<CryptoVec> = RefCell::new(CryptoVec::new());
    static B2: RefCell<CryptoVec> = RefCell::new(CryptoVec::new());
}

pub async fn timeout(instant: tokio::time::Instant, delay: Option<std::time::Duration>) {
    if delay.is_some() {
        tokio::time::delay_until(instant).await
    } else {
        futures::future::pending().await
    };
}

pub async fn run_stream<H: Handler, R>(
    config: Arc<Config>,
    mut stream: R,
    mut handler: H,
) -> Result<(), failure::Error>
where
    R: AsyncRead + AsyncWrite + Tcp + Unpin,
{
    let delay = config.connection_timeout;
    // Writing SSH id.
    let mut write_buffer = SSHBuffer::new();
    write_buffer.send_ssh_id(config.as_ref().server_id.as_bytes());
    stream.write_all(&write_buffer.buffer[..]).await?;

    // Reading SSH id and allocating a session.
    let mut stream = SshRead::new(&mut stream);
    let common = read_ssh_id(config, &mut stream).await?;
    let (sender, receiver) = tokio::sync::mpsc::channel(10);
    let mut session = Session {
        common,
        receiver,
        sender: server::session::Handle { sender },
    };
    session.flush()?;
    stream
        .write_all(&session.common.write_buffer.buffer)
        .await?;
    session.common.write_buffer.buffer.clear();
    let mut buffer = SSHBuffer::new();

    let mut instant = tokio::time::Instant::now();
    while !session.common.disconnected {
        tokio::select! {
            _ = cipher::read(&mut stream, &mut buffer, &session.common.cipher) => {
                if buffer.buffer.len() < 5 || buffer.buffer[5] == crate::msg::DISCONNECT {
                    break;
                } else if buffer.buffer[5] <= 4 {
                    continue;
                }
                debug!("buffer = {:?}", &buffer.buffer[..]);
                reply(&mut session, &mut handler, &buffer.buffer[5..]).await?;
                if let Some(delay) = delay {
                    instant = tokio::time::Instant::now() + delay
                }
            }
            _ = timeout(instant, delay) => break,
            msg = session.receiver.recv() => {
                match msg {
                    Some((id, ChannelMsg::Data { data })) => {
                        session.data(id, &data);
                    }
                    Some((id, ChannelMsg::ExtendedData { ext, data })) => {
                        session.extended_data(id, ext, &data);